rapidtide 3.0a9__py3-none-any.whl → 3.0a10__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.
- rapidtide/OrthoImageItem.py +12 -3
- rapidtide/RapidtideDataset.py +33 -4
- rapidtide/tidepoolTemplate.py +0 -4
- rapidtide/tidepoolTemplate.ui +0 -7
- rapidtide/tidepoolTemplate_alt.py +3 -8
- rapidtide/tidepoolTemplate_alt.ui +6 -16
- rapidtide/tidepoolTemplate_alt_qt6.py +3 -8
- rapidtide/tidepoolTemplate_big.py +10 -15
- rapidtide/tidepoolTemplate_big.ui +14 -24
- rapidtide/tidepoolTemplate_big_qt6.py +10 -15
- rapidtide/tidepoolTemplate_qt6.py +0 -4
- rapidtide/workflows/tidepool.py +311 -186
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/METADATA +1 -1
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/RECORD +18 -19
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/WHEEL +1 -1
- rapidtide/tidepoolTemplate_alt2.ui +0 -1965
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/LICENSE +0 -0
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/entry_points.txt +0 -0
- {rapidtide-3.0a9.dist-info → rapidtide-3.0a10.dist-info}/top_level.txt +0 -0
rapidtide/workflows/tidepool.py
CHANGED
|
@@ -30,7 +30,6 @@ import pandas as pd
|
|
|
30
30
|
import pyqtgraph as pg
|
|
31
31
|
from nibabel.affines import apply_affine
|
|
32
32
|
from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
|
|
33
|
-
from statsmodels.robust.scale import mad
|
|
34
33
|
|
|
35
34
|
import rapidtide.util as tide_util
|
|
36
35
|
from rapidtide.Colortables import *
|
|
@@ -130,7 +129,86 @@ def _get_parser():
|
|
|
130
129
|
return parser
|
|
131
130
|
|
|
132
131
|
|
|
133
|
-
def
|
|
132
|
+
def addDataset(
|
|
133
|
+
thisdatafileroot,
|
|
134
|
+
anatname=None,
|
|
135
|
+
geommaskname=None,
|
|
136
|
+
userise=False,
|
|
137
|
+
usecorrout=True,
|
|
138
|
+
useatlas=False,
|
|
139
|
+
forcetr=False,
|
|
140
|
+
forceoffset=False,
|
|
141
|
+
offsettime=0.0,
|
|
142
|
+
ignoredimmatch=False,
|
|
143
|
+
):
|
|
144
|
+
global currentdataset, thesubjects, whichsubject, datafileroots
|
|
145
|
+
global verbosity
|
|
146
|
+
|
|
147
|
+
print("Loading", thisdatafileroot)
|
|
148
|
+
thissubject = RapidtideDataset(
|
|
149
|
+
"main",
|
|
150
|
+
thisdatafileroot,
|
|
151
|
+
anatname=anatname,
|
|
152
|
+
geommaskname=geommaskname,
|
|
153
|
+
userise=userise,
|
|
154
|
+
usecorrout=usecorrout,
|
|
155
|
+
useatlas=useatlas,
|
|
156
|
+
forcetr=forcetr,
|
|
157
|
+
forceoffset=forceoffset,
|
|
158
|
+
offsettime=offsettime,
|
|
159
|
+
verbose=verbosity,
|
|
160
|
+
)
|
|
161
|
+
if len(thesubjects) > 0:
|
|
162
|
+
# check to see that the dimensions match
|
|
163
|
+
dimmatch, sizematch, spacematch, affinematch = check_rt_spatialmatch(
|
|
164
|
+
thissubject, thesubjects[0]
|
|
165
|
+
)
|
|
166
|
+
if dimmatch or ignoredimmatch:
|
|
167
|
+
thesubjects.append(thissubject)
|
|
168
|
+
else:
|
|
169
|
+
print(f"dataset {thisdatafileroot} does not match loaded data - skipping")
|
|
170
|
+
else:
|
|
171
|
+
thesubjects.append(thissubject)
|
|
172
|
+
|
|
173
|
+
# list the datasets
|
|
174
|
+
for idx, subject in enumerate(thesubjects):
|
|
175
|
+
print(f"subject {idx}: {subject.fileroot}")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def updateFileMenu():
|
|
179
|
+
global thesubjects, whichsubject
|
|
180
|
+
global fileMenu, sel_open
|
|
181
|
+
global sel_files
|
|
182
|
+
|
|
183
|
+
if pyqtversion == 5:
|
|
184
|
+
qactionfunc = QtWidgets.QAction
|
|
185
|
+
else:
|
|
186
|
+
qactionfunc = QtGui.QAction
|
|
187
|
+
|
|
188
|
+
# scrub file menu
|
|
189
|
+
if sel_files is not None:
|
|
190
|
+
for sel_file in sel_files:
|
|
191
|
+
fileMenu.removeAction(sel_file)
|
|
192
|
+
del sel_file
|
|
193
|
+
|
|
194
|
+
# now build it back
|
|
195
|
+
if len(thesubjects) > 0:
|
|
196
|
+
sel_files = []
|
|
197
|
+
for idx, subject in enumerate(thesubjects):
|
|
198
|
+
if idx == whichsubject:
|
|
199
|
+
indicator = "\u2714 "
|
|
200
|
+
else:
|
|
201
|
+
indicator = " "
|
|
202
|
+
sel_files.append(qactionfunc(indicator + subject.fileroot, win))
|
|
203
|
+
sel_files[-1].triggered.connect(partial(selectDataset, idx))
|
|
204
|
+
fileMenu.addAction(sel_files[-1])
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def datasetPicker():
|
|
208
|
+
global currentdataset, thesubjects, whichsubject, datafileroots
|
|
209
|
+
global ui, win, defaultdict, overlagGraphicsViews
|
|
210
|
+
global verbosity
|
|
211
|
+
|
|
134
212
|
mydialog = QtWidgets.QFileDialog()
|
|
135
213
|
if pyqtversion == 5:
|
|
136
214
|
options = mydialog.Options()
|
|
@@ -146,7 +224,36 @@ def selectFile():
|
|
|
146
224
|
datafileroot = str(lagfilename[:bidsstartloc])
|
|
147
225
|
else:
|
|
148
226
|
datafileroot = str(lagfilename[: lagfilename.find("lagtimes.nii.gz")])
|
|
149
|
-
|
|
227
|
+
datafileroots.append(datafileroot)
|
|
228
|
+
addDataset(datafileroots[-1])
|
|
229
|
+
whichsubject = len(thesubjects) - 1
|
|
230
|
+
selectDataset(whichsubject)
|
|
231
|
+
|
|
232
|
+
# update the file menu
|
|
233
|
+
updateFileMenu()
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def selectDataset(thesubject):
|
|
237
|
+
global currentdataset, thesubjects, whichsubject, datafileroots
|
|
238
|
+
global ui, win, defaultdict, overlagGraphicsViews
|
|
239
|
+
global verbosity, uiinitialized
|
|
240
|
+
|
|
241
|
+
whichsubject = thesubject
|
|
242
|
+
if uiinitialized:
|
|
243
|
+
thesubjects[whichsubject].setfocusregressor(currentdataset.focusregressor)
|
|
244
|
+
thesubjects[whichsubject].setfocusmap(currentdataset.focusmap)
|
|
245
|
+
currentdataset = thesubjects[whichsubject]
|
|
246
|
+
activateDataset(
|
|
247
|
+
currentdataset,
|
|
248
|
+
ui,
|
|
249
|
+
win,
|
|
250
|
+
defaultdict,
|
|
251
|
+
overlayGraphicsViews,
|
|
252
|
+
verbosity=verbosity,
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
# update the file menu
|
|
256
|
+
updateFileMenu()
|
|
150
257
|
|
|
151
258
|
|
|
152
259
|
class xyztlocation(QtWidgets.QWidget):
|
|
@@ -314,10 +421,17 @@ class xyztlocation(QtWidgets.QWidget):
|
|
|
314
421
|
# print('resetting T spinbox values')
|
|
315
422
|
if self.TPosSpinBox is not None:
|
|
316
423
|
self.TPosSpinBox.setValue(self.tpos)
|
|
424
|
+
self.TPosSpinBox.setRange(0, self.tdim - 1)
|
|
317
425
|
if self.TCoordSpinBox is not None:
|
|
318
426
|
self.TCoordSpinBox.setValue(self.tcoord)
|
|
427
|
+
tllcoord = self.tr2real(0)
|
|
428
|
+
tulcoord = self.tr2real(self.tdim - 1)
|
|
429
|
+
tmin = np.min([tllcoord, tulcoord])
|
|
430
|
+
tmax = np.max([tllcoord, tulcoord])
|
|
431
|
+
self.TCoordSpinBox.setRange(tmin, tmax)
|
|
319
432
|
if self.TimeSlider is not None:
|
|
320
433
|
self.TimeSlider.setValue((self.tpos))
|
|
434
|
+
self.TimeSlider.setRange(0, self.tdim - 1)
|
|
321
435
|
# print('done resetting T spinbox values')
|
|
322
436
|
self.updatedT.emit()
|
|
323
437
|
|
|
@@ -349,6 +463,8 @@ class xyztlocation(QtWidgets.QWidget):
|
|
|
349
463
|
self.updateXYZValues(emitsignal=emitsignal)
|
|
350
464
|
|
|
351
465
|
def setTpos(self, tpos):
|
|
466
|
+
if tpos > self.tdim:
|
|
467
|
+
tpos = self.tdim
|
|
352
468
|
if self.tpos != tpos:
|
|
353
469
|
self.tpos = tpos
|
|
354
470
|
self.tcoord = self.tr2real(self.tpos)
|
|
@@ -469,77 +585,7 @@ class xyztlocation(QtWidgets.QWidget):
|
|
|
469
585
|
self.movieTimer.start(int(self.frametime))
|
|
470
586
|
|
|
471
587
|
|
|
472
|
-
|
|
473
|
-
sigKeyPress = QtCore.pyqtSignal(object)
|
|
474
|
-
|
|
475
|
-
def __init__(self, *args, **kwargs):
|
|
476
|
-
super().__init__(*args, **kwargs)
|
|
477
|
-
|
|
478
|
-
def keyPressEvent(self, ev):
|
|
479
|
-
self.sigKeyPress.emit(ev)"""
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
def nextFileButtonPressed():
|
|
483
|
-
global currentdataset, thesubjects, whichsubject
|
|
484
|
-
global defaultdict, overlayGraphicsViews
|
|
485
|
-
numsubjects = len(thesubjects)
|
|
486
|
-
whichsubject = (whichsubject + 1) % numsubjects
|
|
487
|
-
print(f"subject number set to {whichsubject}")
|
|
488
|
-
thesubjects[whichsubject].setfocusregressor(currentdataset.focusregressor)
|
|
489
|
-
thesubjects[whichsubject].setfocusmap(currentdataset.focusmap)
|
|
490
|
-
currentdataset = thesubjects[whichsubject]
|
|
491
|
-
activatedataset(
|
|
492
|
-
currentdataset,
|
|
493
|
-
ui,
|
|
494
|
-
win,
|
|
495
|
-
defaultdict,
|
|
496
|
-
overlayGraphicsViews,
|
|
497
|
-
verbosity=verbosity,
|
|
498
|
-
doinit=False,
|
|
499
|
-
)
|
|
500
|
-
updateRegressor()
|
|
501
|
-
updateRegressorSpectrum()
|
|
502
|
-
updateUI(
|
|
503
|
-
callingfunc="nextFileButtonPressed",
|
|
504
|
-
orthoimages=True,
|
|
505
|
-
histogram=True,
|
|
506
|
-
focusvals=True,
|
|
507
|
-
)
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
"""def keyPressed(evt):
|
|
511
|
-
global currentsubject, thesubjects, whichsubject
|
|
512
|
-
global defaultdict, overlayGraphicsViews
|
|
513
|
-
numsubjects = len(thesubjects)
|
|
514
|
-
if evt.key() == QtCore.Qt.Key.Key_F:
|
|
515
|
-
whichsubject = (whichsubject + 1) % numsubjects
|
|
516
|
-
print("Key_Up")
|
|
517
|
-
elif evt.key() == QtCore.Qt.Key.Key_B:
|
|
518
|
-
whichsubject = (whichsubject - 1) % numsubjects
|
|
519
|
-
print("Key_Down")
|
|
520
|
-
elif evt.key() == QtCore.Qt.Key.Key_Left:
|
|
521
|
-
whichsubject = (whichsubject - 1) % numsubjects
|
|
522
|
-
print("Key_Left")
|
|
523
|
-
elif evt.key() == QtCore.Qt.Key.Key_Right:
|
|
524
|
-
whichsubject = (whichsubject + 1) % numsubjects
|
|
525
|
-
print("Key_Right")
|
|
526
|
-
else:
|
|
527
|
-
print(evt.key())
|
|
528
|
-
print(f"subject number set to {whichsubject}")
|
|
529
|
-
currentdataset = thesubjects[whichsubject]
|
|
530
|
-
activatedataset(
|
|
531
|
-
currentdataset,
|
|
532
|
-
ui,
|
|
533
|
-
win,
|
|
534
|
-
defaultdict,
|
|
535
|
-
overlayGraphicsViews,
|
|
536
|
-
verbosity=verbosity,
|
|
537
|
-
doinit=False,
|
|
538
|
-
)
|
|
539
|
-
updateOrthoImages()"""
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
def logstatus(thetextbox, thetext):
|
|
588
|
+
def logStatus(thetextbox, thetext):
|
|
543
589
|
if pyqtversion == 5:
|
|
544
590
|
thetextbox.moveCursor(QtGui.QTextCursor.End)
|
|
545
591
|
thetextbox.insertPlainText(thetext + "\n")
|
|
@@ -871,7 +917,7 @@ def updateAveragingMode():
|
|
|
871
917
|
print("in updateAveragingMode")
|
|
872
918
|
if ("atlas" in overlays) and (not atlasaveragingdone):
|
|
873
919
|
calcAtlasStats()
|
|
874
|
-
|
|
920
|
+
setAtlasMask()
|
|
875
921
|
if ("atlas" in overlays) and False:
|
|
876
922
|
updateAtlasStats()
|
|
877
923
|
if averagingmode is not None:
|
|
@@ -938,7 +984,7 @@ def MAD_radioButton_clicked(enabled):
|
|
|
938
984
|
updateAveragingMode()
|
|
939
985
|
|
|
940
986
|
|
|
941
|
-
def
|
|
987
|
+
def transparencyCheckboxClicked():
|
|
942
988
|
global LUT_alpha, LUT_endalpha, ui, overlays, currentdataset
|
|
943
989
|
global verbosity
|
|
944
990
|
|
|
@@ -1034,7 +1080,7 @@ def rainbow_radioButton_clicked(enabled):
|
|
|
1034
1080
|
updateLUT()
|
|
1035
1081
|
|
|
1036
1082
|
|
|
1037
|
-
def
|
|
1083
|
+
def setMask(maskname):
|
|
1038
1084
|
global overlays, loadedfuncmaps, ui, atlasaveragingdone, currentdataset
|
|
1039
1085
|
maskinfodicts = {}
|
|
1040
1086
|
maskinfodicts["nomask"] = {
|
|
@@ -1049,6 +1095,10 @@ def set_mask(maskname):
|
|
|
1049
1095
|
"msg": "Using valid fit points as functional mask",
|
|
1050
1096
|
"label": "Valid mask",
|
|
1051
1097
|
}
|
|
1098
|
+
maskinfodicts["brainmask"] = {
|
|
1099
|
+
"msg": "Externally provided brain mask",
|
|
1100
|
+
"label": "Brain mask",
|
|
1101
|
+
}
|
|
1052
1102
|
maskinfodicts["refinemask"] = {
|
|
1053
1103
|
"msg": "Voxel refinement mask",
|
|
1054
1104
|
"label": "Refine mask",
|
|
@@ -1071,16 +1121,16 @@ def set_mask(maskname):
|
|
|
1071
1121
|
overlays[themap].setFuncMask(overlays[maskname].data)
|
|
1072
1122
|
atlasaveragingdone = False
|
|
1073
1123
|
updateAveragingMode()
|
|
1074
|
-
updateUI(callingfunc=f"
|
|
1124
|
+
updateUI(callingfunc=f"setMask({maskname})", orthoimages=True, histogram=True)
|
|
1075
1125
|
|
|
1076
1126
|
|
|
1077
|
-
def
|
|
1127
|
+
def setAtlasMask():
|
|
1078
1128
|
global overlays, loadedfuncmaps, ui, currentdataset
|
|
1079
1129
|
print("Using all defined atlas regions as functional mask")
|
|
1080
1130
|
ui.setMask_Button.setText("Valid mask")
|
|
1081
1131
|
for themap in currentdataset.loadedfuncmaps:
|
|
1082
1132
|
overlays[themap].setFuncMask(overlays["atlasmask"].data)
|
|
1083
|
-
updateUI(callingfunc="
|
|
1133
|
+
updateUI(callingfunc="setAtlasMask", orthoimages=True, histogram=True)
|
|
1084
1134
|
|
|
1085
1135
|
|
|
1086
1136
|
def overlay_radioButton_clicked(which, enabled):
|
|
@@ -1096,6 +1146,8 @@ def overlay_radioButton_clicked(which, enabled):
|
|
|
1096
1146
|
currentdataset.setfocusmap(panetomap[which] + "_atlasstat")
|
|
1097
1147
|
else:
|
|
1098
1148
|
currentdataset.setfocusmap(panetomap[which])
|
|
1149
|
+
thedispmin = overlays[currentdataset.focusmap].dispmin
|
|
1150
|
+
thedispmax = overlays[currentdataset.focusmap].dispmax
|
|
1099
1151
|
if verbosity > 1:
|
|
1100
1152
|
print("currentdataset.focusmap set to ", currentdataset.focusmap)
|
|
1101
1153
|
if overlays[currentdataset.focusmap].lut_state == gen_gray_state():
|
|
@@ -1122,7 +1174,9 @@ def overlay_radioButton_clicked(which, enabled):
|
|
|
1122
1174
|
overlays[currentdataset.focusmap].tr,
|
|
1123
1175
|
overlays[currentdataset.focusmap].toffset,
|
|
1124
1176
|
)
|
|
1125
|
-
|
|
1177
|
+
overlays[currentdataset.focusmap].dispmin = thedispmin
|
|
1178
|
+
overlays[currentdataset.focusmap].dispmax = thedispmax
|
|
1179
|
+
updateDispLimits()
|
|
1126
1180
|
updateUI(
|
|
1127
1181
|
callingfunc="overlay_radioButton_clicked",
|
|
1128
1182
|
histogram=True,
|
|
@@ -1275,7 +1329,7 @@ def printfocusvals():
|
|
|
1275
1329
|
global ui, overlays, currentdataset
|
|
1276
1330
|
global currentloc
|
|
1277
1331
|
global simfuncFitter
|
|
1278
|
-
|
|
1332
|
+
logStatus(
|
|
1279
1333
|
ui.logOutput,
|
|
1280
1334
|
"\n\nValues at location "
|
|
1281
1335
|
+ "{0},{1},{2}".format(currentloc.xpos, currentloc.ypos, currentloc.zpos),
|
|
@@ -1297,7 +1351,7 @@ def printfocusvals():
|
|
|
1297
1351
|
+ str(":")
|
|
1298
1352
|
+ "{:.3f}".format(round(focusval, 3))
|
|
1299
1353
|
)
|
|
1300
|
-
|
|
1354
|
+
logStatus(ui.logOutput, outstring)
|
|
1301
1355
|
else:
|
|
1302
1356
|
if focusval > 0.0:
|
|
1303
1357
|
if simfuncFitter is not None:
|
|
@@ -1308,7 +1362,7 @@ def printfocusvals():
|
|
|
1308
1362
|
+ str(":\n\t ")
|
|
1309
1363
|
+ failstring.replace(", ", "\n\t ")
|
|
1310
1364
|
)
|
|
1311
|
-
|
|
1365
|
+
logStatus(ui.logOutput, outstring)
|
|
1312
1366
|
else:
|
|
1313
1367
|
outstring = (
|
|
1314
1368
|
indentstring
|
|
@@ -1316,7 +1370,7 @@ def printfocusvals():
|
|
|
1316
1370
|
+ str(":")
|
|
1317
1371
|
+ str(currentdataset.atlaslabels[int(focusval) - 1])
|
|
1318
1372
|
)
|
|
1319
|
-
|
|
1373
|
+
logStatus(ui.logOutput, outstring)
|
|
1320
1374
|
|
|
1321
1375
|
|
|
1322
1376
|
def regressor_radioButton_clicked(theregressor, enabled):
|
|
@@ -1326,15 +1380,22 @@ def regressor_radioButton_clicked(theregressor, enabled):
|
|
|
1326
1380
|
updateRegressorSpectrum()
|
|
1327
1381
|
|
|
1328
1382
|
|
|
1329
|
-
def
|
|
1330
|
-
currentdataset, ui, win, defaultdict, overlayGraphicsViews, verbosity=0, doinit=False
|
|
1331
|
-
):
|
|
1383
|
+
def activateDataset(currentdataset, ui, win, defaultdict, overlayGraphicsViews, verbosity=0):
|
|
1332
1384
|
global regressors, overlays
|
|
1333
1385
|
global mainwin
|
|
1334
1386
|
global xdim, ydim, zdim, tdim, xpos, ypos, zpos, tpos
|
|
1335
1387
|
global timeaxis
|
|
1336
1388
|
global usecorrout
|
|
1337
1389
|
global orthoimagedict
|
|
1390
|
+
global panesinitialized, uiinitialized
|
|
1391
|
+
global currentloc
|
|
1392
|
+
|
|
1393
|
+
if uiinitialized:
|
|
1394
|
+
currentloc.xdim = currentdataset.xdim
|
|
1395
|
+
currentloc.ydim = currentdataset.ydim
|
|
1396
|
+
currentloc.xdim = currentdataset.zdim
|
|
1397
|
+
currentloc.tdim = currentdataset.tdim
|
|
1398
|
+
currentloc.setTpos(currentloc.tpos)
|
|
1338
1399
|
|
|
1339
1400
|
if verbosity > 1:
|
|
1340
1401
|
print("getting regressors")
|
|
@@ -1508,7 +1569,7 @@ def activatedataset(
|
|
|
1508
1569
|
|
|
1509
1570
|
if verbosity > 1:
|
|
1510
1571
|
print("focusmap is:", currentdataset.focusmap, "bgmap is:", bgmap)
|
|
1511
|
-
if
|
|
1572
|
+
if not panesinitialized:
|
|
1512
1573
|
if bgmap is None:
|
|
1513
1574
|
mainwin = OrthoImageItem(
|
|
1514
1575
|
overlays[currentdataset.focusmap],
|
|
@@ -1533,12 +1594,12 @@ def activatedataset(
|
|
|
1533
1594
|
else:
|
|
1534
1595
|
mainwin.setMap(overlays[currentdataset.focusmap])
|
|
1535
1596
|
|
|
1536
|
-
if verbosity > 1:
|
|
1537
|
-
print("loading panes")
|
|
1538
1597
|
availablepanes = len(overlayGraphicsViews)
|
|
1598
|
+
if verbosity > 0:
|
|
1599
|
+
print(f"loading {availablepanes} available panes")
|
|
1539
1600
|
numnotloaded = 0
|
|
1540
1601
|
numloaded = 0
|
|
1541
|
-
if
|
|
1602
|
+
if not panesinitialized:
|
|
1542
1603
|
orthoimagedict = {}
|
|
1543
1604
|
for idx, themap in enumerate(currentdataset.dispmaps):
|
|
1544
1605
|
if overlays[themap].display_state:
|
|
@@ -1546,11 +1607,15 @@ def activatedataset(
|
|
|
1546
1607
|
(numloaded > availablepanes - 2) and (themap != "corrout")
|
|
1547
1608
|
):
|
|
1548
1609
|
if verbosity > 1:
|
|
1549
|
-
print(
|
|
1610
|
+
print(
|
|
1611
|
+
f"skipping map {themap}({idx}): out of display panes ({numloaded=}, {availablepanes=})"
|
|
1612
|
+
)
|
|
1550
1613
|
numnotloaded += 1
|
|
1551
1614
|
else:
|
|
1552
1615
|
if verbosity > 1:
|
|
1553
|
-
print(
|
|
1616
|
+
print(
|
|
1617
|
+
f"loading map {themap}=({idx}) into pane {numloaded} of {availablepanes}"
|
|
1618
|
+
)
|
|
1554
1619
|
if bgmap is None:
|
|
1555
1620
|
loadpane(
|
|
1556
1621
|
overlays[themap],
|
|
@@ -1572,7 +1637,7 @@ def activatedataset(
|
|
|
1572
1637
|
bgmap=overlays[bgmap],
|
|
1573
1638
|
sm_imgsize=sm_imgsize,
|
|
1574
1639
|
)
|
|
1575
|
-
|
|
1640
|
+
numloaded += 1
|
|
1576
1641
|
else:
|
|
1577
1642
|
if verbosity > 1:
|
|
1578
1643
|
print("not loading map ", themap, "(", idx, "): display_state is False")
|
|
@@ -1588,6 +1653,21 @@ def activatedataset(
|
|
|
1588
1653
|
if numnotloaded > 0:
|
|
1589
1654
|
print("WARNING:", numnotloaded, "maps could not be loaded - not enough panes")
|
|
1590
1655
|
|
|
1656
|
+
# record that we've been through once
|
|
1657
|
+
panesinitialized = True
|
|
1658
|
+
|
|
1659
|
+
if uiinitialized:
|
|
1660
|
+
# update the windows
|
|
1661
|
+
updateUI(
|
|
1662
|
+
callingfunc="activateDataset",
|
|
1663
|
+
orthoimages=True,
|
|
1664
|
+
histogram=True,
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
# update the regressor
|
|
1668
|
+
updateRegressor()
|
|
1669
|
+
updateRegressorSpectrum()
|
|
1670
|
+
|
|
1591
1671
|
|
|
1592
1672
|
def loadpane(
|
|
1593
1673
|
themap,
|
|
@@ -1627,6 +1707,7 @@ def loadpane(
|
|
|
1627
1707
|
def tidepool(args):
|
|
1628
1708
|
global vLine
|
|
1629
1709
|
global ui, win
|
|
1710
|
+
global fileMenu, sel_open, sel_files
|
|
1630
1711
|
global movierunning
|
|
1631
1712
|
global focusmap, bgmap, focusregressor
|
|
1632
1713
|
global maps
|
|
@@ -1643,9 +1724,10 @@ def tidepool(args):
|
|
|
1643
1724
|
global imageadj
|
|
1644
1725
|
global harvestcolormaps
|
|
1645
1726
|
global atlasaveragingdone
|
|
1646
|
-
global currentdataset, thesubjects, whichsubject
|
|
1727
|
+
global currentdataset, thesubjects, whichsubject, datafileroots
|
|
1647
1728
|
global defaultdict, overlayGraphicsViews
|
|
1648
1729
|
global verbosity
|
|
1730
|
+
global panesinitialized, uiinitialized
|
|
1649
1731
|
global simfuncFitter
|
|
1650
1732
|
global simfunc_ax, simfuncCurve, simfuncfitCurve, simfuncTLine, simfuncPeakMarker, simfuncCurvePoint, simfuncCaption
|
|
1651
1733
|
|
|
@@ -1671,6 +1753,10 @@ def tidepool(args):
|
|
|
1671
1753
|
tpos = 0
|
|
1672
1754
|
verbosity = 0
|
|
1673
1755
|
simfuncFitter = None
|
|
1756
|
+
datafileroots = []
|
|
1757
|
+
panesinitialized = False
|
|
1758
|
+
uiinitialized = False
|
|
1759
|
+
sel_files = None
|
|
1674
1760
|
|
|
1675
1761
|
if pyqtversion == 5:
|
|
1676
1762
|
if args.uistyle == "normal":
|
|
@@ -1702,7 +1788,6 @@ def tidepool(args):
|
|
|
1702
1788
|
else:
|
|
1703
1789
|
geommaskname = None
|
|
1704
1790
|
|
|
1705
|
-
datafileroots = []
|
|
1706
1791
|
if args.datafileroot is not None:
|
|
1707
1792
|
print("using ", args.datafileroot, " as the root file name list")
|
|
1708
1793
|
datafileroots = args.datafileroot
|
|
@@ -1729,34 +1814,25 @@ def tidepool(args):
|
|
|
1729
1814
|
# make the main window
|
|
1730
1815
|
app = QtWidgets.QApplication([])
|
|
1731
1816
|
print("setting up output window")
|
|
1732
|
-
# win = KeyPressWindow()
|
|
1733
|
-
# win.sigKeyPress.connect(keyPressed)
|
|
1734
1817
|
win = QtWidgets.QMainWindow()
|
|
1735
1818
|
ui = uiTemplate.Ui_MainWindow()
|
|
1736
1819
|
ui.setupUi(win)
|
|
1737
1820
|
win.show()
|
|
1738
1821
|
win.setWindowTitle("TiDePool")
|
|
1739
1822
|
|
|
1740
|
-
|
|
1823
|
+
# create the menu bar
|
|
1741
1824
|
print("creating menu bar")
|
|
1742
1825
|
menuBar = win.menuBar()
|
|
1743
|
-
fileMenu =
|
|
1826
|
+
fileMenu = menuBar.addMenu("File")
|
|
1744
1827
|
if pyqtversion == 5:
|
|
1745
1828
|
qactionfunc = QtWidgets.QAction
|
|
1746
1829
|
else:
|
|
1747
1830
|
qactionfunc = QtGui.QAction
|
|
1748
|
-
sel_open = qactionfunc("
|
|
1749
|
-
sel_open.triggered.connect(
|
|
1831
|
+
sel_open = qactionfunc("Add dataset...", win)
|
|
1832
|
+
sel_open.triggered.connect(datasetPicker)
|
|
1750
1833
|
fileMenu.addAction(sel_open)
|
|
1751
|
-
|
|
1752
|
-
print("done creating menu bar")
|
|
1753
|
-
|
|
1754
|
-
# get inputfile root name if necessary
|
|
1755
|
-
if len(datafileroots) == 0:
|
|
1756
|
-
datafileroots.append(selectFile())
|
|
1757
|
-
if len(datafileroots) == 0:
|
|
1758
|
-
print("No input file specified - exiting.")
|
|
1759
|
-
sys.exit()
|
|
1834
|
+
fileMenu.addSeparator()
|
|
1835
|
+
print("done creating menu bar")
|
|
1760
1836
|
|
|
1761
1837
|
# wire up the ortho image windows for mouse interaction
|
|
1762
1838
|
vb_colorbar = pg.ViewBox(enableMouse=False)
|
|
@@ -1784,6 +1860,10 @@ def tidepool(args):
|
|
|
1784
1860
|
if harvestcolormaps:
|
|
1785
1861
|
ui.largeimage_horizontalLayout.addWidget(imageadj)
|
|
1786
1862
|
|
|
1863
|
+
if args.uistyle == "big":
|
|
1864
|
+
extramaps = True
|
|
1865
|
+
else:
|
|
1866
|
+
extramaps = False
|
|
1787
1867
|
defaultdict = {
|
|
1788
1868
|
"lagmask": {
|
|
1789
1869
|
"colormap": gen_gray_state(),
|
|
@@ -1815,6 +1895,12 @@ def tidepool(args):
|
|
|
1815
1895
|
"display": False,
|
|
1816
1896
|
"funcmask": None,
|
|
1817
1897
|
},
|
|
1898
|
+
"brainmask": {
|
|
1899
|
+
"colormap": gen_gray_state(),
|
|
1900
|
+
"label": "Brain mask",
|
|
1901
|
+
"display": False,
|
|
1902
|
+
"funcmask": None,
|
|
1903
|
+
},
|
|
1818
1904
|
"p_lt_0p050_mask": {
|
|
1819
1905
|
"colormap": gen_gray_state(),
|
|
1820
1906
|
"label": "p<0.05",
|
|
@@ -1890,12 +1976,42 @@ def tidepool(args):
|
|
|
1890
1976
|
"MTT": {
|
|
1891
1977
|
"colormap": gen_spectrum_state(),
|
|
1892
1978
|
"label": "MTT",
|
|
1893
|
-
"display":
|
|
1979
|
+
"display": extramaps,
|
|
1894
1980
|
"funcmask": "p_lt_0p050_mask",
|
|
1895
1981
|
},
|
|
1896
1982
|
"R2": {
|
|
1897
1983
|
"colormap": gen_thermal_state(),
|
|
1898
|
-
"label": "Fit R2",
|
|
1984
|
+
"label": "GLM Fit R2",
|
|
1985
|
+
"display": extramaps,
|
|
1986
|
+
"funcmask": "p_lt_0p050_mask",
|
|
1987
|
+
},
|
|
1988
|
+
"CoV": {
|
|
1989
|
+
"colormap": gen_thermal_state(),
|
|
1990
|
+
"label": "Coefficient of variation",
|
|
1991
|
+
"display": True,
|
|
1992
|
+
"funcmask": "p_lt_0p050_mask",
|
|
1993
|
+
},
|
|
1994
|
+
"confoundR2": {
|
|
1995
|
+
"colormap": gen_thermal_state(),
|
|
1996
|
+
"label": "Confound Fit R2",
|
|
1997
|
+
"display": extramaps,
|
|
1998
|
+
"funcmask": "p_lt_0p050_mask",
|
|
1999
|
+
},
|
|
2000
|
+
"varBefore": {
|
|
2001
|
+
"colormap": gen_thermal_state(),
|
|
2002
|
+
"label": "LFO variance before GLM",
|
|
2003
|
+
"display": extramaps,
|
|
2004
|
+
"funcmask": "p_lt_0p050_mask",
|
|
2005
|
+
},
|
|
2006
|
+
"varAfter": {
|
|
2007
|
+
"colormap": gen_thermal_state(),
|
|
2008
|
+
"label": "LFO variance after GLM",
|
|
2009
|
+
"display": extramaps,
|
|
2010
|
+
"funcmask": "p_lt_0p050_mask",
|
|
2011
|
+
},
|
|
2012
|
+
"varChange": {
|
|
2013
|
+
"colormap": gen_thermal_state(),
|
|
2014
|
+
"label": "LFO variance decrease %",
|
|
1899
2015
|
"display": True,
|
|
1900
2016
|
"funcmask": "p_lt_0p050_mask",
|
|
1901
2017
|
},
|
|
@@ -1908,7 +2024,7 @@ def tidepool(args):
|
|
|
1908
2024
|
"fitNorm": {
|
|
1909
2025
|
"colormap": gen_thermal_state(),
|
|
1910
2026
|
"label": "fitNorm",
|
|
1911
|
-
"display":
|
|
2027
|
+
"display": False,
|
|
1912
2028
|
"funcmask": "p_lt_0p050_mask",
|
|
1913
2029
|
},
|
|
1914
2030
|
"gaussout": {
|
|
@@ -1920,7 +2036,7 @@ def tidepool(args):
|
|
|
1920
2036
|
"failimage": {
|
|
1921
2037
|
"colormap": gen_spectrum_state(),
|
|
1922
2038
|
"label": "Fit failure reason",
|
|
1923
|
-
"display":
|
|
2039
|
+
"display": extramaps,
|
|
1924
2040
|
"funcmask": None,
|
|
1925
2041
|
},
|
|
1926
2042
|
"anatomic": {
|
|
@@ -1944,7 +2060,7 @@ def tidepool(args):
|
|
|
1944
2060
|
"neglog10p": {
|
|
1945
2061
|
"colormap": gen_thermal_state(),
|
|
1946
2062
|
"label": "Correlation fit -log10p",
|
|
1947
|
-
"display":
|
|
2063
|
+
"display": extramaps,
|
|
1948
2064
|
"funcmask": "None",
|
|
1949
2065
|
},
|
|
1950
2066
|
"delayoffset": {
|
|
@@ -1999,7 +2115,7 @@ def tidepool(args):
|
|
|
1999
2115
|
ui.rainbow_radioButton.clicked.connect(rainbow_radioButton_clicked)
|
|
2000
2116
|
|
|
2001
2117
|
# wire up the transparency checkbox
|
|
2002
|
-
ui.transparency_checkBox.stateChanged.connect(
|
|
2118
|
+
ui.transparency_checkBox.stateChanged.connect(transparencyCheckboxClicked)
|
|
2003
2119
|
|
|
2004
2120
|
overlaybuttons = [
|
|
2005
2121
|
ui.overlay_radioButton_01,
|
|
@@ -2058,13 +2174,14 @@ def tidepool(args):
|
|
|
2058
2174
|
theview.hide()
|
|
2059
2175
|
|
|
2060
2176
|
# define things for the popup mask menu
|
|
2061
|
-
|
|
2177
|
+
popMaskMenu = QtWidgets.QMenu(win)
|
|
2062
2178
|
if pyqtversion == 5:
|
|
2063
2179
|
qactionfunc = QtWidgets.QAction
|
|
2064
2180
|
else:
|
|
2065
2181
|
qactionfunc = QtGui.QAction
|
|
2066
2182
|
sel_nomask = qactionfunc("No mask", win)
|
|
2067
2183
|
sel_lagmask = qactionfunc("Valid fit", win)
|
|
2184
|
+
sel_brainmask = qactionfunc("Externally provided brain mask", win)
|
|
2068
2185
|
sel_refinemask = qactionfunc("Voxels used in refine", win)
|
|
2069
2186
|
sel_meanmask = qactionfunc("Voxels used in mean regressor calculation", win)
|
|
2070
2187
|
sel_preselectmask = qactionfunc(
|
|
@@ -2075,24 +2192,38 @@ def tidepool(args):
|
|
|
2075
2192
|
sel_0p005 = qactionfunc("p<0.005", win)
|
|
2076
2193
|
sel_0p001 = qactionfunc("p<0.001", win)
|
|
2077
2194
|
|
|
2078
|
-
sel_nomask.triggered.connect(partial(
|
|
2079
|
-
sel_lagmask.triggered.connect(partial(
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2195
|
+
sel_nomask.triggered.connect(partial(setMask, "nomask"))
|
|
2196
|
+
sel_lagmask.triggered.connect(partial(setMask, "lagmask"))
|
|
2197
|
+
sel_brainmask.triggered.connect(partial(setMask, "brainmask"))
|
|
2198
|
+
sel_refinemask.triggered.connect(partial(setMask, "refinemask"))
|
|
2199
|
+
sel_meanmask.triggered.connect(partial(setMask, "meanmask"))
|
|
2200
|
+
sel_preselectmask.triggered.connect(partial(setMask, "preselectmask"))
|
|
2201
|
+
sel_0p05.triggered.connect(partial(setMask, "p_lt_0p050_mask"))
|
|
2202
|
+
sel_0p01.triggered.connect(partial(setMask, "p_lt_0p010_mask"))
|
|
2203
|
+
sel_0p005.triggered.connect(partial(setMask, "p_lt_0p005_mask"))
|
|
2204
|
+
sel_0p001.triggered.connect(partial(setMask, "p_lt_0p001_mask"))
|
|
2205
|
+
popMaskMenu.addAction(sel_nomask)
|
|
2088
2206
|
numspecial = 0
|
|
2089
2207
|
|
|
2090
|
-
|
|
2208
|
+
# configure the mask selection popup menu
|
|
2209
|
+
def on_mask_context_menu(point):
|
|
2091
2210
|
# show context menu
|
|
2092
|
-
|
|
2211
|
+
popMaskMenu.exec(ui.setMask_Button.mapToGlobal(point))
|
|
2093
2212
|
|
|
2094
2213
|
ui.setMask_Button.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
|
|
2095
|
-
ui.setMask_Button.customContextMenuRequested.connect(
|
|
2214
|
+
ui.setMask_Button.customContextMenuRequested.connect(on_mask_context_menu)
|
|
2215
|
+
|
|
2216
|
+
# configure the file selection popup menu
|
|
2217
|
+
def on_file_context_menu(point):
|
|
2218
|
+
# show context menu
|
|
2219
|
+
popMaskMenu.exec(ui.setFile_Button.mapToGlobal(point))
|
|
2220
|
+
|
|
2221
|
+
try:
|
|
2222
|
+
ui.setFile_Button.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
|
|
2223
|
+
ui.setFile_Button.customContextMenuRequested.connect(on_file_context_menu)
|
|
2224
|
+
setfilebuttonexists = True
|
|
2225
|
+
except AttributeError:
|
|
2226
|
+
setfilebuttonexists = False
|
|
2096
2227
|
|
|
2097
2228
|
# wire up the regressor selection radio buttons
|
|
2098
2229
|
regressorbuttons = [
|
|
@@ -2116,52 +2247,41 @@ def tidepool(args):
|
|
|
2116
2247
|
|
|
2117
2248
|
# read in all the datasets
|
|
2118
2249
|
thesubjects = []
|
|
2119
|
-
|
|
2120
|
-
print("loading datasets...")
|
|
2121
|
-
for thisdatafileroot in datafileroots:
|
|
2122
|
-
print("Loading", thisdatafileroot)
|
|
2123
|
-
thissubject = RapidtideDataset(
|
|
2124
|
-
"main",
|
|
2125
|
-
thisdatafileroot,
|
|
2126
|
-
anatname=anatname,
|
|
2127
|
-
geommaskname=geommaskname,
|
|
2128
|
-
userise=userise,
|
|
2129
|
-
usecorrout=usecorrout,
|
|
2130
|
-
useatlas=useatlas,
|
|
2131
|
-
forcetr=forcetr,
|
|
2132
|
-
forceoffset=forceoffset,
|
|
2133
|
-
offsettime=offsettime,
|
|
2134
|
-
verbose=verbosity,
|
|
2135
|
-
)
|
|
2136
|
-
if len(thesubjects) > 0:
|
|
2137
|
-
# check to see that the dimensions match
|
|
2138
|
-
dimmatch, sizematch, spacematch, affinematch = check_rt_spatialmatch(
|
|
2139
|
-
thissubject, thesubjects[0]
|
|
2140
|
-
)
|
|
2141
|
-
if dimmatch or args.ignoredimmatch:
|
|
2142
|
-
thesubjects.append(thissubject)
|
|
2143
|
-
else:
|
|
2144
|
-
print(f"dataset {thisdatafileroot} does not match loaded data - skipping")
|
|
2145
|
-
else:
|
|
2146
|
-
thesubjects.append(thissubject)
|
|
2147
2250
|
whichsubject = 0
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2251
|
+
if len(datafileroots) > 0:
|
|
2252
|
+
print("loading prespecified datasets...")
|
|
2253
|
+
for thisdatafileroot in datafileroots:
|
|
2254
|
+
addDataset(
|
|
2255
|
+
thisdatafileroot,
|
|
2256
|
+
anatname=anatname,
|
|
2257
|
+
geommaskname=geommaskname,
|
|
2258
|
+
userise=userise,
|
|
2259
|
+
usecorrout=usecorrout,
|
|
2260
|
+
useatlas=useatlas,
|
|
2261
|
+
forcetr=forcetr,
|
|
2262
|
+
forceoffset=forceoffset,
|
|
2263
|
+
offsettime=offsettime,
|
|
2264
|
+
ignoredimmatch=args.ignoredimmatch,
|
|
2265
|
+
)
|
|
2266
|
+
currentdataset = thesubjects[whichsubject]
|
|
2267
|
+
activateDataset(
|
|
2268
|
+
currentdataset,
|
|
2269
|
+
ui,
|
|
2270
|
+
win,
|
|
2271
|
+
defaultdict,
|
|
2272
|
+
overlayGraphicsViews,
|
|
2273
|
+
verbosity=verbosity,
|
|
2274
|
+
)
|
|
2275
|
+
# update the file menu
|
|
2276
|
+
updateFileMenu()
|
|
2277
|
+
else:
|
|
2278
|
+
# get inputfile root name if necessary
|
|
2279
|
+
datasetPicker()
|
|
2158
2280
|
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
else:
|
|
2164
|
-
thebutton.clicked.connect(nextFileButtonPressed)
|
|
2281
|
+
# check to see that something is loaded
|
|
2282
|
+
if len(thesubjects) == 0:
|
|
2283
|
+
print("No input datasets specified - exiting.")
|
|
2284
|
+
sys.exit()
|
|
2165
2285
|
|
|
2166
2286
|
# wire up the display range controls
|
|
2167
2287
|
ui.resetDispLimits_Button.clicked.connect(resetDispLimits)
|
|
@@ -2263,29 +2383,32 @@ def tidepool(args):
|
|
|
2263
2383
|
if verbosity > 1:
|
|
2264
2384
|
print("loadedfuncmasks", currentdataset.loadedfuncmasks)
|
|
2265
2385
|
if len(currentdataset.loadedfuncmasks) > 0:
|
|
2266
|
-
|
|
2386
|
+
popMaskMenu.addSeparator()
|
|
2267
2387
|
if "lagmask" in currentdataset.loadedfuncmasks:
|
|
2268
|
-
|
|
2388
|
+
popMaskMenu.addAction(sel_lagmask)
|
|
2389
|
+
numspecial += 1
|
|
2390
|
+
if "brainmask" in currentdataset.loadedfuncmasks:
|
|
2391
|
+
popMaskMenu.addAction(sel_brainmask)
|
|
2269
2392
|
numspecial += 1
|
|
2270
2393
|
if "refinemask" in currentdataset.loadedfuncmasks:
|
|
2271
|
-
|
|
2394
|
+
popMaskMenu.addAction(sel_refinemask)
|
|
2272
2395
|
numspecial += 1
|
|
2273
2396
|
if "meanmask" in currentdataset.loadedfuncmasks:
|
|
2274
|
-
|
|
2397
|
+
popMaskMenu.addAction(sel_meanmask)
|
|
2275
2398
|
numspecial += 1
|
|
2276
2399
|
if "preselectmask" in currentdataset.loadedfuncmasks:
|
|
2277
|
-
|
|
2400
|
+
popMaskMenu.addAction(sel_preselectmask)
|
|
2278
2401
|
numspecial += 1
|
|
2279
2402
|
if numspecial > 0:
|
|
2280
|
-
|
|
2403
|
+
popMaskMenu.addSeparator()
|
|
2281
2404
|
if "p_lt_0p050_mask" in currentdataset.loadedfuncmasks:
|
|
2282
|
-
|
|
2405
|
+
popMaskMenu.addAction(sel_0p05)
|
|
2283
2406
|
if "p_lt_0p010_mask" in currentdataset.loadedfuncmasks:
|
|
2284
|
-
|
|
2407
|
+
popMaskMenu.addAction(sel_0p01)
|
|
2285
2408
|
if "p_lt_0p005_mask" in currentdataset.loadedfuncmasks:
|
|
2286
|
-
|
|
2409
|
+
popMaskMenu.addAction(sel_0p005)
|
|
2287
2410
|
if "p_lt_0p001_mask" in currentdataset.loadedfuncmasks:
|
|
2288
|
-
|
|
2411
|
+
popMaskMenu.addAction(sel_0p001)
|
|
2289
2412
|
|
|
2290
2413
|
# initialize the location picker
|
|
2291
2414
|
global currentloc
|
|
@@ -2331,5 +2454,7 @@ def tidepool(args):
|
|
|
2331
2454
|
|
|
2332
2455
|
updateUI(callingfunc="main thread", orthoimages=True, focusvals=True)
|
|
2333
2456
|
updateRegressor()
|
|
2457
|
+
updateRegressorSpectrum()
|
|
2458
|
+
uiinitialized = True
|
|
2334
2459
|
|
|
2335
2460
|
QtWidgets.QApplication.instance().exec()
|