rapidtide 2.9.6__py3-none-any.whl → 3.1.3__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 (405) hide show
  1. cloud/gmscalc-HCPYA +1 -1
  2. cloud/mount-and-run +2 -0
  3. cloud/rapidtide-HCPYA +3 -3
  4. rapidtide/Colortables.py +538 -38
  5. rapidtide/OrthoImageItem.py +1094 -51
  6. rapidtide/RapidtideDataset.py +1709 -114
  7. rapidtide/__init__.py +0 -8
  8. rapidtide/_version.py +4 -4
  9. rapidtide/calccoherence.py +242 -97
  10. rapidtide/calcnullsimfunc.py +240 -140
  11. rapidtide/calcsimfunc.py +314 -129
  12. rapidtide/correlate.py +1211 -389
  13. rapidtide/data/examples/src/testLD +56 -0
  14. rapidtide/data/examples/src/test_findmaxlag.py +2 -2
  15. rapidtide/data/examples/src/test_mlregressallt.py +32 -17
  16. rapidtide/data/examples/src/testalign +1 -1
  17. rapidtide/data/examples/src/testatlasaverage +35 -7
  18. rapidtide/data/examples/src/testboth +21 -0
  19. rapidtide/data/examples/src/testcifti +11 -0
  20. rapidtide/data/examples/src/testdelayvar +13 -0
  21. rapidtide/data/examples/src/testdlfilt +25 -0
  22. rapidtide/data/examples/src/testfft +35 -0
  23. rapidtide/data/examples/src/testfileorfloat +37 -0
  24. rapidtide/data/examples/src/testfmri +92 -42
  25. rapidtide/data/examples/src/testfuncs +3 -3
  26. rapidtide/data/examples/src/testglmfilt +8 -6
  27. rapidtide/data/examples/src/testhappy +84 -51
  28. rapidtide/data/examples/src/testinitdelay +19 -0
  29. rapidtide/data/examples/src/testmodels +33 -0
  30. rapidtide/data/examples/src/testnewrefine +26 -0
  31. rapidtide/data/examples/src/testnoiseamp +2 -2
  32. rapidtide/data/examples/src/testppgproc +17 -0
  33. rapidtide/data/examples/src/testrefineonly +22 -0
  34. rapidtide/data/examples/src/testretro +26 -13
  35. rapidtide/data/examples/src/testretrolagtcs +16 -0
  36. rapidtide/data/examples/src/testrolloff +11 -0
  37. rapidtide/data/examples/src/testsimdata +45 -28
  38. rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
  39. rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
  40. rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
  41. rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
  42. rapidtide/data/models/model_cnn_pytorch_fulldata/loss.png +0 -0
  43. rapidtide/data/models/model_cnn_pytorch_fulldata/loss.txt +1 -0
  44. rapidtide/data/models/model_cnn_pytorch_fulldata/model.pth +0 -0
  45. rapidtide/data/models/model_cnn_pytorch_fulldata/model_meta.json +80 -0
  46. rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.png +0 -0
  47. rapidtide/data/models/model_cnnbp_pytorch_fullldata/loss.txt +1 -0
  48. rapidtide/data/models/model_cnnbp_pytorch_fullldata/model.pth +0 -0
  49. rapidtide/data/models/model_cnnbp_pytorch_fullldata/model_meta.json +138 -0
  50. rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.png +0 -0
  51. rapidtide/data/models/model_cnnfft_pytorch_fulldata/loss.txt +1 -0
  52. rapidtide/data/models/model_cnnfft_pytorch_fulldata/model.pth +0 -0
  53. rapidtide/data/models/model_cnnfft_pytorch_fulldata/model_meta.json +128 -0
  54. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.png +0 -0
  55. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/loss.txt +1 -0
  56. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model.pth +0 -0
  57. rapidtide/data/models/model_ppgattention_pytorch_w128_fulldata/model_meta.json +49 -0
  58. rapidtide/data/models/model_revised_tf2/model.keras +0 -0
  59. rapidtide/data/models/{model_serdar → model_revised_tf2}/model_meta.json +1 -1
  60. rapidtide/data/models/model_serdar2_tf2/model.keras +0 -0
  61. rapidtide/data/models/{model_serdar2 → model_serdar2_tf2}/model_meta.json +1 -1
  62. rapidtide/data/models/model_serdar_tf2/model.keras +0 -0
  63. rapidtide/data/models/{model_revised → model_serdar_tf2}/model_meta.json +1 -1
  64. rapidtide/data/reference/HCP1200v2_MTT_2mm.nii.gz +0 -0
  65. rapidtide/data/reference/HCP1200v2_binmask_2mm.nii.gz +0 -0
  66. rapidtide/data/reference/HCP1200v2_csf_2mm.nii.gz +0 -0
  67. rapidtide/data/reference/HCP1200v2_gray_2mm.nii.gz +0 -0
  68. rapidtide/data/reference/HCP1200v2_graylaghist.json +7 -0
  69. rapidtide/data/reference/HCP1200v2_graylaghist.tsv.gz +0 -0
  70. rapidtide/data/reference/HCP1200v2_laghist.json +7 -0
  71. rapidtide/data/reference/HCP1200v2_laghist.tsv.gz +0 -0
  72. rapidtide/data/reference/HCP1200v2_mask_2mm.nii.gz +0 -0
  73. rapidtide/data/reference/HCP1200v2_maxcorr_2mm.nii.gz +0 -0
  74. rapidtide/data/reference/HCP1200v2_maxtime_2mm.nii.gz +0 -0
  75. rapidtide/data/reference/HCP1200v2_maxwidth_2mm.nii.gz +0 -0
  76. rapidtide/data/reference/HCP1200v2_negmask_2mm.nii.gz +0 -0
  77. rapidtide/data/reference/HCP1200v2_timepercentile_2mm.nii.gz +0 -0
  78. rapidtide/data/reference/HCP1200v2_white_2mm.nii.gz +0 -0
  79. rapidtide/data/reference/HCP1200v2_whitelaghist.json +7 -0
  80. rapidtide/data/reference/HCP1200v2_whitelaghist.tsv.gz +0 -0
  81. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2.xml +131 -0
  82. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_regions.txt +60 -0
  83. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1-seg2_space-MNI152NLin6Asym_2mm.nii.gz +0 -0
  84. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
  85. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
  86. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
  87. rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL2_space-MNI152NLin6Asym_2mm_mask.nii.gz +0 -0
  88. rapidtide/data/reference/MNI152_T1_1mm_Brain_FAST_seg.nii.gz +0 -0
  89. rapidtide/data/reference/MNI152_T1_1mm_Brain_Mask.nii.gz +0 -0
  90. rapidtide/data/reference/MNI152_T1_2mm_Brain_FAST_seg.nii.gz +0 -0
  91. rapidtide/data/reference/MNI152_T1_2mm_Brain_Mask.nii.gz +0 -0
  92. rapidtide/decorators.py +91 -0
  93. rapidtide/dlfilter.py +2553 -414
  94. rapidtide/dlfiltertorch.py +5201 -0
  95. rapidtide/externaltools.py +328 -13
  96. rapidtide/fMRIData_class.py +108 -92
  97. rapidtide/ffttools.py +168 -0
  98. rapidtide/filter.py +2704 -1462
  99. rapidtide/fit.py +2361 -579
  100. rapidtide/genericmultiproc.py +197 -0
  101. rapidtide/happy_supportfuncs.py +3255 -548
  102. rapidtide/helper_classes.py +587 -1116
  103. rapidtide/io.py +2569 -468
  104. rapidtide/linfitfiltpass.py +784 -0
  105. rapidtide/makelaggedtcs.py +267 -97
  106. rapidtide/maskutil.py +555 -25
  107. rapidtide/miscmath.py +835 -144
  108. rapidtide/multiproc.py +217 -44
  109. rapidtide/patchmatch.py +752 -0
  110. rapidtide/peakeval.py +32 -32
  111. rapidtide/ppgproc.py +2205 -0
  112. rapidtide/qualitycheck.py +353 -40
  113. rapidtide/refinedelay.py +854 -0
  114. rapidtide/refineregressor.py +939 -0
  115. rapidtide/resample.py +725 -204
  116. rapidtide/scripts/__init__.py +1 -0
  117. rapidtide/scripts/{adjustoffset → adjustoffset.py} +7 -2
  118. rapidtide/scripts/{aligntcs → aligntcs.py} +7 -2
  119. rapidtide/scripts/{applydlfilter → applydlfilter.py} +7 -2
  120. rapidtide/scripts/applyppgproc.py +28 -0
  121. rapidtide/scripts/{atlasaverage → atlasaverage.py} +7 -2
  122. rapidtide/scripts/{atlastool → atlastool.py} +7 -2
  123. rapidtide/scripts/{calcicc → calcicc.py} +7 -2
  124. rapidtide/scripts/{calctexticc → calctexticc.py} +7 -2
  125. rapidtide/scripts/{calcttest → calcttest.py} +7 -2
  126. rapidtide/scripts/{ccorrica → ccorrica.py} +7 -2
  127. rapidtide/scripts/delayvar.py +28 -0
  128. rapidtide/scripts/{diffrois → diffrois.py} +7 -2
  129. rapidtide/scripts/{endtidalproc → endtidalproc.py} +7 -2
  130. rapidtide/scripts/{fdica → fdica.py} +7 -2
  131. rapidtide/scripts/{filtnifti → filtnifti.py} +7 -2
  132. rapidtide/scripts/{filttc → filttc.py} +7 -2
  133. rapidtide/scripts/{fingerprint → fingerprint.py} +20 -16
  134. rapidtide/scripts/{fixtr → fixtr.py} +7 -2
  135. rapidtide/scripts/{gmscalc → gmscalc.py} +7 -2
  136. rapidtide/scripts/{happy → happy.py} +7 -2
  137. rapidtide/scripts/{happy2std → happy2std.py} +7 -2
  138. rapidtide/scripts/{happywarp → happywarp.py} +8 -4
  139. rapidtide/scripts/{histnifti → histnifti.py} +7 -2
  140. rapidtide/scripts/{histtc → histtc.py} +7 -2
  141. rapidtide/scripts/{glmfilt → linfitfilt.py} +7 -4
  142. rapidtide/scripts/{localflow → localflow.py} +7 -2
  143. rapidtide/scripts/{mergequality → mergequality.py} +7 -2
  144. rapidtide/scripts/{pairproc → pairproc.py} +7 -2
  145. rapidtide/scripts/{pairwisemergenifti → pairwisemergenifti.py} +7 -2
  146. rapidtide/scripts/{physiofreq → physiofreq.py} +7 -2
  147. rapidtide/scripts/{pixelcomp → pixelcomp.py} +7 -2
  148. rapidtide/scripts/{plethquality → plethquality.py} +7 -2
  149. rapidtide/scripts/{polyfitim → polyfitim.py} +7 -2
  150. rapidtide/scripts/{proj2flow → proj2flow.py} +7 -2
  151. rapidtide/scripts/{rankimage → rankimage.py} +7 -2
  152. rapidtide/scripts/{rapidtide → rapidtide.py} +7 -2
  153. rapidtide/scripts/{rapidtide2std → rapidtide2std.py} +7 -2
  154. rapidtide/scripts/{resamplenifti → resamplenifti.py} +7 -2
  155. rapidtide/scripts/{resampletc → resampletc.py} +7 -2
  156. rapidtide/scripts/retrolagtcs.py +28 -0
  157. rapidtide/scripts/retroregress.py +28 -0
  158. rapidtide/scripts/{roisummarize → roisummarize.py} +7 -2
  159. rapidtide/scripts/{runqualitycheck → runqualitycheck.py} +7 -2
  160. rapidtide/scripts/{showarbcorr → showarbcorr.py} +7 -2
  161. rapidtide/scripts/{showhist → showhist.py} +7 -2
  162. rapidtide/scripts/{showstxcorr → showstxcorr.py} +7 -2
  163. rapidtide/scripts/{showtc → showtc.py} +7 -2
  164. rapidtide/scripts/{showxcorr_legacy → showxcorr_legacy.py} +8 -8
  165. rapidtide/scripts/{showxcorrx → showxcorrx.py} +7 -2
  166. rapidtide/scripts/{showxy → showxy.py} +7 -2
  167. rapidtide/scripts/{simdata → simdata.py} +7 -2
  168. rapidtide/scripts/{spatialdecomp → spatialdecomp.py} +7 -2
  169. rapidtide/scripts/{spatialfit → spatialfit.py} +7 -2
  170. rapidtide/scripts/{spatialmi → spatialmi.py} +7 -2
  171. rapidtide/scripts/{spectrogram → spectrogram.py} +7 -2
  172. rapidtide/scripts/stupidramtricks.py +238 -0
  173. rapidtide/scripts/{synthASL → synthASL.py} +7 -2
  174. rapidtide/scripts/{tcfrom2col → tcfrom2col.py} +7 -2
  175. rapidtide/scripts/{tcfrom3col → tcfrom3col.py} +7 -2
  176. rapidtide/scripts/{temporaldecomp → temporaldecomp.py} +7 -2
  177. rapidtide/scripts/{testhrv → testhrv.py} +1 -1
  178. rapidtide/scripts/{threeD → threeD.py} +7 -2
  179. rapidtide/scripts/{tidepool → tidepool.py} +7 -2
  180. rapidtide/scripts/{variabilityizer → variabilityizer.py} +7 -2
  181. rapidtide/simFuncClasses.py +2113 -0
  182. rapidtide/simfuncfit.py +312 -108
  183. rapidtide/stats.py +579 -247
  184. rapidtide/tests/.coveragerc +27 -6
  185. rapidtide-2.9.6.data/scripts/fdica → rapidtide/tests/cleanposttest +4 -6
  186. rapidtide/tests/happycomp +9 -0
  187. rapidtide/tests/resethappytargets +1 -1
  188. rapidtide/tests/resetrapidtidetargets +1 -1
  189. rapidtide/tests/resettargets +1 -1
  190. rapidtide/tests/runlocaltest +3 -3
  191. rapidtide/tests/showkernels +1 -1
  192. rapidtide/tests/test_aliasedcorrelate.py +4 -4
  193. rapidtide/tests/test_aligntcs.py +1 -1
  194. rapidtide/tests/test_calcicc.py +1 -1
  195. rapidtide/tests/test_cleanregressor.py +184 -0
  196. rapidtide/tests/test_congrid.py +70 -81
  197. rapidtide/tests/test_correlate.py +1 -1
  198. rapidtide/tests/test_corrpass.py +4 -4
  199. rapidtide/tests/test_delayestimation.py +54 -59
  200. rapidtide/tests/test_dlfiltertorch.py +437 -0
  201. rapidtide/tests/test_doresample.py +2 -2
  202. rapidtide/tests/test_externaltools.py +69 -0
  203. rapidtide/tests/test_fastresampler.py +9 -5
  204. rapidtide/tests/test_filter.py +96 -57
  205. rapidtide/tests/test_findmaxlag.py +50 -19
  206. rapidtide/tests/test_fullrunhappy_v1.py +15 -10
  207. rapidtide/tests/test_fullrunhappy_v2.py +19 -13
  208. rapidtide/tests/test_fullrunhappy_v3.py +28 -13
  209. rapidtide/tests/test_fullrunhappy_v4.py +30 -11
  210. rapidtide/tests/test_fullrunhappy_v5.py +62 -0
  211. rapidtide/tests/test_fullrunrapidtide_v1.py +61 -7
  212. rapidtide/tests/test_fullrunrapidtide_v2.py +26 -14
  213. rapidtide/tests/test_fullrunrapidtide_v3.py +28 -8
  214. rapidtide/tests/test_fullrunrapidtide_v4.py +16 -8
  215. rapidtide/tests/test_fullrunrapidtide_v5.py +15 -6
  216. rapidtide/tests/test_fullrunrapidtide_v6.py +142 -0
  217. rapidtide/tests/test_fullrunrapidtide_v7.py +114 -0
  218. rapidtide/tests/test_fullrunrapidtide_v8.py +66 -0
  219. rapidtide/tests/test_getparsers.py +158 -0
  220. rapidtide/tests/test_io.py +59 -18
  221. rapidtide/tests/{test_glmpass.py → test_linfitfiltpass.py} +10 -10
  222. rapidtide/tests/test_mi.py +1 -1
  223. rapidtide/tests/test_miscmath.py +1 -1
  224. rapidtide/tests/test_motionregress.py +5 -5
  225. rapidtide/tests/test_nullcorr.py +6 -9
  226. rapidtide/tests/test_padvec.py +216 -0
  227. rapidtide/tests/test_parserfuncs.py +101 -0
  228. rapidtide/tests/test_phaseanalysis.py +1 -1
  229. rapidtide/tests/test_rapidtideparser.py +59 -53
  230. rapidtide/tests/test_refinedelay.py +296 -0
  231. rapidtide/tests/test_runmisc.py +5 -5
  232. rapidtide/tests/test_sharedmem.py +60 -0
  233. rapidtide/tests/test_simroundtrip.py +132 -0
  234. rapidtide/tests/test_simulate.py +1 -1
  235. rapidtide/tests/test_stcorrelate.py +4 -2
  236. rapidtide/tests/test_timeshift.py +2 -2
  237. rapidtide/tests/test_valtoindex.py +1 -1
  238. rapidtide/tests/test_zRapidtideDataset.py +5 -3
  239. rapidtide/tests/utils.py +10 -9
  240. rapidtide/tidepoolTemplate.py +88 -70
  241. rapidtide/tidepoolTemplate.ui +60 -46
  242. rapidtide/tidepoolTemplate_alt.py +88 -53
  243. rapidtide/tidepoolTemplate_alt.ui +62 -52
  244. rapidtide/tidepoolTemplate_alt_qt6.py +921 -0
  245. rapidtide/tidepoolTemplate_big.py +1125 -0
  246. rapidtide/tidepoolTemplate_big.ui +2386 -0
  247. rapidtide/tidepoolTemplate_big_qt6.py +1129 -0
  248. rapidtide/tidepoolTemplate_qt6.py +793 -0
  249. rapidtide/util.py +1389 -148
  250. rapidtide/voxelData.py +1048 -0
  251. rapidtide/wiener.py +138 -25
  252. rapidtide/wiener2.py +114 -8
  253. rapidtide/workflows/adjustoffset.py +107 -5
  254. rapidtide/workflows/aligntcs.py +86 -3
  255. rapidtide/workflows/applydlfilter.py +231 -89
  256. rapidtide/workflows/applyppgproc.py +540 -0
  257. rapidtide/workflows/atlasaverage.py +309 -48
  258. rapidtide/workflows/atlastool.py +130 -9
  259. rapidtide/workflows/calcSimFuncMap.py +490 -0
  260. rapidtide/workflows/calctexticc.py +202 -10
  261. rapidtide/workflows/ccorrica.py +123 -15
  262. rapidtide/workflows/cleanregressor.py +415 -0
  263. rapidtide/workflows/delayvar.py +1268 -0
  264. rapidtide/workflows/diffrois.py +84 -6
  265. rapidtide/workflows/endtidalproc.py +149 -9
  266. rapidtide/workflows/fdica.py +197 -17
  267. rapidtide/workflows/filtnifti.py +71 -4
  268. rapidtide/workflows/filttc.py +76 -5
  269. rapidtide/workflows/fitSimFuncMap.py +578 -0
  270. rapidtide/workflows/fixtr.py +74 -4
  271. rapidtide/workflows/gmscalc.py +116 -6
  272. rapidtide/workflows/happy.py +1242 -480
  273. rapidtide/workflows/happy2std.py +145 -13
  274. rapidtide/workflows/happy_parser.py +277 -59
  275. rapidtide/workflows/histnifti.py +120 -4
  276. rapidtide/workflows/histtc.py +85 -4
  277. rapidtide/workflows/{glmfilt.py → linfitfilt.py} +128 -14
  278. rapidtide/workflows/localflow.py +329 -29
  279. rapidtide/workflows/mergequality.py +80 -4
  280. rapidtide/workflows/niftidecomp.py +323 -19
  281. rapidtide/workflows/niftistats.py +178 -8
  282. rapidtide/workflows/pairproc.py +99 -5
  283. rapidtide/workflows/pairwisemergenifti.py +86 -3
  284. rapidtide/workflows/parser_funcs.py +1488 -56
  285. rapidtide/workflows/physiofreq.py +139 -12
  286. rapidtide/workflows/pixelcomp.py +211 -9
  287. rapidtide/workflows/plethquality.py +105 -23
  288. rapidtide/workflows/polyfitim.py +159 -19
  289. rapidtide/workflows/proj2flow.py +76 -3
  290. rapidtide/workflows/rankimage.py +115 -8
  291. rapidtide/workflows/rapidtide.py +1785 -1858
  292. rapidtide/workflows/rapidtide2std.py +101 -3
  293. rapidtide/workflows/rapidtide_parser.py +590 -389
  294. rapidtide/workflows/refineDelayMap.py +249 -0
  295. rapidtide/workflows/refineRegressor.py +1215 -0
  296. rapidtide/workflows/regressfrommaps.py +308 -0
  297. rapidtide/workflows/resamplenifti.py +86 -4
  298. rapidtide/workflows/resampletc.py +92 -4
  299. rapidtide/workflows/retrolagtcs.py +442 -0
  300. rapidtide/workflows/retroregress.py +1501 -0
  301. rapidtide/workflows/roisummarize.py +176 -7
  302. rapidtide/workflows/runqualitycheck.py +72 -7
  303. rapidtide/workflows/showarbcorr.py +172 -16
  304. rapidtide/workflows/showhist.py +87 -3
  305. rapidtide/workflows/showstxcorr.py +161 -4
  306. rapidtide/workflows/showtc.py +172 -10
  307. rapidtide/workflows/showxcorrx.py +250 -62
  308. rapidtide/workflows/showxy.py +186 -16
  309. rapidtide/workflows/simdata.py +418 -112
  310. rapidtide/workflows/spatialfit.py +83 -8
  311. rapidtide/workflows/spatialmi.py +252 -29
  312. rapidtide/workflows/spectrogram.py +306 -33
  313. rapidtide/workflows/synthASL.py +157 -6
  314. rapidtide/workflows/tcfrom2col.py +77 -3
  315. rapidtide/workflows/tcfrom3col.py +75 -3
  316. rapidtide/workflows/tidepool.py +3829 -666
  317. rapidtide/workflows/utils.py +45 -19
  318. rapidtide/workflows/utils_doc.py +293 -0
  319. rapidtide/workflows/variabilityizer.py +118 -5
  320. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info}/METADATA +30 -223
  321. rapidtide-3.1.3.dist-info/RECORD +393 -0
  322. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info}/WHEEL +1 -1
  323. rapidtide-3.1.3.dist-info/entry_points.txt +65 -0
  324. rapidtide-3.1.3.dist-info/top_level.txt +2 -0
  325. rapidtide/calcandfitcorrpairs.py +0 -262
  326. rapidtide/data/examples/src/testoutputsize +0 -45
  327. rapidtide/data/models/model_revised/model.h5 +0 -0
  328. rapidtide/data/models/model_serdar/model.h5 +0 -0
  329. rapidtide/data/models/model_serdar2/model.h5 +0 -0
  330. rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm.nii.gz +0 -0
  331. rapidtide/data/reference/ASPECTS_nlin_asym_09c_2mm_mask.nii.gz +0 -0
  332. rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm.nii.gz +0 -0
  333. rapidtide/data/reference/ATTbasedFlowTerritories_split_nlin_asym_09c_2mm_mask.nii.gz +0 -0
  334. rapidtide/data/reference/HCP1200_binmask_2mm_2009c_asym.nii.gz +0 -0
  335. rapidtide/data/reference/HCP1200_lag_2mm_2009c_asym.nii.gz +0 -0
  336. rapidtide/data/reference/HCP1200_mask_2mm_2009c_asym.nii.gz +0 -0
  337. rapidtide/data/reference/HCP1200_negmask_2mm_2009c_asym.nii.gz +0 -0
  338. rapidtide/data/reference/HCP1200_sigma_2mm_2009c_asym.nii.gz +0 -0
  339. rapidtide/data/reference/HCP1200_strength_2mm_2009c_asym.nii.gz +0 -0
  340. rapidtide/glmpass.py +0 -434
  341. rapidtide/refine_factored.py +0 -641
  342. rapidtide/scripts/retroglm +0 -23
  343. rapidtide/workflows/glmfrommaps.py +0 -202
  344. rapidtide/workflows/retroglm.py +0 -643
  345. rapidtide-2.9.6.data/scripts/adjustoffset +0 -23
  346. rapidtide-2.9.6.data/scripts/aligntcs +0 -23
  347. rapidtide-2.9.6.data/scripts/applydlfilter +0 -23
  348. rapidtide-2.9.6.data/scripts/atlasaverage +0 -23
  349. rapidtide-2.9.6.data/scripts/atlastool +0 -23
  350. rapidtide-2.9.6.data/scripts/calcicc +0 -22
  351. rapidtide-2.9.6.data/scripts/calctexticc +0 -23
  352. rapidtide-2.9.6.data/scripts/calcttest +0 -22
  353. rapidtide-2.9.6.data/scripts/ccorrica +0 -23
  354. rapidtide-2.9.6.data/scripts/diffrois +0 -23
  355. rapidtide-2.9.6.data/scripts/endtidalproc +0 -23
  356. rapidtide-2.9.6.data/scripts/filtnifti +0 -23
  357. rapidtide-2.9.6.data/scripts/filttc +0 -23
  358. rapidtide-2.9.6.data/scripts/fingerprint +0 -593
  359. rapidtide-2.9.6.data/scripts/fixtr +0 -23
  360. rapidtide-2.9.6.data/scripts/glmfilt +0 -24
  361. rapidtide-2.9.6.data/scripts/gmscalc +0 -22
  362. rapidtide-2.9.6.data/scripts/happy +0 -25
  363. rapidtide-2.9.6.data/scripts/happy2std +0 -23
  364. rapidtide-2.9.6.data/scripts/happywarp +0 -350
  365. rapidtide-2.9.6.data/scripts/histnifti +0 -23
  366. rapidtide-2.9.6.data/scripts/histtc +0 -23
  367. rapidtide-2.9.6.data/scripts/localflow +0 -23
  368. rapidtide-2.9.6.data/scripts/mergequality +0 -23
  369. rapidtide-2.9.6.data/scripts/pairproc +0 -23
  370. rapidtide-2.9.6.data/scripts/pairwisemergenifti +0 -23
  371. rapidtide-2.9.6.data/scripts/physiofreq +0 -23
  372. rapidtide-2.9.6.data/scripts/pixelcomp +0 -23
  373. rapidtide-2.9.6.data/scripts/plethquality +0 -23
  374. rapidtide-2.9.6.data/scripts/polyfitim +0 -23
  375. rapidtide-2.9.6.data/scripts/proj2flow +0 -23
  376. rapidtide-2.9.6.data/scripts/rankimage +0 -23
  377. rapidtide-2.9.6.data/scripts/rapidtide +0 -23
  378. rapidtide-2.9.6.data/scripts/rapidtide2std +0 -23
  379. rapidtide-2.9.6.data/scripts/resamplenifti +0 -23
  380. rapidtide-2.9.6.data/scripts/resampletc +0 -23
  381. rapidtide-2.9.6.data/scripts/retroglm +0 -23
  382. rapidtide-2.9.6.data/scripts/roisummarize +0 -23
  383. rapidtide-2.9.6.data/scripts/runqualitycheck +0 -23
  384. rapidtide-2.9.6.data/scripts/showarbcorr +0 -23
  385. rapidtide-2.9.6.data/scripts/showhist +0 -23
  386. rapidtide-2.9.6.data/scripts/showstxcorr +0 -23
  387. rapidtide-2.9.6.data/scripts/showtc +0 -23
  388. rapidtide-2.9.6.data/scripts/showxcorr_legacy +0 -536
  389. rapidtide-2.9.6.data/scripts/showxcorrx +0 -23
  390. rapidtide-2.9.6.data/scripts/showxy +0 -23
  391. rapidtide-2.9.6.data/scripts/simdata +0 -23
  392. rapidtide-2.9.6.data/scripts/spatialdecomp +0 -23
  393. rapidtide-2.9.6.data/scripts/spatialfit +0 -23
  394. rapidtide-2.9.6.data/scripts/spatialmi +0 -23
  395. rapidtide-2.9.6.data/scripts/spectrogram +0 -23
  396. rapidtide-2.9.6.data/scripts/synthASL +0 -23
  397. rapidtide-2.9.6.data/scripts/tcfrom2col +0 -23
  398. rapidtide-2.9.6.data/scripts/tcfrom3col +0 -23
  399. rapidtide-2.9.6.data/scripts/temporaldecomp +0 -23
  400. rapidtide-2.9.6.data/scripts/threeD +0 -236
  401. rapidtide-2.9.6.data/scripts/tidepool +0 -23
  402. rapidtide-2.9.6.data/scripts/variabilityizer +0 -23
  403. rapidtide-2.9.6.dist-info/RECORD +0 -359
  404. rapidtide-2.9.6.dist-info/top_level.txt +0 -86
  405. {rapidtide-2.9.6.dist-info → rapidtide-3.1.3.dist-info/licenses}/LICENSE +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  # -*- coding: utf-8 -*-
