rapidtide 3.0.11__py3-none-any.whl → 3.1.1__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.
Files changed (144) hide show
  1. rapidtide/Colortables.py +492 -27
  2. rapidtide/OrthoImageItem.py +1049 -46
  3. rapidtide/RapidtideDataset.py +1533 -86
  4. rapidtide/_version.py +3 -3
  5. rapidtide/calccoherence.py +196 -29
  6. rapidtide/calcnullsimfunc.py +188 -40
  7. rapidtide/calcsimfunc.py +242 -42
  8. rapidtide/correlate.py +1203 -383
  9. rapidtide/data/examples/src/testLD +56 -0
  10. rapidtide/data/examples/src/testalign +1 -1
  11. rapidtide/data/examples/src/testdelayvar +0 -1
  12. rapidtide/data/examples/src/testfmri +53 -3
  13. rapidtide/data/examples/src/testglmfilt +5 -5
  14. rapidtide/data/examples/src/testhappy +29 -7
  15. rapidtide/data/examples/src/testppgproc +17 -0
  16. rapidtide/data/examples/src/testrolloff +11 -0
  17. rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
  18. rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
  19. rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
  20. rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
  21. rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
  22. rapidtide/decorators.py +91 -0
  23. rapidtide/dlfilter.py +2226 -110
  24. rapidtide/dlfiltertorch.py +4842 -0
  25. rapidtide/externaltools.py +327 -12
  26. rapidtide/fMRIData_class.py +79 -40
  27. rapidtide/filter.py +1899 -810
  28. rapidtide/fit.py +2011 -581
  29. rapidtide/genericmultiproc.py +93 -18
  30. rapidtide/happy_supportfuncs.py +2047 -172
  31. rapidtide/helper_classes.py +584 -43
  32. rapidtide/io.py +2370 -372
  33. rapidtide/linfitfiltpass.py +346 -99
  34. rapidtide/makelaggedtcs.py +210 -24
  35. rapidtide/maskutil.py +448 -62
  36. rapidtide/miscmath.py +827 -121
  37. rapidtide/multiproc.py +210 -22
  38. rapidtide/patchmatch.py +242 -42
  39. rapidtide/peakeval.py +31 -31
  40. rapidtide/ppgproc.py +2203 -0
  41. rapidtide/qualitycheck.py +352 -39
  42. rapidtide/refinedelay.py +431 -57
  43. rapidtide/refineregressor.py +494 -189
  44. rapidtide/resample.py +671 -185
  45. rapidtide/scripts/applyppgproc.py +28 -0
  46. rapidtide/scripts/showxcorr_legacy.py +7 -7
  47. rapidtide/scripts/stupidramtricks.py +15 -17
  48. rapidtide/simFuncClasses.py +1052 -77
  49. rapidtide/simfuncfit.py +269 -69
  50. rapidtide/stats.py +540 -238
  51. rapidtide/tests/happycomp +9 -0
  52. rapidtide/tests/test_cleanregressor.py +1 -2
  53. rapidtide/tests/test_dlfiltertorch.py +627 -0
  54. rapidtide/tests/test_findmaxlag.py +24 -8
  55. rapidtide/tests/test_fullrunhappy_v1.py +0 -2
  56. rapidtide/tests/test_fullrunhappy_v2.py +0 -2
  57. rapidtide/tests/test_fullrunhappy_v3.py +11 -4
  58. rapidtide/tests/test_fullrunhappy_v4.py +10 -2
  59. rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
  60. rapidtide/tests/test_getparsers.py +11 -3
  61. rapidtide/tests/test_refinedelay.py +0 -1
  62. rapidtide/tests/test_simroundtrip.py +16 -8
  63. rapidtide/tests/test_stcorrelate.py +3 -1
  64. rapidtide/tests/utils.py +9 -8
  65. rapidtide/tidepoolTemplate.py +142 -38
  66. rapidtide/tidepoolTemplate_alt.py +165 -44
  67. rapidtide/tidepoolTemplate_big.py +189 -52
  68. rapidtide/util.py +1217 -118
  69. rapidtide/voxelData.py +684 -37
  70. rapidtide/wiener.py +136 -23
  71. rapidtide/wiener2.py +113 -7
  72. rapidtide/workflows/adjustoffset.py +105 -3
  73. rapidtide/workflows/aligntcs.py +85 -2
  74. rapidtide/workflows/applydlfilter.py +87 -10
  75. rapidtide/workflows/applyppgproc.py +540 -0
  76. rapidtide/workflows/atlasaverage.py +210 -47
  77. rapidtide/workflows/atlastool.py +100 -3
  78. rapidtide/workflows/calcSimFuncMap.py +288 -69
  79. rapidtide/workflows/calctexticc.py +201 -9
  80. rapidtide/workflows/ccorrica.py +101 -6
  81. rapidtide/workflows/cleanregressor.py +165 -31
  82. rapidtide/workflows/delayvar.py +171 -23
  83. rapidtide/workflows/diffrois.py +81 -3
  84. rapidtide/workflows/endtidalproc.py +144 -4
  85. rapidtide/workflows/fdica.py +195 -15
  86. rapidtide/workflows/filtnifti.py +70 -3
  87. rapidtide/workflows/filttc.py +74 -3
  88. rapidtide/workflows/fitSimFuncMap.py +202 -51
  89. rapidtide/workflows/fixtr.py +73 -3
  90. rapidtide/workflows/gmscalc.py +113 -3
  91. rapidtide/workflows/happy.py +801 -199
  92. rapidtide/workflows/happy2std.py +144 -12
  93. rapidtide/workflows/happy_parser.py +163 -23
  94. rapidtide/workflows/histnifti.py +118 -2
  95. rapidtide/workflows/histtc.py +84 -3
  96. rapidtide/workflows/linfitfilt.py +117 -4
  97. rapidtide/workflows/localflow.py +328 -28
  98. rapidtide/workflows/mergequality.py +79 -3
  99. rapidtide/workflows/niftidecomp.py +322 -18
  100. rapidtide/workflows/niftistats.py +174 -4
  101. rapidtide/workflows/pairproc.py +98 -4
  102. rapidtide/workflows/pairwisemergenifti.py +85 -2
  103. rapidtide/workflows/parser_funcs.py +1421 -40
  104. rapidtide/workflows/physiofreq.py +137 -11
  105. rapidtide/workflows/pixelcomp.py +207 -5
  106. rapidtide/workflows/plethquality.py +103 -21
  107. rapidtide/workflows/polyfitim.py +151 -11
  108. rapidtide/workflows/proj2flow.py +75 -2
  109. rapidtide/workflows/rankimage.py +111 -4
  110. rapidtide/workflows/rapidtide.py +368 -76
  111. rapidtide/workflows/rapidtide2std.py +98 -2
  112. rapidtide/workflows/rapidtide_parser.py +109 -9
  113. rapidtide/workflows/refineDelayMap.py +144 -33
  114. rapidtide/workflows/refineRegressor.py +675 -96
  115. rapidtide/workflows/regressfrommaps.py +161 -37
  116. rapidtide/workflows/resamplenifti.py +85 -3
  117. rapidtide/workflows/resampletc.py +91 -3
  118. rapidtide/workflows/retrolagtcs.py +99 -9
  119. rapidtide/workflows/retroregress.py +176 -26
  120. rapidtide/workflows/roisummarize.py +174 -5
  121. rapidtide/workflows/runqualitycheck.py +71 -3
  122. rapidtide/workflows/showarbcorr.py +149 -6
  123. rapidtide/workflows/showhist.py +86 -2
  124. rapidtide/workflows/showstxcorr.py +160 -3
  125. rapidtide/workflows/showtc.py +159 -3
  126. rapidtide/workflows/showxcorrx.py +190 -10
  127. rapidtide/workflows/showxy.py +185 -15
  128. rapidtide/workflows/simdata.py +264 -38
  129. rapidtide/workflows/spatialfit.py +77 -2
  130. rapidtide/workflows/spatialmi.py +250 -27
  131. rapidtide/workflows/spectrogram.py +305 -32
  132. rapidtide/workflows/synthASL.py +154 -3
  133. rapidtide/workflows/tcfrom2col.py +76 -2
  134. rapidtide/workflows/tcfrom3col.py +74 -2
  135. rapidtide/workflows/tidepool.py +2971 -130
  136. rapidtide/workflows/utils.py +19 -14
  137. rapidtide/workflows/utils_doc.py +293 -0
  138. rapidtide/workflows/variabilityizer.py +116 -3
  139. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/METADATA +10 -8
  140. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/RECORD +144 -128
  141. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/entry_points.txt +1 -0
  142. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/WHEEL +0 -0
  143. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/licenses/LICENSE +0 -0
  144. {rapidtide-3.0.11.dist-info → rapidtide-3.1.1.dist-info}/top_level.txt +0 -0
@@ -23,12 +23,15 @@ A simple GUI for looking at the results of a rapidtide analysis
23
23
  import argparse
24
24
  import os
25
25
  import sys
26
+ from argparse import Namespace
26
27
  from functools import partial
28
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
27
29
 
28
30
  import numpy as np
29
31
  import pandas as pd
30
32
  import pyqtgraph as pg
31
33
  from nibabel.affines import apply_affine
34
+ from numpy.typing import NDArray
32
35
  from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
33
36
 
34
37
  import rapidtide.util as tide_util
@@ -54,7 +57,35 @@ print(f"using {pyqtbinding=}")
54
57
  os.environ["QT_MAC_WANTS_LAYER"] = "1"
55
58
 
56
59
 
57
- def _get_parser():
60
+ def _get_parser() -> Any:
61
+ """
62
+ Create and configure an argument parser for the tidepool program.
63
+
64
+ This function constructs an `argparse.ArgumentParser` object with a set of
65
+ predefined command-line arguments used to control the behavior of the tidepool
66
+ time delay analysis visualization tool. The parser is configured with a
67
+ descriptive help text and default values for various options.
68
+
69
+ Returns
70
+ -------
71
+ argparse.ArgumentParser
72
+ Configured argument parser with all supported command-line options.
73
+
74
+ Notes
75
+ -----
76
+ The parser is designed to be used in a larger application workflow where
77
+ command-line arguments are parsed and used to configure the visualization
78
+ and processing of time delay analysis results.
79
+
80
+ Examples
81
+ --------
82
+ >>> parser = _get_parser()
83
+ >>> args = parser.parse_args(['--risetime', '--uistyle', 'big'])
84
+ >>> print(args.risetime)
85
+ True
86
+ >>> print(args.uistyle)
87
+ 'big'
88
+ """
58
89
  parser = argparse.ArgumentParser(
59
90
  prog="tidepool",
60
91
  description="A program to display the results of a time delay analysis",
@@ -138,18 +169,205 @@ def _get_parser():
138
169
  return parser
139
170
 
140
171
 
172
+ def keyPressed(evt: Any) -> None:
173
+ """
174
+ Handle key press events for dataset navigation.
175
+
176
+ This function processes keyboard input to navigate through different datasets
177
+ in a subjects list. It supports navigation using arrow keys and shift modifier
178
+ for special behavior.
179
+
180
+ Parameters
181
+ ----------
182
+ evt : Any
183
+ The key press event object containing key and modifier information.
184
+ Expected to have methods `key()` and `modifiers()` similar to Qt events.
185
+
186
+ Returns
187
+ -------
188
+ None
189
+ This function does not return any value but modifies global variables
190
+ `currentdataset`, `thesubjects`, and `whichsubject`.
191
+
192
+ Notes
193
+ -----
194
+ - Up/Left arrow keys navigate to the previous dataset
195
+ - Down/Right arrow keys navigate to the next dataset
196
+ - Shift modifier reverses the navigation direction:
197
+ * Shift + Up/Left: jumps to last dataset (index = numelements - 1)
198
+ * Shift + Down/Right: jumps to first dataset (index = 0)
199
+ - The function prints the current dataset information to console
200
+ - Global variables modified: `currentdataset`, `thesubjects`, `whichsubject`
201
+
202
+ Examples
203
+ --------
204
+ >>> keyPressed(event)
205
+ Dataset set to subject_001 (0)
206
+
207
+ >>> keyPressed(shift_event)
208
+ Dataset set to subject_100 (99)
209
+ """
210
+ global currentdataset, thesubjects, whichsubject
211
+
212
+ numelements = len(thesubjects)
213
+
214
+ keymods = None
215
+ if evt.modifiers() & QtCore.Qt.KeyboardModifier.ShiftModifier:
216
+ keymods = "shift"
217
+
218
+ if (evt.key() == QtCore.Qt.Key.Key_Up) or (evt.key() == QtCore.Qt.Key.Key_Left):
219
+ if keymods == "shift":
220
+ whichsubject = numelements - 1
221
+ else:
222
+ whichsubject = (whichsubject - 1) % numelements
223
+ selectDataset(whichsubject)
224
+ print(f"Dataset set to {currentdataset.fileroot[:-1]} ({whichsubject})")
225
+ elif (evt.key() == QtCore.Qt.Key.Key_Down) or (evt.key() == QtCore.Qt.Key.Key_Right):
226
+ if keymods == "shift":
227
+ whichsubject = 0
228
+ else:
229
+ whichsubject = (whichsubject + 1) % numelements
230
+ selectDataset(whichsubject)
231
+ print(f"Dataset set to {currentdataset.fileroot[:-1]} ({whichsubject})")
232
+ else:
233
+ print(evt.key())
234
+
235
+
236
+ class KeyPressWindow(QtWidgets.QMainWindow):
237
+ sigKeyPress = QtCore.pyqtSignal(object)
238
+
239
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
240
+ """
241
+ Initialize the object by calling the parent class constructor.
242
+
243
+ This method serves as a constructor that delegates initialization to the
244
+ parent class, allowing for proper inheritance chain execution.
245
+
246
+ Parameters
247
+ ----------
248
+ *args : tuple
249
+ Variable length argument list passed to the parent class constructor.
250
+ **kwargs : dict
251
+ Arbitrary keyword arguments passed to the parent class constructor.
252
+
253
+ Returns
254
+ -------
255
+ None
256
+ This method does not return any value.
257
+
258
+ Notes
259
+ -----
260
+ This is a standard constructor implementation that ensures proper
261
+ initialization of the parent class when subclassing.
262
+
263
+ Examples
264
+ --------
265
+ >>> class ChildClass(ParentClass):
266
+ ... def __init__(self, *args, **kwargs):
267
+ ... super().__init__(*args, **kwargs)
268
+ ...
269
+ >>> obj = ChildClass(param1, param2, kwarg1=value1)
270
+ """
271
+ super().__init__(*args, **kwargs)
272
+
273
+ def keyPressEvent(self, ev: Any) -> None:
274
+ """
275
+ Handle key press events and emit signal.
276
+
277
+ This method is called when a key press event occurs. It emits the
278
+ ``sigKeyPress`` signal with the event object as parameter.
279
+
280
+ Parameters
281
+ ----------
282
+ ev : Any
283
+ The key press event object containing event information.
284
+
285
+ Returns
286
+ -------
287
+ None
288
+ This method does not return a value.
289
+
290
+ Notes
291
+ -----
292
+ This method is typically used in GUI applications to handle keyboard input
293
+ and propagate key press events to connected signal handlers.
294
+
295
+ Examples
296
+ --------
297
+ >>> def handle_key_press(event):
298
+ ... print(f"Key pressed: {event.key()}")
299
+ ...
300
+ >>> widget.sigKeyPress.connect(handle_key_press)
301
+ >>> # When a key is pressed, the signal will be emitted
302
+ """
303
+ self.sigKeyPress.emit(ev)
304
+
305
+
141
306
  def addDataset(
142
- thisdatafileroot,
143
- anatname=None,
144
- geommaskname=None,
145
- userise=False,
146
- usecorrout=True,
147
- useatlas=False,
148
- forcetr=False,
149
- forceoffset=False,
150
- offsettime=0.0,
151
- ignoredimmatch=False,
152
- ):
307
+ thisdatafileroot: Any,
308
+ anatname: Optional[Any] = None,
309
+ geommaskname: Optional[Any] = None,
310
+ userise: bool = False,
311
+ usecorrout: bool = True,
312
+ useatlas: bool = False,
313
+ forcetr: bool = False,
314
+ forceoffset: bool = False,
315
+ offsettime: float = 0.0,
316
+ ignoredimmatch: bool = False,
317
+ ) -> None:
318
+ """
319
+ Load and add a dataset to the global list of subjects for processing.
320
+
321
+ This function initializes a `RapidtideDataset` object from the specified data root
322
+ and appends it to the global list `thesubjects`. It performs dimension matching
323
+ checks against previously loaded datasets unless `ignoredimmatch` is set to `True`.
324
+
325
+ Parameters
326
+ ----------
327
+ thisdatafileroot : Any
328
+ Root path to the dataset to be loaded.
329
+ anatname : Optional[Any], optional
330
+ Anatomical image filename, by default None.
331
+ geommaskname : Optional[Any], optional
332
+ Geometric mask filename, by default None.
333
+ userise : bool, optional
334
+ Whether to use RISE (respiratory-induced signal enhancement), by default False.
335
+ usecorrout : bool, optional
336
+ Whether to use correlation output, by default True.
337
+ useatlas : bool, optional
338
+ Whether to use atlas-based processing, by default False.
339
+ forcetr : bool, optional
340
+ Whether to force TR (repetition time) correction, by default False.
341
+ forceoffset : bool, optional
342
+ Whether to force offset correction, by default False.
343
+ offsettime : float, optional
344
+ Time offset to apply, by default 0.0.
345
+ ignoredimmatch : bool, optional
346
+ If True, skip dimension matching checks, by default False.
347
+
348
+ Returns
349
+ -------
350
+ None
351
+ This function does not return a value but modifies global variables.
352
+
353
+ Notes
354
+ -----
355
+ - The function modifies global variables: `currentdataset`, `thesubjects`, `whichsubject`, `datafileroots`.
356
+ - If a dataset is not dimensionally compatible with the first loaded dataset and `ignoredimmatch` is False,
357
+ the dataset is skipped.
358
+ - Prints information about the loaded dataset and the list of all loaded subjects.
359
+
360
+ Examples
361
+ --------
362
+ >>> addDataset('/path/to/dataset1')
363
+ Loading /path/to/dataset1
364
+ subject 0: /path/to/dataset1
365
+
366
+ >>> addDataset('/path/to/dataset2', ignoredimmatch=True)
367
+ Loading /path/to/dataset2
368
+ subject 0: /path/to/dataset1
369
+ subject 1: /path/to/dataset2
370
+ """
153
371
  global currentdataset, thesubjects, whichsubject, datafileroots
154
372
  global verbosity
155
373
 
