brkraw 0.3.11__py3-none-any.whl → 0.5.0__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.
- brkraw/__init__.py +9 -3
- brkraw/apps/__init__.py +12 -0
- brkraw/apps/addon/__init__.py +30 -0
- brkraw/apps/addon/core.py +35 -0
- brkraw/apps/addon/dependencies.py +402 -0
- brkraw/apps/addon/installation.py +500 -0
- brkraw/apps/addon/io.py +21 -0
- brkraw/apps/hook/__init__.py +25 -0
- brkraw/apps/hook/core.py +636 -0
- brkraw/apps/loader/__init__.py +10 -0
- brkraw/apps/loader/core.py +622 -0
- brkraw/apps/loader/formatter.py +288 -0
- brkraw/apps/loader/helper.py +797 -0
- brkraw/apps/loader/info/__init__.py +11 -0
- brkraw/apps/loader/info/scan.py +85 -0
- brkraw/apps/loader/info/scan.yaml +90 -0
- brkraw/apps/loader/info/study.py +69 -0
- brkraw/apps/loader/info/study.yaml +156 -0
- brkraw/apps/loader/info/transform.py +92 -0
- brkraw/apps/loader/types.py +220 -0
- brkraw/cli/__init__.py +5 -0
- brkraw/cli/commands/__init__.py +2 -0
- brkraw/cli/commands/addon.py +327 -0
- brkraw/cli/commands/config.py +205 -0
- brkraw/cli/commands/convert.py +903 -0
- brkraw/cli/commands/hook.py +348 -0
- brkraw/cli/commands/info.py +74 -0
- brkraw/cli/commands/init.py +214 -0
- brkraw/cli/commands/params.py +106 -0
- brkraw/cli/commands/prune.py +288 -0
- brkraw/cli/commands/session.py +371 -0
- brkraw/cli/hook_args.py +80 -0
- brkraw/cli/main.py +83 -0
- brkraw/cli/utils.py +60 -0
- brkraw/core/__init__.py +13 -0
- brkraw/core/config.py +380 -0
- brkraw/core/entrypoints.py +25 -0
- brkraw/core/formatter.py +367 -0
- brkraw/core/fs.py +495 -0
- brkraw/core/jcamp.py +600 -0
- brkraw/core/layout.py +451 -0
- brkraw/core/parameters.py +781 -0
- brkraw/core/zip.py +1121 -0
- brkraw/dataclasses/__init__.py +14 -0
- brkraw/dataclasses/node.py +139 -0
- brkraw/dataclasses/reco.py +33 -0
- brkraw/dataclasses/scan.py +61 -0
- brkraw/dataclasses/study.py +131 -0
- brkraw/default/__init__.py +3 -0
- brkraw/default/pruner_specs/deid4share.yaml +42 -0
- brkraw/default/rules/00_default.yaml +4 -0
- brkraw/default/specs/metadata_dicom.yaml +236 -0
- brkraw/default/specs/metadata_transforms.py +92 -0
- brkraw/resolver/__init__.py +7 -0
- brkraw/resolver/affine.py +539 -0
- brkraw/resolver/datatype.py +69 -0
- brkraw/resolver/fid.py +90 -0
- brkraw/resolver/helpers.py +36 -0
- brkraw/resolver/image.py +188 -0
- brkraw/resolver/nifti.py +370 -0
- brkraw/resolver/shape.py +235 -0
- brkraw/schema/__init__.py +3 -0
- brkraw/schema/context_map.yaml +62 -0
- brkraw/schema/meta.yaml +57 -0
- brkraw/schema/niftiheader.yaml +95 -0
- brkraw/schema/pruner.yaml +55 -0
- brkraw/schema/remapper.yaml +128 -0
- brkraw/schema/rules.yaml +154 -0
- brkraw/specs/__init__.py +10 -0
- brkraw/specs/hook/__init__.py +12 -0
- brkraw/specs/hook/logic.py +31 -0
- brkraw/specs/hook/validator.py +22 -0
- brkraw/specs/meta/__init__.py +5 -0
- brkraw/specs/meta/validator.py +156 -0
- brkraw/specs/pruner/__init__.py +15 -0
- brkraw/specs/pruner/logic.py +361 -0
- brkraw/specs/pruner/validator.py +119 -0
- brkraw/specs/remapper/__init__.py +27 -0
- brkraw/specs/remapper/logic.py +924 -0
- brkraw/specs/remapper/validator.py +314 -0
- brkraw/specs/rules/__init__.py +6 -0
- brkraw/specs/rules/logic.py +263 -0
- brkraw/specs/rules/validator.py +103 -0
- brkraw-0.5.0.dist-info/METADATA +81 -0
- brkraw-0.5.0.dist-info/RECORD +88 -0
- {brkraw-0.3.11.dist-info → brkraw-0.5.0.dist-info}/WHEEL +1 -2
- brkraw-0.5.0.dist-info/entry_points.txt +13 -0
- brkraw/lib/__init__.py +0 -4
- brkraw/lib/backup.py +0 -641
- brkraw/lib/bids.py +0 -0
- brkraw/lib/errors.py +0 -125
- brkraw/lib/loader.py +0 -1220
- brkraw/lib/orient.py +0 -194
- brkraw/lib/parser.py +0 -48
- brkraw/lib/pvobj.py +0 -301
- brkraw/lib/reference.py +0 -245
- brkraw/lib/utils.py +0 -471
- brkraw/scripts/__init__.py +0 -0
- brkraw/scripts/brk_backup.py +0 -106
- brkraw/scripts/brkraw.py +0 -744
- brkraw/ui/__init__.py +0 -0
- brkraw/ui/config.py +0 -17
- brkraw/ui/main_win.py +0 -214
- brkraw/ui/previewer.py +0 -225
- brkraw/ui/scan_info.py +0 -72
- brkraw/ui/scan_list.py +0 -73
- brkraw/ui/subj_info.py +0 -128
- brkraw-0.3.11.dist-info/METADATA +0 -25
- brkraw-0.3.11.dist-info/RECORD +0 -28
- brkraw-0.3.11.dist-info/entry_points.txt +0 -3
- brkraw-0.3.11.dist-info/top_level.txt +0 -2
- tests/__init__.py +0 -0
- {brkraw-0.3.11.dist-info → brkraw-0.5.0.dist-info/licenses}/LICENSE +0 -0
brkraw/ui/__init__.py
DELETED
|
File without changes
|
brkraw/ui/config.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
if sys.platform == 'darwin':
|
|
3
|
-
font = 'arial 14'
|
|
4
|
-
button_size = 10
|
|
5
|
-
else:
|
|
6
|
-
font = 'arial 10'
|
|
7
|
-
button_size = 12
|
|
8
|
-
win_pre_width = 250
|
|
9
|
-
win_pst_width = 1050
|
|
10
|
-
win_pre_height = 40
|
|
11
|
-
win_pst_height = 680
|
|
12
|
-
|
|
13
|
-
window_posx = 100
|
|
14
|
-
window_posy = 100
|
|
15
|
-
|
|
16
|
-
viewer_width = 400
|
|
17
|
-
viewer_height = 400
|
brkraw/ui/main_win.py
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
|
-
from tkinter import filedialog
|
|
3
|
-
from brkraw import __version__, load
|
|
4
|
-
from .scan_list import ScanList
|
|
5
|
-
from .scan_info import ScanInfo
|
|
6
|
-
from .subj_info import SubjInfo
|
|
7
|
-
from .previewer import Previewer
|
|
8
|
-
from .config import win_pre_width as _width, win_pre_height as _height
|
|
9
|
-
from .config import win_pst_width, win_pst_height
|
|
10
|
-
from .config import window_posx, window_posy
|
|
11
|
-
|
|
12
|
-
class MainWindow(tk.Tk):
|
|
13
|
-
def __init__(self, *args, **kwargs):
|
|
14
|
-
super(MainWindow, self).__init__(*args, **kwargs)
|
|
15
|
-
self._raw = None
|
|
16
|
-
self._ignore_slope = False
|
|
17
|
-
self._ignore_offset = False
|
|
18
|
-
self._scan_id = None
|
|
19
|
-
self._reco_id = None
|
|
20
|
-
self._output = None
|
|
21
|
-
self.title('BrkRaw GUI - v{}'.format(__version__))
|
|
22
|
-
|
|
23
|
-
# initiated windows size and location
|
|
24
|
-
self.geometry('{}x{}+{}+{}'.format(_width, _height,
|
|
25
|
-
window_posx, window_posy))
|
|
26
|
-
# minimal size
|
|
27
|
-
self.minsize(_width, _height)
|
|
28
|
-
self.maxsize(_width, _height)
|
|
29
|
-
|
|
30
|
-
self._init_layout()
|
|
31
|
-
|
|
32
|
-
def open_filediag(self):
|
|
33
|
-
self._path = filedialog.askopenfilename(
|
|
34
|
-
initialdir = ".",
|
|
35
|
-
title = "Select file",
|
|
36
|
-
filetypes = (("Zip compressed", "*.zip"),
|
|
37
|
-
("Paravision 6 format", "*.PVdatasets"),
|
|
38
|
-
))
|
|
39
|
-
self._extend_layout()
|
|
40
|
-
self._load_dataset()
|
|
41
|
-
|
|
42
|
-
def open_dirdiag(self):
|
|
43
|
-
self._path = filedialog.askdirectory(
|
|
44
|
-
initialdir = ".",
|
|
45
|
-
title = "Select directory")
|
|
46
|
-
self._extend_layout()
|
|
47
|
-
self._load_dataset()
|
|
48
|
-
|
|
49
|
-
def _init_layout(self):
|
|
50
|
-
# level 1
|
|
51
|
-
self._subj_info = SubjInfo(self)
|
|
52
|
-
self._subj_info.pack(
|
|
53
|
-
side=tk.TOP, fill=tk.X, anchor=tk.CENTER)
|
|
54
|
-
|
|
55
|
-
# Button binding
|
|
56
|
-
self._subj_info._loadfile.config(command=self.open_filediag)
|
|
57
|
-
self._subj_info._loaddir.config(command=self.open_dirdiag)
|
|
58
|
-
|
|
59
|
-
def _close(self):
|
|
60
|
-
if self._raw != None:
|
|
61
|
-
self.geometry('{}x{}+{}+{}'.format(_width, _height,
|
|
62
|
-
window_posx, window_posy))
|
|
63
|
-
|
|
64
|
-
# close opened frames
|
|
65
|
-
self._subj_info._clean_path()
|
|
66
|
-
self._subj_info._main_frame.destroy()
|
|
67
|
-
self._subj_info._path.destroy()
|
|
68
|
-
self._subj_info._path_label.destroy()
|
|
69
|
-
# self._subj_info._close.destroy()
|
|
70
|
-
self._subj_info._refresh.destroy()
|
|
71
|
-
self._main_frame.destroy()
|
|
72
|
-
|
|
73
|
-
self._raw.close()
|
|
74
|
-
self._raw = None
|
|
75
|
-
|
|
76
|
-
# minimal size
|
|
77
|
-
self.minsize(_width, _height)
|
|
78
|
-
self.maxsize(_width, _height)
|
|
79
|
-
|
|
80
|
-
def _extend_layout(self):
|
|
81
|
-
# Change windows size
|
|
82
|
-
self._close()
|
|
83
|
-
if len(self._path) != 0:
|
|
84
|
-
self.geometry('{}x{}+{}+{}'.format(win_pst_width, win_pst_height,
|
|
85
|
-
window_posx, window_posy))
|
|
86
|
-
self.minsize(win_pst_width, win_pst_height)
|
|
87
|
-
self.maxsize(win_pst_width, win_pst_height)
|
|
88
|
-
|
|
89
|
-
# extend level 1
|
|
90
|
-
self._subj_info._extend_layout()
|
|
91
|
-
# self._subj_info._close.config(command=self._close)
|
|
92
|
-
self._subj_info._refresh.config(command=self._refresh)
|
|
93
|
-
|
|
94
|
-
self._main_frame = tk.Frame(self)
|
|
95
|
-
self._main_frame.pack(
|
|
96
|
-
side=tk.BOTTOM, fill=tk.BOTH, expand=True)
|
|
97
|
-
|
|
98
|
-
# level 2
|
|
99
|
-
self._scan_list = ScanList(self._main_frame)
|
|
100
|
-
view_frame = tk.Frame(self._main_frame)
|
|
101
|
-
self._scan_list.pack(
|
|
102
|
-
side=tk.LEFT, fill=tk.BOTH)
|
|
103
|
-
view_frame.pack(
|
|
104
|
-
side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
105
|
-
|
|
106
|
-
# level 3
|
|
107
|
-
self._scan_info = ScanInfo(view_frame)
|
|
108
|
-
self._preview = Previewer(view_frame)
|
|
109
|
-
self._preview.pack(
|
|
110
|
-
side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
111
|
-
self._scan_info.pack(
|
|
112
|
-
side=tk.LEFT, fill=tk.BOTH, padx=10, pady=10)
|
|
113
|
-
self._bind_scanlist()
|
|
114
|
-
self._set_convert_button()
|
|
115
|
-
|
|
116
|
-
def _refresh(self):
|
|
117
|
-
self._close()
|
|
118
|
-
self._extend_layout()
|
|
119
|
-
self._load_dataset()
|
|
120
|
-
|
|
121
|
-
def _load_dataset(self):
|
|
122
|
-
if len(self._path) != 0:
|
|
123
|
-
self._raw = load(self._path)
|
|
124
|
-
self._init_update()
|
|
125
|
-
|
|
126
|
-
def _init_update(self):
|
|
127
|
-
# take first image from dataset
|
|
128
|
-
self._scan_id, recos = [v for i, v in enumerate(self._raw._avail.items()) if i == 0][0]
|
|
129
|
-
|
|
130
|
-
self._reco_id = recos[0]
|
|
131
|
-
# update subject info
|
|
132
|
-
self._subj_info.load_data(self._raw)
|
|
133
|
-
|
|
134
|
-
# update scan and reco listbox
|
|
135
|
-
self._scan_list.load_data(self._raw)
|
|
136
|
-
self._scan_list._update_recos(self._raw, self._scan_id)
|
|
137
|
-
|
|
138
|
-
# update scan info of first image
|
|
139
|
-
self._scan_info.load_data(self._raw, self._scan_id, self._reco_id)
|
|
140
|
-
|
|
141
|
-
# update preview of first image
|
|
142
|
-
self._preview.load_data(self._raw, self._scan_id, self._reco_id)
|
|
143
|
-
|
|
144
|
-
def _bind_scanlist(self):
|
|
145
|
-
self._scan_list._scanlist.bind('<<ListboxSelect>>', self._update_scanid)
|
|
146
|
-
self._scan_list._recolist.bind('<<ListboxSelect>>', self._update_recoid)
|
|
147
|
-
|
|
148
|
-
def _update_scanid(self, event):
|
|
149
|
-
w = event.widget
|
|
150
|
-
index = int(w.curselection()[0])
|
|
151
|
-
self._scan_id = self._raw._pvobj.avail_scan_id[index]
|
|
152
|
-
self._reco_id = self._raw._avail[self._scan_id][0]
|
|
153
|
-
self._scan_list._update_recos(self._raw, self._scan_id)
|
|
154
|
-
self._update_data()
|
|
155
|
-
|
|
156
|
-
def _update_recoid(self, event):
|
|
157
|
-
w = event.widget
|
|
158
|
-
index = int(w.curselection()[0])
|
|
159
|
-
self._reco_id = self._raw._avail[self._scan_id][index]
|
|
160
|
-
self._update_data()
|
|
161
|
-
|
|
162
|
-
def _update_data(self):
|
|
163
|
-
# update scan info of first image
|
|
164
|
-
self._scan_info.load_data(self._raw, self._scan_id, self._reco_id)
|
|
165
|
-
# update preview of first image
|
|
166
|
-
self._preview.load_data(self._raw, self._scan_id, self._reco_id)
|
|
167
|
-
|
|
168
|
-
def _set_convert_button(self):
|
|
169
|
-
self._scan_list._updt_bt.config(state=tk.NORMAL)
|
|
170
|
-
self._scan_list._conv_bt.config(state=tk.NORMAL)
|
|
171
|
-
self._scan_list._updt_bt.config(command=self._set_output)
|
|
172
|
-
self._scan_list._conv_bt.config(command=self._save_as)
|
|
173
|
-
|
|
174
|
-
def _set_output(self):
|
|
175
|
-
self._output = filedialog.askdirectory(initialdir=self._output,
|
|
176
|
-
title="Select Output Directory")
|
|
177
|
-
|
|
178
|
-
def _save_as(self):
|
|
179
|
-
date = self._raw.get_scan_time()['date'].strftime("%y%m%d")
|
|
180
|
-
pvobj = self._raw._pvobj
|
|
181
|
-
acqp = self._raw.get_acqp
|
|
182
|
-
this_acqp = acqp(self._scan_id)
|
|
183
|
-
scan_name = this_acqp.parameters['ACQ_scan_name']
|
|
184
|
-
scan_name = scan_name.replace(' ','-')
|
|
185
|
-
filename = '{}_{}_{}_{}_{}_{}_{}'.format(date,
|
|
186
|
-
pvobj.subj_id,
|
|
187
|
-
pvobj.session_id,
|
|
188
|
-
pvobj.study_id,
|
|
189
|
-
self._scan_id,
|
|
190
|
-
self._reco_id,
|
|
191
|
-
scan_name)
|
|
192
|
-
if self._ignore_slope:
|
|
193
|
-
slope = None
|
|
194
|
-
else:
|
|
195
|
-
slope = False
|
|
196
|
-
if self._ignore_offset:
|
|
197
|
-
offset = None
|
|
198
|
-
else:
|
|
199
|
-
offset = False
|
|
200
|
-
self._raw.save_as(self._scan_id, self._reco_id, filename,
|
|
201
|
-
dir=self._output, slope=slope, offset=offset)
|
|
202
|
-
method = self._raw._pvobj._method[self._scan_id].parameters['Method']
|
|
203
|
-
import re
|
|
204
|
-
if re.search('dti', method, re.IGNORECASE):
|
|
205
|
-
self._raw.save_bdata(self._scan_id, filename)
|
|
206
|
-
from tkinter import messagebox
|
|
207
|
-
messagebox.showinfo(title='File conversion',
|
|
208
|
-
message='{}/{}.nii.gz has been converted'.format(self._output,
|
|
209
|
-
filename))
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if __name__ == '__main__':
|
|
213
|
-
root = MainWindow()
|
|
214
|
-
root.mainloop()
|
brkraw/ui/previewer.py
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
|
-
from PIL import Image, ImageTk
|
|
3
|
-
import numpy as np
|
|
4
|
-
from .config import viewer_width, viewer_height
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class Previewer(tk.Frame):
|
|
8
|
-
def __init__(self, *args, **kwargs):
|
|
9
|
-
super(Previewer, self).__init__(*args, **kwargs)
|
|
10
|
-
# variables
|
|
11
|
-
self._dataobj = None
|
|
12
|
-
self._imgobj = None
|
|
13
|
-
self._is_tripilot = False
|
|
14
|
-
self._current_slice = 0
|
|
15
|
-
self._current_frame = 0
|
|
16
|
-
|
|
17
|
-
self.tkimg = None
|
|
18
|
-
self.slice_axis = tk.IntVar()
|
|
19
|
-
self.slice_axis.set(99)
|
|
20
|
-
|
|
21
|
-
self._set_axisbuttons()
|
|
22
|
-
self._set_canvas()
|
|
23
|
-
self._set_sliders()
|
|
24
|
-
|
|
25
|
-
def _set_canvas(self):
|
|
26
|
-
self._canvas = tk.Canvas(self,
|
|
27
|
-
width=viewer_width,
|
|
28
|
-
height=viewer_height)
|
|
29
|
-
self._canvas.place(x=50, y=30)
|
|
30
|
-
|
|
31
|
-
def _set_axisbuttons(self):
|
|
32
|
-
self._axis_buttons = []
|
|
33
|
-
|
|
34
|
-
tk.Label(self, text='Slice Axis::').place(x=50, y=5)
|
|
35
|
-
for i, axis in enumerate(['x', 'y', 'z']):
|
|
36
|
-
button = tk.Radiobutton(self,
|
|
37
|
-
text=axis,
|
|
38
|
-
padx=10,
|
|
39
|
-
variable=self.slice_axis,
|
|
40
|
-
command=self._change_sliceaxis,
|
|
41
|
-
value=i)
|
|
42
|
-
button.place(x=150 + i*50, y=5)
|
|
43
|
-
|
|
44
|
-
if self.slice_axis.get() == 99:
|
|
45
|
-
button['state'] = 'disabled'
|
|
46
|
-
self._axis_buttons.append(button)
|
|
47
|
-
|
|
48
|
-
def _set_sliders(self, n_slice=0, n_frame=0):
|
|
49
|
-
|
|
50
|
-
tk.Label(self, text='Slice').place(x=70, y=455)
|
|
51
|
-
tk.Label(self, text='Frame').place(x=70, y=495)
|
|
52
|
-
self.slice_slider = tk.Scale(self, from_=0, to=n_slice - 1,
|
|
53
|
-
orient=tk.HORIZONTAL,
|
|
54
|
-
command=self._change_slice, length=300)
|
|
55
|
-
|
|
56
|
-
self.frame_slider = tk.Scale(self, from_=0, to=n_frame - 1,
|
|
57
|
-
orient=tk.HORIZONTAL,
|
|
58
|
-
command=self._change_frame, length=300)
|
|
59
|
-
|
|
60
|
-
self.slice_slider.set(self._current_slice)
|
|
61
|
-
self.frame_slider.set(self._current_frame)
|
|
62
|
-
self.slice_slider.place(x=130, y=440)
|
|
63
|
-
self.frame_slider.place(x=130, y=480)
|
|
64
|
-
|
|
65
|
-
if n_slice == 0:
|
|
66
|
-
self.slice_slider.config(state=tk.DISABLED)
|
|
67
|
-
if n_frame == 0:
|
|
68
|
-
self.frame_slider.config(state=tk.DISABLED)
|
|
69
|
-
|
|
70
|
-
def update_image(self):
|
|
71
|
-
self._canvas.create_image((int(viewer_width / 2), int(viewer_height / 2)),
|
|
72
|
-
image=self.tkimg)
|
|
73
|
-
|
|
74
|
-
def _load_image(self, brkraw_obj, scan_id, reco_id):
|
|
75
|
-
from ..lib.utils import multiply_all
|
|
76
|
-
# update image when scan_id and reco_id is changed
|
|
77
|
-
visu_pars = brkraw_obj._get_visu_pars(scan_id, reco_id)
|
|
78
|
-
dataobj = brkraw_obj.get_dataobj(scan_id, reco_id, slope=False)
|
|
79
|
-
|
|
80
|
-
if len(dataobj.shape) > 3:
|
|
81
|
-
x, y, z = dataobj.shape[:3]
|
|
82
|
-
f = multiply_all(dataobj.shape[3:])
|
|
83
|
-
# all converted nifti must be 4D
|
|
84
|
-
self._dataobj = dataobj.reshape([x, y, z, f])[:,:,::-1, ...]
|
|
85
|
-
else:
|
|
86
|
-
self._dataobj = dataobj
|
|
87
|
-
|
|
88
|
-
# shape = brkraw_obj._get_matrix_size(visu_pars, dataobj)
|
|
89
|
-
# self._dataobj = dataobj.reshape(shape[::-1]).T[:,:,::-1, ...]
|
|
90
|
-
|
|
91
|
-
n_slicepacks = brkraw_obj._get_slice_info(visu_pars)['num_slice_packs']
|
|
92
|
-
spatial_info = brkraw_obj._get_spatial_info(visu_pars)
|
|
93
|
-
|
|
94
|
-
self._resol = spatial_info['spatial_resol']
|
|
95
|
-
self._matrix_size = spatial_info['matrix_size']
|
|
96
|
-
|
|
97
|
-
if n_slicepacks > 1:
|
|
98
|
-
self._is_tripilot = True
|
|
99
|
-
else:
|
|
100
|
-
self._is_tripilot = False
|
|
101
|
-
|
|
102
|
-
def _change_sliceaxis(self):
|
|
103
|
-
if self.slice_axis.get() in range(3):
|
|
104
|
-
self._imgobj = np.swapaxes(self._dataobj, axis1=self.slice_axis.get(), axis2=2)
|
|
105
|
-
shape = self._imgobj.shape
|
|
106
|
-
n_slice = shape[2]
|
|
107
|
-
|
|
108
|
-
self._current_slice = int(n_slice / 2)
|
|
109
|
-
self._current_frame = 0
|
|
110
|
-
|
|
111
|
-
shape = self._imgobj.shape
|
|
112
|
-
if len(shape) > 3:
|
|
113
|
-
n_frame = shape[3]
|
|
114
|
-
else:
|
|
115
|
-
n_frame = 0
|
|
116
|
-
n_slice = shape[2]
|
|
117
|
-
|
|
118
|
-
self._current_slice = int(n_slice / 2)
|
|
119
|
-
self._current_frame = 0
|
|
120
|
-
|
|
121
|
-
self._set_sliders(n_slice, n_frame)
|
|
122
|
-
|
|
123
|
-
def _convert_image(self):
|
|
124
|
-
if len(self._imgobj.shape) > 3:
|
|
125
|
-
img = self._imgobj[:,:,self._current_slice,self._current_frame]
|
|
126
|
-
else:
|
|
127
|
-
img = self._imgobj[:,:,self._current_slice]
|
|
128
|
-
|
|
129
|
-
slice_axis = self.slice_axis.get()
|
|
130
|
-
if slice_axis in range(3):
|
|
131
|
-
axis_ref = np.array([0, 1, 2])
|
|
132
|
-
axis_ref[slice_axis], axis_ref[2] = axis_ref[2], axis_ref[slice_axis]
|
|
133
|
-
|
|
134
|
-
self._img_resol = np.array(self._resol[0])[axis_ref]
|
|
135
|
-
self._img_size = np.array(self._matrix_size[0])[axis_ref]
|
|
136
|
-
else:
|
|
137
|
-
self._img_resol = np.array(self._resol[0])
|
|
138
|
-
self._img_size = np.array(self._matrix_size[0])
|
|
139
|
-
|
|
140
|
-
img_fov = self._img_resol.astype(float) * self._img_size.astype(float)
|
|
141
|
-
max_val = img_fov[:2].max()
|
|
142
|
-
img_fov /= max_val
|
|
143
|
-
img_fov *= 400
|
|
144
|
-
|
|
145
|
-
# check resolution
|
|
146
|
-
img_width, img_height = int(img_fov[0]), int(img_fov[1])
|
|
147
|
-
|
|
148
|
-
self.tkimg = self.convert_pil2tk(self.convert_npy2pil(img),
|
|
149
|
-
img_width, img_height)
|
|
150
|
-
|
|
151
|
-
def _change_slice(self, event):
|
|
152
|
-
self._current_slice = self.slice_slider.get()
|
|
153
|
-
self._convert_image()
|
|
154
|
-
self.update_image()
|
|
155
|
-
|
|
156
|
-
def _change_frame(self, event):
|
|
157
|
-
self._current_frame = self.frame_slider.get()
|
|
158
|
-
self._convert_image()
|
|
159
|
-
self.update_image()
|
|
160
|
-
|
|
161
|
-
def load_data(self, brkraw_obj, scan_id, reco_id):
|
|
162
|
-
# load image from dataset
|
|
163
|
-
self._load_image(brkraw_obj, scan_id, reco_id)
|
|
164
|
-
shape = self._dataobj.shape
|
|
165
|
-
if len(shape) > 3:
|
|
166
|
-
n_frame = shape[3]
|
|
167
|
-
else:
|
|
168
|
-
n_frame = 0
|
|
169
|
-
n_slice = shape[2]
|
|
170
|
-
|
|
171
|
-
self._current_slice = int(n_slice/2)
|
|
172
|
-
self._current_frame = 0
|
|
173
|
-
|
|
174
|
-
if self._is_tripilot:
|
|
175
|
-
self.slice_axis.set(99)
|
|
176
|
-
for button in self._axis_buttons:
|
|
177
|
-
button['state'] = 'disabled'
|
|
178
|
-
else:
|
|
179
|
-
for button in self._axis_buttons:
|
|
180
|
-
button['state'] = 'normal'
|
|
181
|
-
self.slice_axis.set(2)
|
|
182
|
-
self._set_sliders(n_slice, n_frame)
|
|
183
|
-
self._imgobj = self._dataobj
|
|
184
|
-
self._convert_image()
|
|
185
|
-
self.update_image()
|
|
186
|
-
|
|
187
|
-
@staticmethod
|
|
188
|
-
def convert_npy2pil(data, mode=None, rescale=True):
|
|
189
|
-
""" convert 2D numpy.array to PIL.Image object
|
|
190
|
-
|
|
191
|
-
Args:
|
|
192
|
-
data: 2D array data
|
|
193
|
-
mode: mode of image object
|
|
194
|
-
link=https://pillow.readthedocs.io/en/latest/handbook/concepts.html#modes
|
|
195
|
-
rescale: rescale value to 0~255
|
|
196
|
-
|
|
197
|
-
Returns: PIL.Image object
|
|
198
|
-
|
|
199
|
-
"""
|
|
200
|
-
if rescale == True:
|
|
201
|
-
rescaled_data = data / data.max() * 255
|
|
202
|
-
else:
|
|
203
|
-
rescaled_data = data
|
|
204
|
-
rescaled_data = rescaled_data.astype('uint8')
|
|
205
|
-
return Image.fromarray(rescaled_data.T, mode=mode)
|
|
206
|
-
|
|
207
|
-
@staticmethod
|
|
208
|
-
def convert_pil2tk(pilobj, width, height, method='nearest'):
|
|
209
|
-
""" convert PIL.Image object to tkinter.PhotoImage object
|
|
210
|
-
This will allow plotting image on Tk.Canvas
|
|
211
|
-
|
|
212
|
-
Args:
|
|
213
|
-
pilobj: 2D image object
|
|
214
|
-
width: width of the image
|
|
215
|
-
height: height of the image
|
|
216
|
-
method: Method for interpolation
|
|
217
|
-
|
|
218
|
-
Returns: TkImage object
|
|
219
|
-
|
|
220
|
-
"""
|
|
221
|
-
if method == 'nearest':
|
|
222
|
-
method = Image.NEAREST
|
|
223
|
-
else:
|
|
224
|
-
method = Image.ANTIALIAS
|
|
225
|
-
return ImageTk.PhotoImage(pilobj.resize((width, height), method))
|
brkraw/ui/scan_info.py
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
|
-
from .config import font
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ScanInfo(tk.Frame):
|
|
6
|
-
def __init__(self, *args, **kwargs):
|
|
7
|
-
super(ScanInfo, self).__init__(*args, **kwargs)
|
|
8
|
-
self.title = tk.Label(self, text='Selected Scan Info')
|
|
9
|
-
self.title.pack(side=tk.TOP, fill=tk.X)
|
|
10
|
-
self.textbox = tk.Text(self, width=30)
|
|
11
|
-
self.textbox.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
|
|
12
|
-
self.textbox.configure(font=font)
|
|
13
|
-
|
|
14
|
-
def load_data(self, brkraw_obj, scan_id, reco_id):
|
|
15
|
-
from brkraw.lib.utils import get_value, is_all_element_same
|
|
16
|
-
visu_pars = brkraw_obj._get_visu_pars(scan_id, reco_id)
|
|
17
|
-
self.textbox.config(state=tk.NORMAL)
|
|
18
|
-
self.textbox.delete('1.0', tk.END)
|
|
19
|
-
|
|
20
|
-
# RepetitionTime
|
|
21
|
-
tr = get_value(visu_pars, 'VisuAcqRepetitionTime')
|
|
22
|
-
tr = ','.join(map(str, tr)) if isinstance(tr, list) else tr
|
|
23
|
-
# EchoTime
|
|
24
|
-
te = get_value(visu_pars, 'VisuAcqEchoTime')
|
|
25
|
-
te = 0 if te is None else te
|
|
26
|
-
te = ','.join(map(str, te)) if isinstance(te, list) else te
|
|
27
|
-
# PixelBandwidth
|
|
28
|
-
pixel_bw = get_value(visu_pars, 'VisuAcqPixelBandwidth')
|
|
29
|
-
# FlipAngle
|
|
30
|
-
flip_angle = get_value(visu_pars, 'VisuAcqFlipAngle')
|
|
31
|
-
# Sequence and Protocol names
|
|
32
|
-
sequence_name = get_value(visu_pars, 'VisuAcqSequenceName')
|
|
33
|
-
protocol_name = get_value(visu_pars, 'VisuAcquisitionProtocol')
|
|
34
|
-
acqpars = brkraw_obj.get_acqp(int(scan_id))
|
|
35
|
-
scan_name = acqpars._parameters['ACQ_scan_name']
|
|
36
|
-
# Dimension
|
|
37
|
-
dim = brkraw_obj._get_dim_info(visu_pars)[0]
|
|
38
|
-
# MatrixSize
|
|
39
|
-
size = brkraw_obj._get_matrix_size(visu_pars)
|
|
40
|
-
size = ' x '.join(map(str, size))
|
|
41
|
-
# FOV size and resolution
|
|
42
|
-
spatial_info = brkraw_obj._get_spatial_info(visu_pars)
|
|
43
|
-
temp_info = brkraw_obj._get_temp_info(visu_pars)
|
|
44
|
-
s_resol = spatial_info['spatial_resol']
|
|
45
|
-
fov_size = spatial_info['fov_size']
|
|
46
|
-
fov_size = ' x '.join(map(str, fov_size))
|
|
47
|
-
s_unit = spatial_info['unit']
|
|
48
|
-
t_resol = '{0:.3f}'.format(temp_info['temporal_resol'])
|
|
49
|
-
t_unit = temp_info['unit']
|
|
50
|
-
s_resol = list(s_resol[0]) if is_all_element_same(s_resol) else s_resol
|
|
51
|
-
s_resol = ' x '.join(['{0:.3f}'.format(r) for r in s_resol])
|
|
52
|
-
# Number of slice packs
|
|
53
|
-
n_slicepacks = brkraw_obj._get_slice_info(visu_pars)['num_slice_packs']
|
|
54
|
-
|
|
55
|
-
# Printing out
|
|
56
|
-
self.textbox.insert(tk.END, 'Sequence:\n - {}\n'.format(sequence_name))
|
|
57
|
-
self.textbox.insert(tk.END, 'Protocol:\n - {}\n'.format(protocol_name))
|
|
58
|
-
self.textbox.insert(tk.END, 'Scan Name:\n - {}\n'.format(scan_name))
|
|
59
|
-
self.textbox.insert(tk.END, 'RepetitionTime:\n - {} msec\n'.format(tr))
|
|
60
|
-
self.textbox.insert(tk.END, 'EchoTime:\n - {} msec\n'.format(te))
|
|
61
|
-
self.textbox.insert(tk.END, 'FlipAngle:\n - {} degree\n\n'.format(flip_angle))
|
|
62
|
-
if isinstance(pixel_bw, float):
|
|
63
|
-
self.textbox.insert(tk.END, 'PixelBandwidth:\n - {0:.3f} Hz\n'.format(pixel_bw))
|
|
64
|
-
else:
|
|
65
|
-
self.textbox.insert(tk.END, 'PixelBandwidth:\n - {} Hz\n'.format(pixel_bw))
|
|
66
|
-
self.textbox.insert(tk.END, 'Dimension:\n - {}D\n'.format(dim))
|
|
67
|
-
self.textbox.insert(tk.END, 'Matrix size:\n - {}\n'.format(size))
|
|
68
|
-
self.textbox.insert(tk.END, 'Number of SlicePacks:\n - {}\n'.format(n_slicepacks))
|
|
69
|
-
self.textbox.insert(tk.END, 'FOV size:\n - {} (mm)\n\n'.format(fov_size))
|
|
70
|
-
self.textbox.insert(tk.END, 'Spatial resolution:\n - {} ({})\n'.format(s_resol, s_unit))
|
|
71
|
-
self.textbox.insert(tk.END, 'Temporal resolution:\n - {} ({})\n'.format(t_resol, t_unit))
|
|
72
|
-
self.textbox.config(state=tk.DISABLED)
|
brkraw/ui/scan_list.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import tkinter as tk
|
|
2
|
-
from .config import font
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ScanList(tk.Frame):
|
|
6
|
-
def __init__(self, *args, **kwargs):
|
|
7
|
-
super(ScanList, self).__init__(*args, **kwargs)
|
|
8
|
-
self._init_scanlist()
|
|
9
|
-
self._init_recolist()
|
|
10
|
-
self._init_buttons()
|
|
11
|
-
|
|
12
|
-
def _init_scanlist(self):
|
|
13
|
-
self._scanlist_label = tk.Label(self, text='Scan ID / Protocol')
|
|
14
|
-
self._scanlist_label.pack(side=tk.TOP, fill=tk.X, pady=5)
|
|
15
|
-
self._scanlist_frame = tk.Frame(self)
|
|
16
|
-
self._scanlist_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=10)
|
|
17
|
-
self._scanlist= tk.Listbox(self._scanlist_frame, width=30,
|
|
18
|
-
exportselection=False)
|
|
19
|
-
self._scanlist.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
20
|
-
self._set_scollbar(self._scanlist_frame, self._scanlist)
|
|
21
|
-
self._scanlist.config(font=font, state=tk.DISABLED)
|
|
22
|
-
self._scanlist_label.config(font=font)
|
|
23
|
-
|
|
24
|
-
def _init_recolist(self):
|
|
25
|
-
self._recolist_label = tk.Label(self, text='Reco ID / DataType')
|
|
26
|
-
self._recolist_label.pack(side=tk.TOP, fill=tk.X, pady=5)
|
|
27
|
-
self._recolist_frame = tk.Frame(self, height=5)
|
|
28
|
-
self._recolist_frame.pack(side=tk.TOP, fill=tk.BOTH, padx=10)
|
|
29
|
-
self._recolist = tk.Listbox(self._recolist_frame, width=30, height=5,
|
|
30
|
-
exportselection=False)
|
|
31
|
-
self._recolist.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
32
|
-
self._set_scollbar(self._recolist_frame, self._recolist)
|
|
33
|
-
self._recolist.config(font=font, state = tk.DISABLED)
|
|
34
|
-
self._recolist_label.config(font=font)
|
|
35
|
-
|
|
36
|
-
def _init_buttons(self):
|
|
37
|
-
self._button_fm = tk.Frame(self)
|
|
38
|
-
self._button_fm.pack(side=tk.TOP, fill=tk.X)
|
|
39
|
-
self._updt_bt = tk.Button(self._button_fm, text='SetOutput')
|
|
40
|
-
self._conv_bt = tk.Button(self._button_fm, text='Convert')
|
|
41
|
-
self._updt_bt.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
42
|
-
self._conv_bt.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
43
|
-
self._updt_bt.config(state=tk.DISABLED, font=font)
|
|
44
|
-
self._conv_bt.config(state=tk.DISABLED, font=font)
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def _set_scollbar(frame, listbox_obj):
|
|
48
|
-
scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL)
|
|
49
|
-
scrollbar.config(command=listbox_obj.yview)
|
|
50
|
-
scrollbar.pack(side=tk.RIGHT, fill="y")
|
|
51
|
-
listbox_obj.config(yscrollcommand=scrollbar.set)
|
|
52
|
-
|
|
53
|
-
def load_data(self, brkraw_obj):
|
|
54
|
-
from brkraw.lib.utils import get_value
|
|
55
|
-
self._scanlist.config(state=tk.NORMAL)
|
|
56
|
-
for scan_id, recos in brkraw_obj._avail.items():
|
|
57
|
-
visu_pars = brkraw_obj._get_visu_pars(scan_id, recos[0])
|
|
58
|
-
protocol_name = get_value(visu_pars, 'VisuAcquisitionProtocol')
|
|
59
|
-
self._scanlist.insert(tk.END, '{}::{}'.format(str(scan_id).zfill(3),
|
|
60
|
-
protocol_name))
|
|
61
|
-
self._scanlist.select_set(0)
|
|
62
|
-
|
|
63
|
-
def _update_recos(self, brkraw_obj, scan_id):
|
|
64
|
-
from brkraw.lib.utils import get_value
|
|
65
|
-
self._recolist.config(state=tk.NORMAL)
|
|
66
|
-
recos = brkraw_obj._avail[scan_id]
|
|
67
|
-
self._recolist.delete(0, tk.END)
|
|
68
|
-
for reco_id in recos:
|
|
69
|
-
visu_pars = brkraw_obj._get_visu_pars(scan_id, reco_id)
|
|
70
|
-
frame_type = get_value(visu_pars, 'VisuCoreFrameType')
|
|
71
|
-
self._recolist.insert(tk.END, '{}::{}'.format(str(reco_id).zfill(3),
|
|
72
|
-
frame_type))
|
|
73
|
-
self._recolist.select_set(0)
|