3
3
  #
4
- # Copyright 2018-2024 Blaise Frederick
4
+ # Copyright 2018-2025 Blaise Frederick
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import argparse
23
23
  import os.path as op
24
24
  import sys
25
25
  from argparse import Namespace
26
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
26
27
 
27
28
  import rapidtide.filter as tide_filt
28
29
  import rapidtide.io as tide_io
@@ -30,12 +31,90 @@ import rapidtide.util as tide_util
30
31
 
31
32
 
32
33
  class IndicateSpecifiedAction(argparse.Action):
33
- def __call__(self, parser, namespace, values, option_string=None):
34
+ def __call__(
35
+ self,
36
+ parser: argparse.ArgumentParser,
37
+ namespace: argparse.Namespace,
38
+ values: Any,
39
+ option_string: Optional[str] = None,
40
+ ) -> None:
41
+ """
42
+ Store the parsed values in the namespace and mark as non-default.
43
+
44
+ This method is called when an argument parser encounters a command-line
45
+ argument that matches this action. It stores the parsed values in the
46
+ namespace and sets a corresponding flag indicating the value was explicitly
47
+ provided (not default).
48
+
49
+ Parameters
50
+ ----------
51
+ parser : argparse.ArgumentParser
52
+ The ArgumentParser object which contains this action.
53
+ namespace : argparse.Namespace
54
+ The namespace object to which the parsed values will be stored.
55
+ values : Any
56
+ The parsed values for the argument.
57
+ option_string : str, optional
58
+ The command-line option string that triggered this action.
59
+
60
+ Returns
61
+ -------
62
+ None
63
+ This method does not return a value.
64
+
65
+ Notes
66
+ -----
67
+ This action stores the values using `setattr(namespace, self.dest, values)`
68
+ and additionally sets `setattr(namespace, self.dest + "_nondefault", True)`
69
+ to indicate that the value was explicitly provided rather than using a default.
70
+
71
+ Examples
72
+ --------
73
+ >>> import argparse
74
+ >>> parser = argparse.ArgumentParser()
75
+ >>> parser.add_argument('--verbose', action='store_true')
76
+ >>> args = parser.parse_args(['--verbose'])
77
+ >>> args.verbose
78
+ True
79
+ """
34
80
  setattr(namespace, self.dest, values)