@@ -184,7 +402,46 @@ def addDataset(
184
402
  print(f"subject {idx}: {subject.fileroot}")
185
403
 
186
404
 
187
- def updateFileMenu():
405
+ def updateFileMenu() -> None:
406
+ """
407
+ Update the file menu with subject options based on current subjects list.
408
+
409
+ This function updates the file menu by removing existing subject actions and
410
+ rebuilding it with current subjects from the global `thesubjects` list. Each
411
+ subject is displayed with a checkmark indicator for the currently selected
412
+ subject (`whichsubject`).
413
+
414
+ Parameters
415
+ ----------
416
+ None
417
+
418
+ Returns
419
+ -------
420
+ None
421
+ This function does not return any value.
422
+
423
+ Notes
424
+ -----
425
+ The function relies on global variables:
426
+ - `thesubjects`: List of subject objects with `fileroot` attribute
427
+ - `whichsubject`: Index of currently selected subject
428
+ - `fileMenu`: QMenu object to be updated
429
+ - `sel_files`: List of QAction objects representing menu items
430
+ - `pyqtbinding`: String indicating the PyQt binding being used
431
+ - `win`: Main window object for QAction parent
432
+
433
+ The function handles different PyQt bindings (PyQt5, PyQt6, PySide6) by
434
+ selecting the appropriate QAction constructor based on the binding.
435
+
436
+ Examples
437
+ --------
438
+ >>> updateFileMenu()
439
+ # Updates the file menu with current subjects and their selection status
440
+
441
+ See Also
442
+ --------
443
+ selectDataset : Function called when a subject menu item is triggered
444
+ """
188
445
  global thesubjects, whichsubject
189
446
  global fileMenu, sel_open
190
447
  global sel_files
@@ -217,7 +474,43 @@ def updateFileMenu():
217
474
  fileMenu.addAction(sel_files[-1])
218
475
 
219
476
 
220
- def datasetPicker():
477
+ def datasetPicker() -> None:
478
+ """
479
+ Open a file dialog to select a lag time file and initialize the dataset.
480
+
481
+ This function opens a Qt file dialog to select a lag time file in BIDS format,
482
+ extracts the data file root path, adds the dataset to the global dataset list,
483
+ selects the newly added dataset, and updates the file menu.
484
+
485
+ Parameters
486
+ ----------
487
+ None
488
+
489
+ Returns
490
+ -------
491
+ None
492
+ This function does not return any value but modifies global variables.
493
+
494
+ Notes
495
+ -----
496
+ The function supports PyQt5, PyQt6, and PySide6 bindings. It expects lag time
497
+ files in the format *_lagtimes.nii.gz or *_desc-maxtime_map.nii.gz.
498
+
499
+ Global variables modified:
500
+ - currentdataset: Current dataset identifier
501
+ - thesubjects: List of subject identifiers
502
+ - whichsubject: Index of currently selected subject
503
+ - datafileroots: List of data file roots
504
+ - ui: User interface object
505
+ - win: Window object
506
+ - overlagGraphicsViews: Graphics views for overlap visualization
507
+ - verbosity: Verbosity level for logging
508
+
509
+ Examples
510
+ --------
511
+ >>> datasetPicker()
512
+ # Opens file dialog and initializes dataset selection
513
+ """
221
514
  global currentdataset, thesubjects, whichsubject, datafileroots
222
515
  global ui, win, defaultdict, overlagGraphicsViews
223
516
  global verbosity
@@ -250,7 +543,42 @@ def datasetPicker():
250
543
  updateFileMenu()
251
544
 
252
545
 
253
- def selectDataset(thesubject):
546
+ def selectDataset(thesubject: Any) -> None:
547
+ """
548
+ Select a dataset for viewing and activate it in the user interface.
549
+
550
+ This function updates the current dataset selection and activates the specified
551
+ dataset in the user interface. It handles focus updates for regressor and map
552
+ components if the UI has been initialized, and triggers necessary updates
553
+ to the file menu.
554
+
555
+ Parameters
556
+ ----------
557
+ thesubject : Any
558
+ The subject identifier or reference to select as the current dataset.
559
+ This parameter determines which dataset from the global `thesubjects`
560
+ collection will be activated.
561
+
562
+ Returns
563
+ -------
564
+ None
565
+ This function does not return any value.
566
+
567
+ Notes
568
+ -----
569
+ This function modifies global variables including:
570
+ - `currentdataset`: Set to the selected subject
571
+ - `whichsubject`: Set to the input parameter `thesubject`
572
+ - Global UI-related variables: `ui`, `win`, `defaultdict`, `overlayGraphicsViews`
573
+
574
+ The function assumes that global variables `thesubjects`, `uiinitialized`,
575
+ `verbosity`, and other required globals are properly initialized before calling.
576
+
577
+ Examples
578
+ --------
579
+ >>> selectDataset('subject_001')
580
+ >>> selectDataset(42)
581
+ """
254
582
  global currentdataset, thesubjects, whichsubject, datafileroots
255
583
  global ui, win, defaultdict, overlagGraphicsViews
256
584
  global verbosity, uiinitialized
@@ -282,28 +610,97 @@ class xyztlocation(QtWidgets.QWidget):
282
610
 
283
611
  def __init__(
284
612
  self,
285
- xpos,
286
- ypos,
287
- zpos,
288
- tpos,
289
- xdim,
290
- ydim,
291
- zdim,
292
- tdim,
293
- toffset,
294
- tr,
295
- affine,
296
- XPosSpinBox=None,
297
- YPosSpinBox=None,
298
- ZPosSpinBox=None,
299
- TPosSpinBox=None,
300
- XCoordSpinBox=None,
301
- YCoordSpinBox=None,
302
- ZCoordSpinBox=None,
303
- TCoordSpinBox=None,
304
- TimeSlider=None,
305
- runMovieButton=None,
306
- ):
613
+ xpos: Any,
614
+ ypos: Any,
615
+ zpos: Any,
616
+ tpos: Any,
617
+ xdim: Any,
618
+ ydim: Any,
619
+ zdim: Any,
620
+ tdim: Any,
621
+ toffset: Any,
622
+ tr: Any,
623
+ affine: Any,
624
+ XPosSpinBox: Optional[Any] = None,
625
+ YPosSpinBox: Optional[Any] = None,
626
+ ZPosSpinBox: Optional[Any] = None,
627
+ TPosSpinBox: Optional[Any] = None,
628
+ XCoordSpinBox: Optional[Any] = None,
629
+ YCoordSpinBox: Optional[Any] = None,
630
+ ZCoordSpinBox: Optional[Any] = None,
631
+ TCoordSpinBox: Optional[Any] = None,
632
+ TimeSlider: Optional[Any] = None,
633
+ runMovieButton: Optional[Any] = None,
634
+ ) -> None:
635
+ """
636
+ Initialize the widget with position and dimension information.
637
+
638
+ This constructor sets up the widget's internal state by initializing
639
+ position, dimension, and time-related attributes. It also connects
640
+ the movie timer to update the display during animation.
641
+
642
+ Parameters
643
+ ----------
644
+ xpos : Any
645
+ X-axis position value.
646
+ ypos : Any
647
+ Y-axis position value.
648
+ zpos : Any
649
+ Z-axis position value.
650
+ tpos : Any
651
+ Time position value.
652
+ xdim : Any
653
+ X-axis dimension.
654
+ ydim : Any
655
+ Y-axis dimension.
656
+ zdim : Any
657
+ Z-axis dimension.
658
+ tdim : Any
659
+ Time dimension.
660
+ toffset : Any
661
+ Time offset value.
662
+ tr : Any
663
+ Repetition time (TR) value.
664
+ affine : Any
665
+ Affine transformation matrix.
666
+ XPosSpinBox : Optional[Any], optional
667
+ Spin box for X position, by default None
668
+ YPosSpinBox : Optional[Any], optional
669
+ Spin box for Y position, by default None
670
+ ZPosSpinBox : Optional[Any], optional
671
+ Spin box for Z position, by default None
672
+ TPosSpinBox : Optional[Any], optional
673
+ Spin box for T position, by default None
674
+ XCoordSpinBox : Optional[Any], optional
675
+ Spin box for X coordinate, by default None
676
+ YCoordSpinBox : Optional[Any], optional
677
+ Spin box for Y coordinate, by default None
678
+ ZCoordSpinBox : Optional[Any], optional
679
+ Spin box for Z coordinate, by default None
680
+ TCoordSpinBox : Optional[Any], optional
681
+ Spin box for T coordinate, by default None
682
+ TimeSlider : Optional[Any], optional
683
+ Time slider widget, by default None
684
+ runMovieButton : Optional[Any], optional
685
+ Button to run the movie, by default None
686
+
687
+ Returns
688
+ -------
689
+ None
690
+ This method does not return a value.
691
+
692
+ Notes
693
+ -----
694
+ The widget initializes internal state variables including `frametime`,
695
+ `movierunning`, and connects the `movieTimer.timeout` signal to the
696
+ `updateMovie` method for animation control.
697
+
698
+ Examples
699
+ --------
700
+ >>> widget = MyClass(xpos=10, ypos=20, zpos=30, tpos=40,
701
+ ... xdim=100, ydim=100, zdim=100, tdim=10,
702
+ ... toffset=0, tr=2.5, affine=np.eye(4))
703
+ """
307
704
  QtWidgets.QWidget.__init__(self)
308
705
 
309
706
  self.XPosSpinBox = XPosSpinBox
@@ -329,7 +726,45 @@ class xyztlocation(QtWidgets.QWidget):
329
726
  self.movierunning = False
330
727
  self.movieTimer.timeout.connect(self.updateMovie)
331
728
 
332
- def setXYZInfo(self, xdim, ydim, zdim, affine):
729
+ def setXYZInfo(self, xdim: Any, ydim: Any, zdim: Any, affine: Any) -> None:
730
+ """
731
+ Set voxel and coordinate information based on dimensions and affine transformation.
732
+
733
+ This function initializes voxel dimensions (`xdim`, `ydim`, `zdim`) and an affine
734
+ transformation matrix (`affine`). It computes the inverse of the affine matrix,
735
+ converts voxel coordinates to real-world coordinates, and sets up spin boxes
736
+ for position and coordinate controls.
737
+
738
+ Parameters
739
+ ----------
740
+ xdim : Any
741
+ The number of voxels along the x-axis.
742
+ ydim : Any
743
+ The number of voxels along the y-axis.
744
+ zdim : Any
745
+ The number of voxels along the z-axis.
746
+ affine : Any
747
+ The 4x4 affine transformation matrix mapping voxel coordinates to real-world
748
+ coordinates.
749
+
750
+ Returns
751
+ -------
752
+ None
753
+ This function does not return any value.
754
+
755
+ Notes
756
+ -----
757
+ - The function assumes the existence of helper methods such as `vox2real`, `setupSpinBox`,
758
+ `getXpos`, `getYpos`, `getZpos`, `getXcoord`, `getYcoord`, and `getZcoord`.
759
+ - Spin boxes for voxel positions (`XPosSpinBox`, `YPosSpinBox`, `ZPosSpinBox`) and
760
+ coordinate positions (`XCoordSpinBox`, `YCoordSpinBox`, `ZCoordSpinBox`) are initialized
761
+ with appropriate ranges and step sizes.
762
+
763
+ Examples
764
+ --------
765
+ >>> setXYZInfo(64, 64, 32, affine_matrix)
766
+ # Initializes voxel and coordinate settings based on given dimensions and affine.
767
+ """
333
768
  self.xdim = xdim
334
769
  self.ydim = ydim
335
770
  self.zdim = zdim
@@ -372,7 +807,44 @@ class xyztlocation(QtWidgets.QWidget):
372
807
  self.zcoord,
373
808
  )
374
809
 
375
- def setTInfo(self, tdim, tr, toffset):
810
+ def setTInfo(self, tdim: Any, tr: Any, toffset: Any) -> None:
811
+ """
812
+ Set time information and configure time-related UI elements.
813
+
814
+ This function initializes time coordinates and configures spin boxes, sliders,
815
+ and movie controls based on the provided time dimensions and transformation
816
+ parameters.
817
+
818
+ Parameters
819
+ ----------
820
+ tdim : Any
821
+ Time dimension parameter used for setting up UI elements and coordinate
822
+ calculations.
823
+ tr : Any
824
+ Time transformation parameter used for coordinate transformations.
825
+ toffset : Any
826
+ Time offset parameter used for setting up time coordinates.
827
+
828
+ Returns
829
+ -------
830
+ None
831
+ This function does not return any value.
832
+
833
+ Notes
834
+ -----
835
+ The function performs the following operations:
836
+ 1. Sets instance variables tdim, toffset, and tr
837
+ 2. Converts time position to real coordinates using tr2real method
838
+ 3. Configures TPosSpinBox with appropriate range and initial value
839
+ 4. Calculates time coordinate bounds and configures TCoordSpinBox
840
+ 5. Sets up TimeSlider with time position range
841
+ 6. Configures runMovieButton for movie playback control
842
+
843
+ Examples
844
+ --------
845
+ >>> setTInfo(100, 0.1, 0.0)
846
+ >>> # Configures time information for 100 time steps with transformation 0.1
847
+ """
376
848
  self.tdim = tdim
377
849
  self.toffset = toffset
378
850
  self.tr = tr
@@ -393,7 +865,38 @@ class xyztlocation(QtWidgets.QWidget):
393
865
  self.setupTimeSlider(self.TimeSlider, self.getTimeSlider, 0, self.tdim - 1, self.tpos)
394
866
  self.setupRunMovieButton(self.runMovieButton, self.runMovieToggle)
395
867
 
396
- def setupRunMovieButton(self, thebutton, thehandler):
868
+ def setupRunMovieButton(self, thebutton: Any, thehandler: Any) -> None:
869
+ """
870
+ Set up the movie button with appropriate text and click handler.
871
+
872
+ This function configures a button to serve as a movie control button by
873
+ setting its text to "Start Movie" and connecting it to the provided handler.
874
+ The button initialization is conditional based on verbosity level.
875
+
876
+ Parameters
877
+ ----------
878
+ thebutton : Any
879
+ The button widget to be configured. Expected to have setText() and
880
+ clicked.connect() methods.
881
+ thehandler : Any
882
+ The callback function or method to be connected to the button's clicked signal.
883
+
884
+ Returns
885
+ -------
886
+ None
887
+ This function does not return any value.
888
+
889
+ Notes
890
+ -----
891
+ The button configuration only occurs if `thebutton` is not None. When
892
+ verbosity level is greater than 1, a message is printed to indicate
893
+ the button initialization.
894
+
895
+ Examples
896
+ --------
897
+ >>> setupRunMovieButton(button_widget, movie_handler)
898
+ >>> # Button text set to "Start Movie" and connected to handler
899
+ """
397
900
  global verbosity
398
901
 
399
902
  if thebutton is not None:
@@ -402,13 +905,102 @@ class xyztlocation(QtWidgets.QWidget):
402
905
  thebutton.setText("Start Movie")
403
906
  thebutton.clicked.connect(thehandler)
404
907
 
405
- def setupTimeSlider(self, theslider, thehandler, minval, maxval, currentval):
908
+ def setupTimeSlider(
909
+ self, theslider: Any, thehandler: Any, minval: Any, maxval: Any, currentval: Any
910
+ ) -> None:
911
+ """
912
+ Set up a time slider with specified parameters and connect event handler.
913
+
914
+ This function configures a slider widget for time selection by setting its range,
915
+ step size, and connecting a value change handler.
916
+
917
+ Parameters
918
+ ----------
919
+ theslider : Any
920
+ The slider widget to be configured. Expected to have methods setRange(),
921
+ setSingleStep(), and valueChanged.connect().
922
+ thehandler : Any
923
+ The event handler function to be connected to the slider's valueChanged signal.
924
+ minval : Any
925
+ The minimum value for the slider range.
926
+ maxval : Any
927
+ The maximum value for the slider range.
928
+ currentval : Any
929
+ The current value of the slider (not used in this implementation).
930
+
931
+ Returns
932
+ -------
933
+ None
934
+ This function does not return any value.
935
+
936
+ Notes
937
+ -----
938
+ The function only configures the slider if it is not None. The slider's single
939
+ step is set to 1, and the valueChanged signal is connected to the provided handler.
940
+
941
+ Examples
942
+ --------
943
+ >>> slider = QSlider()
944
+ >>> def handler(value):
945
+ ... print(f"Slider value: {value}")
946
+ >>> setupTimeSlider(self, slider, handler, 0, 100, 50)
947
+ """
406
948
  if theslider is not None:
407
949
  theslider.setRange(minval, maxval)
408
950
  theslider.setSingleStep(1)
409
951
  theslider.valueChanged.connect(thehandler)
410
952
 
411
- def setupSpinBox(self, thespinbox, thehandler, minval, maxval, stepsize, currentval):
953
+ def setupSpinBox(
954
+ self,
955
+ thespinbox: Any,
956
+ thehandler: Any,
957
+ minval: Any,
958
+ maxval: Any,
959
+ stepsize: Any,
960
+ currentval: Any,
961
+ ) -> None:
962
+ """
963
+ Configure a spin box widget with specified parameters and connect its signal.
964
+
965
+ This function sets up a QSpinBox widget with the provided range, step size, and
966
+ initial value. It also configures wrapping behavior and connects the valueChanged
967
+ signal to the specified handler function.
968
+
969
+ Parameters
970
+ ----------
971
+ thespinbox : Any
972
+ The spin box widget to be configured. Expected to be a QSpinBox or compatible
973
+ widget with setRange, setSingleStep, setValue, setWrapping, and valueChanged
974
+ methods.
975
+ thehandler : Any
976
+ The callback function to be connected to the spin box's valueChanged signal.
977
+ This function will be called whenever the spin box value changes.
978
+ minval : Any
979
+ The minimum value allowed in the spin box.
980
+ maxval : Any
981
+ The maximum value allowed in the spin box.
982
+ stepsize : Any
983
+ The step size for incrementing/decrementing the spin box value.
984
+ currentval : Any
985
+ The initial value to set in the spin box.
986
+
987
+ Returns
988
+ -------
989
+ None
990
+ This function does not return any value.
991
+
992
+ Notes
993
+ -----
994
+ The function performs no validation on input parameters. It assumes that the
995
+ spin box widget has the required methods and that the handler is callable.
996
+ The spin box is configured with wrapping enabled and keyboard tracking disabled.
997
+
998
+ Examples
999
+ --------
1000
+ >>> setupSpinBox(spinbox, on_value_changed, 0, 100, 1, 50)
1001
+ >>> # Configures spinbox to range from 0 to 100 with step size 1,
1002
+ >>> # initial value 50, wrapping enabled, and keyboard tracking disabled.
1003
+ """
412
1004
  if thespinbox is not None:
413
1005
  thespinbox.setRange(minval, maxval)
414
1006
  thespinbox.setSingleStep(stepsize)
@@ -417,7 +1009,39 @@ class xyztlocation(QtWidgets.QWidget):
417
1009
  thespinbox.setKeyboardTracking(False)
418
1010
  thespinbox.valueChanged.connect(thehandler)
419
1011
 