35
81
  setattr(namespace, self.dest + "_nondefault", True)
36
82
 
37
83
 
38
- def detailedversion():
84
+ def detailedversion() -> None:
85
+ """
86
+ Print detailed version information including release version, git metadata, and Python version.
87
+
88
+ This function retrieves version information from the tide_util.version() function and
89
+ prints comprehensive details about the current build, including release version, git
90
+ commit hash, git commit date, whether the working directory is dirty, and the Python
91
+ version being used. The function then exits the program with sys.exit().
92
+
93
+ Returns
94
+ -------
95
+ None
96
+ This function does not return any value and exits the program after printing
97
+ the version information.
98
+
99
+ Notes
100
+ -----
101
+ The function relies on the tide_util.version() function to retrieve git and release
102
+ information. The output includes:
103
+ - release_version: The official release version string
104
+ - git_sha: The git commit hash
105
+ - git_date: The git commit date
106
+ - git_isdirty: Boolean indicating if the working directory has uncommitted changes
107
+ - python_version: The Python version information
108
+
109
+ Examples
110
+ --------
111
+ >>> detailedversion()
112
+ release version: 1.2.3
113
+ git_sha: a1b2c3d4e5f6
114
+ git_date: 2023-10-15 14:30:45
115
+ git_isdirty: False
116
+ python_version: (3, 9, 7, 'final', 0)
117
+ """
39
118
  (
40
119
  release_version,
41
120
  git_sha,
@@ -51,30 +130,141 @@ def detailedversion():
51
130
  sys.exit()
52
131
 
53
132
 
54
- def setifnotset(thedict, thekey, theval):
133
+ def setifnotset(thedict: Dict[str, Any], thekey: str, theval: Any) -> None:
134
+ """
135
+ Set a value in dictionary if key with "_nondefault" suffix is not present.
136
+
137
+ This function checks if a key with the suffix "_nondefault" exists in the
138
+ dictionary. If not found, it prints a message and sets the specified key
139
+ to the given value.
140
+
141
+ Parameters
142
+ ----------
143
+ thedict : dict of str to Any
144
+ The dictionary to modify
145
+ thekey : str
146
+ The key to set in the dictionary
147
+ theval : Any
148
+ The value to set for thekey
149
+
150
+ Returns
151
+ -------
152
+ None
153
+ This function modifies the dictionary in-place and returns None
154
+
155
+ Notes
156
+ -----
157
+ The function uses the convention that keys with "_nondefault" suffix indicate
158
+ that a default value has already been overridden. This is useful for tracking
159
+ which settings have been explicitly set versus those that remain at default values.
160
+
161
+ Examples
162
+ --------
163
+ >>> config = {}
164
+ >>> setifnotset(config, 'debug', True)
165
+ overriding debug
166
+ >>> print(config)
167
+ {'debug': True}
168
+
169
+ >>> config = {'debug_nondefault': True}
170
+ >>> setifnotset(config, 'debug', False)
171
+ >>> print(config)
172
+ {'debug_nondefault': True}
173
+ """
55
174
  if (thekey + "_nondefault") not in thedict.keys():
56
175
  print("overriding " + thekey)
57
176
  thedict[thekey] = theval
58
177
 
59
178
 
60
- def is_valid_file(parser, arg):
179
+ def is_valid_file(parser: argparse.ArgumentParser, arg: Optional[str]) -> Optional[str]:
61
180
  """
62
- Check if argument is existing file.
181
+ Check if argument is an existing file.
182
+
183
+ This function validates that the provided argument corresponds to an existing file.
184
+ If the argument is None, the function returns None without further validation.
185
+ If the argument is not None, it parses the file specification and checks if the file exists.
186
+
187
+ Parameters
188
+ ----------
189
+ parser : argparse.ArgumentParser
190
+ The argument parser object used to raise errors when file validation fails.
191
+ arg : str, optional
192
+ The file path to validate. If None, no validation is performed.
193
+
194
+ Returns
195
+ -------
196
+ str, optional
197
+ Returns the original argument if it is a valid file path, or None if the argument is None.
198
+
199
+ Raises
200
+ ------
201
+ SystemExit
202
+ If the file specified in arg does not exist, the parser will raise a SystemExit error.
203
+
204
+ Notes
205
+ -----
206
+ This function uses `tide_io.parsefilespec()` to parse the file specification and
207
+ `os.path.isfile()` to check file existence.
208
+
209
+ Examples
210
+ --------
211
+ >>> import argparse
212
+ >>> parser = argparse.ArgumentParser()
213
+ >>> is_valid_file(parser, "existing_file.txt")
214
+ 'existing_file.txt'
215
+
216
+ >>> is_valid_file(parser, "nonexistent_file.txt")
217
+ # Raises SystemExit with error message
63
218
  """
64
219
  if arg is not None:
65
220
  thefilename, colspec = tide_io.parsefilespec(arg)
66
221
  else:
67
222
  thefilename = None
68
223
 
69
- if not op.isfile(thefilename) and thefilename is not None:
224
+ if not op.isfile(thefilename) and (thefilename is not None):
70
225
  parser.error("The file {0} does not exist!".format(thefilename))
71
226
 
72
227
  return arg
73
228
 
74
229
 
75
- def invert_float(parser, arg):
230
+ def invert_float(parser: argparse.ArgumentParser, arg: Union[str, float]) -> Union[str, float]:
76
231
  """
77
232
  Check if argument is float or auto.
233
+
234
+ This function validates if the input argument is a float value or the string "auto".
235
+ If the argument is a valid float, it computes the multiplicative inverse (1/x).
236
+ If the argument is "auto", it returns "auto" unchanged.
237
+
238
+ Parameters
239
+ ----------
240
+ parser : argparse.ArgumentParser
241
+ The argument parser object used for validation.
242
+ arg : str or float
243
+ The argument to be checked and inverted. Can be a string representation
244
+ of a float or the string "auto".
245
+
246
+ Returns
247
+ -------
248
+ str or float
249
+ If arg is "auto", returns "auto". Otherwise, returns the multiplicative
250
+ inverse of the float value.
251
+
252
+ Notes
253
+ -----
254
+ This function relies on the `is_float` helper function for validation.
255
+ The multiplicative inverse is computed as 1.0 / arg, so the input must be
256
+ non-zero to avoid division by zero errors.
257
+
258
+ Examples
259
+ --------
260
+ >>> invert_float(parser, 2.0)
261
+ 0.5
262
+
263
+ >>> invert_float(parser, "auto")
264
+ "auto"
265
+
266
+ >>> invert_float(parser, "0.5")
267
+ 2.0
78
268
  """
79
269
  arg = is_float(parser, arg)
80
270
 
@@ -83,35 +273,237 @@ def invert_float(parser, arg):
83
273
  return arg
84
274
 
85
275
 
86
- def is_float(parser, arg):
276
+ def is_float(
277
+ parser: argparse.ArgumentParser,
278
+ arg: Union[str, float],
279
+ minval: Optional[float] = None,
280
+ maxval: Optional[float] = None,
281
+ ) -> Union[str, float]:
87
282
  """
88
283
  Check if argument is float or auto.
284
+
285
+ This function validates that the input argument can be converted to a float
286
+ or is the string "auto". It also checks that the value falls within specified
287
+ bounds if minval or maxval are provided.
288
+
289
+ Parameters
290
+ ----------
291
+ parser : argparse.ArgumentParser
292
+ The argument parser object used for error reporting.
293
+ arg : str or float
294
+ The argument to validate. Can be a string representation of a float
295
+ or the string "auto".
296
+ minval : float, optional
297
+ The minimum allowed value. If specified, the argument must be greater than
298
+ or equal to this value.
299
+ maxval : float, optional
300
+ The maximum allowed value. If specified, the argument must be less than
301
+ or equal to this value.
302
+
303
+ Returns
304
+ -------
305
+ str or float
306
+ Returns the validated argument as a float if it's not "auto", otherwise
307
+ returns the string "auto".
308
+
309
+ Raises
310
+ ------
311
+ SystemExit
312
+ If the argument cannot be converted to a float or violates the min/max
313
+ constraints, the parser will call sys.exit() with an error message.
314
+
315
+ Examples
316
+ --------
317
+ >>> parser = argparse.ArgumentParser()
318
+ >>> is_float(parser, "3.14")
319
+ 3.14
320
+
321
+ >>> is_float(parser, "auto")
322
+ 'auto'
323
+
324
+ >>> is_float(parser, "5", minval=0, maxval=10)
325
+ 5.0
326
+
327
+ >>> is_float(parser, "-1", minval=0)
328
+ SystemExit: Value -1.0 is smaller than 0
89
329
  """
90
330
  if arg != "auto":
91
331
  try:
92
332
  arg = float(arg)
93
333
  except parser.error:
94
334
  parser.error('Value {0} is not a float or "auto"'.format(arg))
335
+ if minval is not None and arg < minval:
336
+ parser.error("Value {0} is smaller than {1}".format(arg, minval))
337
+ if maxval is not None and arg > maxval:
338
+ parser.error("Value {0} is larger than {1}".format(arg, maxval))
339
+
340
+ return arg
341
+
342
+
343
+ def is_valid_file_or_float(
344
+ parser: argparse.ArgumentParser, arg: Optional[str]
345
+ ) -> Union[str, float]:
346
+ """
347
+ Check if argument is an existing file or a valid float value.
348
+
349
+ This function validates whether the input argument is either:
350
+ 1. An existing file path, or
351
+ 2. A valid float number
352
+
353
+ If the argument is not a valid file but can be converted to a float,
354
+ the function returns the float value. Otherwise, it raises an error
355
+ through the provided parser.
356
+
357
+ Parameters
358
+ ----------
359
+ parser : argparse.ArgumentParser
360
+ The argument parser object used to raise errors when validation fails.
361
+ arg : str, optional
362
+ The argument to validate. Can be a file path or a string representation
363
+ of a float number. If None, the function returns None.
364
+
365
+ Returns
366
+ -------
367
+ str or float
368
+ If argument is a valid file path, returns the original string.
369
+ If argument is a valid float, returns the float value.
370
+ If argument is None, returns None.
371
+
372
+ Raises
373
+ ------
374
+ SystemExit
375
+ Raised by the parser when the argument is neither a valid file nor
376
+ a valid float number.
377
+
378
+ Examples
379
+ --------
380
+ >>> parser = argparse.ArgumentParser()
381
+ >>> is_valid_file_or_float(parser, "data.txt")
382
+ "data.txt"
383
+
384
+ >>> is_valid_file_or_float(parser, "3.14")
385
+ 3.14
386
+
387
+ >>> is_valid_file_or_float(parser, "invalid_file.txt")
388
+ SystemExit: Value invalid_file.txt is not a float or a valid filename
389
+ """
390
+ if arg is not None:
391
+ thefilename, colspec = tide_io.parsefilespec(arg)
392
+ else:
393
+ thefilename = None
394
+
395
+ if not op.isfile(thefilename) and thefilename is not None:
396
+ # this is not a file - is it a float?
397
+ try:
398
+ arg = float(arg)
399
+ except ValueError:
400
+ parser.error("Value {0} is not a float or a valid filename".format(arg))
95
401
 
96
402
  return arg
97
403
 
98
404
 
99
- def is_int(parser, arg):
405
+ def is_int(
406
+ parser: argparse.ArgumentParser,
407
+ arg: Union[str, int],
408
+ minval: Optional[int] = None,
409
+ maxval: Optional[int] = None,
410
+ ) -> Union[str, int]:
100
411
  """
101
412
  Check if argument is int or auto.
413
+
414
+ This function validates that the input argument is either an integer or the string "auto".
415
+ If the argument is not "auto", it attempts to convert it to an integer. The function also
416
+ checks that the integer value falls within the specified bounds.
417
+
418
+ Parameters
419
+ ----------
420
+ parser : argparse.ArgumentParser
421
+ The argument parser object used to raise errors when validation fails.
422
+ arg : str or int
423
+ The argument to validate. Can be an integer or the string "auto".
424
+ minval : int, optional
425
+ The minimum allowed value for the integer. If None, no minimum check is performed.
426
+ maxval : int, optional
427
+ The maximum allowed value for the integer. If None, no maximum check is performed.
428
+
429
+ Returns
430
+ -------
431
+ str or int
432
+ Returns the original argument if it is "auto", otherwise returns the converted integer.
433
+
434
+ Raises
435
+ ------
436
+ SystemExit
437
+ Raised by the parser.error() method when validation fails.
438
+
439
+ Examples
440
+ --------
441
+ >>> parser = argparse.ArgumentParser()
442
+ >>> is_int(parser, "42")
443
+ 42
444
+
445
+ >>> is_int(parser, "auto")
446
+ 'auto'
447
+
448
+ >>> is_int(parser, "42", minval=0, maxval=100)
449
+ 42
450
+
451
+ >>> is_int(parser, "42", minval=50) # raises parser.error
452
+ SystemExit: Value 42 is smaller than 50
102
453
  """
103
454
  if arg != "auto":
104
455
  try:
105
456
  arg = int(arg)
106
457
  except parser.error:
107
458
  parser.error('Value {0} is not an int or "auto"'.format(arg))
459
+ if minval is not None and arg < minval:
460
+ parser.error("Value {0} is smaller than {1}".format(arg, minval))
461
+ if maxval is not None and arg > maxval:
462
+ parser.error("Value {0} is larger than {1}".format(arg, maxval))
108
463
 
109
464
  return arg
110
465
 
111
466
 
112
- def is_range(parser, arg):
467
+ def is_range(parser: argparse.ArgumentParser, arg: Optional[List[Any]]) -> Optional[List[Any]]:
113
468
  """
114
469
  Check if argument is min/max pair.
470
+
471
+ This function validates that the provided argument is a list containing exactly two elements
472
+ that can be converted to floats, with the first element being less than or equal to the second.
473
+
474
+ Parameters
475
+ ----------
476
+ parser : argparse.ArgumentParser
477
+ The argument parser object used for error reporting
478
+ arg : list of any, optional
479
+ List containing two elements representing min and max values, or None
480
+
481
+ Returns
482
+ -------
483
+ list of any, optional
484
+ The original argument if validation passes, or None if arg is None
485
+
486
+ Raises
487
+ ------
488
+ SystemExit
489
+ If argument is not None and does not contain exactly two elements, or if min > max
490
+
491
+ Notes
492
+ -----
493
+ This function is typically used as a type validator for argparse arguments.
494
+
495
+ Examples
496
+ --------
497
+ >>> import argparse
498
+ >>> parser = argparse.ArgumentParser()
499
+ >>> is_range(parser, ['1', '10'])
500
+ ['1', '10']
501
+
502
+ >>> is_range(parser, ['10', '1'])
503
+ SystemExit: Argument min must be lower than max.
504
+
505
+ >>> is_range(parser, ['1', '2', '3'])
506
+ SystemExit: Argument must be min/max pair.
115
507
  """
116
508
  if arg is not None and len(arg) != 2:
117
509
  parser.error("Argument must be min/max pair.")
@@ -121,9 +513,37 @@ def is_range(parser, arg):
121
513
  return arg
122
514
 
123
515
 
124
- def is_valid_tag(parser, arg):
516
+ def is_valid_tag(parser: argparse.ArgumentParser, arg: Optional[str]) -> Tuple[str, str]:
125
517
  """
126
518
  Check if argument is existing file.
519
+
520
+ Parameters
521
+ ----------
522
+ parser : argparse.ArgumentParser
523
+ The argument parser object used for error reporting.
524
+ arg : str, optional
525
+ The argument string to validate, expected to be in the format "tagname,value1,value2,...".
526
+ If None, the function will return empty strings.
527
+
528
+ Returns
529
+ -------
530
+ tuple of (str, str)
531
+ A tuple containing (tagname, tagval) where tagname is the first part
532
+ before the first comma and tagval is the rest of the string joined by commas.
533
+
534
+ Notes
535
+ -----
536
+ If the argument contains fewer than 2 comma-separated parts, the parser will
537
+ raise an error with the message "No tag value specified."
538
+
539
+ Examples
540
+ --------
541
+ >>> parser = argparse.ArgumentParser()
542
+ >>> is_valid_tag(parser, "environment,production,us-east")
543
+ ('environment', 'production,us-east')
544
+
545
+ >>> is_valid_tag(parser, "type,web,app")
546
+ ('type', 'web,app')
127
547
  """
128
548
  if arg is not None:
129
549
  argparts = arg.split(",")
@@ -137,6 +557,7 @@ def is_valid_tag(parser, arg):
137
557
 
138
558
  DEFAULT_FILTER_ORDER = 6
139
559
  DEFAULT_PAD_SECONDS = 30.0
560
+ DEFAULT_PREFILTERPADTYPE = "reflect"
140
561
  DEFAULT_PERMUTATIONMETHOD = "shuffle"
141
562
  DEFAULT_NORMTYPE = "stddev"
142
563
  DEFAULT_FILTERBAND = "lfo"
@@ -145,7 +566,43 @@ DEFAULT_PADVAL = 0
145
566
  DEFAULT_WINDOWFUNC = "hamming"
146
567
 
147
568
 
148
- def addreqinputniftifile(parser, varname, addedtext=""):
569
+ def addreqinputniftifile(
570
+ parser: argparse.ArgumentParser, varname: str, addedtext: str = ""
571
+ ) -> None:
572
+ """
573
+ Add a required input NIFTI file argument to an ArgumentParser.
574
+
575
+ This function adds a command-line argument for specifying a required input
576
+ NIFTI file to the provided ArgumentParser. The argument includes validation
577
+ to ensure the file exists and is readable.
578
+
579
+ Parameters
580
+ ----------
581
+ parser : argparse.ArgumentParser
582
+ The ArgumentParser object to which the argument will be added.
583
+ varname : str
584
+ The name of the command-line argument (e.g., '--input' or '-i').
585
+ addedtext : str, optional
586
+ Additional text to append to the help message. Default is empty string.
587
+
588
+ Returns
589
+ -------
590
+ None
591
+ This function modifies the parser in-place and returns nothing.
592
+
593
+ Notes
594
+ -----
595
+ The function uses a lambda function for type validation that calls
596
+ `is_valid_file(parser, x)` to ensure the specified file exists and is
597
+ readable before accepting it as a valid input.
598
+
599
+ Examples
600
+ --------
601
+ >>> import argparse
602
+ >>> parser = argparse.ArgumentParser()
603
+ >>> addreqinputniftifile(parser, '--input', 'Path to the input NIFTI file.')
604
+ >>> args = parser.parse_args(['--input', 'data.nii.gz'])
605
+ """
149
606
  parser.add_argument(
150
607
  varname,
151
608
  type=lambda x: is_valid_file(parser, x),
@@ -153,7 +610,46 @@ def addreqinputniftifile(parser, varname, addedtext=""):
153
610
  )
154
611
 
155
612
 
156
- def addreqoutputniftifile(parser, varname, addedtext=""):
613
+ def addreqoutputniftifile(
614
+ parser: argparse.ArgumentParser, varname: str, addedtext: str = ""
615
+ ) -> None:
616
+ """
617
+ Add a required argument for specifying output NIFTI file name to an argument parser.
618
+
619
+ This function adds a command-line argument to the provided ArgumentParser instance
620
+ that specifies the output NIFTI file name. The argument is required and accepts
621
+ string input.
622
+
623
+ Parameters
624
+ ----------
625
+ parser : argparse.ArgumentParser
626
+ The argument parser to which the output NIFTI file argument will be added.
627
+ varname : str
628
+ The name of the command-line argument (without dashes). This will be used
629
+ as the argument name in the parser.
630
+ addedtext : str, optional
631
+ Additional text to append to the help message. Default is empty string.
632
+
633
+ Returns
634
+ -------
635
+ None
636
+ This function modifies the parser in-place and does not return any value.
637
+
638
+ Notes
639
+ -----
640
+ The added argument will be a required positional argument that accepts a string
641
+ representing the output NIFTI file path. The help message will include the
642
+ provided addedtext to give additional context to users.
643
+
644
+ Examples
645
+ --------
646
+ >>> import argparse
647
+ >>> parser = argparse.ArgumentParser()
648
+ >>> addreqoutputniftifile(parser, "output_file", "Path to the output NIFTI file.")
649
+ >>> args = parser.parse_args(['--output_file', 'output.nii.gz'])
650
+ >>> print(args.output_file)
651
+ output.nii.gz
652
+ """
157
653
  parser.add_argument(
158
654
  varname,
159
655
  type=str,
@@ -161,7 +657,49 @@ def addreqoutputniftifile(parser, varname, addedtext=""):
161
657
  )
162
658
 
163
659
 
164
- def addreqinputtextfile(parser, varname, onecol=False):
660
+ def addreqinputtextfile(
661
+ parser: argparse.ArgumentParser, varname: str, onecol: bool = False
662
+ ) -> None:
663
+ """
664
+ Add a required text file argument to an argument parser for timeseries data.
665
+
666
+ This function adds a command-line argument to specify a text file containing
667
+ one or more timeseries columns. The argument supports column selection options
668
+ depending on whether single or multiple columns are expected.
669
+
670
+ Parameters
671
+ ----------
672
+ parser : argparse.ArgumentParser
673
+ The argument parser to which the text file argument will be added.
674
+ varname : str
675
+ The name of the argument variable (used as the argument flag).
676
+ onecol : bool, optional
677
+ If True, the argument expects a single column selection.
678
+ If False, the argument accepts multiple column specifications.
679
+ Default is False.
680
+
681
+ Returns
682
+ -------
683
+ None
684
+ This function modifies the parser in-place and returns None.
685
+
686
+ Notes
687
+ -----
688
+ The text file can be in BIDS format, which allows column names to be used
689
+ in addition to integer column indices. Column selection syntax varies based
690
+ on the `onecol` parameter:
691
+
692
+ - When `onecol=True`: Use `[:COLUMN]` where COLUMN is an integer or column name
693
+ - When `onecol=False`: Use `[:COLSPEC]` where COLSPEC is an integer, a column
694
+ separated list of ranges, or a comma separated set of column names
695
+
696
+ Examples
697
+ --------
698
+ >>> import argparse
699
+ >>> parser = argparse.ArgumentParser()
700
+ >>> addreqinputtextfile(parser, 'timeseries_file', onecol=False)
701
+ >>> args = parser.parse_args()
702
+ """
165
703
  if onecol:
166
704
  colspecline = (
167
705
  "Use [:COLUMN] to select which column to use, where COLUMN is an "
@@ -180,7 +718,55 @@ def addreqinputtextfile(parser, varname, onecol=False):
180
718
  )
181
719
 
182
720
 
183
- def addreqinputtextfiles(parser, varname, numreq="Two", nargs="*", onecol=False):
721
+ def addreqinputtextfiles(
722
+ parser: argparse.ArgumentParser,
723
+ varname: str,
724
+ numreq: str = "Two",
725
+ nargs: str = "*",
726
+ onecol: bool = False,
727
+ ) -> None:
728
+ """
729
+ Add required input text files argument to an ArgumentParser.
730
+
731
+ This function adds a command-line argument to specify one or more text files
732
+ containing timeseries data. The argument supports various column selection
733
+ options depending on the `onecol` parameter.
734
+
735
+ Parameters
736
+ ----------
737
+ parser : argparse.ArgumentParser
738
+ The ArgumentParser object to which the argument will be added.
739
+ varname : str
740
+ The name of the command-line argument (without dashes).
741
+ numreq : str, optional
742
+ Number of required input files (default is "Two").
743
+ nargs : str, optional
744
+ Argument specification for the number of arguments (default is "*").
745
+ onecol : bool, optional
746
+ If True, single column selection is enabled; if False, multiple column
747
+ selection is enabled (default is False).
748
+
749
+ Returns
750
+ -------
751
+ None
752
+ This function modifies the parser in-place and returns None.
753
+
754
+ Notes
755
+ -----
756
+ The added argument accepts text files with timeseries data. When `onecol` is
757
+ True, column selection uses the format [:COLUMN] where COLUMN is an integer
758
+ or column name (if input file is BIDS). When `onecol` is False, column
759
+ selection uses the format [:COLSPEC] where COLSPEC can be an integer, a
760
+ comma-separated list of ranges, or a comma-separated set of column names
761
+ (if input file is BIDS). Default behavior is to use all columns.
762
+
763
+ Examples
764
+ --------
765
+ >>> import argparse
766
+ >>> parser = argparse.ArgumentParser()
767
+ >>> addreqinputtextfiles(parser, "input_files", numreq="Three", onecol=True)
768
+ >>> args = parser.parse_args()
769
+ """
184
770
  if onecol:
185
771
  colspecline = (
186
772
  "Use [:COLUMN] to select which column to use, where COLUMN is an "
@@ -200,7 +786,52 @@ def addreqinputtextfiles(parser, varname, numreq="Two", nargs="*", onecol=False)
200
786
  )
201
787
 
202
788
 
203
- def addreqoutputtextfile(parser, varname, rootname=False):
789
+ def addreqoutputtextfile(
790
+ parser: argparse.ArgumentParser, varname: str, rootname: bool = False
791
+ ) -> None:
792
+ """
793
+ Add a required argument for specifying output text file name to an argument parser.
794
+
795
+ This function adds a command-line argument to the provided ArgumentParser instance
796
+ that specifies the name of an output text file. The argument is required and
797
+ accepts string values.
798
+
799
+ Parameters
800
+ ----------
801
+ parser : argparse.ArgumentParser
802
+ The ArgumentParser instance to which the output file argument will be added.
803
+ varname : str
804
+ The name of the command-line argument (e.g., '--output-file' or '-o').
805
+ rootname : bool, optional
806
+ If True, the help text will indicate this is a root name for output files
807
+ (default is False, which indicates a single output text file name).
808
+
809
+ Returns
810
+ -------
811
+ None
812
+ This function modifies the parser in-place and does not return any value.
813
+
814
+ Notes
815
+ -----
816
+ This function is typically used when setting up command-line interfaces for
817
+ tools that require a specified output text file name. The argument added is
818
+ required, meaning the parser will raise an error if this argument is not provided.
819
+
820
+ Examples
821
+ --------
822
+ >>> import argparse
823
+ >>> parser = argparse.ArgumentParser()
824
+ >>> addreqoutputtextfile(parser, '--output-file')
825
+ >>> args = parser.parse_args(['--output-file', 'results.txt'])
826
+ >>> print(args.output_file)
827
+ 'results.txt'
828
+
829
+ >>> parser = argparse.ArgumentParser()
830
+ >>> addreqoutputtextfile(parser, '--root-name', rootname=True)
831
+ >>> args = parser.parse_args(['--root-name', 'data'])
832
+ >>> print(args.root_name)
833
+ 'data'
834
+ """
204
835
  if rootname:
205
836
  helpline = "Root name for the output files"
206
837
  else:
@@ -213,9 +844,44 @@ def addreqoutputtextfile(parser, varname, rootname=False):
213
844
 
214
845
 
215
846
  def addtagopts(
216
- opt_group,
217
- helptext="Additional key, value pairs to add to the options json file (useful for tracking analyses).",
218
- ):
847
+ opt_group: argparse._ArgumentGroup,
848
+ helptext: str = "Additional key, value pairs to add to the options json file (useful for tracking analyses).",
849
+ ) -> None:
850
+ """
851
+ Add infotag argument to an argument group for adding key-value pairs to options JSON.
852
+
853
+ This function adds an --infotag command line argument to the provided argument group.
854
+ The argument accepts key-value pairs that are stored as additional metadata in the
855
+ options JSON file, which is useful for tracking analysis runs and experiments.
856
+
857
+ Parameters
858
+ ----------
859
+ opt_group : argparse._ArgumentGroup
860
+ The argument group to which the infotag argument will be added
861
+ helptext : str, optional
862
+ Help text to display for the infotag argument (default: "Additional key, value pairs to add to the options json file (useful for tracking analyses).")
863
+
864
+ Returns
865
+ -------
866
+ None
867
+ This function modifies the argument group in-place and returns None
868
+
869
+ Notes
870
+ -----
871
+ The --infotag argument uses action="append" with nargs=2, allowing multiple
872
+ key-value pairs to be specified on the command line. Each pair is stored as
873
+ a tuple (key, value) in the argument group's parsed arguments.
874
+
875
+ Examples
876
+ --------
877
+ >>> import argparse
878
+ >>> parser = argparse.ArgumentParser()
879
+ >>> group = parser.add_argument_group('Options')
880
+ >>> addtagopts(group)
881
+ >>> args = parser.parse_args(['--infotag', 'experiment', 'run1', '--infotag', 'version', '1.0'])
882
+ >>> args.infotag
883
+ [['experiment', 'run1'], ['version', '1.0']]
884
+ """
219
885
  opt_group.add_argument(
220
886
  "--infotag",
221
887
  action="append",
@@ -226,7 +892,47 @@ def addtagopts(
226
892
  )
227
893
 
228
894
 
229
- def postprocesstagopts(args):
895
+ def postprocesstagopts(args: Namespace) -> Namespace:
896
+ """
897
+ Process infotag options and convert them to INFO_ prefixed environment variables.
898
+
899
+ This function takes a Namespace object containing command line arguments and
900
+ processes any infotag options by converting them into environment variable
901
+ assignments with INFO_ prefix. The original infotag argument is removed from
902
+ the returned namespace.
903
+
904
+ Parameters
905
+ ----------
906
+ args : Namespace
907
+ Command line arguments namespace containing potentially 'infotag' attribute
908
+ which is a list of tuples where each tuple contains (tag_name, tag_value).
909
+
910
+ Returns
911
+ -------
912
+ Namespace
913
+ Updated namespace with infotag options converted to INFO_ prefixed
914
+ environment variables. If infotag is None, returns the original args.
915
+
916
+ Notes
917
+ -----
918
+ The function modifies the input namespace in-place by converting infotag
919
+ entries from tuples of (tag_name, tag_value) to environment variable
920
+ assignments with INFO_ prefix. For example, if infotag contains
921
+ [('version', '1.0')], the result will have INFO_version='1.0' as a new
922
+ attribute in the namespace.
923
+
924
+ Examples
925
+ --------
926
+ >>> from argparse import Namespace
927
+ >>> args = Namespace(infotag=[('version', '1.0'), ('build', '2023')])
928
+ >>> result = postprocesstagopts(args)
929
+ >>> print(result.INFO_version)
930
+ '1.0'
931
+ >>> print(result.INFO_build)
932
+ '2023'
933
+ >>> print(hasattr(result, 'infotag'))
934
+ False
935
+ """
230
936
  if args.infotag is not None:
231
937
  argvars = vars(args)
232
938
  for thetag in argvars["infotag"]:
@@ -237,7 +943,50 @@ def postprocesstagopts(args):
237
943
  return args
238
944
 
239
945
 
240
- def addnormalizationopts(parser, normtarget="timecourse", defaultmethod=DEFAULT_NORMTYPE):
946
+ def addnormalizationopts(
947
+ parser: argparse.ArgumentParser,
948
+ normtarget: str = "timecourse",
949
+ defaultmethod: str = DEFAULT_NORMTYPE,
950
+ ) -> None:
951
+ """
952
+ Add normalization options to an argument parser.
953
+
954
+ This function adds a new argument group titled "Normalization options" to the
955
+ provided argument parser. It includes an argument for specifying the normalization
956
+ method to be applied to the specified target.
957
+
958
+ Parameters
959
+ ----------
960
+ parser : argparse.ArgumentParser
961
+ The argument parser to which the normalization options will be added.
962
+ normtarget : str, optional
963
+ The target data type being normalized (default is "timecourse").
964
+ defaultmethod : str, optional
965
+ The default normalization method to use (default is DEFAULT_NORMTYPE).
966
+
967
+ Returns
968
+ -------
969
+ None
970
+ This function modifies the parser in-place and returns None.
971
+
972
+ Notes
973
+ -----
974
+ The available normalization methods are:
975
+
976
+ - "None" - demean only
977
+ - "percent" - divide by mean
978
+ - "variance" - divide by variance
979
+ - "stddev" or "z" - divide by standard deviation
980
+ - "p2p" - divide by range
981
+ - "mad" - divide by median absolute deviation
982
+
983
+ Examples
984
+ --------
985
+ >>> import argparse
986
+ >>> parser = argparse.ArgumentParser()
987
+ >>> addnormalizationopts(parser)
988
+ >>> args = parser.parse_args()
989
+ """
241
990
  norm_opts = parser.add_argument_group("Normalization options")
242
991
  norm_opts.add_argument(
243
992
  "--normmethod",
@@ -260,7 +1009,38 @@ def addnormalizationopts(parser, normtarget="timecourse", defaultmethod=DEFAULT_
260
1009
  )
261
1010
 
262
1011
 
263
- def addversionopts(parser):
1012
+ def addversionopts(parser: argparse.ArgumentParser) -> None:
1013
+ """
1014
+ Add version-related command line arguments to the given argument parser.
1015
+
1016
+ This function adds two version options to the provided argument parser:
1017
+ '--version' for simplified version information and '--detailedversion'
1018
+ for detailed version information.
1019
+
1020
+ Parameters
1021
+ ----------
1022
+ parser : argparse.ArgumentParser
1023
+ The argument parser to which version options will be added.
1024
+
1025
+ Returns
1026
+ -------
1027
+ None
1028
+ This function modifies the parser in-place and does not return anything.
1029
+
1030
+ Notes
1031
+ -----
1032
+ The version information is retrieved using `tide_util.version()` function.
1033
+ The '--version' option displays only the major version number, while
1034
+ '--detailedversion' shows the complete version information including
1035
+ minor and patch versions.
1036
+
1037
+ Examples
1038
+ --------
1039
+ >>> import argparse
1040
+ >>> parser = argparse.ArgumentParser()
1041
+ >>> addversionopts(parser)
1042
+ >>> args = parser.parse_args(['--version'])
1043
+ """
264
1044
  version_opts = parser.add_argument_group("Version options")
265
1045
  version_opts.add_argument(
266
1046
  "--version",
@@ -276,7 +1056,47 @@ def addversionopts(parser):
276
1056
  )
277
1057
 
278
1058
 
279
- def addsamplerateopts(parser, details=False):
1059
+ def addsamplerateopts(parser: argparse.ArgumentParser, details: bool = False) -> None:
1060
+ """
1061
+ Add sample rate related arguments to an argument parser.
1062
+
1063
+ This function adds mutually exclusive arguments for specifying the sample rate
1064
+ of data files. The user can either specify the sample rate directly using
1065
+ '--samplerate' or define it indirectly using '--sampletime' (which sets the
1066
+ sample rate to 1.0/TSTEP).
1067
+
1068
+ Parameters
1069
+ ----------
1070
+ parser : argparse.ArgumentParser
1071
+ The argument parser to which the sample rate arguments will be added.
1072
+ details : bool, optional
1073
+ If True, additional detailed help text may be included (default is False).
1074
+
1075
+ Returns
1076
+ -------
1077
+ None
1078
+ This function modifies the parser in-place and does not return any value.
1079
+
1080
+ Notes
1081
+ -----
1082
+ The arguments are mutually exclusive - only one of '--samplerate' or '--sampletime'
1083
+ can be specified. If neither is specified, the default sample rate is 1.0.
1084
+
1085
+ Examples
1086
+ --------
1087
+ >>> import argparse
1088
+ >>> parser = argparse.ArgumentParser()
1089
+ >>> addsamplerateopts(parser)
1090
+ >>> args = parser.parse_args(['--samplerate', '44100'])
1091
+ >>> args.samplerate
1092
+ 44100.0
1093
+
1094
+ >>> parser = argparse.ArgumentParser()
1095
+ >>> addsamplerateopts(parser)
1096
+ >>> args = parser.parse_args(['--sampletime', '0.001'])
1097
+ >>> args.samplerate
1098
+ 1000.0
1099
+ """
280
1100
  sampling = parser.add_mutually_exclusive_group()
281
1101
  sampling.add_argument(
282
1102
  "--samplerate",
@@ -305,8 +1125,51 @@ def addsamplerateopts(parser, details=False):
305
1125
 
306
1126
 
307
1127
  def addfilteropts(
308
- parser, filtertarget="timecourses", defaultmethod=DEFAULT_FILTERBAND, details=False
309
- ):
1128
+ parser: argparse.ArgumentParser,
1129
+ filtertarget: str = "timecourses",
1130
+ defaultmethod: str = DEFAULT_FILTERBAND,
1131
+ details: bool = False,
1132
+ ) -> None:
1133
+ """
1134
+ Add filtering options to an argument parser for configuring signal filtering.
1135
+
1136
+ This function adds a group of arguments to the provided `argparse.ArgumentParser`
1137
+ that allow users to specify filtering parameters for timecourses or other signals.
1138
+ It supports predefined filter bands, custom pass/stop frequencies, and various
1139
+ filter types and settings.
1140
+
1141
+ Parameters
1142
+ ----------
1143
+ parser : argparse.ArgumentParser
1144
+ The argument parser to which the filtering options will be added.
1145
+ filtertarget : str, optional
1146
+ The target of the filtering operation (e.g., "timecourses"). Default is "timecourses".
1147
+ defaultmethod : str, optional
1148
+ The default filter band to use. Default is `DEFAULT_FILTERBAND`.
1149
+ details : bool, optional
1150
+ If True, adds additional detailed filtering options such as filter type,
1151
+ Butterworth order, padding, and padding type. Default is False.
1152
+
1153
+ Returns
1154
+ -------
1155
+ None
1156
+ This function modifies the parser in place and does not return any value.
1157
+
1158
+ Notes
1159
+ -----
1160
+ - The `--filterband` argument allows selection of predefined frequency bands.
1161
+ - The `--filterfreqs` and `--filterstopfreqs` arguments allow custom frequency
1162
+ filtering, with `--filterstopfreqs` requiring `--filterfreqs` to be specified.
1163
+ - When `details=True`, additional options such as `--filtertype`, `--butterorder`,
1164
+ `--padseconds`, and `--padtype` are added.
1165
+
1166
+ Examples
1167
+ --------
1168
+ >>> import argparse
1169
+ >>> parser = argparse.ArgumentParser()
1170
+ >>> addfilteropts(parser, filtertarget="signal", defaultmethod="hrv_lf")
1171
+ >>> args = parser.parse_args()
1172
+ """
310
1173
  filt_opts = parser.add_argument_group("Filtering options")
311
1174
  filt_opts.add_argument(
312
1175
  "--filterband",
@@ -325,10 +1188,21 @@ def addfilteropts(
325
1188
  "hrv_hf",
326
1189
  "hrv_vhf",
327
1190
  "lfo_legacy",
1191
+ "lfo_tight",
328
1192
  ],
329
1193
  help=(
330
1194
  f'Filter {filtertarget} to specific band. Use "None" to disable filtering. '
331
- f'Default is "{defaultmethod}".'
1195
+ f'Default is "{defaultmethod}". Ranges are: '
1196
+ f'vlf: {tide_filt.getfilterbandfreqs("vlf", asrange=True)}, '
1197
+ f'lfo: {tide_filt.getfilterbandfreqs("lfo", asrange=True)}, '
1198
+ f'cardiac: {tide_filt.getfilterbandfreqs("cardiac", asrange=True)}, '
1199
+ f'hrv_ulf: {tide_filt.getfilterbandfreqs("hrv_ulf", asrange=True)}, '
1200
+ f'hrv_vlf: {tide_filt.getfilterbandfreqs("hrv_vlf", asrange=True)}, '
1201
+ f'hrv_lf: {tide_filt.getfilterbandfreqs("hrv_lf", asrange=True)}, '
1202
+ f'hrv_hf: {tide_filt.getfilterbandfreqs("hrv_hf", asrange=True)}, '
1203
+ f'hrv_vhf: {tide_filt.getfilterbandfreqs("hrv_vhf", asrange=True)}, '
1204
+ f'lfo_legacy: {tide_filt.getfilterbandfreqs("lfo_legacy", asrange=True)}, '
1205
+ f'lfo_tight: {tide_filt.getfilterbandfreqs("lfo_tight", asrange=True)}'
332
1206
  ),
333
1207
  default=defaultmethod,
334
1208
  )
@@ -395,14 +1269,64 @@ def addfilteropts(
395
1269
  metavar="SECONDS",
396
1270
  help=(
397
1271
  "The number of seconds of padding to add to each end of a "
398
- "filtered timecourse "
1272
+ "timecourse to be filtered "
399
1273
  f"to reduce end effects. Default is {DEFAULT_PAD_SECONDS}."
400
1274
  ),
401
1275
  default=DEFAULT_PAD_SECONDS,
402
1276
  )
1277
+ filt_opts.add_argument(
1278
+ "--padtype",
1279
+ dest="ncfiltpadtype",
1280
+ action="store",
1281
+ type=str,
1282
+ choices=["reflect", "zero", "cyclic", "constant", "constant+"],
1283
+ help=(
1284
+ f"The type of padding at each end of a "
1285
+ "timecourse to be filtered "
1286
+ f'to reduce end effects. Default is "{DEFAULT_PREFILTERPADTYPE}".'
1287
+ ),
1288
+ default=DEFAULT_PREFILTERPADTYPE,
1289
+ )
403
1290
 
404
1291
 
405
- def postprocesssamplerateopts(args, debug=False):
1292
+ def postprocesssamplerateopts(args: Namespace, debug: bool = False) -> Namespace:
1293
+ """
1294
+ Process sample rate options for the application.
1295
+
1296
+ This function handles the sample rate configuration, setting it to a default value
1297
+ when "auto" is specified, or using the provided value otherwise.
1298
+
1299
+ Parameters
1300
+ ----------
1301
+ args : Namespace
1302
+ Command line arguments namespace containing the samplerate option
1303
+ debug : bool, optional
1304
+ Debug flag for additional logging (default is False)
1305
+
1306
+ Returns
1307
+ -------
1308
+ Namespace
1309
+ Updated arguments namespace with processed sample rate value
1310
+
1311
+ Notes
1312
+ -----
1313
+ When samplerate is set to "auto", it will be converted to 1.0. This is typically
1314
+ used as a default fallback value when automatic sample rate detection is not
1315
+ implemented or desired.
1316
+
1317
+ Examples
1318
+ --------
1319
+ >>> import argparse
1320
+ >>> args = argparse.Namespace(samplerate="auto")
1321
+ >>> result = postprocesssamplerateopts(args)
1322
+ >>> print(result.samplerate)
1323
+ 1.0
1324
+
1325
+ >>> args = argparse.Namespace(samplerate=44100)
1326
+ >>> result = postprocesssamplerateopts(args)
1327
+ >>> print(result.samplerate)
1328
+ 44100
1329
+ """
406
1330
  # set the sample rate
407
1331
  if args.samplerate == "auto":
408
1332
  samplerate = 1.0
@@ -413,7 +1337,56 @@ def postprocesssamplerateopts(args, debug=False):
413
1337
  return args
414
1338
 
415
1339
 
416
- def postprocessfilteropts(args, debug=False):
1340
+ def postprocessfilteropts(args: Namespace, debug: bool = False) -> Tuple[Namespace, Any]:
1341
+ """
1342
+ Post-process filter options and configure a non-causal filter for tidal analysis.
1343
+
1344
+ This function configures the filter parameters based on the input arguments,
1345
+ sets up an appropriate filter type (e.g., trapezoidal or arbitrary passband),
1346
+ and initializes a `NoncausalFilter` object for subsequent use in tidal data processing.
1347
+
1348
+ Parameters
1349
+ ----------
1350
+ args : Namespace
1351
+ A namespace object containing filter configuration parameters such as
1352
+ `filtertype`, `filtorder`, `padseconds`, `prefilterpadtype`, `passvec`,
1353
+ `stopvec`, and `filterband`.
1354
+ debug : bool, optional
1355
+ If True, prints debug information about the filter configuration and
1356
+ internal state during processing. Default is False.
1357
+
1358
+ Returns
1359
+ -------
1360
+ Tuple[Namespace, Any]
1361
+ A tuple containing:
1362
+ - `args`: The updated namespace with additional attributes like `arbvec`,
1363
+ `lowerstop`, `lowerpass`, `upperpass`, and `upperstop`.
1364
+ - `theprefilter`: The configured `NoncausalFilter` object used for filtering.
1365
+
1366
+ Notes
1367
+ -----
1368
+ - If `stopvec` is provided without `passvec`, a `ValueError` is raised.
1369
+ - The function supports both predefined filter bands and arbitrary pass/stop
1370
+ frequency vectors.
1371
+ - The `arbvec` is constructed as `[lowerpass, upperpass, lowerstop, upperstop]`
1372
+ for internal use, but the filter expects frequencies in the order
1373
+ `[lowerstop, lowerpass, upperpass, upperstop]`.
1374
+
1375
+ Examples
1376
+ --------
1377
+ >>> import argparse
1378
+ >>> args = argparse.Namespace()
1379
+ >>> args.filtertype = "trapezoidal"
1380
+ >>> args.filtorder = 4
1381
+ >>> args.padseconds = 10
1382
+ >>> args.prefilterpadtype = "constant"
1383
+ >>> args.passvec = [0.1, 0.2]
1384
+ >>> args.stopvec = None
1385
+ >>> args.filterband = "M2"
1386
+ >>> args, filter_obj = postprocessfilteropts(args)
1387
+ >>> print(args.lowerpass)
1388
+ 0.1
1389
+ """
417
1390
  # configure the filter
418
1391
  # set the trapezoidal flag, if using
419
1392
  try:
@@ -428,6 +1401,10 @@ def postprocessfilteropts(args, debug=False):
428
1401
  thepadseconds = args.padseconds
429
1402
  except AttributeError:
430
1403
  args.padseconds = DEFAULT_PAD_SECONDS
1404
+ try:
1405
+ prefilterpadtype = args.prefilterpadtype
1406
+ except AttributeError:
1407
+ args.prefilterpadtype = DEFAULT_PREFILTERPADTYPE
431
1408
 
432
1409
  # if passvec, or passvec and stopvec, are set, we are going set up an arbpass filter
433
1410
  args.arbvec = None
@@ -456,6 +1433,8 @@ def postprocessfilteropts(args, debug=False):
456
1433
  theprefilter = tide_filt.NoncausalFilter(
457
1434
  "arb",
458
1435
  transferfunc=args.filtertype,
1436
+ padtime=args.padseconds,
1437
+ padtype=args.prefilterpadtype,
459
1438
  )
460
1439
  theprefilter.setfreqs(args.arbvec[2], args.arbvec[0], args.arbvec[1], args.arbvec[3])
461
1440
  else:
@@ -463,6 +1442,7 @@ def postprocessfilteropts(args, debug=False):
463
1442
  args.filterband,
464
1443
  transferfunc=args.filtertype,
465
1444
  padtime=args.padseconds,
1445
+ padtype=args.prefilterpadtype,
466
1446
  )
467
1447
 
468
1448
  # set the butterworth order
@@ -489,7 +1469,41 @@ def postprocessfilteropts(args, debug=False):
489
1469
  return args, theprefilter
490
1470
 
491
1471
 
492
- def addwindowopts(parser, windowtype=DEFAULT_WINDOWFUNC):
1472
+ def addwindowopts(parser: argparse.ArgumentParser, windowtype: str = DEFAULT_WINDOWFUNC) -> None:
1473
+ """
1474
+ Add windowing options to an argument parser for correlation analysis.
1475
+
1476
+ This function adds command-line arguments related to windowing operations
1477
+ that can be applied prior to correlation calculations. These options include
1478
+ the choice of window function and zero padding strategy.
1479
+
1480
+ Parameters
1481
+ ----------
1482
+ parser : argparse.ArgumentParser
1483
+ The argument parser to which windowing options will be added.
1484
+ windowtype : str, optional
1485
+ The default window function to use. Default is DEFAULT_WINDOWFUNC.
1486
+
1487
+ Returns
1488
+ -------
1489
+ None
1490
+ This function modifies the parser in-place and returns nothing.
1491
+
1492
+ Notes
1493
+ -----
1494
+ The windowing options are added to a dedicated argument group called "Windowing options".
1495
+ The zero padding parameter allows for control over edge artifacts in correlation calculations,
1496
+ with negative values triggering automatic padding selection.
1497
+
1498
+ Examples
1499
+ --------
1500
+ >>> import argparse
1501
+ >>> parser = argparse.ArgumentParser()
1502
+ >>> addwindowopts(parser)
1503
+ >>> args = parser.parse_args(['--windowfunc', 'hann'])
1504
+ >>> args.windowfunc
1505
+ 'hann'
1506
+ """
493
1507
  wfunc = parser.add_argument_group("Windowing options")
494
1508
  wfunc.add_argument(
495
1509
  "--windowfunc",
@@ -519,7 +1533,43 @@ def addwindowopts(parser, windowtype=DEFAULT_WINDOWFUNC):
519
1533
  )
520
1534
 
521
1535
 
522
- def addplotopts(parser, multiline=True):
1536
+ def addplotopts(parser: argparse.ArgumentParser, multiline: bool = True) -> None:
1537
+ """
1538
+ Add general plot appearance options to an argument parser.
1539
+
1540
+ This function adds a set of arguments to the provided `argparse.ArgumentParser`
1541
+ object that control the appearance of plots, including titles, axis labels,
1542
+ legends, colors, line widths, and output options.
1543
+
1544
+ Parameters
1545
+ ----------
1546
+ parser : argparse.ArgumentParser
1547
+ The argument parser to which the plot options will be added.
1548
+ multiline : bool, optional
1549
+ If True, allows multiple legends and colors to be specified as comma-separated
1550
+ lists. If False, expects single legend and color values. Default is True.
1551
+
1552
+ Returns
1553
+ -------
1554
+ None
1555
+ This function modifies the parser in place and does not return any value.
1556
+
1557
+ Notes
1558
+ -----
1559
+ The arguments added by this function are grouped under "General plot appearance options".
1560
+ The `multiline` parameter affects the behavior of the `--legends`, `--colors`, and
1561
+ `--linewidth` arguments:
1562
+
1563
+ - When `multiline=True`, these arguments accept comma-separated lists.
1564
+ - When `multiline=False`, they expect single values.
1565
+
1566
+ Examples
1567
+ --------
1568
+ >>> import argparse
1569
+ >>> parser = argparse.ArgumentParser()
1570
+ >>> addplotopts(parser, multiline=True)
1571
+ >>> args = parser.parse_args()
1572
+ """
523
1573
  plotopts = parser.add_argument_group("General plot appearance options")
524
1574
  plotopts.add_argument(
525
1575
  "--title",
@@ -528,7 +1578,7 @@ def addplotopts(parser, multiline=True):
528
1578
  type=str,
529
1579
  action="store",
530
1580
  help="Use TITLE as the overall title of the graph.",
531
- default="",
1581
+ default=None,
532
1582
  )
533
1583
  plotopts.add_argument(
534
1584
  "--xlabel",
@@ -537,7 +1587,7 @@ def addplotopts(parser, multiline=True):
537
1587
  type=str,
538
1588
  action="store",
539
1589
  help="Label for the plot x axis.",
540
- default="",
1590
+ default=None,
541
1591
  )
542
1592
  plotopts.add_argument(
543
1593
  "--ylabel",
@@ -546,7 +1596,7 @@ def addplotopts(parser, multiline=True):
546
1596
  type=str,
547
1597
  action="store",
548
1598
  help="Label for the plot y axis.",
549
- default="",
1599
+ default=None,
550
1600
  )
551
1601
  if multiline:
552
1602
  plotopts.add_argument(
@@ -670,7 +1720,40 @@ def addplotopts(parser, multiline=True):
670
1720
  )
671
1721
 
672
1722
 
673
- def addpermutationopts(parser, numreps=10000):
1723
+ def addpermutationopts(parser: argparse.ArgumentParser, numreps: int = 10000) -> None:
1724
+ """
1725
+ Add permutation testing options to an argument parser.
1726
+
1727
+ This function adds command-line arguments for configuring permutation-based
1728
+ significance testing, including the permutation method and number of null
1729
+ correlations to compute.
1730
+
1731
+ Parameters
1732
+ ----------
1733
+ parser : argparse.ArgumentParser
1734
+ The argument parser to which the permutation options will be added.
1735
+ numreps : int, optional
1736
+ Number of null correlations to run for significance estimation.
1737
+ Default is 10000. Set to 0 to disable significance testing.
1738
+
1739
+ Returns
1740
+ -------
1741
+ None
1742
+ This function modifies the parser in-place and does not return any value.
1743
+
1744
+ Notes
1745
+ -----
1746
+ The function adds two main arguments to the parser:
1747
+ 1. ``--permutationmethod``: Specifies the permutation method ('shuffle' or 'phaserandom')
1748
+ 2. ``--numnull``: Sets the number of null correlations for significance testing
1749
+
1750
+ Examples
1751
+ --------
1752
+ >>> import argparse
1753
+ >>> parser = argparse.ArgumentParser()
1754
+ >>> addpermutationopts(parser, numreps=5000)
1755
+ >>> args = parser.parse_args()
1756
+ """
674
1757
  sigcalc_opts = parser.add_argument_group("Significance calculation options")
675
1758
  permutationmethod = sigcalc_opts.add_mutually_exclusive_group()
676
1759
  permutationmethod.add_argument(
@@ -698,16 +1781,55 @@ def addpermutationopts(parser, numreps=10000):
698
1781
  ),
699
1782
  default=numreps,
700
1783
  )