420
- def updateXYZValues(self, emitsignal=True):
1012
+ def updateXYZValues(self, emitsignal: bool = True) -> None:
1013
+ """
1014
+ Update the values of XYZ spinbox widgets with current coordinate values.
1015
+
1016
+ This method updates the displayed values in the XYZ position and coordinate spinbox
1017
+ widgets with the current coordinate values stored in the instance. It can optionally
1018
+ emit a signal to notify other components of the update.
1019
+
1020
+ Parameters
1021
+ ----------
1022
+ emitsignal : bool, optional
1023
+ If True (default), emits the updatedXYZ signal after updating the spinbox values.
1024
+ If False, updates the spinbox values without emitting the signal.
1025
+
1026
+ Returns
1027
+ -------
1028
+ None
1029
+ This method does not return any value.
1030
+
1031
+ Notes
1032
+ -----
1033
+ The method checks if each spinbox widget exists (is not None) before attempting
1034
+ to set its value. This prevents errors when widgets are not initialized or
1035
+ have been deleted.
1036
+
1037
+ Examples
1038
+ --------
1039
+ >>> updateXYZValues()
1040
+ # Updates all XYZ spinbox values and emits signal
1041
+
1042
+ >>> updateXYZValues(emitsignal=False)
1043
+ # Updates all XYZ spinbox values without emitting signal
1044
+ """
421
1045
  # print('resetting XYZ spinbox values')
422
1046
  if self.XPosSpinBox is not None:
423
1047
  self.XPosSpinBox.setValue(self.xpos)
@@ -435,7 +1059,48 @@ class xyztlocation(QtWidgets.QWidget):
435
1059
  if emitsignal:
436
1060
  self.updatedXYZ.emit()
437
1061
 
438
- def updateTValues(self):
1062
+ def updateTValues(self) -> None:
1063
+ """
1064
+ Update T values and ranges for spinboxes and slider based on current time coordinates.
1065
+
1066
+ This method updates the state of T-related UI elements (spinboxes and slider)
1067
+ based on the current time position and coordinate values. It ensures that the
1068
+ UI elements reflect the correct current values and valid ranges for time
1069
+ positioning and coordinate display.
1070
+
1071
+ Parameters
1072
+ ----------
1073
+ self : object
1074
+ The instance of the class containing the method, which should have the
1075
+ following attributes:
1076
+ - TPosSpinBox: QSpinBox for time position
1077
+ - TCoordSpinBox: QSpinBox for time coordinate
1078
+ - TimeSlider: QSlider for time positioning
1079
+ - tpos: Current time position value
1080
+ - tcoord: Current time coordinate value
1081
+ - tdim: Total time dimension
1082
+ - tr2real: Method to convert time coordinates to real values
1083
+
1084
+ Returns
1085
+ -------
1086
+ None
1087
+ This method does not return any value.
1088
+
1089
+ Notes
1090
+ -----
1091
+ The method checks if each UI element exists before attempting to update it.
1092
+ For TCoordSpinBox, the range is calculated based on the minimum and maximum
1093
+ real values of the time coordinate range.
1094
+
1095
+ Examples
1096
+ --------
1097
+ >>> updateTValues()
1098
+ # Updates all T-related UI elements with current time values and ranges
1099
+
1100
+ See Also
1101
+ --------
1102
+ emit : Emits the updatedT signal after updating UI elements
1103
+ """
439
1104
  # print('resetting T spinbox values')
440
1105
  if self.TPosSpinBox is not None:
441
1106
  self.TPosSpinBox.setValue(self.tpos)
@@ -453,34 +1118,254 @@ class xyztlocation(QtWidgets.QWidget):
453
1118
  # print('done resetting T spinbox values')
454
1119
  self.updatedT.emit()
455
1120
 
456
- def real2tr(self, time):
1121
+ def real2tr(self, time: Any) -> None:
1122
+ """
1123
+ Convert real time to trigger time.
1124
+
1125
+ Parameters
1126
+ ----------
1127
+ time : Any
1128
+ The real time value to be converted to trigger time.
1129
+
1130
+ Returns
1131
+ -------
1132
+ int
1133
+ The converted trigger time value.
1134
+
1135
+ Notes
1136
+ -----
1137
+ This function performs a linear transformation from real time to trigger time
1138
+ using the formula: tr = round((time - toffset) / tr), where toffset and tr
1139
+ are attributes of the class instance.
1140
+
1141
+ Examples
1142
+ --------
1143
+ >>> obj = MyClass()
1144
+ >>> obj.toffset = 10.5
1145
+ >>> obj.tr = 0.1
1146
+ >>> obj.real2tr(11.0)
1147
+ 45
1148
+ """
457
1149
  return int(np.round((time - self.toffset) / self.tr, 0))
458
1150
 
459
- def tr2real(self, tpos):
1151
+ def tr2real(self, tpos: Any) -> None:
1152
+ """
1153
+ Convert time position to real time.
1154
+
1155
+ Parameters
1156
+ ----------
1157
+ tpos : Any
1158
+ Time position to be converted to real time. Type can vary depending on
1159
+ the specific implementation context.
1160
+
1161
+ Returns
1162
+ -------
1163
+ None
1164
+ This method returns the result of the calculation: `self.toffset + self.tr * tpos`
1165
+ but does not explicitly return a value in the function body.
1166
+
1167
+ Notes
1168
+ -----
1169
+ This function performs a linear transformation from time position to real time
1170
+ using the formula: real_time = toffset + tr * tpos
1171
+
1172
+ Examples
1173
+ --------
1174
+ >>> obj.tr2real(5)
1175
+ # Returns: self.toffset + self.tr * 5
1176
+ """
460
1177
  return self.toffset + self.tr * tpos
461
1178
 
462
- def real2vox(self, xcoord, ycoord, zcoord):
1179
+ def real2vox(self, xcoord: Any, ycoord: Any, zcoord: Any) -> None:
1180
+ """
1181
+ Convert real coordinates to voxel coordinates using inverse affine transformation.
1182
+
1183
+ This function transforms continuous real-world coordinates into discrete voxel coordinates
1184
+ by applying the inverse affine transformation matrix. The result is rounded to the nearest
1185
+ integer values to obtain valid voxel indices.
1186
+
1187
+ Parameters
1188
+ ----------
1189
+ xcoord : Any
1190
+ X-coordinate in real-world space
1191
+ ycoord : Any
1192
+ Y-coordinate in real-world space
1193
+ zcoord : Any
1194
+ Z-coordinate in real-world space
1195
+
1196
+ Returns
1197
+ -------
1198
+ tuple of int
1199
+ Tuple containing (x, y, z) voxel coordinates as integers
1200
+
1201
+ Notes
1202
+ -----
1203
+ The transformation uses the inverse affine matrix stored in ``self.invaffine``.
1204
+ Coordinates are rounded to the nearest integer using ``np.round``.
1205
+
1206
+ Examples
1207
+ --------
1208
+ >>> voxel_coords = img.real2vox(10.7, 15.2, 20.8)
1209
+ >>> print(voxel_coords)
1210
+ (11, 15, 21)
1211
+ """
463
1212
  x, y, z = apply_affine(self.invaffine, [xcoord, ycoord, zcoord])
464
1213
  return int(np.round(x, 0)), int(np.round(y, 0)), int(np.round(z, 0))
465
1214
 
466
- def vox2real(self, xpos, ypos, zpos):
1215
+ def vox2real(self, xpos: Any, ypos: Any, zpos: Any) -> None:
1216
+ """
1217
+ Convert voxel coordinates to real-world coordinates using the affine transformation.
1218
+
1219
+ This function applies the affine transformation matrix to convert voxel coordinates
1220
+ to real-world (scanner) coordinates. The affine matrix contains the necessary
1221
+ scaling, rotation, and translation information to map voxel indices to physical space.
1222
+
1223
+ Parameters
1224
+ ----------
1225
+ xpos : Any
1226
+ X coordinate in voxel space
1227
+ ypos : Any
1228
+ Y coordinate in voxel space
1229
+ zpos : Any
1230
+ Z coordinate in voxel space
1231
+
1232
+ Returns
1233
+ -------
1234
+ None
1235
+ The function returns the result of apply_affine function which contains
1236
+ the real-world coordinates corresponding to the input voxel coordinates
1237
+
1238
+ Notes
1239
+ -----
1240
+ The affine transformation matrix is stored in ``self.affine`` and contains
1241
+ the spatial transformation parameters needed to map voxel coordinates to
1242
+ scanner coordinates. This is commonly used in neuroimaging applications
1243
+ where voxel indices need to be converted to real-world coordinates for
1244
+ anatomical localization.
1245
+
1246
+ Examples
1247
+ --------
1248
+ >>> # Assuming self.affine is properly initialized
1249
+ >>> real_coords = vox2real(10, 20, 30)
1250
+ >>> print(real_coords)
1251
+ [x_real, y_real, z_real]
1252
+ """
467
1253
  return apply_affine(self.affine, [xpos, ypos, zpos])
468
1254
 
469
- def setXYZpos(self, xpos, ypos, zpos, emitsignal=True):
1255
+ def setXYZpos(self, xpos: Any, ypos: Any, zpos: Any, emitsignal: bool = True) -> None:
1256
+ """
1257
+ Set the XYZ position coordinates and update corresponding values.
1258
+
1259
+ Parameters
1260
+ ----------
1261
+ xpos : Any
1262
+ X coordinate position value
1263
+ ypos : Any
1264
+ Y coordinate position value
1265
+ zpos : Any
1266
+ Z coordinate position value
1267
+ emitsignal : bool, default=True
1268
+ Whether to emit a signal after updating coordinates
1269
+
1270
+ Returns
1271
+ -------
1272
+ None
1273
+ This method does not return any value
1274
+
1275
+ Notes
1276
+ -----
1277
+ This method updates the internal position coordinates and converts voxel
1278
+ coordinates to real-world coordinates using the `vox2real` method. The
1279
+ `updateXYZValues` method is called to propagate the changes.
1280
+
1281
+ Examples
1282
+ --------
1283
+ >>> obj.setXYZpos(10, 20, 30)
1284
+ >>> obj.setXYZpos(10, 20, 30, emitsignal=False)
1285
+ """
470
1286
  self.xpos = xpos
471
1287
  self.ypos = ypos
472
1288
  self.zpos = zpos
473
1289
  self.xcoord, self.ycoord, self.zcoord = self.vox2real(self.xpos, self.ypos, self.zpos)
474
1290
  self.updateXYZValues(emitsignal=emitsignal)
475
1291
 
476
- def setXYZcoord(self, xcoord, ycoord, zcoord, emitsignal=True):
1292
+ def setXYZcoord(self, xcoord: Any, ycoord: Any, zcoord: Any, emitsignal: bool = True) -> None:
1293
+ """
1294
+ Set the XYZ coordinates and update corresponding voxel positions.
1295
+
1296
+ This method assigns the provided XYZ coordinates to the object's coordinate attributes
1297
+ and converts them to voxel coordinates using the real2vox transformation. It then
1298
+ updates the XYZ values and optionally emits a signal.
1299
+
1300
+ Parameters
1301
+ ----------
1302
+ xcoord : Any
1303
+ The x-coordinate value to be set
1304
+ ycoord : Any
1305
+ The y-coordinate value to be set
1306
+ zcoord : Any
1307
+ The z-coordinate value to be set
1308
+ emitsignal : bool, optional
1309
+ Whether to emit a signal after updating coordinates (default is True)
1310
+
1311
+ Returns
1312
+ -------
1313
+ None
1314
+ This method does not return any value
1315
+
1316
+ Notes
1317
+ -----
1318
+ The method internally calls `real2vox` to convert real coordinates to voxel coordinates
1319
+ and `updateXYZValues` to propagate the changes. The `emitsignal` parameter controls
1320
+ whether the signal emission is skipped for performance reasons when multiple updates
1321
+ are needed.
1322
+
1323
+ Examples
1324
+ --------
1325
+ >>> obj.setXYZcoord(10.5, 20.3, 5.0)
1326
+ >>> obj.setXYZcoord(10.5, 20.3, 5.0, emitsignal=False)
1327
+ """
477
1328
  self.xcoord = xcoord
478
1329
  self.ycoord = ycoord
479
1330
  self.zcoord = zcoord
480
1331
  self.xpos, self.ypos, self.zpos = self.real2vox(self.xcoord, self.ycoord, self.zcoord)
481
1332
  self.updateXYZValues(emitsignal=emitsignal)
482
1333
 
483
- def setTpos(self, tpos):
1334
+ def setTpos(self, tpos: Any) -> None:
1335
+ """
1336
+ Set the temporal position and update related coordinates and values.
1337
+
1338
+ This method updates the temporal position (`tpos`) of the object, ensuring it
1339
+ does not exceed the maximum temporal dimension (`tdim`). When the position
1340
+ changes, the corresponding real coordinates are calculated and the temporal
1341
+ values are updated accordingly.
1342
+
1343
+ Parameters
1344
+ ----------
1345
+ tpos : Any
1346
+ The temporal position to set. If greater than `self.tdim`, it will be
1347
+ capped at `self.tdim`.
1348
+
1349
+ Returns
1350
+ -------
1351
+ None
1352
+ This method modifies the object in-place and does not return any value.
1353
+
1354
+ Notes
1355
+ -----
1356
+ The method performs an equality check before updating to avoid unnecessary
1357
+ computations when the position remains unchanged.
1358
+
1359
+ Examples
1360
+ --------
1361
+ >>> obj.setTpos(5)
1362
+ >>> obj.tpos
1363
+ 5
1364
+
1365
+ >>> obj.setTpos(10)
1366
+ >>> obj.tpos
1367
+ 5 # capped at tdim = 5
1368
+ """
484
1369
  if tpos > self.tdim:
485
1370
  tpos = self.tdim
486
1371
  if self.tpos != tpos:
@@ -488,13 +1373,71 @@ class xyztlocation(QtWidgets.QWidget):
488
1373
  self.tcoord = self.tr2real(self.tpos)
489
1374
  self.updateTValues()
490
1375
 
491
- def setTcoord(self, tcoord):
1376
+ def setTcoord(self, tcoord: Any) -> None:
1377
+ """
1378
+ Set the t-coordinate and update related values.
1379
+
1380
+ Parameters
1381
+ ----------
1382
+ tcoord : Any
1383
+ The new t-coordinate value to be set. Type can vary depending on the implementation.
1384
+
1385
+ Returns
1386
+ -------
1387
+ None
1388
+ This method does not return any value.
1389
+
1390
+ Notes
1391
+ -----
1392
+ If the provided t-coordinate differs from the current one, this method will:
1393
+ 1. Update the internal `tcoord` attribute
1394
+ 2. Convert the new t-coordinate to tr-coordinates using `real2tr` method
1395
+ 3. Update all related t-values by calling `updateTValues()`
1396
+
1397
+ Examples
1398
+ --------
1399
+ >>> obj.setTcoord(5.0)
1400
+ >>> obj.tcoord
1401
+ 5.0
1402
+ >>> obj.tpos
1403
+ [converted_tr_coordinates]
1404
+ """
492
1405
  if self.tcoord != tcoord:
493
1406
  self.tcoord = tcoord
494
1407
  self.tpos = self.real2tr(self.tcoord)
495
1408
  self.updateTValues()
496
1409
 
497
- def getXpos(self, event):
1410
+ def getXpos(self, event: Any) -> None:
1411
+ """
1412
+ Update the X coordinate position and related values based on spin box input.
1413
+
1414
+ This method retrieves the current value from the X position spin box, compares
1415
+ it with the stored X position, and updates the position if changed. When updated,
1416
+ it converts the voxel coordinates to real-world coordinates and triggers an
1417
+ update of all coordinate values.
1418
+
1419
+ Parameters
1420
+ ----------
1421
+ event : Any
1422
+ Event object passed to the method (typically from GUI interaction).
1423
+ This parameter is not used within the method implementation.
1424
+
1425
+ Returns
1426
+ -------
1427
+ None
1428
+ This method does not return any value.
1429
+
1430
+ Notes
1431
+ -----
1432
+ The method performs coordinate conversion using the `vox2real` method and
1433
+ triggers an update of all coordinate values through `updateXYZValues` with
1434
+ `emitsignal=True` to propagate changes to connected components.
1435
+
1436
+ Examples
1437
+ --------
1438
+ >>> getXpos(event)
1439
+ # Updates X position and related coordinates when spin box value changes
1440
+ """
498
1441
  # print('entering getXpos')
499
1442
  newx = int(self.XPosSpinBox.value())
500
1443
  if self.xpos != newx:
@@ -502,7 +1445,41 @@ class xyztlocation(QtWidgets.QWidget):
502
1445
  self.xcoord, self.ycoord, self.zcoord = self.vox2real(self.xpos, self.ypos, self.zpos)
503
1446
  self.updateXYZValues(emitsignal=True)
504
1447
 
505
- def getYpos(self, event):
1448
+ def getYpos(self, event: Any) -> None:
1449
+ """
1450
+ Update Y position coordinate and related values.
1451
+
1452
+ This method retrieves the current Y position from the spin box widget,
1453
+ updates the internal Y position attribute if it has changed, and then
1454
+ recalculates the corresponding real-world coordinates using the voxel-to-real
1455
+ transformation. Finally, it updates the XYZ coordinate values and emits a
1456
+ signal to notify other components of the change.
1457
+
1458
+ Parameters
1459
+ ----------
1460
+ event : Any
1461
+ Event object passed by the GUI framework when the spin box value changes.
1462
+ This parameter is typically not used within the method but is required
1463
+ for compatibility with Qt's signal-slot mechanism.
1464
+
1465
+ Returns
1466
+ -------
1467
+ None
1468
+ This method does not return any value.
1469
+
1470
+ Notes
1471
+ -----
1472
+ The method performs a comparison between the current Y position and the
1473
+ new value from the spin box. If they differ, the method updates the internal
1474
+ state and triggers coordinate recalculation. The voxel-to-real transformation
1475
+ is handled by the `vox2real` method which converts voxel coordinates to
1476
+ real-world coordinates.
1477
+
1478
+ Examples
1479
+ --------
1480
+ >>> getYpos(event)
1481
+ # Updates Y position and related coordinates when spin box value changes
1482
+ """
506
1483
  # print('entering getYpos')
507
1484
  newy = int(self.YPosSpinBox.value())
508
1485
  if self.ypos != newy:
@@ -510,7 +1487,36 @@ class xyztlocation(QtWidgets.QWidget):
510
1487
  self.xcoord, self.ycoord, self.zcoord = self.vox2real(self.xpos, self.ypos, self.zpos)
511
1488
  self.updateXYZValues(emitsignal=True)
512
1489
 
513
- def getZpos(self, event):
1490
+ def getZpos(self, event: Any) -> None:
1491
+ """
1492
+ Update Z position and corresponding coordinates based on spin box value.
1493
+
1494
+ This method retrieves the current Z position value from the Z position spin box,
1495
+ updates the internal zpos attribute if the value has changed, and calculates
1496
+ the corresponding real-world coordinates using the vox2real transformation.
1497
+ It then updates the XYZ coordinate display values.
1498
+
1499
+ Parameters
1500
+ ----------
1501
+ event : Any
1502
+ Event object passed to the method (typically from GUI interaction).
1503
+ The specific content of this parameter is not used within the method.
1504
+
1505
+ Returns
1506
+ -------
1507
+ None
1508
+ This method does not return any value.
1509
+
1510
+ Notes
1511
+ -----
1512
+ The method only updates coordinates and emits signals when the Z position
1513
+ value actually changes from the current stored value.
1514
+
1515
+ Examples
1516
+ --------
1517
+ >>> getZpos(event=None)
1518
+ # Updates zpos and corresponding coordinates if value changed
1519
+ """
514
1520
  # print('entering getZpos')