701
- sigcalc_opts.add_argument(
702
- "--skipsighistfit",
703
- dest="dosighistfit",
704
- action="store_false",
705
- help=("Do not fit significance histogram with a Johnson SB function."),
706
- default=True,
707
- )
708
1784
 
709
1785
 
710
- def addsearchrangeopts(parser, details=False, defaultmin=-30.0, defaultmax=30.0):
1786
+ def addsearchrangeopts(
1787
+ parser: argparse.ArgumentParser,
1788
+ details: bool = False,
1789
+ defaultmin: float = -30.0,
1790
+ defaultmax: float = 30.0,
1791
+ ) -> None:
1792
+ """
1793
+ Add search range options to an argument parser for lag fitting.
1794
+
1795
+ This function adds command-line arguments for specifying the range of lags
1796
+ to consider during fitting operations. It provides options for setting
1797
+ the minimum and maximum lag values, as well as an optional fixed delay
1798
+ parameter.
1799
+
1800
+ Parameters
1801
+ ----------
1802
+ parser : argparse.ArgumentParser
1803
+ The argument parser to which the search range options will be added.
1804
+ details : bool, optional
1805
+ If True, adds additional detailed options including --fixdelay.
1806
+ Default is False.
1807
+ defaultmin : float, optional
1808
+ The default minimum lag value in seconds. Default is -30.0.
1809
+ defaultmax : float, optional
1810
+ The default maximum lag value in seconds. Default is 30.0.
1811
+
1812
+ Returns
1813
+ -------
1814
+ None
1815
+ This function modifies the parser in-place and returns None.
1816
+
1817
+ Notes
1818
+ -----
1819
+ The function adds two main arguments:
1820
+ - --searchrange: Specifies the lag range from LAGMIN to LAGMAX
1821
+ - --fixdelay: When details=True, sets a fixed delay time for all voxels
1822
+
1823
+ Examples
1824
+ --------
1825
+ >>> import argparse
1826
+ >>> parser = argparse.ArgumentParser()
1827
+ >>> addsearchrangeopts(parser)
1828
+ >>> args = parser.parse_args(['--searchrange', '-10', '10'])
1829
+
1830
+ >>> addsearchrangeopts(parser, details=True)
1831
+ >>> args = parser.parse_args(['--searchrange', '-5', '5', '--fixdelay', '2.0'])
1832
+ """
711
1833
  parser.add_argument(
712
1834
  "--searchrange",
713
1835
  dest="lag_extrema",
@@ -724,7 +1846,7 @@ def addsearchrangeopts(parser, details=False, defaultmin=-30.0, defaultmax=30.0)
724
1846
  if details:
725
1847
  parser.add_argument(
726
1848
  "--fixdelay",
727
- dest="fixeddelayvalue",
1849
+ dest="initialdelayvalue",
728
1850
  action="store",
729
1851
  type=float,
730
1852
  metavar="DELAYTIME",
@@ -733,16 +1855,69 @@ def addsearchrangeopts(parser, details=False, defaultmin=-30.0, defaultmax=30.0)
733
1855
  )
734
1856
 
735
1857
 
736
- def postprocesssearchrangeopts(args):
1858
+ def postprocesssearchrangeopts(args: Namespace) -> Namespace:
1859
+ """
1860
+ Post-process search range options for delay estimation.
1861
+
1862
+ This function handles additional argument parsing for delay estimation parameters
1863
+ that cannot be handled by argparse alone. It processes initial delay values and
1864
+ sets appropriate lag extrema for search range optimization.
1865
+
1866
+ Parameters
1867
+ ----------
1868
+ args : argparse.Namespace
1869
+ Namespace containing command line arguments. Expected attributes include:
1870
+ - initialdelayvalue : float, optional
1871
+ Initial delay value to fix for delay estimation
1872
+ - lag_extrema : tuple of float
1873
+ Tuple containing (lag_min, lag_max) for search range
1874
+ - lag_extrema_nondefault : tuple of float, optional
1875
+ Non-default lag extrema values to override defaults
1876
+
1877
+ Returns
1878
+ -------
1879
+ argparse.Namespace
1880
+ Updated args namespace with processed delay and search range parameters.
1881
+ Adds/updates the following attributes:
1882
+ - fixdelay : bool
1883
+ Flag indicating if delay was fixed
1884
+ - lagmin : float
1885
+ Minimum lag value for search range
1886
+ - lagmax : float
1887
+ Maximum lag value for search range
1888
+ - lagmin_nondefault : bool
1889
+ Flag indicating if lagmin was overridden from default
1890
+ - lagmax_nondefault : bool
1891
+ Flag indicating if lagmax was overridden from default
1892
+
1893
+ Notes
1894
+ -----
1895
+ If initialdelayvalue is provided, the function sets fixdelay=True and creates
1896
+ a search range centered around the initial delay value with ±10.0 range.
1897
+
1898
+ Examples
1899
+ --------
1900
+ >>> import argparse
1901
+ >>> args = argparse.Namespace()
1902
+ >>> args.initialdelayvalue = 5.0
1903
+ >>> args.lag_extrema = (-10.0, 10.0)
1904
+ >>> result = postprocesssearchrangeopts(args)
1905
+ >>> print(result.fixdelay)
1906
+ True
1907
+ >>> print(result.lagmin)
1908
+ -5.0
1909
+ >>> print(result.lagmax)
1910
+ 15.0
1911
+ """
737
1912
  # Additional argument parsing not handled by argparse
738
1913
  # first handle fixed delay
739
1914
  try:
740
- test = args.fixeddelayvalue
1915
+ test = args.initialdelayvalue
741
1916
  except:
742
- args.fixeddelayvalue = None
743
- if args.fixeddelayvalue is not None:
1917
+ args.initialdelayvalue = None
1918
+ if args.initialdelayvalue is not None:
744
1919
  args.fixdelay = True
745
- args.lag_extrema = (args.fixeddelayvalue - 10.0, args.fixeddelayvalue + 10.0)
1920
+ args.lag_extrema = (args.initialdelayvalue - 10.0, args.initialdelayvalue + 10.0)
746
1921
  else:
747
1922
  args.fixdelay = False
748
1923
 
@@ -758,7 +1933,45 @@ def postprocesssearchrangeopts(args):
758
1933
  return args
759
1934
 
760
1935
 
761
- def addtimerangeopts(parser):
1936
+ def addtimerangeopts(parser: argparse.ArgumentParser) -> None:
1937
+ """
1938
+ Add time range arguments to an argument parser for timepoint filtering.
1939
+
1940
+ This function adds a command-line argument '--timerange' that allows users
1941
+ to specify a range of timepoints to include in the analysis. The argument
1942
+ accepts two integer values representing the start and end timepoints.
1943
+
1944
+ Parameters
1945
+ ----------
1946
+ parser : argparse.ArgumentParser
1947
+ The argument parser to which the time range arguments will be added.
1948
+
1949
+ Returns
1950
+ -------
1951
+ None
1952
+ This function modifies the parser in-place and does not return any value.
1953
+
1954
+ Notes
1955
+ -----
1956
+ - The time range is inclusive on both ends
1957
+ - If END is set to -1, analysis will continue to the last timepoint
1958
+ - Negative values for START will be automatically set to 0
1959
+ - Default behavior (no timerange specified) is to use all timepoints
1960
+ - Both START and END must be non-negative integers when not equal to -1
1961
+
1962
+ Examples
1963
+ --------
1964
+ >>> import argparse
1965
+ >>> parser = argparse.ArgumentParser()
1966
+ >>> addtimerangeopts(parser)
1967
+ >>> args = parser.parse_args(['--timerange', '10', '50'])
1968
+ >>> args.timerange
1969
+ (10, 50)
1970
+
1971
+ >>> args = parser.parse_args(['--timerange', '0', '-1'])
1972
+ >>> args.timerange
1973
+ (0, -1)
1974
+ """
762
1975
  parser.add_argument(
763
1976
  "--timerange",
764
1977
  dest="timerange",
@@ -776,7 +1989,52 @@ def addtimerangeopts(parser):
776
1989
  )
777
1990
 
778
1991
 
779
- def postprocesstimerangeopts(args):
1992
+ def postprocesstimerangeopts(args: Namespace) -> Namespace:
1993
+ """
1994
+ Process timerange options and set start and end points for time range filtering.
1995
+
1996
+ This function takes a namespace object containing timerange information and
1997
+ converts it into startpoint and endpoint values that can be used for time
1998
+ range filtering operations. The timerange is expected to be a list or tuple
1999
+ with two elements: [start_time, end_time].
2000
+
2001
+ Parameters
2002
+ ----------
2003
+ args : Namespace
2004
+ A namespace object containing a 'timerange' attribute. The timerange
2005
+ should be a list or tuple of two elements: [start_time, end_time].
2006
+ The end_time can be -1 to indicate no upper bound.
2007
+
2008
+ Returns
2009
+ -------
2010
+ Namespace
2011
+ The same namespace object with added 'startpoint' and 'endpoint' attributes
2012
+ set based on the timerange values.
2013
+
2014
+ Notes
2015
+ -----
2016
+ - If the end_time in timerange is -1, the endpoint is set to 10000000000
2017
+ - Both startpoint and endpoint are converted to integers
2018
+ - The function modifies the input namespace in-place and returns it
2019
+
2020
+ Examples
2021
+ --------
2022
+ >>> args = Namespace()
2023
+ >>> args.timerange = [100, 200]
2024
+ >>> result = postprocesstimerangeopts(args)
2025
+ >>> print(result.startpoint)
2026
+ 100
2027
+ >>> print(result.endpoint)
2028
+ 200
2029
+
2030
+ >>> args = Namespace()
2031
+ >>> args.timerange = [50, -1]
2032
+ >>> result = postprocesstimerangeopts(args)
2033
+ >>> print(result.startpoint)
2034
+ 50
2035
+ >>> print(result.endpoint)
2036
+ 10000000000
2037
+ """
780
2038
  args.startpoint = int(args.timerange[0])
781
2039
  if args.timerange[1] == -1:
782
2040
  args.endpoint = 10000000000
@@ -785,7 +2043,54 @@ def postprocesstimerangeopts(args):
785
2043
  return args
786
2044
 
787
2045
 
788
- def parserange(timerange, descriptor="timerange", debug=False):
2046
+ def parserange(
2047
+ timerange: Tuple[int, int], descriptor: str = "timerange", debug: bool = False
2048
+ ) -> Tuple[int, int]:
2049
+ """
2050
+ Parse and validate a time range tuple, ensuring valid start and end points.
2051
+
2052
+ This function processes a time range tuple by handling negative values and
2053
+ validating the relationship between start and end points. Negative start values
2054
+ are set to 0, and negative end values are set to 100000000. The function ensures
2055
+ that the start point is strictly less than the end point.
2056
+
2057
+ Parameters
2058
+ ----------
2059
+ timerange : tuple of int
2060
+ A tuple containing (start, end) time points. Negative values are handled
2061
+ according to the function's logic.
2062
+ descriptor : str, optional
2063
+ A descriptive name used in error messages, default is "timerange".
2064
+ debug : bool, optional
2065
+ If True, prints debug information including startpoint, endpoint, and
2066
+ original timerange values, default is False.
2067
+
2068
+ Returns
2069
+ -------
2070
+ tuple of int
2071
+ A validated tuple containing (startpoint, endpoint) where both values
2072
+ are non-negative and startpoint < endpoint.
2073
+
2074
+ Raises
2075
+ ------
2076
+ ValueError
2077
+ If the calculated startpoint is greater than or equal to the calculated
2078
+ endpoint.
2079
+
2080
+ Examples
2081
+ --------
2082
+ >>> parserange((10, 20))
2083
+ (10, 20)
2084
+
2085
+ >>> parserange((-5, 15))
2086
+ (0, 15)
2087
+
2088
+ >>> parserange((10, -5))
2089
+ (10, 100000000)
2090
+
2091
+ >>> parserange((20, 10))
2092
+ ValueError: timerange startpoint must be < endpoint
2093
+ """
789
2094
  if timerange[0] < 0:
790
2095
  startpoint = 0
791
2096
  else:
@@ -803,7 +2108,39 @@ def parserange(timerange, descriptor="timerange", debug=False):
803
2108
  return startpoint, endpoint
804
2109
 
805
2110
 
806
- def addsimilarityopts(parser):
2111
+ def addsimilarityopts(parser: argparse.ArgumentParser) -> None:
2112
+ """
2113
+ Add mutual information similarity options to an argument parser.
2114
+
2115
+ This function adds a command-line argument for specifying the time constant
2116
+ of temporal smoothing to apply to the mutual information function. The
2117
+ smoothing helps reduce noise in the similarity calculations.
2118
+
2119
+ Parameters
2120
+ ----------
2121
+ parser : argparse.ArgumentParser
2122
+ The argument parser to which the mutual information smoothing options will be added.
2123
+
2124
+ Returns
2125
+ -------
2126
+ None
2127
+ This function modifies the parser in-place and does not return any value.
2128
+
2129
+ Notes
2130
+ -----
2131
+ The smoothing time constant (TAU) controls the temporal smoothing of the
2132
+ mutual information function. When TAU <= 0.0, smoothing is disabled.
2133
+ Default value is 3.0 seconds.
2134
+
2135
+ Examples
2136
+ --------
2137
+ >>> import argparse
2138
+ >>> parser = argparse.ArgumentParser()
2139
+ >>> addsimilarityopts(parser)
2140
+ >>> args = parser.parse_args(['--mutualinfosmoothingtime', '2.5'])
2141
+ >>> args.smoothingtime
2142
+ 2.5
2143
+ """
807
2144
  parser.add_argument(
808
2145
  "--mutualinfosmoothingtime",
809
2146
  dest="smoothingtime",
@@ -819,9 +2156,61 @@ def addsimilarityopts(parser):
819
2156
  )
820
2157
 
821
2158
 
822
- def setargs(thegetparserfunc, inputargs=None):
2159
+ def setargs(
2160
+ thegetparserfunc: Callable[[], argparse.ArgumentParser],
2161
+ inputargs: Optional[List[str]] = None,
2162
+ ) -> Tuple[Namespace, List[str]]:
823
2163
  """
824
2164
  Compile arguments for rapidtide workflow.
2165
+
2166
+ This function processes command line arguments or a provided argument list
2167
+ using an argument parser function. It handles both interactive command line
2168
+ argument parsing and programmatic argument parsing with error handling.
2169
+
2170
+ Parameters
2171
+ ----------
2172
+ thegetparserfunc : callable
2173
+ A function that returns an argparse.ArgumentParser object. This function
2174
+ should not take any arguments and should return a configured parser.
2175
+ inputargs : list of str, optional
2176
+ List of arguments to parse. If None (default), arguments are parsed
2177
+ from sys.argv. Default is None.
2178
+
2179
+ Returns
2180
+ -------
2181
+ tuple
2182
+ A tuple containing:
2183
+ - args : argparse.Namespace
2184
+ Parsed arguments as a namespace object
2185
+ - argstowrite : list of str
2186
+ The argument list that was parsed (either sys.argv or inputargs)
2187
+
2188
+ Raises
2189
+ ------
2190
+ SystemExit
2191
+ If the argument parser encounters an error or --help option is used.
2192
+
2193
+ Notes
2194
+ -----
2195
+ This function provides a unified interface for argument parsing in the
2196
+ rapidtide workflow, supporting both command line and programmatic usage.
2197
+ When --help is invoked, a helpful message is displayed before raising
2198
+ SystemExit.
2199
+
2200
+ Examples
2201
+ --------
2202
+ >>> from argparse import ArgumentParser
2203
+ >>> def get_parser():
2204
+ ... parser = ArgumentParser()
2205
+ ... parser.add_argument('--input', help='Input file')
2206
+ ... return parser
2207
+ >>> args, arglist = setargs(get_parser)
2208
+ >>> args.input
2209
+ None
2210
+
2211
+ >>> args, arglist = setargs(get_parser, ['--input', 'test.txt'])
2212
+ >>> args.input
2213
+ 'test.txt'
825
2214
  """
826
2215
  if inputargs is None:
827
2216
  # get arguments from the command line
@@ -846,9 +2235,52 @@ def setargs(thegetparserfunc, inputargs=None):
846
2235
  return args, argstowrite
847
2236
 
848
2237
 
849
- def generic_init(theparser, themain, inputargs=None):
2238
+ def generic_init(
2239
+ theparser: Callable[[], argparse.ArgumentParser],
2240
+ themain: Callable[[Namespace], None],
2241
+ inputargs: Optional[List[str]] = None,
2242
+ ) -> None:
850
2243
  """
851
2244
  Compile arguments either from the command line, or from an argument list.
2245
+
2246
+ This function serves as a generic initialization wrapper that handles
2247
+ argument parsing for command-line applications. It can parse arguments
2248
+ from either sys.argv or a provided list of arguments, and then executes
2249
+ the main function with the parsed arguments.
2250
+
2251
+ Parameters
2252
+ ----------
2253
+ theparser : Callable[[], argparse.ArgumentParser]
2254
+ A callable that returns an argparse.ArgumentParser instance
2255
+ configured with the desired command-line arguments.
2256
+ themain : Callable[[Namespace], None]
2257
+ A callable that takes a parsed arguments Namespace object
2258
+ and performs the main application logic.
2259
+ inputargs : List[str], optional
2260
+ List of argument strings to parse. If None, arguments are parsed
2261
+ from sys.argv. Default is None.
2262
+
2263
+ Returns
2264
+ -------
2265
+ None
2266
+ This function does not return any value.
2267
+
2268
+ Notes
2269
+ -----
2270
+ The function automatically saves the raw command line as an attribute
2271
+ `commandline` on the parsed arguments object for later use.
2272
+
2273
+ Examples
2274
+ --------
2275
+ >>> def create_parser():
2276
+ ... parser = argparse.ArgumentParser()
2277
+ ... parser.add_argument('--verbose', action='store_true')
2278
+ ... return parser
2279
+ ...
2280
+ >>> def main_func(args):
2281
+ ... print(f"Verbose mode: {args.verbose}")
2282
+ ...
2283
+ >>> generic_init(create_parser, main_func)
852
2284
  """
853
2285
  if inputargs is None:
854
2286
  print("processing command line arguments")