515
1521
  newz = int(self.ZPosSpinBox.value())
516
1522
  if self.zpos != newz:
@@ -518,7 +1524,38 @@ class xyztlocation(QtWidgets.QWidget):
518
1524
  self.xcoord, self.ycoord, self.zcoord = self.vox2real(self.xpos, self.ypos, self.zpos)
519
1525
  self.updateXYZValues(emitsignal=True)
520
1526
 
521
- def getTpos(self, event):
1527
+ def getTpos(self, event: Any) -> None:
1528
+ """
1529
+ Update time position and related properties based on spin box value.
1530
+
1531
+ This method retrieves the current value from the time position spin box,
1532
+ updates the internal time position tracking, converts it to real coordinates,
1533
+ and manages the movie timer if the movie is running.
1534
+
1535
+ Parameters
1536
+ ----------
1537
+ event : Any
1538
+ Event object passed to the method (typically from GUI interaction).
1539
+ The specific content of this parameter depends on the calling context.
1540
+
1541
+ Returns
1542
+ -------
1543
+ None
1544
+ This method does not return any value.
1545
+
1546
+ Notes
1547
+ -----
1548
+ - If the new time position differs from the current one, the method updates
1549
+ both `tpos` and `tcoord` attributes
1550
+ - When the movie is running, the movie timer is stopped and restarted with
1551
+ the new time position value
1552
+ - The `updateTValues()` method is called to refresh all time-related displays
1553
+
1554
+ Examples
1555
+ --------
1556
+ >>> getTpos(event)
1557
+ # Updates time position and related properties based on spin box value
1558
+ """
522
1559
  # print('entering getTpos')
523
1560
  newt = int(self.TPosSpinBox.value())
524
1561
  if self.tpos != newt:
@@ -529,59 +1566,314 @@ class xyztlocation(QtWidgets.QWidget):
529
1566
  self.movieTimer.start(int(self.tpos))
530
1567
  self.updateTValues()
531
1568
 
532
- def getXcoord(self, event):
1569
+ def getXcoord(self, event: Any) -> None:
1570
+ """
1571
+ Update the X coordinate value and corresponding voxel coordinates.
1572
+
1573
+ This method retrieves the current value from the X coordinate spin box and updates
1574
+ the internal X coordinate value if it has changed. When the coordinate changes,
1575
+ the corresponding voxel coordinates are recalculated and the XYZ values are updated.
1576
+
1577
+ Parameters
1578
+ ----------
1579
+ event : Any
1580
+ The event object associated with the coordinate change. This parameter is
1581
+ typically provided by Qt event handling mechanisms but is not used within
1582
+ the method implementation.
1583
+
1584
+ Returns
1585
+ -------
1586
+ None
1587
+ This method does not return any value.
1588
+
1589
+ Notes
1590
+ -----
1591
+ The method triggers an update of voxel coordinates using the `real2vox` conversion
1592
+ function and emits a signal to update the XYZ display values when the coordinate
1593
+ changes.
1594
+
1595
+ Examples
1596
+ --------
1597
+ >>> getXcoord(event)
1598
+ # Updates X coordinate and corresponding voxel values
1599
+ """
533
1600
  newxcoord = self.XCoordSpinBox.value()
534
1601
  if self.xcoord != newxcoord:
535
1602
  self.xcoord = newxcoord
536
1603
  self.xpos, self.ypos, self.zpos = self.real2vox(self.xcoord, self.ycoord, self.zcoord)
537
1604
  self.updateXYZValues(emitsignal=True)
538
1605
 
539
- def getYcoord(self, event):
1606
+ def getYcoord(self, event: Any) -> None:
1607
+ """
1608
+ Update Y coordinate and related voxel coordinates when Y coordinate spin box value changes.
1609
+
1610
+ This method is typically called when the Y coordinate spin box widget value is changed.
1611
+ It updates the internal Y coordinate value and recalculates the corresponding voxel coordinates
1612
+ using the real-to-voxel conversion function. The XYZ values are then updated and signal is emitted
1613
+ to notify other components of the change.
1614
+
1615
+ Parameters
1616
+ ----------
1617
+ event : Any
1618
+ Event object triggered by the spin box value change. This parameter is typically
1619
+ provided by Qt's signal-slot mechanism but is not used within the method.
1620
+
1621
+ Returns
1622
+ -------
1623
+ None
1624
+ This method does not return any value.
1625
+
1626
+ Notes
1627
+ -----
1628
+ The method only updates the coordinates and emits signals when the new Y coordinate
1629
+ value differs from the current stored value. This prevents unnecessary updates when
1630
+ the spin box value hasn't actually changed.
1631
+
1632
+ Examples
1633
+ --------
1634
+ >>> getYcoord(event)
1635
+ # Updates self.ycoord and recalculates voxel coordinates when spin box value changes
1636
+ """
540
1637
  newycoord = self.YCoordSpinBox.value()
541
1638
  if self.ycoord != newycoord:
542
1639
  self.ycoord = newycoord
543
1640
  self.xpos, self.ypos, self.zpos = self.real2vox(self.xcoord, self.ycoord, self.zcoord)
544
1641
  self.updateXYZValues(emitsignal=True)
545
1642
 
546
- def getZcoord(self, event):
1643
+ def getZcoord(self, event: Any) -> None:
1644
+ """
1645
+ Update Z coordinate and related position values.
1646
+
1647
+ This method retrieves the current Z coordinate value from the spin box widget,
1648
+ updates the internal Z coordinate attribute if it has changed, and then
1649
+ converts the real coordinates to voxel coordinates. Finally, it updates the
1650
+ XYZ value displays and emits a signal to notify other components of the change.
1651
+
1652
+ Parameters
1653
+ ----------
1654
+ event : Any
1655
+ The event that triggered this method call. Typically a Qt event object
1656
+ or None if called programmatically.
1657
+
1658
+ Returns
1659
+ -------
1660
+ None
1661
+ This method does not return any value.
1662
+
1663
+ Notes
1664
+ -----
1665
+ The method performs coordinate conversion using the `real2vox` method and
1666
+ updates the internal position attributes (`xpos`, `ypos`, `zpos`). It also
1667
+ emits a signal through `updateXYZValues` to notify other components of the
1668
+ coordinate change.
1669
+
1670
+ Examples
1671
+ --------
1672
+ >>> getZcoord(event=None)
1673
+ # Updates Z coordinate and related position values
1674
+ """
547
1675
  newzcoord = self.ZCoordSpinBox.value()
548
1676
  if self.zcoord != newzcoord:
549
1677
  self.zcoord = newzcoord
550
1678
  self.xpos, self.ypos, self.zpos = self.real2vox(self.xcoord, self.ycoord, self.zcoord)
551
1679
  self.updateXYZValues(emitsignal=True)
552
1680
 
553
- def getTcoord(self, event):
1681
+ def getTcoord(self, event: Any) -> None:
1682
+ """
1683
+ Update time coordinate values based on spin box changes.
1684
+
1685
+ This method retrieves the current value from the TCoordSpinBox widget and
1686
+ updates the internal time coordinate tracking when a change is detected.
1687
+ It also calculates the corresponding real position and updates related values.
1688
+
1689
+ Parameters
1690
+ ----------
1691
+ event : Any
1692
+ Event object passed to the method (typically from GUI interactions).
1693
+ The specific content of this parameter depends on the calling context.
1694
+
1695
+ Returns
1696
+ -------
1697
+ None
1698
+ This method does not return any value.
1699
+
1700
+ Notes
1701
+ -----
1702
+ The method only updates internal state when the new coordinate value differs
1703
+ from the current stored value. This prevents unnecessary recalculations.
1704
+
1705
+ Examples
1706
+ --------
1707
+ >>> getTcoord(event)
1708
+ # Updates internal tcoord, tpos, and related values when spin box value changes
1709
+ """
554
1710
  newtcoord = self.TCoordSpinBox.value()
555
1711
  if self.tcoord != newtcoord:
556
1712
  self.tcoord = newtcoord
557
1713
  self.tpos = self.real2tr(self.tcoord)
558
1714
  self.updateTValues()
559
1715
 
560
- def getTimeSlider(self):
1716
+ def getTimeSlider(self) -> None:
1717
+ """
1718
+ Retrieve current time slider value and update related coordinates.
1719
+
1720
+ This method reads the current value from the time slider widget, converts
1721
+ it to real-time coordinates using the tr2real transformation function,
1722
+ and updates the time-related values in the system.
1723
+
1724
+ Returns
1725
+ -------
1726
+ None
1727
+ This method does not return any value but updates instance attributes
1728
+ self.tpos, self.tcoord, and triggers self.updateTValues().
1729
+
1730
+ Notes
1731
+ -----
1732
+ The method assumes that self.TimeSlider is a valid slider widget with a
1733
+ value() method, and that self.tr2real is a defined transformation function.
1734
+ The updateTValues() method is called after coordinate calculation to
1735
+ synchronize dependent time values.
1736
+
1737
+ Examples
1738
+ --------
1739
+ >>> getTimeSlider()
1740
+ # Updates self.tpos, self.tcoord, and calls self.updateTValues()
1741
+ """
561
1742
  self.tpos = self.TimeSlider.value()
562
1743
  self.tcoord = self.tr2real(self.tpos)
563
1744
  self.updateTValues()
564
1745
 
565
- def updateMovie(self):
1746
+ def updateMovie(self) -> None:
1747
+ """
1748
+ Update the movie position and related values.
1749
+
1750
+ This method advances the movie position by one step, wrapping around to the
1751
+ beginning when the end is reached. It also updates the temporal values and
1752
+ optionally prints debug information based on verbosity level.
1753
+
1754
+ Parameters
1755
+ ----------
1756
+ None
1757
+
1758
+ Returns
1759
+ -------
1760
+ None
1761
+ This method does not return any value.
1762
+
1763
+ Notes
1764
+ -----
1765
+ The method uses modulo arithmetic to cycle through temporal positions.
1766
+ When verbosity level is greater than 1, debug information including
1767
+ current position (tpos) and T coordinate value is printed to console.
1768
+
1769
+ Examples
1770
+ --------
1771
+ >>> updateMovie()
1772
+ # Advances movie position and updates related values
1773
+ """
566
1774
  # self.tpos = (self.tpos + 1) % self.tdim
567
1775
  self.setTpos((self.tpos + 1) % self.tdim)
568
1776
  self.updateTValues()
569
1777
  if verbosity > 1:
570
1778
  print(f"Tpos, t: {self.tpos}, {self.TCoordSpinBox.value()}")
571
1779
 
572
- def stopMovie(self):
1780
+ def stopMovie(self) -> None:
1781
+ """
1782
+ Stop the movie playback and reset the UI state.
1783
+
1784
+ This method stops the currently running movie by setting the movie running flag to False,
1785
+ stopping the movie timer, and updating the button text to "Start Movie" if the button exists.
1786
+
1787
+ Notes
1788
+ -----
1789
+ This method assumes that the class has the following attributes:
1790
+ - movierunning: boolean flag indicating if movie is currently running
1791
+ - movieTimer: timer object with a stop() method
1792
+ - runMovieButton: button widget with setText() method
1793
+
1794
+ Examples
1795
+ --------
1796
+ >>> player = MoviePlayer()
1797
+ >>> player.startMovie()
1798
+ >>> player.stopMovie()
1799
+ >>> player.movierunning
1800
+ False
1801
+ """
573
1802
  self.movierunning = False
574
1803
  self.movieTimer.stop()
575
1804
  if self.runMovieButton is not None:
576
1805
  self.runMovieButton.setText("Start Movie")
577
1806
 
578
- def startMovie(self):
1807
+ def startMovie(self) -> None:
1808
+ """
1809
+ Start movie playback and update UI controls.
1810
+
1811
+ This method initiates movie playback by setting the movie running flag to True,
1812
+ updating the button text to "Stop Movie" if the button exists, and starting
1813
+ the movie timer with the specified frame time.
1814
+
1815
+ Parameters
1816
+ ----------
1817
+ None
1818
+
1819
+ Returns
1820
+ -------
1821
+ None
1822
+ This method does not return any value.
1823
+
1824
+ Notes
1825
+ -----
1826
+ The method assumes that `self.movierunning`, `self.runMovieButton`, and
1827
+ `self.movieTimer` attributes are properly initialized before calling this method.
1828
+ The `self.frametime` attribute should contain the frame time in milliseconds.
1829
+
1830
+ Examples
1831
+ --------
1832
+ >>> movie_player.startMovie()
1833
+ >>> # Movie playback started, button text changed to "Stop Movie"
1834
+ """
579
1835
  self.movierunning = True
580
1836
  if self.runMovieButton is not None:
581
1837
  self.runMovieButton.setText("Stop Movie")
582
1838
  self.movieTimer.start(int(self.frametime))
583
1839
 
584
- def runMovieToggle(self, event):
1840
+ def runMovieToggle(self, event: Any) -> None:
1841
+ """
1842
+ Toggle movie playback state.
1843
+
1844
+ Toggles the movie playback state between running and stopped. If the movie is currently
1845
+ running, it will be stopped. If the movie is stopped, it will be started.
1846
+
1847
+ Parameters
1848
+ ----------
1849
+ event : Any
1850
+ The event that triggered the toggle action. Type and content may vary depending
1851
+ on the event source (e.g., button click, keyboard shortcut).
1852
+
1853
+ Returns
1854
+ -------
1855
+ None
1856
+ This method does not return any value.
1857
+
1858
+ Notes
1859
+ -----
1860
+ This function uses a global `verbosity` variable to control debug output. When
1861
+ verbosity level is greater than 1, informational messages are printed to the console
1862
+ indicating the current state and action being performed.
1863
+
1864
+ Examples
1865
+ --------
1866
+ >>> # Assuming self.movierunning is False
1867
+ >>> runMovieToggle(event=None)
1868
+ entering runMovieToggle
1869
+ movie is not running - turning on
1870
+ leaving runMovieToggle
1871
+ >>> # Assuming self.movierunning is True
1872
+ >>> runMovieToggle(event=None)
1873
+ entering runMovieToggle
1874
+ movie is running - turning off
1875
+ leaving runMovieToggle
1876
+ """
585
1877
  if verbosity > 1:
586
1878
  print("entering runMovieToggle")
587
1879
  if self.movierunning:
@@ -595,7 +1887,32 @@ class xyztlocation(QtWidgets.QWidget):
595
1887
  if verbosity > 1:
596
1888
  print("leaving runMovieToggle")
597
1889
 
598
- def setFrametime(self, frametime):
1890
+ def setFrametime(self, frametime: Any) -> None:
1891
+ """
1892
+ Set the frame time for the movie timer.
1893
+
1894
+ Parameters
1895
+ ----------
1896
+ frametime : Any
1897
+ The frame time to set. Typically an integer or float representing
1898
+ the time interval in milliseconds between frames.
1899
+
1900
+ Returns
1901
+ -------
1902
+ None
1903
+ This method does not return any value.
1904
+
1905
+ Notes
1906
+ -----
1907
+ If the movie is currently running, this method will stop the movie timer,
1908
+ update the frame time, and then restart the timer with the new frame time.
1909
+ If the movie is not running, only the frame time will be updated.
1910
+
1911
+ Examples
1912
+ --------
1913
+ >>> player.setFrametime(100)
1914
+ >>> player.setFrametime(50.5)
1915
+ """
599
1916
  if self.movierunning:
600
1917
  self.movieTimer.stop()
601
1918
  self.frametime = frametime
@@ -603,7 +1920,39 @@ class xyztlocation(QtWidgets.QWidget):
603
1920
  self.movieTimer.start(int(self.frametime))
604
1921
 
605
1922
 
606
- def logStatus(thetextbox, thetext):
1923
+ def logStatus(thetextbox: Any, thetext: Any) -> None:
1924
+ """
1925
+ Log text to a text box and scroll to the bottom.
1926
+
1927
+ This function inserts text into a text box widget and ensures the scroll bar
1928
+ is positioned at the bottom to show the newly added text. The behavior differs
1929
+ slightly depending on the PyQt binding being used.
1930
+
1931
+ Parameters
1932
+ ----------
1933
+ thetextbox : Any
1934
+ A text box widget (typically QTextEdit or QPlainTextEdit) where the text
1935
+ will be inserted.
1936
+ thetext : Any
1937
+ The text string to be inserted into the text box.
1938
+
1939
+ Returns
1940
+ -------
1941
+ None
1942
+ This function does not return any value.
1943
+
1944
+ Notes
1945
+ -----
1946
+ - For PyQt5, the cursor is moved to the end before inserting text
1947
+ - For PyQt6 and PySide6, no special cursor handling is performed
1948
+ - The text is always appended with a newline character
1949
+ - The scroll bar is automatically set to the maximum value to show the latest text
1950
+
1951
+ Examples
1952
+ --------
1953
+ >>> logStatus(textbox_widget, "Processing completed")
1954
+ >>> logStatus(textbox_widget, "Error: File not found")
1955
+ """
607
1956
  if pyqtbinding == "pyqt5":
608
1957
  thetextbox.moveCursor(QtGui.QTextCursor.End)
609
1958
  elif pyqtbinding == "pyqt6":
@@ -617,19 +1966,110 @@ def logStatus(thetextbox, thetext):
617
1966
  sb.setValue(sb.maximum())
618
1967
 
619
1968
 
620
- def getMinDispLimit():
1969
+ def getMinDispLimit() -> None:
1970
+ """
1971
+ Update the minimum display limit for the current focus map from the UI spin box.
1972
+
1973
+ This function retrieves the current value from the display minimum double spin box
1974
+ in the user interface and sets it as the minimum display limit for the currently
1975
+ focused map in the overlays dictionary. It then calls updateDispLimits() to refresh
1976
+ the display limits.
1977
+
1978
+ Parameters
1979
+ ----------
1980
+ None
1981
+
1982
+ Returns
1983
+ -------
1984
+ None
1985
+ This function does not return any value.
1986
+
1987
+ Notes
1988
+ -----
1989
+ This function modifies global variables: ui, overlays, and currentdataset.
1990
+ The function assumes that ui.dispmin_doubleSpinBox exists and has a value() method.
1991
+ The function assumes that overlays and currentdataset are properly initialized
1992
+ global variables with the expected structure.
1993
+
1994
+ Examples
1995
+ --------
1996
+ >>> getMinDispLimit()
1997
+ # Updates overlays[currentdataset.focusmap].dispmin with ui.dispmin_doubleSpinBox.value()
1998
+ # and calls updateDispLimits()
1999
+ """
621
2000
  global ui, overlays, currentdataset
622
2001
  overlays[currentdataset.focusmap].dispmin = ui.dispmin_doubleSpinBox.value()
623
2002
  updateDispLimits()
624
2003
 
625
2004
 
626
- def getMaxDispLimit():
2005
+ def getMaxDispLimit() -> None:
2006
+ """
2007
+ Update the maximum display limit for the current focus map.
2008
+
2009
+ This function retrieves the current value from the display maximum spin box
2010
+ in the user interface and sets it as the maximum display limit for the
2011
+ currently focused map in the overlays dictionary. It then calls the
2012
+ updateDispLimits function to refresh the display settings.
2013
+
2014
+ Parameters
2015
+ ----------
2016
+ None
2017
+
2018
+ Returns
2019
+ -------
2020
+ None
2021
+ This function does not return any value.
2022
+
2023
+ Notes
2024
+ -----
2025
+ This function modifies global variables: ui, overlays, and currentdataset.
2026
+ The function assumes that ui.dispmax_doubleSpinBox exists and has a value() method.
2027
+ The function assumes that overlays and currentdataset are properly initialized
2028
+ global variables with the expected structure.
2029
+
2030
+ Examples
2031
+ --------
2032
+ >>> getMaxDispLimit()
2033
+ # Updates the display maximum limit for the current focus map
2034
+ """
627
2035
  global ui, overlays, currentdataset
628
2036
  overlays[currentdataset.focusmap].dispmax = ui.dispmax_doubleSpinBox.value()
629
2037
  updateDispLimits()
630
2038
 
631
2039
 
632
- def updateDispLimits():
2040
+ def updateDispLimits() -> None:
2041
+ """
2042
+ Update display limits for the current dataset's focus map.
2043
+
2044
+ This function configures the minimum and maximum display range spin boxes
2045
+ based on the current dataset's focus map values. It sets the range, single
2046
+ step size, and current values for both the minimum and maximum display
2047
+ spin boxes, then triggers an UI update.
2048
+
2049
+ Parameters
2050
+ ----------
2051
+ None
2052
+
2053
+ Returns
2054
+ -------
2055
+ None
2056
+ This function does not return any value.
2057
+
2058
+ Notes
2059
+ -----
2060
+ The function modifies global variables:
2061
+ - ui: User interface object containing display spin boxes
2062
+ - overlays: Data structure containing overlay information
2063
+ - currentdataset: Current dataset object with focusmap attribute
2064
+
2065
+ The single step size is calculated as 1/100th of the range between
2066
+ minimum and maximum values of the current focus map.
2067
+
2068
+ Examples
2069
+ --------
2070
+ >>> updateDispLimits()
2071
+ # Updates the display limits UI elements based on current dataset
2072
+ """
633
2073
  global ui, overlays, currentdataset
634
2074
  ui.dispmin_doubleSpinBox.setRange(
635
2075
  overlays[currentdataset.focusmap].minval,
@@ -652,21 +2092,92 @@ def updateDispLimits():
652
2092
  updateUI(callingfunc="updateDispLimits", orthoimages=True)
653
2093
 
654
2094
 
655
- def resetDispLimits():
2095
+ def resetDispLimits() -> None:
2096
+ """
2097
+ Reset display limits for the current focus map to their minimum and maximum values.
2098
+
2099
+ This function resets the display minimum and maximum values of the currently
2100
+ focused map in the overlays dictionary to match the actual minimum and maximum
2101
+ values of that map. After resetting the limits, it updates the display.
2102
+
2103
+ Notes
2104
+ -----
2105
+ This function modifies global variables `overlays` and `currentdataset`.
2106
+ The `dispmin` and `dispmax` attributes of the focus map are updated in-place.
2107
+
2108
+ Examples
2109
+ --------
2110
+ >>> resetDispLimits()
2111
+ # Resets display limits for the current focus map
2112
+ """
656
2113
  global overlays, currentdataset
657
2114
  overlays[currentdataset.focusmap].dispmin = overlays[currentdataset.focusmap].minval
658
2115
  overlays[currentdataset.focusmap].dispmax = overlays[currentdataset.focusmap].maxval
659
2116
  updateDispLimits()
660
2117
 
661
2118
 
662
- def resetDispSmart():
2119
+ def resetDispSmart() -> None:
2120
+ """
2121
+ Reset display limits to robust minimum and maximum values for the current focus map.
2122
+
2123
+ This function resets the display minimum and maximum values of the currently
2124
+ focused map to their robust counterparts, effectively restoring default display
2125
+ limits. It then updates the display limits in the interface.
2126
+
2127
+ Notes
2128
+ -----
2129
+ This function modifies global variables `overlays` and `currentdataset`.
2130
+ The reset operation affects only the currently focused map as determined
2131
+ by `currentdataset.focusmap`.
2132
+
2133
+ Examples
2134
+ --------
2135
+ >>> resetDispSmart()
2136
+ # Resets display limits for the current focus map to robust values
2137
+ """
663
2138
  global overlays, currentdataset
664
2139
  overlays[currentdataset.focusmap].dispmin = overlays[currentdataset.focusmap].robustmin
665
2140
  overlays[currentdataset.focusmap].dispmax = overlays[currentdataset.focusmap].robustmax
666
2141
  updateDispLimits()
667
2142
 
668
2143
 
669
- def updateSimilarityFunc():
2144
+ def updateSimilarityFunc() -> None:
2145
+ """
2146
+ Update the similarity function plot based on the current dataset and location.
2147
+
2148
+ This function updates various plot elements (curves, lines, markers, captions)
2149
+ to reflect the similarity function data at the current spatial and temporal location.
2150
+ It handles both correlation and mutual information similarity metrics, and displays
2151
+ fitting results or failure reasons accordingly.
2152
+
2153
+ Parameters
2154
+ ----------
2155
+ None
2156
+
2157
+ Returns
2158
+ -------
2159
+ None
2160
+ This function does not return any value. It modifies global plot elements in place.
2161
+
2162
+ Notes
2163
+ -----
2164
+ The function relies on several global variables:
2165
+ - `overlays`: Dictionary containing data arrays such as 'corrout', 'gaussout', 'lagtimes', etc.
2166
+ - `timeaxis`: Array of time values used for plotting.
2167
+ - `currentloc`: Object with attributes `xpos`, `ypos`, `zpos`, and `tpos` indicating current location.
2168
+ - `currentdataset`: Object with attribute `similaritymetric` indicating the metric used.
2169
+ - `simfunc_ax`: The matplotlib axes object for the similarity function plot.
2170
+ - `simfuncCurve`, `simfuncfitCurve`, `simfuncTLine`, `simfuncPeakMarker`, `simfuncCurvePoint`,
2171
+ `simfuncCaption`, `simfuncFitter`: Plot elements managed by the function.
2172
+ - `verbosity`: Controls the level of printed output for debugging.
2173
+
2174
+ Examples
2175
+ --------
2176
+ Assuming all global variables are properly initialized, calling this function will update
2177
+ the similarity function plot to show the current data:
2178
+
2179
+ >>> updateSimilarityFunc()
2180
+ """
670
2181
  global overlays, timeaxis, currentloc
671
2182
  global currentdataset
672
2183
  global simfunc_ax, simfuncCurve, simfuncfitCurve, simfuncTLine, simfuncPeakMarker, simfuncCurvePoint, simfuncCaption, simfuncFitter
@@ -727,7 +2238,43 @@ def updateSimilarityFunc():
727
2238
  simfuncPeakMarker.setData(x=[], y=[], symbol="d")
728
2239
 
729
2240
 
730
- def updateHistogram():
2241
+ def updateHistogram() -> None:
2242
+ """
2243
+ Update the histogram display with current dataset statistics.
2244
+
2245
+ This function plots the histogram data for the currently focused dataset,
2246
+ adds statistical reference lines, and updates the display limits.
2247
+
2248
+ Parameters
2249
+ ----------
2250
+ None
2251
+
2252
+ Returns
2253
+ -------
2254
+ None
2255
+ This function does not return any value.
2256
+
2257
+ Notes
2258
+ -----
2259
+ The function modifies global variables:
2260
+ - hist_ax: The histogram axis object to be updated
2261
+ - overlays: Container holding histogram data and statistics
2262
+ - currentdataset: Current dataset object with focusmap attribute
2263
+
2264
+ The histogram includes:
2265
+ - Green reference lines at 2nd, 25th, 50th, 75th, and 98th percentiles
2266
+ - Blue brush fill for the histogram area
2267
+ - Automatic y-axis scaling based on maximum histogram value
2268
+
2269
+ Examples
2270
+ --------
2271
+ >>> updateHistogram()
2272
+ # Updates the histogram display with current dataset data
2273
+
2274
+ See Also
2275
+ --------
2276
+ updateDispLimits : Function called after histogram update to refresh display
2277
+ """
731
2278
  global hist_ax, overlays, currentdataset
732
2279
  hist_ax.plot(
733
2280
  overlays[currentdataset.focusmap].histx,
@@ -757,13 +2304,69 @@ def updateHistogram():
757
2304
  # found this routine at https://github.com/abhilb/pyqtgraphutils/blob/master/pyqtgraphutils.py
758
2305
  class RectangleItem(pg.GraphicsObject):
759
2306
  def __init__(self, topLeft, size, color=(0, 128, 0, 128)):
2307
+ """
2308
+ Initialize a graphics object with specified position, size, and color.
2309
+
2310
+ Parameters
2311
+ ----------
2312
+ topLeft : tuple of int
2313
+ The top-left corner coordinates (x, y) of the graphics object.
2314
+ size : tuple of int
2315
+ The dimensions (width, height) of the graphics object.
2316
+ color : tuple of int, optional
2317
+ The RGBA color values (r, g, b, a) for the graphics object.
2318
+ Default is (0, 128, 0, 128) which represents green with 50% opacity.
2319
+
2320
+ Returns
2321
+ -------
2322
+ None
2323
+ This method initializes the object and does not return any value.
2324
+
2325
+ Notes
2326
+ -----
2327
+ This constructor calls the parent class initializer from pg.GraphicsObject
2328
+ and generates the initial picture representation of the graphics object.
2329
+
2330
+ Examples
2331
+ --------
2332
+ >>> obj = GraphicsObject((10, 20), (100, 50))
2333
+ >>> obj = GraphicsObject((0, 0), (800, 600), (255, 0, 0, 255))
2334
+ """
760
2335
  pg.GraphicsObject.__init__(self)
761
2336
  self.topLeft = topLeft
762
2337
  self.size = size
763
2338
  self.color = color
764
2339
  self.generatePicture()
765
2340
 
766
- def generatePicture(self):
2341
+ def generatePicture(self) -> None:
2342
+ """
2343
+ Generate a picture representation of the object using Qt graphics primitives.
2344
+
2345
+ This method creates a Qt picture object containing a rectangle shape based on
2346
+ the object's color, top-left position, and size properties.
2347
+
2348
+ Returns
2349
+ -------
2350
+ None
2351
+ This method does not return any value but stores the generated picture
2352
+ in the instance variable `self.picture`.
2353
+
2354
+ Notes
2355
+ -----
2356
+ The generated picture is created using Qt's QPainter and QPicture classes.
2357
+ The rectangle is drawn with both pen and brush set to the object's color,
2358
+ and the rectangle is positioned according to `self.topLeft` and sized according
2359
+ to `self.size`.
2360
+
2361
+ Examples
2362
+ --------
2363
+ >>> obj = MyClass()
2364
+ >>> obj.color = 'red'
2365
+ >>> obj.topLeft = [10, 20]
2366
+ >>> obj.size = [100, 50]
2367
+ >>> obj.generatePicture()
2368
+ >>> # Picture is now stored in obj.picture
2369
+ """
767
2370
  self.picture = QtGui.QPicture()
768
2371
  p = QtGui.QPainter(self.picture)
769
2372
  p.setPen(pg.mkPen(self.color))
@@ -773,14 +2376,92 @@ class RectangleItem(pg.GraphicsObject):
773
2376
  p.drawRect(QtCore.QRectF(tl, size))
774
2377
  p.end()
775
2378
 
776
- def paint(self, p, *args):
2379
+ def paint(self, p: Any, *args: Any) -> None:
2380
+ """
2381
+ Draw the picture using the provided painter object.
2382
+
2383
+ This method renders the stored picture onto the given painter object
2384
+ at position (0, 0).
2385
+
2386
+ Parameters
2387
+ ----------
2388
+ p : Any
2389
+ The painter object that will be used to draw the picture.
2390
+ This object must have a `drawPicture` method compatible with the
2391
+ expected interface.
2392
+ *args : Any
2393
+ Additional arguments that may be passed to the drawing operation.
2394
+ These are forwarded directly to the underlying drawing method.
2395
+
2396
+ Returns
2397
+ -------
2398
+ None
2399
+ This method does not return any value.
2400
+
2401
+ Notes
2402
+ -----
2403
+ The picture is drawn at coordinates (0, 0) relative to the painter's
2404
+ coordinate system. The actual drawing behavior depends on the
2405
+ implementation of the `drawPicture` method in the provided painter object.
2406
+
2407
+ Examples
2408
+ --------
2409
+ >>> painter = SomePainter()
2410
+ >>> obj.paint(painter)
2411
+ >>> obj.paint(painter, additional_param)
2412
+ """
777
2413
  p.drawPicture(0, 0, self.picture)
778
2414
 
779
- def boundingRect(self):
2415
+ def boundingRect(self) -> None:
2416
+ """
2417
+ Return the bounding rectangle of the picture.
2418
+
2419
+ Returns
2420
+ -------
2421
+ QtCore.QRectF
2422
+ The bounding rectangle of the picture as a QRectF object.
2423
+
2424
+ Notes
2425
+ -----
2426
+ This method retrieves the bounding rectangle that encompasses the entire picture
2427
+ content. The returned rectangle defines the minimal area that contains all
2428
+ graphical elements of the picture.
2429
+
2430
+ Examples
2431
+ --------
2432
+ >>> rect = picture.boundingRect()
2433
+ >>> print(rect)
2434
+ QRectF(0, 0, 100, 100)
2435
+ """
780
2436
  return QtCore.QRectF(self.picture.boundingRect())
781
2437
 
782
2438
 
783
- def updateRegressor():
2439
+ def updateRegressor() -> None:
2440
+ """
2441
+ Update the regressor plot with data from the currently focused regressor.
2442
+
2443
+ This function retrieves the currently focused regressor from the dataset and
2444
+ plots its time data on the global `regressor_ax` axis. It also adds a text
2445
+ label with kurtosis statistics and a rectangle highlighting the calculation
2446
+ limits defined in the dataset.
2447
+
2448
+ Notes
2449
+ -----
2450
+ The function modifies global variables: `regressor_ax`, `liveplots`, and
2451
+ `currentdataset`. It assumes that `currentdataset` has a `focusregressor`
2452
+ attribute and a `getregressors()` method returning a dictionary of regressors.
2453
+
2454
+ Examples
2455
+ --------
2456
+ Assuming `currentdataset` is properly initialized and contains regressor data,
2457
+ calling this function will update the plot on `regressor_ax` with the current
2458
+ regressor's data and statistics.
2459
+
2460
+ See Also
2461
+ --------
2462
+ currentdataset : The dataset object containing regressor information.
2463
+ regressor_ax : The PyQtGraph axis used for plotting.
2464
+ """
784
2465
  global regressor_ax, liveplots, currentdataset
785
2466
  focusregressor = currentdataset.focusregressor
786
2467
  regressors = currentdataset.getregressors()
@@ -819,7 +2500,44 @@ def updateRegressor():
819
2500
  print("currentdataset.focusregressor is None!")
820
2501
 
821
2502
 
822
- def updateRegressorSpectrum():
2503
+ def updateRegressorSpectrum() -> None:
2504
+ """
2505
+ Update the regressor spectrum plot with the currently focused regressor data.
2506
+
2507
+ This function retrieves the regressor spectrum data for the currently focused
2508
+ regressor and updates the plot in the global `regressorspectrum_ax` axis. It
2509
+ plots the spectrum data as a line with filled area under the curve, sets the
2510
+ x-axis range based on the samplerate, and adjusts the y-axis range to fit the
2511
+ data with a 25% padding. A rectangle is added to highlight the filter limits
2512
+ of the regressor.
2513
+
2514
+ Parameters
2515
+ ----------
2516
+ None
2517
+
2518
+ Returns
2519
+ -------
2520
+ None
2521
+ This function does not return any value. It modifies the global plot axis
2522
+ `regressorspectrum_ax` in place.
2523
+
2524
+ Notes
2525
+ -----
2526
+ The function relies on global variables:
2527
+ - `regressorspectrum_ax`: The PyQtGraph axis object for plotting
2528
+ - `liveplots`: Global variable controlling live plotting behavior
2529
+ - `currentdataset`: Global dataset object containing regressor data
2530
+
2531
+ The function uses the following attributes from `currentdataset`:
2532
+ - `focusregressor`: Index of the currently focused regressor
2533
+ - `regressorfilterlimits`: Tuple of (lower, upper) filter limits
2534
+ - `getregressors()`: Method returning the regressor data
2535
+
2536
+ Examples
2537
+ --------
2538
+ >>> updateRegressorSpectrum()
2539
+ # Updates the regressor spectrum plot with the current focus regressor data
2540
+ """
823
2541
  global regressorspectrum_ax, liveplots, currentdataset
824
2542
  focusregressor = currentdataset.focusregressor
825
2543
  regressorfilterlimits = currentdataset.regressorfilterlimits
@@ -849,7 +2567,35 @@ def updateRegressorSpectrum():
849
2567
  regressorspectrum_ax.addItem(therectangle)
850
2568
 
851
2569
 
852
- def calcAtlasStats():
2570
+ def calcAtlasStats() -> None:
2571
+ """
2572
+ Calculate statistical measures for each region in the atlas across functional maps.
2573
+
2574
+ This function performs atlas-based averaging of functional data, computing statistics
2575
+ such as mean, median, standard deviation, median absolute deviation (MAD), and coefficient
2576
+ of variation (CoV) for each region in the atlas. It also saves the results to CSV files
2577
+ and updates the overlay dictionary with new statistical maps.
2578
+
2579
+ The function requires the presence of an atlas map in the `overlays` dictionary and
2580
+ assumes that `currentdataset` contains the necessary data including functional maps
2581
+ and atlas labels. The results are saved with filenames based on the dataset's root
2582
+ and atlas name.
2583
+
2584
+ Notes
2585
+ -----
2586
+ This function modifies global variables:
2587
+ - `atlasstats`: Dictionary storing computed statistics for each map and region.
2588
+ - `atlasaveragingdone`: Boolean flag indicating completion of averaging.
2589
+ - `overlays`: Updated with new statistical map overlays.
2590
+
2591
+ Examples
2592
+ --------
2593
+ >>> calcAtlasStats()
2594
+ Performing atlas averaging...
2595
+ Calculating stats for region 1 ( Region1 )
2596
+ ...
2597
+ Done performing atlas averaging
2598
+ """
853
2599
  global overlays, atlasstats, averagingmode, currentdataset
854
2600
  global atlasaveragingdone
855
2601
  print("in calcAtlasStats")
@@ -906,7 +2652,27 @@ def calcAtlasStats():
906
2652
  print("cannot perform average - no atlas map found")
907
2653
 
908
2654
 
909
- def updateAtlasStats():
2655
+ def updateAtlasStats() -> None:
2656
+ """
2657
+ Update atlas statistics for all loaded functional maps.
2658
+
2659
+ This function updates the atlas statistics data for all functional maps
2660
+ in the current dataset. It iterates through loaded functional maps and
2661
+ assigns atlas statistics values based on the current averaging mode.
2662
+
2663
+ Notes
2664
+ -----
2665
+ The function modifies global variables: overlays, atlasstats, averagingmode,
2666
+ and currentdataset. It only processes maps when an "atlas" overlay exists
2667
+ and averagingmode is not None.
2668
+
2669
+ Examples
2670
+ --------
2671
+ >>> updateAtlasStats()
2672
+ in updateAtlasStats
2673
+ loading mean into map1_atlasstat
2674
+ loading mean into map2_atlasstat
2675
+ """
910
2676
  global overlays, atlasstats, averagingmode, currentdataset
911
2677
  print("in updateAtlasStats")
912
2678
  if "atlas" in overlays and (averagingmode is not None):
@@ -921,7 +2687,40 @@ def updateAtlasStats():
921
2687
  overlays[themap + "_atlasstat"].updateStats()
922
2688
 
923
2689
 
924
- def doAtlasAveraging(state):
2690
+ def doAtlasAveraging(state: Any) -> None:
2691
+ """
2692
+ Toggle atlas averaging functionality based on the provided state.
2693
+
2694
+ This function controls whether atlas averaging is enabled or disabled.
2695
+ When enabled, it sets a global flag and updates ortho images. When disabled,
2696
+ it clears the flag and updates ortho images accordingly.
2697
+
2698
+ Parameters
2699
+ ----------
2700
+ state : Any
2701
+ The state indicating whether atlas averaging should be enabled.
2702
+ Typically a QtCore.Qt.CheckState value (Checked or Unchecked).
2703
+
2704
+ Returns
2705
+ -------
2706
+ None
2707
+ This function does not return any value.
2708
+
2709
+ Notes
2710
+ -----
2711
+ This function modifies the global variable `atlasaveragingdone` and calls
2712
+ `updateOrthoImages()` to refresh the ortho images display.
2713
+
2714
+ Examples
2715
+ --------
2716
+ >>> doAtlasAveraging(QtCore.Qt.CheckState.Checked)
2717
+ in doAtlasAveraging
2718
+ atlas averaging is turned on
2719
+
2720
+ >>> doAtlasAveraging(QtCore.Qt.CheckState.Unchecked)
2721
+ in doAtlasAveraging
2722
+ atlas averaging is turned off
2723
+ """
925
2724
  global atlasaveragingdone
926
2725
  print("in doAtlasAveraging")
927
2726
  if state == QtCore.Qt.CheckState.Checked:
@@ -933,7 +2732,53 @@ def doAtlasAveraging(state):
933
2732
  updateOrthoImages()
934
2733
 
935
2734
 
936
- def updateAveragingMode():
2735
+ def updateAveragingMode() -> None:
2736
+ """
2737
+ Update the averaging mode for the current dataset and refresh display components.
2738
+
2739
+ This function handles the updating of averaging mode settings, including:
2740
+ - Calculating atlas statistics when needed
2741
+ - Updating focus map paths with atlas statistics suffix
2742
+ - Resetting display limits and smart settings
2743
+ - Updating the user interface components
2744
+
2745
+ The function checks if atlas overlays are present and if atlas averaging has been completed,
2746
+ then performs necessary calculations and updates. It also manages the focus map path
2747
+ based on the current averaging mode setting.
2748
+
2749
+ Notes
2750
+ -----
2751
+ This function modifies global variables including:
2752
+ - averagingmode
2753
+ - focusmap
2754
+ - atlasaveragingdone
2755
+ - overlays
2756
+ - currentdataset
2757
+
2758
+ Parameters
2759
+ ----------
2760
+ None
2761
+
2762
+ Returns
2763
+ -------
2764
+ None
2765
+ This function does not return any value but modifies global state.
2766
+
2767
+ Examples
2768
+ --------
2769
+ >>> updateAveragingMode()
2770
+ in updateAveragingMode
2771
+ averaging mode set to None
2772
+
2773
+ See Also
2774
+ --------
2775
+ calcAtlasStats : Calculate atlas statistics
2776
+ setAtlasMask : Set atlas mask based on current settings
2777
+ updateAtlasStats : Update atlas statistics
2778
+ resetDispLimits : Reset display limits
2779
+ resetDispSmart : Reset display smart settings
2780
+ updateUI : Update user interface components
2781
+ """
937
2782
  global averagingmode, focusmap
938
2783
  global atlasaveragingdone
939
2784
  global overlays
@@ -960,7 +2805,35 @@ def updateAveragingMode():
960
2805
  )
961
2806
 
962
2807
 
963
- def raw_radioButton_clicked(enabled):
2808
+ def raw_radioButton_clicked(enabled: Any) -> None:
2809
+ """
2810
+ Handle raw radio button click event.
2811
+
2812
+ This function is triggered when the raw radio button is clicked. It sets the
2813
+ averaging mode to None and updates the averaging mode display.
2814
+
2815
+ Parameters
2816
+ ----------
2817
+ enabled : Any
2818
+ Boolean value indicating whether the radio button is selected. When True,
2819
+ the function executes the averaging mode reset and update operations.
2820
+
2821
+ Returns
2822
+ -------
2823
+ None
2824
+ This function does not return any value.
2825
+
2826
+ Notes
2827
+ -----
2828
+ This function modifies the global variable `averagingmode` and calls
2829
+ `updateAveragingMode()` function. The function prints a debug message
2830
+ "in raw_radioButton_clicked" when executed.
2831
+
2832
+ Examples
2833
+ --------
2834
+ >>> raw_radioButton_clicked(True)
2835
+ in raw_radioButton_clicked
2836
+ """
964
2837
  global averagingmode
965
2838
  if enabled:
966
2839
  print("in raw_radioButton_clicked")
@@ -968,7 +2841,37 @@ def raw_radioButton_clicked(enabled):
968
2841
  updateAveragingMode()
969
2842
 
970
2843
 
971
- def mean_radioButton_clicked(enabled):
2844
+ def mean_radioButton_clicked(enabled: Any) -> None:
2845
+ """
2846
+ Handle the click event for the mean radio button.
2847
+
2848
+ This function is triggered when the mean radio button is selected. It updates
2849
+ the global averaging mode to "mean" and calls the updateAveragingMode function
2850
+ to apply the change.
2851
+
2852
+ Parameters
2853
+ ----------
2854
+ enabled : Any
2855
+ Boolean value indicating whether the radio button is selected. When True,
2856
+ the averaging mode is set to "mean".
2857
+
2858
+ Returns
2859
+ -------
2860
+ None
2861
+ This function does not return any value.
2862
+
2863
+ Notes
2864
+ -----
2865
+ This function modifies the global variable `averagingmode` and calls
2866
+ `updateAveragingMode()` to propagate the change.
2867
+
2868
+ Examples
2869
+ --------
2870
+ >>> mean_radioButton_clicked(True)
2871
+ in mean_radioButton_clicked
2872
+ >>> print(averagingmode)
2873
+ 'mean'
2874
+ """
972
2875
  global averagingmode
973
2876
  if enabled:
974
2877
  print("in mean_radioButton_clicked")
@@ -976,7 +2879,37 @@ def mean_radioButton_clicked(enabled):
976
2879
  updateAveragingMode()
977
2880
 
978
2881
 
979
- def median_radioButton_clicked(enabled):
2882
+ def median_radioButton_clicked(enabled: Any) -> None:
2883
+ """
2884
+ Handle the click event for the median radio button.
2885
+
2886
+ This function is called when the median radio button is clicked. It updates
2887
+ the global averaging mode to "median" and triggers an update of the averaging
2888
+ mode in the application.
2889
+
2890
+ Parameters
2891
+ ----------
2892
+ enabled : Any
2893
+ A boolean or boolean-like value indicating whether the radio button is selected.
2894
+ When True, the median averaging mode is activated.
2895
+
2896
+ Returns
2897
+ -------
2898
+ None
2899
+ This function does not return any value.
2900
+
2901
+ Notes
2902
+ -----
2903
+ This function modifies the global variable `averagingmode` and calls `updateAveragingMode()`.
2904
+ The function prints a debug message "in median_radioButton_clicked" when executed.
2905
+
2906
+ Examples
2907
+ --------
2908
+ >>> median_radioButton_clicked(True)
2909
+ in median_radioButton_clicked
2910
+ >>> median_radioButton_clicked(False)
2911
+ # No output, but averagingmode remains unchanged
2912
+ """
980
2913
  global averagingmode
981
2914
  if enabled:
982
2915
  print("in median_radioButton_clicked")
@@ -984,7 +2917,37 @@ def median_radioButton_clicked(enabled):
984
2917
  updateAveragingMode()
985
2918
 
986
2919
 
987
- def CoV_radioButton_clicked(enabled):
2920
+ def CoV_radioButton_clicked(enabled: Any) -> None:
2921
+ """
2922
+ Handle the click event for the CoV radio button.
2923
+
2924
+ This function is triggered when the CoV radio button is clicked. It updates
2925
+ the global averaging mode to "CoV" and calls the updateAveragingMode function
2926
+ to refresh the display.
2927
+
2928
+ Parameters
2929
+ ----------
2930
+ enabled : Any
2931
+ Boolean value indicating whether the radio button is selected. When True,
2932
+ the averaging mode is set to "CoV".
2933
+
2934
+ Returns
2935
+ -------
2936
+ None
2937
+ This function does not return any value.
2938
+
2939
+ Notes
2940
+ -----
2941
+ This function modifies the global variable `averagingmode` and calls
2942
+ `updateAveragingMode()` to update the user interface.
2943
+
2944
+ Examples
2945
+ --------
2946
+ >>> CoV_radioButton_clicked(True)
2947
+ in CoV_radioButton_clicked
2948
+ >>> print(averagingmode)
2949
+ 'CoV'
2950
+ """
988
2951
  global averagingmode
989
2952
  if enabled:
990
2953
  print("in CoV_radioButton_clicked")
@@ -992,7 +2955,35 @@ def CoV_radioButton_clicked(enabled):
992
2955
  updateAveragingMode()
993
2956
 
994
2957
 
995
- def std_radioButton_clicked(enabled):
2958
+ def std_radioButton_clicked(enabled: Any) -> None:
2959
+ """
2960
+ Handle the click event for the standard deviation radio button.
2961
+
2962
+ This function is called when the standard deviation radio button is clicked.
2963
+ It updates the global averaging mode to "std" and triggers an update of the
2964
+ averaging mode in the application.
2965
+
2966
+ Parameters
2967
+ ----------
2968
+ enabled : Any
2969
+ Boolean value indicating whether the radio button is selected. Typically
2970
+ True when the button is clicked and becomes active.
2971
+
2972
+ Returns
2973
+ -------
2974
+ None
2975
+ This function does not return any value.
2976
+
2977
+ Notes
2978
+ -----
2979
+ This function modifies the global variable `averagingmode` and calls
2980
+ `updateAveragingMode()` to propagate the change throughout the application.
2981
+
2982
+ Examples
2983
+ --------
2984
+ >>> std_radioButton_clicked(True)
2985
+ in std_radioButton_clicked
2986
+ """
996
2987
  global averagingmode
997
2988
  if enabled:
998
2989
  print("in std_radioButton_clicked")
@@ -1000,7 +2991,34 @@ def std_radioButton_clicked(enabled):
1000
2991
  updateAveragingMode()
1001
2992
 
1002
2993
 
1003
- def MAD_radioButton_clicked(enabled):
2994
+ def MAD_radioButton_clicked(enabled: Any) -> None:
2995
+ """
2996
+ Handle radio button click event for MAD (Median Absolute Deviation) averaging mode.
2997
+
2998
+ This function is triggered when the MAD radio button is clicked. It updates the global
2999
+ averaging mode to "MAD" and calls the updateAveragingMode function to refresh the UI.
3000
+
3001
+ Parameters
3002
+ ----------
3003
+ enabled : Any
3004
+ Boolean value indicating whether the radio button is selected. Typically True
3005
+ when the button is clicked and becomes active.
3006
+
3007
+ Returns
3008
+ -------
3009
+ None
3010
+ This function does not return any value.
3011
+
3012
+ Notes
3013
+ -----
3014
+ This function modifies the global variable `averagingmode` and calls `updateAveragingMode()`.
3015
+ The function prints a debug message "in MAD_radioButton_clicked" when executed.
3016
+
3017
+ Examples
3018
+ --------
3019
+ >>> MAD_radioButton_clicked(True)
3020
+ in MAD_radioButton_clicked
3021
+ """
1004
3022
  global averagingmode
1005
3023
  if enabled:
1006
3024
  print("in MAD_radioButton_clicked")
@@ -1008,7 +3026,27 @@ def MAD_radioButton_clicked(enabled):
1008
3026
  updateAveragingMode()
1009
3027
 
1010
3028
 
1011
- def transparencyCheckboxClicked():
3029
+ def transparencyCheckboxClicked() -> None:
3030
+ """
3031
+ Handle transparency checkbox click event to update layer transparency settings.
3032
+
3033
+ This function is triggered when the transparency checkbox in the user interface
3034
+ is clicked. It updates the endalpha value based on the checkbox state and
3035
+ applies the new transparency settings to all loaded function maps in the current dataset.
3036
+
3037
+ The function modifies global variables and updates the visualization state
3038
+ of all overlays in the current dataset.
3039
+
3040
+ Notes
3041
+ -----
3042
+ This function assumes that the global variables ui, overlays, currentdataset,
3043
+ LUT_alpha, LUT_endalpha, and verbosity are properly initialized before calling.
3044
+
3045
+ Examples
3046
+ --------
3047
+ >>> transparencyCheckboxClicked()
3048
+ # Updates transparency settings for all overlays in current dataset
3049
+ """
1012
3050
  global LUT_alpha, LUT_endalpha, ui, overlays, currentdataset
1013
3051
  global verbosity
1014
3052
 
@@ -1025,7 +3063,39 @@ def transparencyCheckboxClicked():
1025
3063
  updateLUT()
1026
3064
 
1027
3065
 
1028
- def gray_radioButton_clicked(enabled):
3066
+ def gray_radioButton_clicked(enabled: Any) -> None:
3067
+ """
3068
+ Handle the click event for the gray radio button in the image visualization interface.
3069
+
3070
+ This function updates the lookup table (LUT) of the current focus map to a grayscale
3071
+ representation when the gray radio button is selected. It restores the previous LUT
3072
+ state and updates the visualization accordingly.
3073
+
3074
+ Parameters
3075
+ ----------
3076
+ enabled : Any
3077
+ Boolean value indicating whether the gray radio button is selected. When True,
3078
+ the focus map is updated to display in grayscale.
3079
+
3080
+ Returns
3081
+ -------
3082
+ None
3083
+ This function does not return any value.
3084
+
3085
+ Notes
3086
+ -----
3087
+ This function modifies global variables including `imageadj`, `overlays`, `currentdataset`,
3088
+ `LUT_alpha`, and `LUT_endalpha`. The function assumes that `gen_gray_state()` is a
3089
+ predefined function that generates the grayscale lookup table state.
3090
+
3091
+ Examples
3092
+ --------
3093
+ >>> gray_radioButton_clicked(True)
3094
+ # Sets the current focus map to grayscale display
3095
+
3096
+ >>> gray_radioButton_clicked(False)
3097
+ # Does not change the display (assuming other radio buttons handle this case)
3098
+ """
1029
3099
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1030
3100
 
1031
3101
  if enabled:
@@ -1039,7 +3109,41 @@ def gray_radioButton_clicked(enabled):
1039
3109
  updateLUT()
1040
3110
 
1041
3111
 
1042
- def thermal_radioButton_clicked(enabled):
3112
+ def thermal_radioButton_clicked(enabled: Any) -> None:
3113
+ """
3114
+ Handle the click event for the thermal radio button.
3115
+
3116
+ This function is called when the thermal radio button is clicked. It updates
3117
+ the lookup table (LUT) for the current focus map overlay when the thermal
3118
+ visualization is enabled, and restores the previous LUT state.
3119
+
3120
+ Parameters
3121
+ ----------
3122
+ enabled : Any
3123
+ A boolean or boolean-like value indicating whether the thermal
3124
+ visualization is enabled. When True, the thermal LUT is applied to
3125
+ the current overlay.
3126
+
3127
+ Returns
3128
+ -------
3129
+ None
3130
+ This function does not return any value.
3131
+
3132
+ Notes
3133
+ -----
3134
+ This function modifies global variables including `imageadj`, `overlays`,
3135
+ `currentdataset`, `LUT_alpha`, and `LUT_endalpha`. The function assumes
3136
+ that `gen_thermal_state()` returns a valid LUT state and that the necessary
3137
+ overlay and dataset objects exist.
3138
+
3139
+ Examples
3140
+ --------
3141
+ >>> thermal_radioButton_clicked(True)
3142
+ # Applies thermal LUT to current overlay and updates display
3143
+
3144
+ >>> thermal_radioButton_clicked(False)
3145
+ # No action taken if enabled is False
3146
+ """
1043
3147
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1044
3148
  if enabled:
1045
3149
  overlays[currentdataset.focusmap].setLUT(
@@ -1052,7 +3156,45 @@ def thermal_radioButton_clicked(enabled):
1052
3156
  updateLUT()
1053
3157
 
1054
3158
 
1055
- def plasma_radioButton_clicked(enabled):
3159
+ def plasma_radioButton_clicked(enabled: Any) -> None:
3160
+ """
3161
+ Handle the click event for the plasma radio button in the visualization interface.
3162
+
3163
+ This function updates the lookup table (LUT) of the current focus map overlay
3164
+ when the plasma radio button is selected. It applies a plasma color scheme
3165
+ and restores the previous LUT state for proper visualization.
3166
+
3167
+ Parameters
3168
+ ----------
3169
+ enabled : Any
3170
+ Boolean or equivalent value indicating whether the plasma radio button is selected.
3171
+ When True, the plasma LUT is applied to the current overlay.
3172
+
3173
+ Returns
3174
+ -------
3175
+ None
3176
+ This function does not return any value.
3177
+
3178
+ Notes
3179
+ -----
3180
+ This function modifies global variables:
3181
+ - imageadj: Image adjustment object
3182
+ - overlays: Dictionary of overlay objects
3183
+ - currentdataset: Current dataset object
3184
+ - LUT_alpha: Alpha value for LUT
3185
+ - LUT_endalpha: End alpha value for LUT
3186
+
3187
+ The function relies on the global `gen_plasma_state()` function to generate
3188
+ the plasma color mapping state.
3189
+
3190
+ Examples
3191
+ --------
3192
+ >>> plasma_radioButton_clicked(True)
3193
+ # Applies plasma LUT to current overlay and updates visualization
3194
+
3195
+ >>> plasma_radioButton_clicked(False)
3196
+ # No action taken (function only processes when enabled is True)
3197
+ """
1056
3198
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1057
3199
  if enabled:
1058
3200
  overlays[currentdataset.focusmap].setLUT(
@@ -1065,7 +3207,39 @@ def plasma_radioButton_clicked(enabled):
1065
3207
  updateLUT()
1066
3208
 
1067
3209
 
1068
- def viridis_radioButton_clicked(enabled):
3210
+ def viridis_radioButton_clicked(enabled: Any) -> None:
3211
+ """
3212
+ Handle the click event for the viridis colormap radio button.
3213
+
3214
+ This function updates the colormap of the current focus map to viridis when
3215
+ the radio button is enabled. It restores the lookup table state and updates
3216
+ the color mapping accordingly.
3217
+
3218
+ Parameters
3219
+ ----------
3220
+ enabled : Any
3221
+ Flag indicating whether the viridis radio button is selected. When True,
3222
+ the viridis colormap is applied to the current focus map.
3223
+
3224
+ Returns
3225
+ -------
3226
+ None
3227
+ This function does not return any value.
3228
+
3229
+ Notes
3230
+ -----
3231
+ This function modifies global variables including imageadj, overlays,
3232
+ currentdataset, LUT_alpha, and LUT_endalpha. The function assumes that
3233
+ the necessary global state has been properly initialized before calling.
3234
+
3235
+ Examples
3236
+ --------
3237
+ >>> viridis_radioButton_clicked(True)
3238
+ # Applies viridis colormap to current focus map
3239
+
3240
+ >>> viridis_radioButton_clicked(False)
3241
+ # No action taken (function does nothing when enabled is False)
3242
+ """
1069
3243
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1070
3244
  if enabled:
1071
3245
  overlays[currentdataset.focusmap].setLUT(
@@ -1078,7 +3252,45 @@ def viridis_radioButton_clicked(enabled):
1078
3252
  updateLUT()
1079
3253
 
1080
3254
 
1081
- def turbo_radioButton_clicked(enabled):
3255
+ def turbo_radioButton_clicked(enabled: Any) -> None:
3256
+ """
3257
+ Handle the click event for the turbo radio button in the visualization interface.
3258
+
3259
+ This function updates the lookup table (LUT) for the current focus map when the turbo
3260
+ radio button is enabled. It applies the turbo color scheme with specified alpha values
3261
+ and restores the previous LUT state for proper visualization continuity.
3262
+
3263
+ Parameters
3264
+ ----------
3265
+ enabled : Any
3266
+ Boolean or equivalent value indicating whether the turbo radio button is selected.
3267
+ When True, the turbo LUT is applied to the current focus map.
3268
+
3269
+ Returns
3270
+ -------
3271
+ None
3272
+ This function does not return any value.
3273
+
3274
+ Notes
3275
+ -----
3276
+ This function modifies global variables:
3277
+ - imageadj: Image adjustment object
3278
+ - overlays: Dictionary of overlay objects
3279
+ - currentdataset: Current dataset object
3280
+ - LUT_alpha: Alpha value for LUT
3281
+ - LUT_endalpha: End alpha value for LUT
3282
+
3283
+ The function restores the LUT state from the saved state and updates the visualization
3284
+ through the updateLUT() function call.
3285
+
3286
+ Examples
3287
+ --------
3288
+ >>> turbo_radioButton_clicked(True)
3289
+ # Applies turbo LUT to current focus map and updates visualization
3290
+
3291
+ >>> turbo_radioButton_clicked(False)
3292
+ # No action taken (function only processes when enabled is True)
3293
+ """
1082
3294
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1083
3295
  if enabled:
1084
3296
  overlays[currentdataset.focusmap].setLUT(
@@ -1091,7 +3303,45 @@ def turbo_radioButton_clicked(enabled):
1091
3303
  updateLUT()
1092
3304
 
1093
3305
 
1094
- def rainbow_radioButton_clicked(enabled):
3306
+ def rainbow_radioButton_clicked(enabled: Any) -> None:
3307
+ """
3308
+ Handle the click event for the rainbow radio button in the GUI.
3309
+
3310
+ This function is triggered when the rainbow radio button is selected. It updates
3311
+ the lookup table (LUT) of the current focus map overlay with a spectral color
3312
+ gradient and restores the previous LUT state.
3313
+
3314
+ Parameters
3315
+ ----------
3316
+ enabled : Any
3317
+ Boolean or equivalent value indicating whether the rainbow mode is enabled.
3318
+ When True, the function applies the spectral LUT to the current overlay.
3319
+
3320
+ Returns
3321
+ -------
3322
+ None
3323
+ This function does not return any value.
3324
+
3325
+ Notes
3326
+ -----
3327
+ This function modifies global variables including:
3328
+ - imageadj: Image adjustment object
3329
+ - overlays: Dictionary of overlay objects
3330
+ - currentdataset: Current dataset object
3331
+ - LUT_alpha: Alpha value for LUT
3332
+ - LUT_endalpha: End alpha value for LUT
3333
+
3334
+ The function calls `gen_spectrum_state()` to generate the spectral color
3335
+ gradient and `updateLUT()` to refresh the display.
3336
+
3337
+ Examples
3338
+ --------
3339
+ >>> rainbow_radioButton_clicked(True)
3340
+ # Applies rainbow color mapping to current overlay
3341
+
3342
+ >>> rainbow_radioButton_clicked(False)
3343
+ # No effect (function only acts when enabled is True)
3344
+ """
1095
3345
  global imageadj, overlays, currentdataset, LUT_alpha, LUT_endalpha
1096
3346
  if enabled:
1097
3347
  overlays[currentdataset.focusmap].setLUT(
@@ -1104,7 +3354,48 @@ def rainbow_radioButton_clicked(enabled):
1104
3354
  updateLUT()
1105
3355
 
1106
3356
 
1107
- def setMask(maskname):
3357
+ def setMask(maskname: Any) -> None:
3358
+ """
3359
+ Set the functional mask for the current dataset and update associated UI elements.
3360
+
3361
+ This function configures the functional mask based on the provided mask name,
3362
+ updates the user interface, and triggers re-computation of averaging modes.
3363
+ It supports various predefined mask types including 'nomask', 'meanmask', 'lagmask',
3364
+ 'brainmask', 'refinemask', 'preselectmask', and p-value-based masks.
3365
+
3366
+ Parameters
3367
+ ----------
3368
+ maskname : Any
3369
+ Name of the mask to be applied. Supported values include:
3370
+ - 'nomask': Disables functional mask
3371
+ - 'meanmask': Mean regressor seed mask
3372
+ - 'lagmask': Uses valid fit points as functional mask
3373
+ - 'brainmask': Externally provided brain mask
3374
+ - 'refinemask': Voxel refinement mask
3375
+ - 'preselectmask': Preselected mean regressor seed mask
3376
+ - 'p_lt_X_mask': P-value threshold masks (e.g., 'p_lt_0p05_mask' for p < 0.05)
3377
+
3378
+ Returns
3379
+ -------
3380
+ None
3381
+ This function does not return any value.
3382
+
3383
+ Notes
3384
+ -----
3385
+ The function modifies global variables:
3386
+ - `overlays`: Updates mask data for each functional map.
3387
+ - `loadedfuncmaps`: Iterates over loaded functional maps to apply the mask.
3388
+ - `ui`: Updates the mask button text in the user interface.
3389
+ - `atlasaveragingdone`: Resets to False to trigger re-computation.
3390
+ - `currentdataset`: Sets the functional mask name in the dataset.
3391
+
3392
+ Examples
3393
+ --------
3394
+ >>> setMask("meanmask")
3395
+ Mean regressor seed mask
3396
+ >>> setMask("p_lt_0p01_mask")
3397
+ Setting functional mask to p<0.01
3398
+ """
1108
3399
  global overlays, loadedfuncmaps, ui, atlasaveragingdone, currentdataset
1109
3400
  maskinfodicts = {}
1110
3401
  maskinfodicts["nomask"] = {
@@ -1149,7 +3440,30 @@ def setMask(maskname):
1149
3440
  updateUI(callingfunc=f"setMask({maskname})", orthoimages=True, histogram=True)
1150
3441
 
1151
3442
 
1152
- def setAtlasMask():
3443
+ def setAtlasMask() -> None:
3444
+ """
3445
+ Set functional mask using all defined atlas regions.
3446
+
3447
+ This function activates the atlas mask for all loaded functional maps in the current dataset.
3448
+ It updates the UI to reflect that a valid mask has been applied and applies the atlas mask
3449
+ data to all functional maps in the overlays dictionary.
3450
+
3451
+ Notes
3452
+ -----
3453
+ This function modifies global variables: overlays, loadedfuncmaps, ui, and currentdataset.
3454
+ The function calls updateUI after applying the mask to refresh the visualization.
3455
+
3456
+ See Also
3457
+ --------
3458
+ updateUI : Updates the user interface after mask application.
3459
+ overlays : Global dictionary containing all loaded map objects.
3460
+ currentdataset : Global object containing current dataset information.
3461
+
3462
+ Examples
3463
+ --------
3464
+ >>> setAtlasMask()
3465
+ Using all defined atlas regions as functional mask
3466
+ """
1153
3467
  global overlays, loadedfuncmaps, ui, currentdataset
1154
3468
  print("Using all defined atlas regions as functional mask")
1155
3469
  ui.setMask_Button.setText("Valid mask")
@@ -1158,7 +3472,40 @@ def setAtlasMask():
1158
3472
  updateUI(callingfunc="setAtlasMask", orthoimages=True, histogram=True)
1159
3473
 
1160
3474
 
1161
- def overlay_radioButton_clicked(which, enabled):
3475
+ def overlay_radioButton_clicked(which: Any, enabled: Any) -> None:
3476
+ """
3477
+ Handle the click event of an overlay radio button.
3478
+
3479
+ This function is triggered when a user clicks on an overlay radio button. It updates
3480
+ the current dataset's focus map, adjusts display limits, and synchronizes the UI
3481
+ with the selected overlay settings. It also manages the visibility and state of
3482
+ related UI elements such as color lookup table (LUT) radio buttons and time position
3483
+ information.
3484
+
3485
+ Parameters
3486
+ ----------
3487
+ which : Any
3488
+ Index or identifier of the clicked radio button.
3489
+ enabled : Any
3490
+ Boolean or equivalent indicating whether the radio button is selected.
3491
+
3492
+ Returns
3493
+ -------
3494
+ None
3495
+ This function does not return any value.
3496
+
3497
+ Notes
3498
+ -----
3499
+ This function modifies global variables including `imageadj`, `overlays`, `currentdataset`,
3500
+ `panetomap`, `ui`, `overlaybuttons`, `currentloc`, `atlasaveragingdone`, and `verbosity`.
3501
+ The function assumes that `currentdataset`, `currentloc`, and `overlays` are properly initialized
3502
+ and contain valid data structures.
3503
+
3504
+ Examples
3505
+ --------
3506
+ >>> overlay_radioButton_clicked(0, True)
3507
+ # Sets the focus map to the first overlay and updates UI accordingly.
3508
+ """
1162
3509
  global imageadj, overlays, currentdataset, panetomap, ui, overlaybuttons
1163
3510
  global currentloc, atlasaveragingdone
1164
3511
  global verbosity
@@ -1213,7 +3560,42 @@ def overlay_radioButton_clicked(which, enabled):
1213
3560
  )
1214
3561
 
1215
3562
 
1216
- def updateTimepoint(event):
3563
+ def updateTimepoint(event: Any) -> None:
3564
+ """
3565
+ Update the current timepoint based on mouse event coordinates.
3566
+
3567
+ This function handles mouse events to update the current timepoint in the
3568
+ visualization. It maps the mouse position to the time axis, validates the
3569
+ time value, updates the current location, and refreshes the UI components.
3570
+
3571
+ Parameters
3572
+ ----------
3573
+ event : Any
3574
+ Mouse event containing position information. The event is expected to
3575
+ have a `pos()` method that returns the mouse coordinates.
3576
+
3577
+ Returns
3578
+ -------
3579
+ None
3580
+ This function does not return any value but modifies global variables
3581
+ including `currentloc.tpos`, `ui.TimeSlider.value`, and triggers UI updates.
3582
+
3583
+ Notes
3584
+ -----
3585
+ This function modifies global state variables including:
3586
+ - `currentloc.tpos`: Updates the current timepoint index
3587
+ - `ui.TimeSlider`: Updates the slider position
3588
+ - `data`, `overlays`, `simfunc_ax`, `tr`, `tpos`, `timeaxis`, `currentloc`, `ui`, `currentdataset`, `vLine`, `verbosity`
3589
+
3590
+ The function uses `tide_util.valtoindex()` to convert time values to array indices
3591
+ and calls `updateUI()` to refresh the visualization components.
3592
+
3593
+ Examples
3594
+ --------
3595
+ >>> # Assuming a mouse event is generated
3596
+ >>> updateTimepoint(mouse_event)
3597
+ >>> # Updates current timepoint and refreshes UI
3598
+ """
1217
3599
  global data, overlays, simfunc_ax, tr, tpos, timeaxis, currentloc, ui
1218
3600
  global currentdataset
1219
3601
  global vLine
@@ -1235,7 +3617,40 @@ def updateTimepoint(event):
1235
3617
  )
1236
3618
 
1237
3619
 
1238
- def updateLUT():
3620
+ def updateLUT() -> None:
3621
+ """
3622
+ Update the lookup table for the current dataset and associated UI elements.
3623
+
3624
+ This function updates the color lookup table for the currently focused dataset
3625
+ and synchronizes it with the colorbar display. If harvest colormaps are enabled,
3626
+ it also saves the current image adjustment state. The function triggers a UI update
3627
+ to reflect the changes in the orthographic images.
3628
+
3629
+ Parameters
3630
+ ----------
3631
+ None
3632
+
3633
+ Returns
3634
+ -------
3635
+ None
3636
+ This function does not return any value.
3637
+
3638
+ Notes
3639
+ -----
3640
+ This function relies on global variables:
3641
+ - img_colorbar: The colorbar object to update
3642
+ - overlays: Collection of overlay data structures
3643
+ - currentdataset: Current dataset object containing focusmap information
3644
+ - harvestcolormaps: Flag indicating whether to save colormap states
3645
+
3646
+ The function updates the lookup table for the current focusmap and calls
3647
+ updateUI with specific parameters to refresh the user interface.
3648
+
3649
+ Examples
3650
+ --------
3651
+ >>> updateLUT()
3652
+ # Updates the lookup table and refreshes the UI without returning any value
3653
+ """
1239
3654
  global img_colorbar
1240
3655
  global overlays, currentdataset
1241
3656
  global harvestcolormaps
@@ -1257,7 +3672,48 @@ def updateLUT():
1257
3672
  timecourse_ax.plot(timeaxis, selected, clear=True)"""
1258
3673
 
1259
3674
 
1260
- def mapwithLUT(theimage, themask, theLUT, dispmin, dispmax):
3675
+ def mapwithLUT(
3676
+ theimage: NDArray, themask: NDArray, theLUT: Any, dispmin: Any, dispmax: Any
3677
+ ) -> None:
3678
+ """
3679
+ Map image data using a lookup table with optional masking.
3680
+
3681
+ This function applies a lookup table to map input image data to output values,
3682
+ with optional masking and scaling based on display range parameters.
3683
+
3684
+ Parameters
3685
+ ----------
3686
+ theimage : NDArray
3687
+ Input image data to be mapped
3688
+ themask : NDArray
3689
+ Mask array where values less than 1 will be set to 0 in the output
3690
+ theLUT : array-like
3691
+ Lookup table array used for mapping
3692
+ dispmin : float
3693
+ Minimum display value used for scaling
3694
+ dispmax : float
3695
+ Maximum display value used for scaling
3696
+
3697
+ Returns
3698
+ -------
3699
+ NDArray
3700
+ Mapped data with shape matching input image, where values are
3701
+ mapped using the lookup table and masked according to themask parameter
3702
+
3703
+ Notes
3704
+ -----
3705
+ - The function performs linear scaling of input data to index the lookup table
3706
+ - Values outside the valid range are clipped to the lookup table bounds
3707
+ - The alpha channel (4th channel) of the output is set to 0 where mask values are less than 1
3708
+
3709
+ Examples
3710
+ --------
3711
+ >>> import numpy as np
3712
+ >>> image = np.array([[0, 128, 255], [64, 192, 32]])
3713
+ >>> mask = np.array([[1, 1, 0], [1, 0, 1]])
3714
+ >>> lut = np.array([0, 50, 100, 150, 200, 255])
3715
+ >>> result = mapwithLUT(image, mask, lut, 0, 255)
3716
+ """
1261
3717
  offset = dispmin
1262
3718
  scale = len(theLUT) / (dispmax - dispmin)
1263
3719
  scaleddata = np.rint((theimage - offset) * scale).astype("int32")
@@ -1268,7 +3724,28 @@ def mapwithLUT(theimage, themask, theLUT, dispmin, dispmax):
1268
3724
  return mappeddata
1269
3725
 
1270
3726
 
1271
- def updateTFromControls():
3727
+ def updateTFromControls() -> None:
3728
+ """
3729
+ Update the time position from control values and refresh the UI.
3730
+
3731
+ This function synchronizes the time position displayed in the main window
3732
+ with the current location's time position, then updates various UI components
3733
+ including orthoimages, similarity functions, and focus values.
3734
+
3735
+ Notes
3736
+ -----
3737
+ This function modifies global variables `mainwin` and `currentloc`.
3738
+ The time position update does not emit a signal to prevent recursive updates.
3739
+
3740
+ See Also
3741
+ --------
3742
+ updateUI : Function called to refresh UI components after time position update.
3743
+
3744
+ Examples
3745
+ --------
3746
+ >>> updateTFromControls()
3747
+ # Updates main window time position and refreshes UI components
3748
+ """
1272
3749
  global mainwin, currentloc
1273
3750
  mainwin.setTpos(currentloc.tpos, emitsignal=False)
1274
3751
  updateUI(
@@ -1279,7 +3756,34 @@ def updateTFromControls():
1279
3756
  )
1280
3757
 
1281
3758
 
1282
- def updateXYZFromControls():
3759
+ def updateXYZFromControls() -> None:
3760
+ """
3761
+ Update XYZ position coordinates from control inputs and refresh UI components.
3762
+
3763
+ This function synchronizes the global current location coordinates with the main
3764
+ window's position display and triggers updates to various UI elements including
3765
+ orthographic images, similarity functions, and focus values.
3766
+
3767
+ Parameters
3768
+ ----------
3769
+ None
3770
+
3771
+ Returns
3772
+ -------
3773
+ None
3774
+ This function does not return any value.
3775
+
3776
+ Notes
3777
+ -----
3778
+ The function relies on global variables `mainwin` and `currentloc` which must be
3779
+ properly initialized before calling this function. The position update is performed
3780
+ without emitting signals to prevent recursive updates.
3781
+
3782
+ Examples
3783
+ --------
3784
+ >>> updateXYZFromControls()
3785
+ # Updates the main window's XYZ position and refreshes related UI components
3786
+ """
1283
3787
  global mainwin, currentloc
1284
3788
  mainwin.setXYZpos(currentloc.xpos, currentloc.ypos, currentloc.zpos, emitsignal=False)
1285
3789
  updateUI(
@@ -1290,21 +3794,82 @@ def updateXYZFromControls():
1290
3794
  )
1291
3795
 
1292
3796
 
1293
- def updateXYZFromMainWin():
3797
+ def updateXYZFromMainWin() -> None:
3798
+ """
3799
+ Update XYZ position from main window coordinates and refresh UI.
3800
+
3801
+ This function synchronizes the current location's XYZ position with the
3802
+ coordinates stored in the main window, then updates the user interface
3803
+ to reflect these changes. The synchronization is performed without emitting
3804
+ a signal to prevent recursive updates.
3805
+
3806
+ Notes
3807
+ -----
3808
+ This function relies on global variables `mainwin` and `currentloc`. The
3809
+ `mainwin` object must have `xpos`, `ypos`, and `zpos` attributes, while
3810
+ `currentloc` must have a `setXYZpos` method.
3811
+
3812
+ Examples
3813
+ --------
3814
+ >>> updateXYZFromMainWin()
3815
+ # Updates current location with main window coordinates and refreshes UI
3816
+ """
1294
3817
  global mainwin, currentloc
1295
3818
  currentloc.setXYZpos(mainwin.xpos, mainwin.ypos, mainwin.zpos, emitsignal=False)
1296
3819
  updateUI(callingfunc="updateXYZFromMainWin", similarityfunc=True, focusvals=True)
1297
3820
 
1298
3821
 
1299
3822
  def updateUI(
1300
- orthoimages=False,
1301
- histogram=False,
1302
- LUT=False,
1303
- similarityfunc=False,
1304
- focusvals=False,
1305
- callingfunc=None,
1306
- verbose=0,
1307
- ):
3823
+ orthoimages: bool = False,
3824
+ histogram: bool = False,
3825
+ LUT: bool = False,
3826
+ similarityfunc: bool = False,
3827
+ focusvals: bool = False,
3828
+ callingfunc: Optional[Any] = None,
3829
+ verbose: int = 0,
3830
+ ) -> None:
3831
+ """
3832
+ Update the user interface components based on specified flags.
3833
+
3834
+ This function updates various UI elements including orthoimages, histogram,
3835
+ lookup table (LUT), similarity function, and focus values. The function
3836
+ supports verbose output for debugging purposes and can be called from
3837
+ different functions to track execution flow.
3838
+
3839
+ Parameters
3840
+ ----------
3841
+ orthoimages : bool, optional
3842
+ Flag to update orthoimages display. Default is False.
3843
+ histogram : bool, optional
3844
+ Flag to update histogram display. Default is False.
3845
+ LUT : bool, optional
3846
+ Flag to update lookup table display. Default is False.
3847
+ similarityfunc : bool, optional
3848
+ Flag to update similarity function display. Default is False.
3849
+ focusvals : bool, optional
3850
+ Flag to update focus values display. Default is False.
3851
+ callingfunc : Any, optional
3852
+ The function that called this function, used for verbose output.
3853
+ Default is None.
3854
+ verbose : int, optional
3855
+ Verbosity level. If greater than 1, prints detailed information
3856
+ about the function call. Default is 0.
3857
+
3858
+ Returns
3859
+ -------
3860
+ None
3861
+ This function does not return any value.
3862
+
3863
+ Notes
3864
+ -----
3865
+ When LUT flag is True, orthoimages flag is automatically set to True
3866
+ as LUT updates require orthoimages to be updated as well.
3867
+
3868
+ Examples
3869
+ --------
3870
+ >>> updateUI(histogram=True, LUT=True)
3871
+ >>> updateUI(verbose=2, callingfunc="main")
3872
+ """
1308
3873
  if verbose > 1:
1309
3874
  if callingfunc is None:
1310
3875
  print("updateUI called with:")
@@ -1329,7 +3894,36 @@ def updateUI(
1329
3894
  printfocusvals()
1330
3895
 
1331
3896
 
1332
- def updateOrthoImages():
3897
+ def updateOrthoImages() -> None:
3898
+ """
3899
+ Update orthographic image displays with current location and time position.
3900
+
3901
+ This function updates all orthographic images in the visualization system
3902
+ with the current spatial coordinates and time position. It also updates
3903
+ the main window's map display and time slider to reflect the current state.
3904
+
3905
+ Notes
3906
+ -----
3907
+ This function relies on several global variables that must be properly
3908
+ initialized before calling this function:
3909
+
3910
+ - hist: Historical data container
3911
+ - currentdataset: Current dataset information
3912
+ - maps: Map data structure
3913
+ - panetomap: Mapping between panes and maps
3914
+ - ui: User interface components
3915
+ - mainwin: Main window object
3916
+ - orthoimagedict: Dictionary of orthographic images
3917
+ - currentloc: Current location object with xpos, ypos, zpos, and tpos attributes
3918
+ - overlays: Overlay data structure
3919
+ - xdim, ydim, zdim: Dimension parameters
3920
+ - imagadj: Image adjustment parameters
3921
+
3922
+ Examples
3923
+ --------
3924
+ >>> updateOrthoImages()
3925
+ # Updates all orthographic images with current position and time
3926
+ """
1333
3927
  global hist
1334
3928
  global currentdataset
1335
3929
  global maps
@@ -1353,7 +3947,34 @@ def updateOrthoImages():
1353
3947
  ui.TimeSlider.setValue(currentloc.tpos)
1354
3948
 
1355
3949
 
1356
- def printfocusvals():
3950
+ def printfocusvals() -> None:
3951
+ """
3952
+ Print focus values for all overlays at the current location.
3953
+
3954
+ This function logs the focus values of all overlays (except 'mnibrainmask')
3955
+ at the current spatial and temporal position. The output includes labels
3956
+ and corresponding focus values, formatted with indentation. Special handling
3957
+ is applied for 'atlas' and 'failimage' overlays to display atlas labels or
3958
+ diagnostic failure messages, respectively.
3959
+
3960
+ Notes
3961
+ -----
3962
+ This function modifies the global state by accessing and updating global
3963
+ variables: `ui`, `overlays`, `currentdataset`, `currentloc`, and `simfuncFitter`.
3964
+
3965
+ Examples
3966
+ --------
3967
+ Assuming `currentloc` is set and `overlays` contains valid data:
3968
+
3969
+ >>> printfocusvals()
3970
+ Values at location 10, 20, 30
3971
+ Overlay1: 45.678
3972
+ Overlay2: 12.345
3973
+ atlas: BrainRegionA
3974
+ failimage:
3975
+ Error: Invalid data
3976
+ Reason: Out of bounds
3977
+ """
1357
3978
  global ui, overlays, currentdataset
1358
3979
  global currentloc
1359
3980
  global simfuncFitter
@@ -1401,14 +4022,89 @@ def printfocusvals():
1401
4022
  logStatus(ui.logOutput, outstring)
1402
4023
 
1403
4024
 
1404
- def regressor_radioButton_clicked(theregressor, enabled):
4025
+ def regressor_radioButton_clicked(theregressor: Any, enabled: Any) -> None:
4026
+ """
4027
+ Handle radio button click event for regressor selection.
4028
+
4029
+ This function updates the current dataset's regressor focus and triggers
4030
+ updates to the regressor and its spectrum visualization.
4031
+
4032
+ Parameters
4033
+ ----------
4034
+ theregressor : Any
4035
+ The regressor object or identifier that was clicked
4036
+ enabled : Any
4037
+ Boolean or indicator showing whether the regressor is enabled
4038
+
4039
+ Returns
4040
+ -------
4041
+ None
4042
+ This function does not return any value
4043
+
4044
+ Notes
4045
+ -----
4046
+ This function modifies global state through `currentdataset.setfocusregressor()`
4047
+ and calls two update functions: `updateRegressor()` and `updateRegressorSpectrum()`.
4048
+
4049
+ Examples
4050
+ --------
4051
+ >>> regressor_radioButton_clicked('linear_regression', True)
4052
+ >>> regressor_radioButton_clicked('polynomial_regression', False)
4053
+ """
1405
4054
  global currentdataset
1406
4055
  currentdataset.setfocusregressor(theregressor)
1407
4056
  updateRegressor()
1408
4057
  updateRegressorSpectrum()
1409
4058
 
1410
4059
 
1411
- def activateDataset(currentdataset, ui, win, defaultdict, overlayGraphicsViews, verbosity=0):
4060
+ def activateDataset(
4061
+ currentdataset: Any,
4062
+ ui: Any,
4063
+ win: Any,
4064
+ defaultdict: Any,
4065
+ overlayGraphicsViews: Any,
4066
+ verbosity: int = 0,
4067
+ ) -> None:
4068
+ """
4069
+ Initialize and activate dataset for visualization and analysis.
4070
+
4071
+ This function sets up the global state and UI elements based on the provided dataset,
4072
+ configures overlay displays, initializes image viewers, and updates the user interface
4073
+ to reflect the current dataset's properties.
4074
+
4075
+ Parameters
4076
+ ----------
4077
+ currentdataset : Any
4078
+ Object containing dataset metadata and data, including dimensions, regressors,
4079
+ overlays, and file paths.
4080
+ ui : Any
4081
+ User interface object containing widgets such as radio buttons, buttons, and
4082
+ graphics views for display.
4083
+ win : Any
4084
+ Main window object used to set the window title.
4085
+ defaultdict : Any
4086
+ Dictionary containing default display settings for overlays, such as colormap,
4087
+ display state, and labels.
4088
+ overlayGraphicsViews : Any
4089
+ List or collection of graphics views used for displaying overlay images.
4090
+ verbosity : int, optional
4091
+ Level of verbosity for logging output. Default is 0 (no output).
4092
+
4093
+ Returns
4094
+ -------
4095
+ None
4096
+ This function does not return a value but modifies global state and UI elements.
4097
+
4098
+ Notes
4099
+ -----
4100
+ This function modifies global variables including `regressors`, `overlays`, `mainwin`,
4101
+ `xdim`, `ydim`, `zdim`, `tdim`, `xpos`, `ypos`, `zpos`, `tpos`, `timeaxis`,
4102
+ `usecorrout`, `orthoimagedict`, `panesinitialized`, `uiinitialized`, and `currentloc`.
4103
+
4104
+ Examples
4105
+ --------
4106
+ >>> activateDataset(dataset, ui, window, defaults, graphics_views, verbosity=1)
4107
+ """
1412
4108
  global regressors, overlays
1413
4109
  global mainwin
1414
4110
  global xdim, ydim, zdim, tdim, xpos, ypos, zpos, tpos
@@ -1704,15 +4400,58 @@ def activateDataset(currentdataset, ui, win, defaultdict, overlayGraphicsViews,
1704
4400
 
1705
4401
 
1706
4402
  def loadpane(
1707
- themap,
1708
- thepane,
1709
- view,
1710
- button,
1711
- panemap,
1712
- orthoimagedict,
1713
- bgmap=None,
1714
- sm_imgsize=32.0,
1715
- ):
4403
+ themap: Any,
4404
+ thepane: Any,
4405
+ view: Any,
4406
+ button: Any,
4407
+ panemap: Any,
4408
+ orthoimagedict: Any,
4409
+ bgmap: Optional[Any] = None,
4410
+ sm_imgsize: float = 32.0,
4411
+ ) -> None:
4412
+ """
4413
+ Load and initialize an ortho image item for a given map pane.
4414
+
4415
+ This function creates an OrthoImageItem object and stores it in the
4416
+ orthoimagedict using the map name as the key. It also updates the panemap
4417
+ to associate the pane with the map name.
4418
+
4419
+ Parameters
4420
+ ----------
4421
+ themap : Any
4422
+ The map object to be loaded into the pane
4423
+ thepane : Any
4424
+ The pane identifier where the map will be displayed
4425
+ view : Any
4426
+ The view configuration for the map display
4427
+ button : Any
4428
+ The button configuration for the map interaction
4429
+ panemap : Any
4430
+ Dictionary mapping panes to map names
4431
+ orthoimagedict : Any
4432
+ Dictionary storing ortho image items keyed by map names
4433
+ bgmap : Any, optional
4434
+ Background map object, default is None
4435
+ sm_imgsize : float, optional
4436
+ Size of the image items, default is 32.0
4437
+
4438
+ Returns
4439
+ -------
4440
+ None
4441
+ This function modifies the orthoimagedict and panemap in-place
4442
+
4443
+ Notes
4444
+ -----
4445
+ The function checks if the map has a display state before creating the
4446
+ OrthoImageItem. The OrthoImageItem is initialized with the same view
4447
+ values for all three parameters, which may need to be adjusted based on
4448
+ specific requirements.
4449
+
4450
+ Examples
4451
+ --------
4452
+ >>> loadpane(map_obj, pane_id, view_config, button_config, panemap, orthoimagedict)
4453
+ >>> loadpane(map_obj, pane_id, view_config, button_config, panemap, orthoimagedict, bgmap=bg_obj)
4454
+ """
1716
4455
  if themap.display_state:
1717
4456
  if bgmap is None:
1718
4457
  orthoimagedict[themap.name] = OrthoImageItem(
@@ -1738,7 +4477,48 @@ def loadpane(
1738
4477
  panemap[thepane] = themap.name
1739
4478
 
1740
4479
 
1741
- def tidepool(args):
4480
+ def tidepool(args: Any) -> None:
4481
+ """
4482
+ Initialize and run the TiDePool GUI application for rapidtide data analysis.
4483
+
4484
+ This function sets up the main graphical user interface for the TiDePool
4485
+ application, initializes global variables, configures the UI based on
4486
+ command-line arguments, and starts the Qt event loop for user interaction.
4487
+
4488
+ Parameters
4489
+ ----------
4490
+ args : Any
4491
+ Command-line arguments parsed by argparse. Expected to contain attributes
4492
+ such as uistyle, anatname, geommaskname, datafileroot, offsettime, trval,
4493
+ userise, useatlas, verbose, and ignoredimmatch.
4494
+
4495
+ Returns
4496
+ -------
4497
+ None
4498
+ This function does not return any value.
4499
+
4500
+ Notes
4501
+ -----
4502
+ The function initializes numerous global variables related to the UI state,
4503
+ image data, and analysis parameters. It dynamically imports UI templates
4504
+ based on the Qt binding being used (PyQt5, PyQt6, or PySide6) and the
4505
+ specified UI style (normal or big).
4506
+
4507
+ The function sets up various Qt widgets including main window, menu bar,
4508
+ image views, colorbars, and plot windows for displaying analysis results.
4509
+ It also configures event handlers for user interactions and initializes
4510
+ the data loading process.
4511
+
4512
+ Examples
4513
+ --------
4514
+ >>> import argparse
4515
+ >>> parser = argparse.ArgumentParser()
4516
+ >>> parser.add_argument('--uistyle', default='normal')
4517
+ >>> parser.add_argument('--verbose', action='store_true')
4518
+ >>> args = parser.parse_args()
4519
+ >>> tidepool(args)
4520
+ # Starts the TiDePool GUI with specified settings
4521
+ """
1742
4522
  global vLine
1743
4523
  global ui, win
1744
4524
  global fileMenu, sel_open, sel_files
@@ -1857,7 +4637,9 @@ def tidepool(args):
1857
4637
  # make the main window
1858
4638
  app = QtWidgets.QApplication([])
1859
4639
  print("setting up output window")
1860
- win = QtWidgets.QMainWindow()
4640
+ win = KeyPressWindow()
4641
+ win.sigKeyPress.connect(keyPressed)
4642
+ # win = QtWidgets.QMainWindow()
1861
4643
  ui = uiTemplate.Ui_MainWindow()
1862
4644
  ui.setupUi(win)
1863
4645
  win.show()
@@ -2263,7 +5045,36 @@ def tidepool(args):
2263
5045
  numspecial = 0
2264
5046
 
2265
5047
  # configure the mask selection popup menu
2266
- def on_mask_context_menu(point):
5048
+ def on_mask_context_menu(point: Any) -> None:
5049
+ """
5050
+ Show context menu for mask operations.
5051
+
5052
+ This function displays a context menu at the specified point coordinates
5053
+ for mask-related operations. The menu is positioned relative to the
5054
+ setMask_Button widget.
5055
+
5056
+ Parameters
5057
+ ----------
5058
+ point : Any
5059
+ The point coordinates where the context menu should be displayed.
5060
+ Typically a QPoint object or similar coordinate representation.
5061
+
5062
+ Returns
5063
+ -------
5064
+ None
5065
+ This function does not return any value.
5066
+
5067
+ Notes
5068
+ -----
5069
+ The context menu is displayed using the exec() method on the popMaskMenu
5070
+ object, with the point converted to global coordinates using the
5071
+ mapToGlobal() method of the setMask_Button widget.
5072
+
5073
+ Examples
5074
+ --------
5075
+ >>> on_mask_context_menu(QPoint(100, 150))
5076
+ # Displays context menu at global coordinates (100, 150)
5077
+ """
2267
5078
  # show context menu
2268
5079
  popMaskMenu.exec(ui.setMask_Button.mapToGlobal(point))
2269
5080
 
@@ -2271,7 +5082,37 @@ def tidepool(args):
2271
5082
  ui.setMask_Button.customContextMenuRequested.connect(on_mask_context_menu)
2272
5083
 
2273
5084
  # configure the file selection popup menu
2274
- def on_file_context_menu(point):
5085
+ def on_file_context_menu(point: Any) -> None:
5086
+ """
5087
+ Show context menu at specified point.
5088
+
5089
+ This function displays a context menu when a user right-clicks on a file
5090
+ element in the UI. The menu is positioned at the global coordinates
5091
+ corresponding to the provided point relative to the file button.
5092
+
5093
+ Parameters
5094
+ ----------
5095
+ point : Any
5096
+ The point coordinates where the context menu should be displayed.
5097
+ Typically this is a QPoint object from Qt's event system.
5098
+
5099
+ Returns
5100
+ -------
5101
+ None
5102
+ This function does not return any value.
5103
+
5104
+ Notes
5105
+ -----
5106
+ The context menu is displayed using the `exec_` method of the popup menu,
5107
+ which blocks execution until the menu is closed. The menu position is
5108
+ converted from local coordinates to global coordinates using the
5109
+ `mapToGlobal` method of the file button widget.
5110
+
5111
+ Examples
5112
+ --------
5113
+ >>> on_file_context_menu(QPoint(100, 150))
5114
+ # Displays context menu at global position (100, 150)
5115
+ """
2275
5116
  # show context menu
2276
5117
  popMaskMenu.exec(ui.setFile_Button.mapToGlobal(point))
2277
5118