rapidtide 3.0.7__py3-none-any.whl → 3.0.8__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 (50) hide show
  1. rapidtide/_version.py +3 -3
  2. rapidtide/calcnullsimfunc.py +1 -3
  3. rapidtide/data/examples/src/test_findmaxlag.py +1 -1
  4. rapidtide/data/examples/src/testfmri +22 -16
  5. rapidtide/data/examples/src/testnewrefine +0 -23
  6. rapidtide/fMRIData_class.py +29 -52
  7. rapidtide/fit.py +4 -4
  8. rapidtide/happy_supportfuncs.py +1 -1
  9. rapidtide/helper_classes.py +0 -1099
  10. rapidtide/linfitfiltpass.py +59 -0
  11. rapidtide/makelaggedtcs.py +10 -0
  12. rapidtide/refinedelay.py +10 -19
  13. rapidtide/simFuncClasses.py +1132 -0
  14. rapidtide/simfuncfit.py +30 -30
  15. rapidtide/stats.py +5 -2
  16. rapidtide/tests/.coveragerc +6 -0
  17. rapidtide/tests/cleanposttest +1 -1
  18. rapidtide/tests/runlocaltest +2 -2
  19. rapidtide/tests/test_cleanregressor.py +3 -3
  20. rapidtide/tests/test_congrid.py +1 -1
  21. rapidtide/tests/test_corrpass.py +3 -3
  22. rapidtide/tests/test_delayestimation.py +8 -7
  23. rapidtide/tests/test_findmaxlag.py +2 -2
  24. rapidtide/tests/test_fullrunrapidtide_v3.py +2 -1
  25. rapidtide/tests/test_getparsers.py +14 -6
  26. rapidtide/tests/test_io.py +2 -6
  27. rapidtide/tests/test_nullcorr.py +3 -3
  28. rapidtide/tests/test_refinedelay.py +20 -5
  29. rapidtide/tidepoolTemplate_alt.py +1 -1
  30. rapidtide/util.py +7 -0
  31. rapidtide/voxelData.py +3 -6
  32. rapidtide/workflows/cleanregressor.py +2 -2
  33. rapidtide/workflows/delayvar.py +44 -58
  34. rapidtide/workflows/{delayestimation.py → estimateDelayMap.py} +84 -31
  35. rapidtide/workflows/rapidtide.py +361 -865
  36. rapidtide/workflows/rapidtide_parser.py +8 -41
  37. rapidtide/workflows/refineDelayMap.py +138 -0
  38. rapidtide/{RegressorRefiner.py → workflows/refineRegressor.py} +200 -28
  39. rapidtide/workflows/regressfrommaps.py +35 -27
  40. rapidtide/workflows/retrolagtcs.py +5 -6
  41. rapidtide/workflows/retroregress.py +93 -193
  42. rapidtide/workflows/showarbcorr.py +2 -2
  43. rapidtide/workflows/showxcorrx.py +5 -5
  44. rapidtide/workflows/tidepool.py +5 -5
  45. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/METADATA +2 -2
  46. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/RECORD +50 -48
  47. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/WHEEL +0 -0
  48. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/entry_points.txt +0 -0
  49. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/licenses/LICENSE +0 -0
  50. {rapidtide-3.0.7.dist-info → rapidtide-3.0.8.dist-info}/top_level.txt +0 -0
@@ -25,7 +25,6 @@ import warnings
25
25
  from pathlib import Path
26
26
 
27
27
  import numpy as np
28
- from scipy import ndimage
29
28
  from scipy.stats import rankdata
30
29
 
31
30
  import rapidtide.calccoherence as tide_calccoherence
@@ -40,17 +39,16 @@ import rapidtide.linfitfiltpass as tide_linfitfiltpass
40
39
  import rapidtide.maskutil as tide_mask
41
40
  import rapidtide.miscmath as tide_math
42
41
  import rapidtide.multiproc as tide_multiproc
43
- import rapidtide.patchmatch as tide_patch
44
- import rapidtide.peakeval as tide_peakeval
45
- import rapidtide.refinedelay as tide_refinedelay
46
- import rapidtide.RegressorRefiner as tide_regrefiner
47
42
  import rapidtide.resample as tide_resample
48
- import rapidtide.simfuncfit as tide_simfuncfit
43
+ import rapidtide.simFuncClasses as tide_simFuncClasses
49
44
  import rapidtide.stats as tide_stats
50
45
  import rapidtide.util as tide_util
51
46
  import rapidtide.voxelData as tide_voxelData
52
47
  import rapidtide.wiener as tide_wiener
53
48
  import rapidtide.workflows.cleanregressor as tide_cleanregressor
49
+ import rapidtide.workflows.estimateDelayMap as tide_estimateDelayMap
50
+ import rapidtide.workflows.refineDelayMap as tide_refineDelayMap
51
+ import rapidtide.workflows.refineRegressor as tide_refineRegressor
54
52
  import rapidtide.workflows.regressfrommaps as tide_regressfrommaps
55
53
 
56
54
  from .utils import setup_logger
@@ -117,8 +115,8 @@ def echocancel(thetimecourse, echooffset, thetimestep, outputname, padtimepoints
117
115
 
118
116
 
119
117
  def rapidtide_main(argparsingfunc):
120
- threaddebug = False
121
118
  optiondict, theprefilter = argparsingfunc
119
+ optiondict["threaddebug"] = False
122
120
 
123
121
  optiondict["nodename"] = platform.node()
124
122
 
@@ -277,7 +275,7 @@ def rapidtide_main(argparsingfunc):
277
275
  mklmaxthreads = mkl.get_max_threads()
278
276
  if not (1 <= optiondict["mklthreads"] <= mklmaxthreads):
279
277
  optiondict["mklthreads"] = mklmaxthreads
280
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
278
+ tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
281
279
  LGR.info(f"using {optiondict['mklthreads']} MKL threads")
282
280
 
283
281
  # Generate MemoryLGR output file with column names
@@ -298,15 +296,6 @@ def rapidtide_main(argparsingfunc):
298
296
  nativespaceshape = theinputdata.nativespaceshape
299
297
  fmritr = theinputdata.timestep
300
298
  optiondict["filetype"] = theinputdata.filetype
301
- if theinputdata.filetype == "cifti":
302
- fileiscifti = True
303
- optiondict["textio"] = False
304
- elif theinputdata.filetype == "text":
305
- fileiscifti = False
306
- optiondict["textio"] = True
307
- else:
308
- fileiscifti = False
309
- optiondict["textio"] = False
310
299
 
311
300
  # check to see if we need to adjust the oversample factor
312
301
  if optiondict["oversampfactor"] < 0:
@@ -629,7 +618,6 @@ def rapidtide_main(argparsingfunc):
629
618
  )
630
619
  else:
631
620
  internaloffsetexcludemask_valid = None
632
-
633
621
  tide_util.logmem("after selecting valid voxels")
634
622
 
635
623
  # move fmri_data_valid into shared memory
@@ -701,7 +689,7 @@ def rapidtide_main(argparsingfunc):
701
689
  print(f"{fmritr=}")
702
690
  print(f"{validstart=}")
703
691
  print(f"{validend=}")
704
- tide_util.disablemkl(optiondict["nprocs_confoundregress"], debug=threaddebug)
692
+ tide_util.disablemkl(optiondict["nprocs_confoundregress"], debug=optiondict["threaddebug"])
705
693
  (
706
694
  mergedregressors,
707
695
  mergedregressorlabels,
@@ -718,7 +706,7 @@ def rapidtide_main(argparsingfunc):
718
706
  orthogonalize=optiondict["orthogonalize"],
719
707
  showprogressbar=optiondict["showprogressbar"],
720
708
  )
721
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
709
+ tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
722
710
  if confoundr2 is None:
723
711
  print("There are no nonzero confound regressors - exiting")
724
712
  sys.exit()
@@ -742,7 +730,7 @@ def rapidtide_main(argparsingfunc):
742
730
  theheader["dim"][4] = 1
743
731
  theheader["pixdim"][4] = 1.0
744
732
  maplist = [
745
- (confoundr2, "confoundfilterR2", "map", None, "R2 of the motion/confound regression")
733
+ (confoundr2, "confoundfilterR2", "map", None, "R2 of the motion/confound regression"),
746
734
  ]
747
735
  tide_io.savemaplist(
748
736
  outputname,
@@ -1256,7 +1244,7 @@ def rapidtide_main(argparsingfunc):
1256
1244
  # Set up for the delay finding/refinement passes
1257
1245
  ####################################################
1258
1246
  # initialize the Correlator
1259
- theCorrelator = tide_classes.Correlator(
1247
+ theCorrelator = tide_simFuncClasses.Correlator(
1260
1248
  Fs=oversampfreq,
1261
1249
  ncprefilter=theprefilter,
1262
1250
  negativegradient=optiondict["negativegradient"],
@@ -1289,7 +1277,7 @@ def rapidtide_main(argparsingfunc):
1289
1277
  dummy, trimmedcorrscale, dummy = theCorrelator.getfunction()
1290
1278
 
1291
1279
  # initialize the MutualInformationator
1292
- theMutualInformationator = tide_classes.MutualInformationator(
1280
+ theMutualInformationator = tide_simFuncClasses.MutualInformationator(
1293
1281
  Fs=oversampfreq,
1294
1282
  smoothingtime=optiondict["smoothingtime"],
1295
1283
  ncprefilter=theprefilter,
@@ -1384,26 +1372,35 @@ def rapidtide_main(argparsingfunc):
1384
1372
  LGR.debug(
1385
1373
  f"allocating memory for correlation arrays {internalcorrshape} {internalvalidcorrshape}"
1386
1374
  )
1375
+ corrout, corrout_shm = tide_util.allocarray(
1376
+ internalvalidcorrshape,
1377
+ rt_floatset,
1378
+ shared=optiondict["sharedmem"],
1379
+ name=f"corrout_{optiondict['pid']}",
1380
+ )
1381
+ gaussout, gaussout_shm = tide_util.allocarray(
1382
+ internalvalidcorrshape,
1383
+ rt_floatset,
1384
+ shared=optiondict["sharedmem"],
1385
+ name=f"gaussout_{optiondict['pid']}",
1386
+ )
1387
+ windowout, windowout_shm = tide_util.allocarray(
1388
+ internalvalidcorrshape,
1389
+ rt_floatset,
1390
+ shared=optiondict["sharedmem"],
1391
+ name=f"windowout_{optiondict['pid']}",
1392
+ )
1393
+ outcorrarray, outcorrarray_shm = tide_util.allocarray(
1394
+ internalcorrshape,
1395
+ rt_floatset,
1396
+ shared=optiondict["sharedmem"],
1397
+ name=f"outcorrarray_{optiondict['pid']}",
1398
+ )
1387
1399
  if optiondict["sharedmem"]:
1388
- corrout, corrout_shm = tide_util.allocshared(
1389
- internalvalidcorrshape, rt_floatset, name=f"corrout_{optiondict['pid']}"
1390
- )
1391
- gaussout, gaussout_shm = tide_util.allocshared(
1392
- internalvalidcorrshape, rt_floatset, name=f"gaussout_{optiondict['pid']}"
1393
- )
1394
- windowout, windowout_shm = tide_util.allocshared(
1395
- internalvalidcorrshape, rt_floatset, name=f"windowout_{optiondict['pid']}"
1396
- )
1397
- outcorrarray, outcorrarray_shm = tide_util.allocshared(
1398
- internalcorrshape, rt_floatset, name=f"outcorrarray_{optiondict['pid']}"
1399
- )
1400
1400
  ramlocation = "in shared memory"
1401
1401
  else:
1402
- corrout = np.zeros(internalvalidcorrshape, dtype=rt_floattype)
1403
- gaussout = np.zeros(internalvalidcorrshape, dtype=rt_floattype)
1404
- windowout = np.zeros(internalvalidcorrshape, dtype=rt_floattype)
1405
- outcorrarray = np.zeros(internalcorrshape, dtype=rt_floattype)
1406
1402
  ramlocation = "locally"
1403
+
1407
1404
  optiondict["totalcorrelationbytes"] = (
1408
1405
  corrout.nbytes + gaussout.nbytes + windowout.nbytes + outcorrarray.nbytes
1409
1406
  )
@@ -1467,6 +1464,69 @@ def rapidtide_main(argparsingfunc):
1467
1464
  2 * numpadtrs + np.shape(initial_fmri_x)[0],
1468
1465
  )
1469
1466
 
1467
+ # now do the arrays for delay refinement
1468
+ if optiondict["dolinfitfilt"] or optiondict["docvrmap"] or optiondict["refinedelay"]:
1469
+ if optiondict["refinedelay"]:
1470
+ derivaxissize = np.max([2, optiondict["regressderivs"] + 1])
1471
+ else:
1472
+ derivaxissize = optiondict["regressderivs"] + 1
1473
+ internalvalidspaceshapederivs = (
1474
+ internalvalidspaceshape,
1475
+ derivaxissize,
1476
+ )
1477
+ sLFOfitmean, sLFOfitmean_shm = tide_util.allocarray(
1478
+ internalvalidspaceshape,
1479
+ rt_outfloattype,
1480
+ shared=optiondict["sharedmem"],
1481
+ name=f"sLFOfitmean_{optiondict['pid']}",
1482
+ )
1483
+ rvalue, rvalue_shm = tide_util.allocarray(
1484
+ internalvalidspaceshape,
1485
+ rt_outfloattype,
1486
+ shared=optiondict["sharedmem"],
1487
+ name=f"rvalue_{optiondict['pid']}",
1488
+ )
1489
+ r2value, r2value_shm = tide_util.allocarray(
1490
+ internalvalidspaceshape,
1491
+ rt_outfloattype,
1492
+ shared=optiondict["sharedmem"],
1493
+ name=f"r2value_{optiondict['pid']}",
1494
+ )
1495
+ fitNorm, fitNorm_shm = tide_util.allocarray(
1496
+ internalvalidspaceshapederivs,
1497
+ rt_outfloattype,
1498
+ shared=optiondict["sharedmem"],
1499
+ name=f"fitNorm_{optiondict['pid']}",
1500
+ )
1501
+ fitcoeff, fitcoeff_shm = tide_util.allocarray(
1502
+ internalvalidspaceshapederivs,
1503
+ rt_outfloattype,
1504
+ shared=optiondict["sharedmem"],
1505
+ name=f"fitcoeff_{optiondict['pid']}",
1506
+ )
1507
+ lagtc, lagtc_shm = tide_util.allocarray(
1508
+ internalvalidfmrishape,
1509
+ rt_floattype,
1510
+ shared=optiondict["sharedmem"],
1511
+ name=f"lagtc_{optiondict['pid']}",
1512
+ )
1513
+ if optiondict["sharedmem"]:
1514
+ ramlocation = "in shared memory"
1515
+ else:
1516
+ ramlocation = "locally"
1517
+
1518
+ optiondict["totalRefineDelaybytes"] = (
1519
+ sLFOfitmean.nbytes
1520
+ + rvalue.nbytes
1521
+ + r2value.nbytes
1522
+ + fitNorm.nbytes
1523
+ + fitcoeff.nbytes
1524
+ + lagtc.nbytes
1525
+ )
1526
+ thesize, theunit = tide_util.format_bytes(optiondict["totalRefineDelaybytes"])
1527
+ print(f"allocated {thesize:.3f} {theunit} {ramlocation} for delay refinement")
1528
+ tide_util.logmem("after derivative delay/sLFO filter array allocation")
1529
+
1470
1530
  # prepare for regressor refinement, if we're doing it
1471
1531
  if (
1472
1532
  optiondict["passes"] > 1
@@ -1475,7 +1535,7 @@ def rapidtide_main(argparsingfunc):
1475
1535
  or optiondict["convergencethresh"] is not None
1476
1536
  ):
1477
1537
  # we will be doing regressor refinement, so configure the refiner
1478
- theRegressorRefiner = tide_regrefiner.RegressorRefiner(
1538
+ theRegressorRefiner = tide_refineRegressor.RegressorRefiner(
1479
1539
  internalvalidfmrishape,
1480
1540
  internalvalidpaddedfmrishape,
1481
1541
  optiondict["pid"],
@@ -1524,7 +1584,7 @@ def rapidtide_main(argparsingfunc):
1524
1584
  LGR.verbose(f"edgebufferfrac set to {optiondict['edgebufferfrac']}")
1525
1585
 
1526
1586
  # initialize the correlation fitter
1527
- theFitter = tide_classes.SimilarityFunctionFitter(
1587
+ theFitter = tide_simFuncClasses.SimilarityFunctionFitter(
1528
1588
  lagmod=optiondict["lagmod"],
1529
1589
  lthreshval=optiondict["lthreshval"],
1530
1590
  uthreshval=optiondict["uthreshval"],
@@ -1552,7 +1612,7 @@ def rapidtide_main(argparsingfunc):
1552
1612
  windowfunc=optiondict["windowfunc"],
1553
1613
  )
1554
1614
 
1555
- tide_util.disablemkl(optiondict["nprocs_calcsimilarity"], debug=threaddebug)
1615
+ tide_util.disablemkl(optiondict["nprocs_calcsimilarity"], debug=optiondict["threaddebug"])
1556
1616
  (
1557
1617
  voxelsprocessed_echo,
1558
1618
  theglobalmaxlist,
@@ -1576,7 +1636,7 @@ def rapidtide_main(argparsingfunc):
1576
1636
  rt_floatset=rt_floatset,
1577
1637
  rt_floattype=rt_floattype,
1578
1638
  )
1579
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
1639
+ tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
1580
1640
 
1581
1641
  for i in range(len(theglobalmaxlist)):
1582
1642
  theglobalmaxlist[i] = corrscale[theglobalmaxlist[i]] - optiondict["simcalcoffset"]
@@ -1731,7 +1791,7 @@ def rapidtide_main(argparsingfunc):
1731
1791
  theSimFunc = theMutualInformationator
1732
1792
  else:
1733
1793
  theSimFunc = theCorrelator
1734
- tide_util.disablemkl(optiondict["nprocs_getNullDist"], debug=threaddebug)
1794
+ tide_util.disablemkl(optiondict["nprocs_getNullDist"], debug=optiondict["threaddebug"])
1735
1795
  simdistdata = tide_nullsimfunc.getNullDistributionData(
1736
1796
  oversampfreq,
1737
1797
  theSimFunc,
@@ -1746,7 +1806,7 @@ def rapidtide_main(argparsingfunc):
1746
1806
  rt_floatset=np.float64,
1747
1807
  rt_floattype="float64",
1748
1808
  )
1749
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
1809
+ tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
1750
1810
 
1751
1811
  tide_io.writebidstsv(
1752
1812
  f"{outputname}_desc-simdistdata_info",
@@ -1786,6 +1846,8 @@ def rapidtide_main(argparsingfunc):
1786
1846
  twotail=optiondict["bipolar"],
1787
1847
  nozero=optiondict["nohistzero"],
1788
1848
  )
1849
+ if sigfit is None:
1850
+ optiondict["ampthreshfromsig"] = False
1789
1851
  if pcts is not None:
1790
1852
  for i in range(len(thepvalnames)):
1791
1853
  optiondict[
@@ -1841,455 +1903,108 @@ def rapidtide_main(argparsingfunc):
1841
1903
  optiondict["currentstage"] = f"precorrelation_pass{thepass}"
1842
1904
  tide_io.writedicttojson(optiondict, f"{outputname}_desc-runoptions_info.json")
1843
1905
 
1844
- # tide_delayestimate.estimateDelay(
1845
- # fmri_data_valid[:, validsimcalcstart : validsimcalcend + 1],
1846
- # initial_fmri_x[validsimcalcstart : validsimcalcend + 1],
1847
- # os_fmri_x[osvalidsimcalcstart : osvalidsimcalcend + 1],
1848
- # theMutualInformationator,
1849
- # thepass,
1850
- # )
1851
- ########################
1852
- # Delay estimation start
1853
- ########################
1854
- # Step 1 - Correlation step
1855
- if optiondict["similaritymetric"] == "mutualinfo":
1856
- similaritytype = "Mutual information"
1857
- elif optiondict["similaritymetric"] == "correlation":
1858
- similaritytype = "Correlation"
1859
- else:
1860
- similaritytype = "MI enhanced correlation"
1861
- LGR.info(f"\n\n{similaritytype} calculation, pass {thepass}")
1862
- TimingLGR.info(f"{similaritytype} calculation start, pass {thepass}")
1863
-
1864
- tide_util.disablemkl(optiondict["nprocs_calcsimilarity"], debug=threaddebug)
1865
- if optiondict["similaritymetric"] == "mutualinfo":
1866
- theMutualInformationator.setlimits(lagmininpts, lagmaxinpts)
1867
- (
1868
- voxelsprocessed_cp,
1869
- theglobalmaxlist,
1870
- trimmedcorrscale,
1871
- ) = tide_calcsimfunc.correlationpass(
1872
- fmri_data_valid[:, validsimcalcstart : validsimcalcend + 1],
1873
- cleaned_referencetc,
1874
- theMutualInformationator,
1875
- initial_fmri_x[validsimcalcstart : validsimcalcend + 1],
1876
- os_fmri_x[osvalidsimcalcstart : osvalidsimcalcend + 1],
1877
- lagmininpts,
1878
- lagmaxinpts,
1879
- corrout,
1880
- meanval,
1881
- nprocs=optiondict["nprocs_calcsimilarity"],
1882
- alwaysmultiproc=optiondict["alwaysmultiproc"],
1883
- oversampfactor=optiondict["oversampfactor"],
1884
- interptype=optiondict["interptype"],
1885
- showprogressbar=optiondict["showprogressbar"],
1886
- chunksize=optiondict["mp_chunksize"],
1887
- rt_floatset=rt_floatset,
1888
- rt_floattype=rt_floattype,
1889
- debug=optiondict["focaldebug"],
1890
- )
1891
- else:
1892
- (
1893
- voxelsprocessed_cp,
1894
- theglobalmaxlist,
1895
- trimmedcorrscale,
1896
- ) = tide_calcsimfunc.correlationpass(
1897
- fmri_data_valid[:, validsimcalcstart : validsimcalcend + 1],
1898
- cleaned_referencetc,
1899
- theCorrelator,
1900
- initial_fmri_x[validsimcalcstart : validsimcalcend + 1],
1901
- os_fmri_x[osvalidsimcalcstart : osvalidsimcalcend + 1],
1902
- lagmininpts,
1903
- lagmaxinpts,
1904
- corrout,
1905
- meanval,
1906
- nprocs=optiondict["nprocs_calcsimilarity"],
1907
- alwaysmultiproc=optiondict["alwaysmultiproc"],
1908
- oversampfactor=optiondict["oversampfactor"],
1909
- interptype=optiondict["interptype"],
1910
- showprogressbar=optiondict["showprogressbar"],
1911
- chunksize=optiondict["mp_chunksize"],
1912
- rt_floatset=rt_floatset,
1913
- rt_floattype=rt_floattype,
1914
- debug=optiondict["focaldebug"],
1915
- )
1916
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
1917
-
1918
- for i in range(len(theglobalmaxlist)):
1919
- theglobalmaxlist[i] = corrscale[theglobalmaxlist[i]] - optiondict["simcalcoffset"]
1920
- namesuffix = "_desc-globallag_hist"
1921
- tide_stats.makeandsavehistogram(
1922
- np.asarray(theglobalmaxlist),
1923
- len(corrscale),
1924
- 0,
1925
- outputname + namesuffix,
1926
- displaytitle="Histogram of lag times from global lag calculation",
1927
- therange=(corrscale[0], corrscale[-1]),
1928
- refine=False,
1929
- dictvarname="globallaghist_pass" + str(thepass),
1930
- append=(optiondict["echocancel"] or (thepass > 1)),
1931
- thedict=optiondict,
1932
- )
1933
-
1934
- if optiondict["checkpoint"]:
1935
- outcorrarray[:, :] = 0.0
1936
- outcorrarray[validvoxels, :] = corrout[:, :]
1937
- if theinputdata.filetype == "text":
1938
- tide_io.writenpvecs(
1939
- outcorrarray.reshape(nativecorrshape),
1940
- f"{outputname}_corrout_prefit_pass" + str(thepass) + ".txt",
1941
- )
1942
- else:
1943
- savename = f"{outputname}_desc-corroutprefit_pass-" + str(thepass)
1944
- tide_io.savetonifti(outcorrarray.reshape(nativecorrshape), theheader, savename)
1945
-
1946
- TimingLGR.info(
1947
- f"{similaritytype} calculation end, pass {thepass}",
1948
- {
1949
- "message2": voxelsprocessed_cp,
1950
- "message3": "voxels",
1951
- },
1952
- )
1953
-
1954
- # Step 1b. Do a peak prefit
1955
- if optiondict["similaritymetric"] == "hybrid":
1956
- LGR.info(f"\n\nPeak prefit calculation, pass {thepass}")
1957
- TimingLGR.info(f"Peak prefit calculation start, pass {thepass}")
1958
-
1959
- tide_util.disablemkl(optiondict["nprocs_peakeval"], debug=threaddebug)
1960
- voxelsprocessed_pe, thepeakdict = tide_peakeval.peakevalpass(
1961
- fmri_data_valid[:, validsimcalcstart : validsimcalcend + 1],
1962
- cleaned_referencetc,
1963
- initial_fmri_x[validsimcalcstart : validsimcalcend + 1],
1964
- os_fmri_x[osvalidsimcalcstart : osvalidsimcalcend + 1],
1965
- theMutualInformationator,
1966
- trimmedcorrscale,
1967
- corrout,
1968
- nprocs=optiondict["nprocs_peakeval"],
1969
- alwaysmultiproc=optiondict["alwaysmultiproc"],
1970
- bipolar=optiondict["bipolar"],
1971
- oversampfactor=optiondict["oversampfactor"],
1972
- interptype=optiondict["interptype"],
1973
- showprogressbar=optiondict["showprogressbar"],
1974
- chunksize=optiondict["mp_chunksize"],
1975
- rt_floatset=rt_floatset,
1976
- rt_floattype=rt_floattype,
1977
- )
1978
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
1979
-
1980
- TimingLGR.info(
1981
- f"Peak prefit end, pass {thepass}",
1982
- {
1983
- "message2": voxelsprocessed_pe,
1984
- "message3": "voxels",
1985
- },
1986
- )
1987
- mipeaks = lagtimes * 0.0
1988
- for i in range(numvalidspatiallocs):
1989
- if len(thepeakdict[str(i)]) > 0:
1990
- mipeaks[i] = thepeakdict[str(i)][0][0]
1991
- else:
1992
- thepeakdict = None
1993
-
1994
- # Step 2 - similarity function fitting and time lag estimation
1995
- # write out the current version of the run options
1996
- optiondict["currentstage"] = f"presimfuncfit_pass{thepass}"
1997
- tide_io.writedicttojson(optiondict, f"{outputname}_desc-runoptions_info.json")
1998
- LGR.info(f"\n\nTime lag estimation pass {thepass}")
1999
- TimingLGR.info(f"Time lag estimation start, pass {thepass}")
2000
-
2001
- theFitter.setfunctype(optiondict["similaritymetric"])
2002
- theFitter.setcorrtimeaxis(trimmedcorrscale)
2003
-
2004
- # use initial lags if this is a hybrid fit
2005
- if optiondict["similaritymetric"] == "hybrid" and thepeakdict is not None:
2006
- initlags = mipeaks
2007
- else:
2008
- initlags = None
2009
-
2010
- tide_util.disablemkl(optiondict["nprocs_fitcorr"], debug=threaddebug)
2011
- voxelsprocessed_fc = tide_simfuncfit.fitcorr(
2012
- trimmedcorrscale,
2013
- theFitter,
1906
+ # step 1 - do the initial delay estimation
1907
+ internaldespeckleincludemask = tide_estimateDelayMap.estimateDelay(
1908
+ fmri_data_valid,
1909
+ validsimcalcstart,
1910
+ validsimcalcend,
1911
+ osvalidsimcalcstart,
1912
+ osvalidsimcalcend,
1913
+ initial_fmri_x,
1914
+ os_fmri_x,
1915
+ theCorrelator,
1916
+ theMutualInformationator,
1917
+ cleaned_referencetc,
2014
1918
  corrout,
1919
+ meanval,
1920
+ corrscale,
1921
+ outputname,
1922
+ outcorrarray,
1923
+ validvoxels,
1924
+ nativecorrshape,
1925
+ nativespaceshape,
1926
+ bidsbasedict,
1927
+ numspatiallocs,
1928
+ gaussout,
1929
+ theinitialdelay,
1930
+ windowout,
1931
+ R2,
1932
+ thesizes,
1933
+ internalspaceshape,
1934
+ numvalidspatiallocs,
1935
+ theinputdata,
1936
+ theheader,
1937
+ theFitter,
2015
1938
  fitmask,
2016
- failreason,
2017
1939
  lagtimes,
2018
1940
  lagstrengths,
2019
1941
  lagsigma,
2020
- gaussout,
2021
- windowout,
2022
- R2,
2023
- despeckling=False,
2024
- peakdict=thepeakdict,
2025
- nprocs=optiondict["nprocs_fitcorr"],
2026
- alwaysmultiproc=optiondict["alwaysmultiproc"],
2027
- fixdelay=optiondict["fixdelay"],
2028
- initialdelayvalue=theinitialdelay,
2029
- showprogressbar=optiondict["showprogressbar"],
2030
- chunksize=optiondict["mp_chunksize"],
2031
- despeckle_thresh=optiondict["despeckle_thresh"],
2032
- initiallags=initlags,
2033
- rt_floatset=rt_floatset,
2034
- rt_floattype=rt_floattype,
1942
+ failreason,
1943
+ outmaparray,
1944
+ lagmininpts,
1945
+ lagmaxinpts,
1946
+ thepass,
1947
+ optiondict,
1948
+ LGR,
1949
+ TimingLGR,
1950
+ rt_floatset=np.float64,
1951
+ rt_floattype="float64",
2035
1952
  )
2036
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
2037
1953
 
2038
- TimingLGR.info(
2039
- f"Time lag estimation end, pass {thepass}",
2040
- {
2041
- "message2": voxelsprocessed_fc,
2042
- "message3": "voxels",
2043
- },
2044
- )
1954
+ # refine delay
1955
+ if optiondict["refinedelayeachpass"]:
1956
+ if optiondict["delayoffsetgausssigma"] < 0.0 and theinputdata.filetype != "text":
1957
+ # set gausssigma automatically
1958
+ optiondict["delayoffsetgausssigma"] = np.mean([xdim, ydim, slicethickness]) / 2.0
2045
1959
 
2046
- # Step 2b - Correlation time despeckle
2047
- if optiondict["despeckle_passes"] > 0:
2048
- LGR.info(f"\n\n{similaritytype} despeckling pass {thepass}")
2049
- LGR.info(f"\tUsing despeckle_thresh = {optiondict['despeckle_thresh']:.3f}")
2050
- TimingLGR.info(f"{similaritytype} despeckle start, pass {thepass}")
2051
-
2052
- # find lags that are very different from their neighbors, and refit starting at the median lag for the point
2053
- voxelsprocessed_fc_ds = 0
2054
- despecklingdone = False
2055
- lastnumdespeckled = 1000000
2056
- for despecklepass in range(optiondict["despeckle_passes"]):
2057
- LGR.info(f"\n\n{similaritytype} despeckling subpass {despecklepass + 1}")
2058
- outmaparray *= 0.0
2059
- outmaparray[validvoxels] = eval("lagtimes")[:]
2060
-
2061
- # find voxels to despeckle
2062
- medianlags = ndimage.median_filter(
2063
- outmaparray.reshape(nativespaceshape), 3
2064
- ).reshape(numspatiallocs)
2065
- # voxels that we're happy with have initlags set to -1000000.0
2066
- initlags = np.where(
2067
- np.abs(outmaparray - medianlags) > optiondict["despeckle_thresh"],
2068
- medianlags,
2069
- -1000000.0,
2070
- )[validvoxels]
2071
-
2072
- if len(initlags) > 0:
2073
- numdespeckled = len(np.where(initlags != -1000000.0)[0])
2074
- if lastnumdespeckled > numdespeckled > 0:
2075
- lastnumdespeckled = numdespeckled
2076
- tide_util.disablemkl(optiondict["nprocs_fitcorr"], debug=threaddebug)
2077
- voxelsprocessed_thispass = tide_simfuncfit.fitcorr(
2078
- trimmedcorrscale,
2079
- theFitter,
2080
- corrout,
2081
- fitmask,
2082
- failreason,
2083
- lagtimes,
2084
- lagstrengths,
2085
- lagsigma,
2086
- gaussout,
2087
- windowout,
2088
- R2,
2089
- despeckling=True,
2090
- peakdict=thepeakdict,
2091
- nprocs=optiondict["nprocs_fitcorr"],
2092
- alwaysmultiproc=optiondict["alwaysmultiproc"],
2093
- fixdelay=optiondict["fixdelay"],
2094
- initialdelayvalue=theinitialdelay,
2095
- showprogressbar=optiondict["showprogressbar"],
2096
- chunksize=optiondict["mp_chunksize"],
2097
- despeckle_thresh=optiondict["despeckle_thresh"],
2098
- initiallags=initlags,
2099
- rt_floatset=rt_floatset,
2100
- rt_floattype=rt_floattype,
2101
- )
2102
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
2103
-
2104
- voxelsprocessed_fc_ds += voxelsprocessed_thispass
2105
- optiondict[
2106
- "despecklemasksize_pass" + str(thepass) + "_d" + str(despecklepass + 1)
2107
- ] = voxelsprocessed_thispass
2108
- optiondict[
2109
- "despecklemaskpct_pass" + str(thepass) + "_d" + str(despecklepass + 1)
2110
- ] = (100.0 * voxelsprocessed_thispass / optiondict["corrmasksize"])
2111
- else:
2112
- despecklingdone = True
2113
- else:
2114
- despecklingdone = True
2115
- if despecklingdone:
2116
- LGR.info("Nothing left to do! Terminating despeckling")
2117
- break
2118
-
2119
- internaldespeckleincludemask = np.where(
2120
- np.abs(outmaparray - medianlags) > optiondict["despeckle_thresh"],
2121
- medianlags,
2122
- 0.0,
2123
- )
2124
- if optiondict["savedespecklemasks"] and (optiondict["despeckle_passes"] > 0):
2125
- despecklesavemask = np.where(
2126
- internaldespeckleincludemask[validvoxels] == 0.0, 0, 1
2127
- )
2128
- if thepass == optiondict["passes"]:
2129
- if theinputdata.filetype != "text":
2130
- if theinputdata.filetype == "cifti":
2131
- timeindex = theheader["dim"][0] - 1
2132
- spaceindex = theheader["dim"][0]
2133
- theheader["dim"][timeindex] = 1
2134
- theheader["dim"][spaceindex] = numspatiallocs
2135
- else:
2136
- theheader["dim"][0] = 3
2137
- theheader["dim"][4] = 1
2138
- theheader["pixdim"][4] = 1.0
2139
- masklist = [
2140
- (
2141
- despecklesavemask,
2142
- "despeckle",
2143
- "mask",
2144
- None,
2145
- "Voxels that underwent despeckling in the final pass",
2146
- )
2147
- ]
2148
- tide_io.savemaplist(
2149
- outputname,
2150
- masklist,
2151
- validvoxels,
2152
- nativespaceshape,
2153
- theheader,
2154
- bidsbasedict,
2155
- filetype=theinputdata.filetype,
2156
- rt_floattype=rt_floattype,
2157
- cifti_hdr=theinputdata.cifti_hdr,
2158
- )
2159
- LGR.info(
2160
- f"\n\n{voxelsprocessed_fc_ds} voxels despeckled in "
2161
- f"{optiondict['despeckle_passes']} passes"
2162
- )
2163
- TimingLGR.info(
2164
- f"{similaritytype} despeckle end, pass {thepass}",
2165
- {
2166
- "message2": voxelsprocessed_fc_ds,
2167
- "message3": "voxels",
2168
- },
2169
- )
1960
+ if optiondict["sLFOfiltmask"]:
1961
+ sLFOfiltmask = fitmask + 0.0
1962
+ else:
1963
+ sLFOfiltmask = fitmask * 0.0 + 1.0
2170
1964
 
2171
- # Step 2c - patch shifting
2172
- if optiondict["patchshift"]:
2173
- outmaparray *= 0.0
2174
- outmaparray[validvoxels] = eval("lagtimes")[:]
2175
- # new method
2176
- masklist = [
2177
- (
2178
- outmaparray[validvoxels],
2179
- f"lagtimes_prepatch_pass{thepass}",
2180
- "map",
2181
- None,
2182
- f"Input lagtimes map prior to patch map generation pass {thepass}",
2183
- ),
2184
- ]
2185
- tide_io.savemaplist(
1965
+ optiondict["regressfiltthreshval"] = 0.0
1966
+
1967
+ (
1968
+ delayoffset,
1969
+ regressderivratios,
1970
+ medfiltregressderivratios,
1971
+ filteredregressderivratios,
1972
+ optiondict["delayoffsetMAD"],
1973
+ ) = tide_refineDelayMap.refineDelay(
1974
+ fmri_data_valid,
1975
+ initial_fmri_x,
1976
+ xdim,
1977
+ ydim,
1978
+ slicethickness,
1979
+ sLFOfiltmask,
1980
+ genlagtc,
1981
+ oversamptr,
1982
+ sLFOfitmean,
1983
+ rvalue,
1984
+ r2value,
1985
+ fitNorm,
1986
+ fitcoeff,
1987
+ lagtc,
2186
1988
  outputname,
2187
- masklist,
2188
1989
  validvoxels,
2189
1990
  nativespaceshape,
2190
- theheader,
2191
- bidsbasedict,
2192
- filetype=theinputdata.filetype,
1991
+ theinputdata,
1992
+ lagtimes,
1993
+ optiondict,
1994
+ LGR,
1995
+ TimingLGR,
1996
+ outputlevel=optiondict["outputlevel"],
1997
+ gausssigma=optiondict["delayoffsetgausssigma"],
1998
+ patchthresh=optiondict["delaypatchthresh"],
1999
+ mindelay=optiondict["mindelay"],
2000
+ maxdelay=optiondict["maxdelay"],
2001
+ numpoints=optiondict["numpoints"],
2002
+ histlen=optiondict["histlen"],
2003
+ rt_floatset=rt_floatset,
2193
2004
  rt_floattype=rt_floattype,
2194
- cifti_hdr=theinputdata.cifti_hdr,
2005
+ debug=optiondict["debug"],
2195
2006
  )
2196
-
2197
- # create list of anomalous 3D regions that don't match surroundings
2198
- if theinputdata.nim_affine is not None:
2199
- # make an atlas of anomalous patches - each patch shares the same integer value
2200
- step1 = tide_patch.calc_DoG(
2201
- outmaparray.reshape(nativespaceshape).copy(),
2202
- theinputdata.nim_affine,
2203
- thesizes,
2204
- fwhm=optiondict["patchfwhm"],
2205
- ratioopt=False,
2206
- debug=True,
2207
- )
2208
- masklist = [
2209
- (
2210
- step1.reshape(internalspaceshape)[validvoxels],
2211
- f"DoG_pass{thepass}",
2212
- "map",
2213
- None,
2214
- f"DoG map for pass {thepass}",
2215
- ),
2216
- ]
2217
- tide_io.savemaplist(
2218
- outputname,
2219
- masklist,
2220
- validvoxels,
2221
- nativespaceshape,
2222
- theheader,
2223
- bidsbasedict,
2224
- filetype=theinputdata.filetype,
2225
- rt_floattype=rt_floattype,
2226
- cifti_hdr=theinputdata.cifti_hdr,
2227
- )
2228
- step2 = tide_patch.invertedflood3D(
2229
- step1,
2230
- 1,
2231
- )
2232
- masklist = [
2233
- (
2234
- step2.reshape(internalspaceshape)[validvoxels],
2235
- f"invertflood_pass{thepass}",
2236
- "map",
2237
- None,
2238
- f"Inverted flood map for pass {thepass}",
2239
- ),
2240
- ]
2241
- tide_io.savemaplist(
2242
- outputname,
2243
- masklist,
2244
- validvoxels,
2245
- nativespaceshape,
2246
- theheader,
2247
- bidsbasedict,
2248
- filetype=theinputdata.filetype,
2249
- rt_floattype=rt_floattype,
2250
- cifti_hdr=theinputdata.cifti_hdr,
2251
- )
2252
-
2253
- patchmap = tide_patch.separateclusters(
2254
- step2,
2255
- sizethresh=optiondict["patchminsize"],
2256
- debug=True,
2257
- )
2258
- # patchmap = tide_patch.getclusters(
2259
- # outmaparray.reshape(nativespaceshape),
2260
- # theinputdata.nim_affine,
2261
- # thesizes,
2262
- # fwhm=optiondict["patchfwhm"],
2263
- # ratioopt=True,
2264
- # sizethresh=optiondict["patchminsize"],
2265
- # debug=True,
2266
- # )
2267
- masklist = [
2268
- (
2269
- patchmap[validvoxels],
2270
- f"patch_pass{thepass}",
2271
- "map",
2272
- None,
2273
- f"Patch map for despeckling pass {thepass}",
2274
- ),
2275
- ]
2276
- tide_io.savemaplist(
2277
- outputname,
2278
- masklist,
2279
- validvoxels,
2280
- nativespaceshape,
2281
- theheader,
2282
- bidsbasedict,
2283
- filetype=theinputdata.filetype,
2284
- rt_floattype=rt_floattype,
2285
- cifti_hdr=theinputdata.cifti_hdr,
2286
- )
2287
-
2288
- # now shift the patches to align with the majority of the image
2289
- tide_patch.interppatch(lagtimes, patchmap[validvoxels])
2290
- ########################
2291
- # Delay estimation end
2292
- ########################
2007
+ lagtimes[:] = lagtimes + delayoffset
2293
2008
 
2294
2009
  # Step 2d - make a rank order map
2295
2010
  timepercentile = (
@@ -2333,147 +2048,37 @@ def rapidtide_main(argparsingfunc):
2333
2048
  or optiondict["initregressorpreselect"]
2334
2049
  or optiondict["dofinalrefine"]
2335
2050
  ):
2336
- LGR.info(f"\n\nRegressor refinement, pass {thepass}")
2337
- TimingLGR.info(f"Regressor refinement start, pass {thepass}")
2338
- if optiondict["refineoffset"]:
2339
- # check that we won't end up excluding all voxels from offset calculation before accepting mask
2340
- offsetmask = np.uint16(fitmask)
2341
- if internaloffsetincludemask_valid is not None:
2342
- offsetmask[np.where(internaloffsetincludemask_valid == 0)] = 0
2343
- if internaloffsetexcludemask_valid is not None:
2344
- offsetmask[np.where(internaloffsetexcludemask_valid != 0.0)] = 0
2345
- if tide_stats.getmasksize(offsetmask) == 0:
2346
- LGR.warning(
2347
- "NB: cannot exclude voxels from offset calculation mask - including for this pass"
2348
- )
2349
- offsetmask = fitmask + 0
2350
-
2351
- peaklag, dummy, dummy = tide_stats.gethistprops(
2352
- lagtimes[np.where(offsetmask > 0)],
2353
- optiondict["histlen"],
2354
- pickleft=optiondict["pickleft"],
2355
- peakthresh=optiondict["pickleftthresh"],
2356
- )
2357
- optiondict["offsettime"] = peaklag
2358
- optiondict["offsettime_total"] += peaklag
2359
- optiondict[f"offsettime_pass{thepass}"] = optiondict["offsettime"]
2360
- optiondict[f"offsettime_total_pass{thepass}"] = optiondict["offsettime_total"]
2361
- LGR.info(
2362
- f"offset time set to {optiondict['offsettime']:.3f}, "
2363
- f"total is {optiondict['offsettime_total']:.3f}"
2364
- )
2365
-
2366
- if optiondict["refinedespeckled"] or (optiondict["despeckle_passes"] == 0):
2367
- # if refinedespeckled is true, or there is no despeckling, masks are unaffected
2368
- thisinternalrefineexcludemask_valid = internalrefineexcludemask_valid
2369
- else:
2370
- # if refinedespeckled is false and there is despeckling, need to make a proper mask
2371
- if internalrefineexcludemask_valid is None:
2372
- # if there is currently no exclude mask, set exclude mask = despeckle mask
2373
- thisinternalrefineexcludemask_valid = np.where(
2374
- internaldespeckleincludemask[validvoxels] == 0.0, 0, 1
2375
- )
2376
- else:
2377
- # if there is a current exclude mask, add any voxels that are being despeckled
2378
- thisinternalrefineexcludemask_valid = np.where(
2379
- internalrefineexcludemask_valid > 0, 1, 0
2380
- )
2381
- thisinternalrefineexcludemask_valid[
2382
- np.where(internaldespeckleincludemask[validvoxels] != 0.0)
2383
- ] = 1
2384
-
2385
- # now check that we won't end up excluding all voxels from refinement before accepting mask
2386
- overallmask = np.uint16(fitmask)
2387
- if internalrefineincludemask_valid is not None:
2388
- overallmask[np.where(internalrefineincludemask_valid == 0)] = 0
2389
- if thisinternalrefineexcludemask_valid is not None:
2390
- overallmask[np.where(thisinternalrefineexcludemask_valid != 0.0)] = 0
2391
- if tide_stats.getmasksize(overallmask) == 0:
2392
- LGR.warning(
2393
- "NB: cannot exclude despeckled voxels from refinement - including for this pass"
2394
- )
2395
- thisinternalrefineexcludemask_valid = internalrefineexcludemask_valid
2396
- theRegressorRefiner.setmasks(
2397
- internalrefineincludemask_valid, thisinternalrefineexcludemask_valid
2398
- )
2399
-
2400
- # regenerate regressor for next pass
2401
- # create the refinement mask
2402
- LGR.info("making refine mask")
2403
- createdmask = theRegressorRefiner.makemask(lagstrengths, lagtimes, lagsigma, fitmask)
2404
- print(f"Refine mask has {theRegressorRefiner.refinemaskvoxels} voxels")
2405
- if not createdmask:
2406
- print("no voxels qualify for refinement - exiting")
2407
- sys.exit()
2408
-
2409
- # align timecourses to prepare for refinement
2410
- LGR.info("aligning timecourses")
2411
- tide_util.disablemkl(optiondict["nprocs_refine"], debug=threaddebug)
2412
- voxelsprocessed_rra = theRegressorRefiner.alignvoxels(
2413
- fmri_data_valid, fmritr, lagtimes
2414
- )
2415
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
2416
- LGR.info(f"align complete: {voxelsprocessed_rra=}")
2417
-
2418
- # prenormalize
2419
- LGR.info("prenormalizing timecourses")
2420
- theRegressorRefiner.prenormalize(lagtimes, lagstrengths, R2)
2421
-
2422
- # now doing the refinement
2423
- (
2424
- voxelsprocessed_rr,
2425
- outputdict,
2426
- previousnormoutputdata,
2427
- resampref_y,
2428
- resampnonosref_y,
2429
- stoprefining,
2430
- refinestopreason,
2431
- genlagtc,
2432
- ) = theRegressorRefiner.refine(
2433
- theprefilter,
2434
- fmritr,
2435
- thepass,
2436
- lagstrengths,
2437
- lagtimes,
2438
- previousnormoutputdata,
2439
- optiondict["corrmasksize"],
2440
- )
2441
- TimingLGR.info(
2442
- f"Regressor refinement end, pass {thepass}",
2443
- {
2444
- "message2": voxelsprocessed_rr,
2445
- "message3": "voxels",
2446
- },
2447
- )
2448
- for key, value in outputdict.items():
2449
- optiondict[key] = value
2450
-
2451
- # Save shifted timecourses for César
2452
- if optiondict["saveintermediatemaps"] and optiondict["savelagregressors"]:
2453
- theheader = theinputdata.copyheader()
2454
- bidspasssuffix = f"_intermediatedata-pass{thepass}"
2455
- maplist = [
2456
- (
2457
- (theRegressorRefiner.getpaddedshiftedtcs())[:, numpadtrs:-numpadtrs],
2458
- "shiftedtcs",
2459
- "bold",
2460
- None,
2461
- "The filtered input fMRI data, in voxels used for refinement, time shifted by the negated delay in every voxel so that the moving blood component is aligned.",
2462
- ),
2463
- ]
2464
- tide_io.savemaplist(
2465
- f"{outputname}{bidspasssuffix}",
2466
- maplist,
2051
+ (resampref_y, resampnonosref_y, stoprefining, refinestopreason, genlagtc) = (
2052
+ tide_refineRegressor.refineRegressor(
2053
+ LGR,
2054
+ TimingLGR,
2055
+ thepass,
2056
+ optiondict,
2057
+ fitmask,
2058
+ internaloffsetincludemask_valid,
2059
+ internaloffsetexcludemask_valid,
2060
+ internalrefineincludemask_valid,
2061
+ internalrefineexcludemask_valid,
2062
+ internaldespeckleincludemask,
2467
2063
  validvoxels,
2064
+ theRegressorRefiner,
2065
+ lagtimes,
2066
+ lagstrengths,
2067
+ lagsigma,
2068
+ fmri_data_valid,
2069
+ fmritr,
2070
+ R2,
2071
+ theprefilter,
2072
+ previousnormoutputdata,
2073
+ theinputdata,
2074
+ numpadtrs,
2075
+ outputname,
2468
2076
  nativefmrishape,
2469
- theheader,
2470
2077
  bidsbasedict,
2471
- filetype=theinputdata.filetype,
2472
- rt_floattype=rt_floattype,
2473
- cifti_hdr=theinputdata.cifti_hdr,
2474
- debug=True,
2078
+ rt_floatset=np.float64,
2079
+ rt_floattype="float64",
2475
2080
  )
2476
- # We are done with refinement.
2081
+ )
2477
2082
  # End of main pass loop
2478
2083
 
2479
2084
  if optiondict["convergencethresh"] is None:
@@ -2536,23 +2141,27 @@ def rapidtide_main(argparsingfunc):
2536
2141
  internalvalidcoherenceshape = (numvalidspatiallocs, coherencefreqaxissize)
2537
2142
 
2538
2143
  # now allocate the arrays needed for the coherence calculation
2144
+ coherencefunc, coherencefunc_shm = tide_util.allocarray(
2145
+ internalvalidcoherenceshape,
2146
+ rt_outfloatset,
2147
+ shared=optiondict["sharedmem"],
2148
+ name=f"coherencefunc_{optiondict['pid']}",
2149
+ )
2150
+ coherencepeakval, coherencepeakval_shm = tide_util.allocarray(
2151
+ numvalidspatiallocs,
2152
+ rt_outfloatset,
2153
+ shared=optiondict["sharedmem"],
2154
+ name=f"coherencepeakval_{optiondict['pid']}",
2155
+ )
2156
+ coherencepeakfreq, coherencepeakfreq_shm = tide_util.allocarray(
2157
+ numvalidspatiallocs,
2158
+ rt_outfloatset,
2159
+ shared=optiondict["sharedmem"],
2160
+ name=f"coherencepeakfreq_{optiondict['pid']}",
2161
+ )
2539
2162
  if optiondict["sharedmem"]:
2540
- coherencefunc, coherencefunc_shm = tide_util.allocshared(
2541
- internalvalidcoherenceshape,
2542
- rt_outfloatset,
2543
- name=f"coherencefunc_{optiondict['pid']}",
2544
- )
2545
- coherencepeakval, coherencepeakval_shm = tide_util.allocshared(
2546
- numvalidspatiallocs, rt_outfloatset, name=f"coherencepeakval_{optiondict['pid']}"
2547
- )
2548
- coherencepeakfreq, coherencepeakfreq_shm = tide_util.allocshared(
2549
- numvalidspatiallocs, rt_outfloatset, name=f"coherencepeakfreq_{optiondict['pid']}"
2550
- )
2551
2163
  ramlocation = "in shared memory"
2552
2164
  else:
2553
- coherencefunc = np.zeros(internalvalidcoherenceshape, dtype=rt_outfloattype)
2554
- coherencepeakval = np.zeros(numvalidspatiallocs, dtype=rt_outfloattype)
2555
- coherencepeakfreq = np.zeros(numvalidspatiallocs, dtype=rt_outfloattype)
2556
2165
  ramlocation = "locally"
2557
2166
  optiondict["totalcoherencebytes"] = (
2558
2167
  coherencefunc.nbytes + coherencepeakval.nbytes + coherencepeakfreq.nbytes
@@ -2560,7 +2169,7 @@ def rapidtide_main(argparsingfunc):
2560
2169
  thesize, theunit = tide_util.format_bytes(optiondict["totalcoherencebytes"])
2561
2170
  print(f"allocated {thesize:.3f} {theunit} {ramlocation} for coherence calculation")
2562
2171
 
2563
- tide_util.disablemkl(1, debug=threaddebug)
2172
+ tide_util.disablemkl(1, debug=optiondict["threaddebug"])
2564
2173
  voxelsprocessed_coherence = tide_calccoherence.coherencepass(
2565
2174
  fmri_data_valid,
2566
2175
  theCoherer,
@@ -2570,10 +2179,10 @@ def rapidtide_main(argparsingfunc):
2570
2179
  alt=True,
2571
2180
  showprogressbar=optiondict["showprogressbar"],
2572
2181
  chunksize=optiondict["mp_chunksize"],
2573
- nprocs=1,
2182
+ nprocs=optiondict["nprocs"],
2574
2183
  alwaysmultiproc=optiondict["alwaysmultiproc"],
2575
2184
  )
2576
- tide_util.enablemkl(optiondict["mklthreads"], debug=threaddebug)
2185
+ tide_util.enablemkl(optiondict["mklthreads"], debug=optiondict["threaddebug"])
2577
2186
 
2578
2187
  # save the results of the calculations
2579
2188
  theheader = theinputdata.copyheader(
@@ -2608,17 +2217,21 @@ def rapidtide_main(argparsingfunc):
2608
2217
  LGR.info("\n\nWiener deconvolution")
2609
2218
 
2610
2219
  # now allocate the arrays needed for Wiener deconvolution
2220
+ wienerdeconv, wienerdeconv_shm = tide_util.allocarray(
2221
+ internalvalidspaceshape,
2222
+ rt_outfloatset,
2223
+ shared=optiondict["sharedmem"],
2224
+ name=f"wienerdeconv_{optiondict['pid']}",
2225
+ )
2226
+ wpeak, wpeak_shm = tide_util.allocarray(
2227
+ internalvalidspaceshape,
2228
+ rt_outfloatset,
2229
+ shared=optiondict["sharedmem"],
2230
+ name=f"wpeak_{optiondict['pid']}",
2231
+ )
2611
2232
  if optiondict["sharedmem"]:
2612
- wienerdeconv, wienerdeconv_shm = tide_util.allocshared(
2613
- internalvalidspaceshape, rt_outfloatset, name=f"wienerdeconv_{optiondict['pid']}"
2614
- )
2615
- wpeak, wpeak_shm = tide_util.allocshared(
2616
- internalvalidspaceshape, rt_outfloatset, name=f"wpeak_{optiondict['pid']}"
2617
- )
2618
2233
  ramlocation = "in shared memory"
2619
2234
  else:
2620
- wienerdeconv = np.zeros(internalvalidspaceshape, dtype=rt_outfloattype)
2621
- wpeak = np.zeros(internalvalidspaceshape, dtype=rt_outfloattype)
2622
2235
  ramlocation = "locally"
2623
2236
  optiondict["totalwienerbytes"] = wienerdeconv.nbytes + wpeak.nbytes
2624
2237
  thesize, theunit = tide_util.format_bytes(optiondict["totalwienerbytes"])
@@ -2628,6 +2241,7 @@ def rapidtide_main(argparsingfunc):
2628
2241
  numspatiallocs,
2629
2242
  fmri_data_valid,
2630
2243
  threshval,
2244
+ lagtc,
2631
2245
  optiondict,
2632
2246
  wienerdeconv,
2633
2247
  wpeak,
@@ -2656,9 +2270,10 @@ def rapidtide_main(argparsingfunc):
2656
2270
  optiondict["currentstage"] = "presLFOfit"
2657
2271
  tide_io.writedicttojson(optiondict, f"{outputname}_desc-runoptions_info.json")
2658
2272
  if optiondict["dolinfitfilt"] or optiondict["docvrmap"] or optiondict["refinedelay"]:
2659
- sLFOfiltmask = fitmask + 0.0
2660
- if optiondict["nosLFOfiltmask"]:
2661
- sLFOfiltmask = sLFOfiltmask * 0.0 + 1.0
2273
+ if optiondict["sLFOfiltmask"]:
2274
+ sLFOfiltmask = fitmask + 0.0
2275
+ else:
2276
+ sLFOfiltmask = fitmask * 0.0 + 1.0
2662
2277
  if optiondict["dolinfitfilt"]:
2663
2278
  if optiondict["refinedelay"]:
2664
2279
  TimingLGR.info("Setting up for delay refinement and sLFO filtering")
@@ -2721,66 +2336,27 @@ def rapidtide_main(argparsingfunc):
2721
2336
  TimingLGR.info("End moving fmri_data to shared memory")
2722
2337
  theinputdata.unload()
2723
2338
 
2724
- # now allocate the arrays needed for sLFO filtering
2725
- if optiondict["refinedelay"]:
2726
- derivaxissize = np.max(
2727
- [optiondict["refineregressderivs"] + 1, optiondict["regressderivs"] + 1]
2728
- )
2729
- else:
2730
- derivaxissize = optiondict["regressderivs"] + 1
2731
- internalvalidspaceshapederivs = (
2732
- internalvalidspaceshape,
2733
- derivaxissize,
2339
+ # allocate the arrays needed for sLFO filtering
2340
+ movingsignal, movingsignal_shm = tide_util.allocarray(
2341
+ internalvalidfmrishape,
2342
+ rt_outfloattype,
2343
+ shared=optiondict["sharedmem"],
2344
+ name=f"movingsignal_{optiondict['pid']}",
2345
+ )
2346
+ filtereddata, filtereddata_shm = tide_util.allocarray(
2347
+ internalvalidfmrishape,
2348
+ rt_outfloattype,
2349
+ shared=optiondict["sharedmem"],
2350
+ name=f"filtereddata_{optiondict['pid']}",
2734
2351
  )
2735
2352
  if optiondict["sharedmem"]:
2736
- sLFOfitmean, sLFOfitmean_shm = tide_util.allocshared(
2737
- internalvalidspaceshape, rt_outfloatset, name=f"sLFOfitmean_{optiondict['pid']}"
2738
- )
2739
- rvalue, rvalue_shm = tide_util.allocshared(
2740
- internalvalidspaceshape, rt_outfloatset, name=f"rvalue_{optiondict['pid']}"
2741
- )
2742
- r2value, r2value_shm = tide_util.allocshared(
2743
- internalvalidspaceshape, rt_outfloatset, name=f"r2value_{optiondict['pid']}"
2744
- )
2745
- fitNorm, fitNorm_shm = tide_util.allocshared(
2746
- internalvalidspaceshapederivs, rt_outfloatset, name=f"fitNorm_{optiondict['pid']}"
2747
- )
2748
- fitcoeff, fitcoeff_shm = tide_util.allocshared(
2749
- internalvalidspaceshapederivs, rt_outfloatset, name=f"fitcoeff_{optiondict['pid']}"
2750
- )
2751
- movingsignal, movingsignal_shm = tide_util.allocshared(
2752
- internalvalidfmrishape, rt_outfloatset, name=f"movingsignal_{optiondict['pid']}"
2753
- )
2754
- lagtc, lagtc_shm = tide_util.allocshared(
2755
- internalvalidfmrishape, rt_floatset, name=f"lagtc_{optiondict['pid']}"
2756
- )
2757
- filtereddata, filtereddata_shm = tide_util.allocshared(
2758
- internalvalidfmrishape, rt_outfloatset, name=f"filtereddata_{optiondict['pid']}"
2759
- )
2760
2353
  ramlocation = "in shared memory"
2761
2354
  else:
2762
- sLFOfitmean = np.zeros(internalvalidspaceshape, dtype=rt_outfloattype)
2763
- rvalue = np.zeros(internalvalidspaceshape, dtype=rt_outfloattype)
2764
- r2value = np.zeros(internalvalidspaceshape, dtype=rt_outfloattype)
2765
- fitNorm = np.zeros(internalvalidspaceshapederivs, dtype=rt_outfloattype)
2766
- fitcoeff = np.zeros(internalvalidspaceshapederivs, dtype=rt_outfloattype)
2767
- movingsignal = np.zeros(internalvalidfmrishape, dtype=rt_outfloattype)
2768
- lagtc = np.zeros(internalvalidfmrishape, dtype=rt_floattype)
2769
- filtereddata = np.zeros(internalvalidfmrishape, dtype=rt_outfloattype)
2770
2355
  ramlocation = "locally"
2771
2356
 
2772
- optiondict["totalsLFOfilterbytes"] = (
2773
- sLFOfitmean.nbytes
2774
- + rvalue.nbytes
2775
- + r2value.nbytes
2776
- + fitNorm.nbytes
2777
- + fitcoeff.nbytes
2778
- + movingsignal.nbytes
2779
- + lagtc.nbytes
2780
- + filtereddata.nbytes
2781
- )
2357
+ optiondict["totalsLFOfilterbytes"] = movingsignal.nbytes + filtereddata.nbytes
2782
2358
  thesize, theunit = tide_util.format_bytes(optiondict["totalsLFOfilterbytes"])
2783
- print(f"allocated {thesize:.3f} {theunit} {ramlocation} for sLFO filter/delay refinement")
2359
+ print(f"allocated {thesize:.3f} {theunit} {ramlocation} for sLFO filter")
2784
2360
  tide_util.logmem("before sLFO filter")
2785
2361
 
2786
2362
  if optiondict["dolinfitfilt"]:
@@ -2829,121 +2405,52 @@ def rapidtide_main(argparsingfunc):
2829
2405
  if optiondict["refinedelay"]:
2830
2406
  TimingLGR.info("Delay refinement start")
2831
2407
  LGR.info("\n\nDelay refinement")
2408
+
2832
2409
  if optiondict["delayoffsetgausssigma"] < 0.0 and theinputdata.filetype != "text":
2833
2410
  # set gausssigma automatically
2834
2411
  optiondict["delayoffsetgausssigma"] = np.mean([xdim, ydim, slicethickness]) / 2.0
2835
2412
 
2836
- regressderivratios, regressrvalues = tide_refinedelay.getderivratios(
2413
+ (
2414
+ delayoffset,
2415
+ regressderivratios,
2416
+ medfiltregressderivratios,
2417
+ filteredregressderivratios,
2418
+ optiondict["delayoffsetMAD"],
2419
+ ) = tide_refineDelayMap.refineDelay(
2837
2420
  fmri_data_valid,
2838
- validvoxels,
2839
2421
  initial_fmri_x,
2840
- lagtimes,
2422
+ xdim,
2423
+ ydim,
2424
+ slicethickness,
2841
2425
  sLFOfiltmask,
2842
2426
  genlagtc,
2843
- mode,
2844
- outputname,
2845
2427
  oversamptr,
2846
2428
  sLFOfitmean,
2847
2429
  rvalue,
2848
2430
  r2value,
2849
- fitNorm[:, : (optiondict["refineregressderivs"] + 1)],
2850
- fitcoeff[:, : (optiondict["refineregressderivs"] + 1)],
2851
- movingsignal,
2431
+ fitNorm,
2432
+ fitcoeff,
2852
2433
  lagtc,
2853
- filtereddata,
2434
+ outputname,
2435
+ validvoxels,
2436
+ nativespaceshape,
2437
+ theinputdata,
2438
+ lagtimes,
2439
+ optiondict,
2854
2440
  LGR,
2855
2441
  TimingLGR,
2856
- optiondict,
2857
- regressderivs=optiondict["refineregressderivs"],
2442
+ outputlevel=optiondict["outputlevel"],
2443
+ gausssigma=optiondict["delayoffsetgausssigma"],
2444
+ patchthresh=optiondict["delaypatchthresh"],
2445
+ mindelay=optiondict["mindelay"],
2446
+ maxdelay=optiondict["maxdelay"],
2447
+ numpoints=optiondict["numpoints"],
2448
+ histlen=optiondict["histlen"],
2449
+ rt_floatset=rt_floatset,
2450
+ rt_floattype=rt_floattype,
2858
2451
  debug=optiondict["debug"],
2859
2452
  )
2860
-
2861
- if optiondict["refineregressderivs"] == 1:
2862
- medfiltregressderivratios, filteredregressderivratios, delayoffsetMAD = (
2863
- tide_refinedelay.filterderivratios(
2864
- regressderivratios,
2865
- nativespaceshape,
2866
- validvoxels,
2867
- (xdim, ydim, slicethickness),
2868
- gausssigma=optiondict["delayoffsetgausssigma"],
2869
- patchthresh=optiondict["delaypatchthresh"],
2870
- filetype=theinputdata.filetype,
2871
- rt_floattype="float64",
2872
- debug=optiondict["debug"],
2873
- )
2874
- )
2875
- optiondict["delayoffsetMAD"] = delayoffsetMAD
2876
-
2877
- # find the mapping of derivative ratios to delays
2878
- tide_refinedelay.trainratiotooffset(
2879
- genlagtc,
2880
- initial_fmri_x,
2881
- outputname,
2882
- optiondict["outputlevel"],
2883
- mindelay=optiondict["mindelay"],
2884
- maxdelay=optiondict["maxdelay"],
2885
- numpoints=optiondict["numpoints"],
2886
- debug=optiondict["debug"],
2887
- )
2888
-
2889
- # now calculate the delay offsets
2890
- delayoffset = np.zeros_like(filteredregressderivratios)
2891
- if optiondict["debug"]:
2892
- print(
2893
- f"calculating delayoffsets for {filteredregressderivratios.shape[0]} voxels"
2894
- )
2895
- for i in range(filteredregressderivratios.shape[0]):
2896
- delayoffset[i], closestoffset = tide_refinedelay.ratiotodelay(
2897
- filteredregressderivratios[i]
2898
- )
2899
- else:
2900
- medfiltregressderivratios = np.zeros_like(regressderivratios)
2901
- filteredregressderivratios = np.zeros_like(regressderivratios)
2902
- delayoffsetMAD = np.zeros(optiondict["refineregressderivs"], dtype=float)
2903
- for i in range(optiondict["refineregressderivs"]):
2904
- (
2905
- medfiltregressderivratios[i, :],
2906
- filteredregressderivratios[i, :],
2907
- delayoffsetMAD[i],
2908
- ) = tide_refinedelay.filterderivratios(
2909
- regressderivratios[i, :],
2910
- (xsize, ysize, numslices),
2911
- validvoxels,
2912
- (xdim, ydim, slicethickness),
2913
- gausssigma=optiondict["delayoffsetgausssigma"],
2914
- patchthresh=optiondict["delaypatchthresh"],
2915
- filetype=theinputdata.filetype,
2916
- rt_floattype=rt_floattype,
2917
- debug=optiondict["debug"],
2918
- )
2919
- optiondict[f"delayoffsetMAD_{i + 1}"] = delayoffsetMAD[i]
2920
-
2921
- # now calculate the delay offsets
2922
- delayoffset = np.zeros_like(filteredregressderivratios[0, :])
2923
- if optiondict["debug"]:
2924
- print(
2925
- f"calculating delayoffsets for {filteredregressderivratios.shape[1]} voxels"
2926
- )
2927
- for i in range(filteredregressderivratios.shape[1]):
2928
- delayoffset[i] = tide_refinedelay.coffstodelay(
2929
- filteredregressderivratios[:, i],
2930
- mindelay=optiondict["mindelay"],
2931
- maxdelay=optiondict["maxdelay"],
2932
- )
2933
-
2934
- namesuffix = "_desc-delayoffset_hist"
2935
- if optiondict["dolinfitfilt"]:
2936
- tide_stats.makeandsavehistogram(
2937
- delayoffset[np.where(sLFOfiltmask > 0)],
2938
- optiondict["histlen"],
2939
- 1,
2940
- outputname + namesuffix,
2941
- displaytitle="Histogram of delay offsets calculated from regression coefficients",
2942
- dictvarname="delayoffsethist",
2943
- thedict=optiondict,
2944
- )
2945
2453
  lagtimesrefined = lagtimes + delayoffset
2946
-
2947
2454
  ####################################################
2948
2455
  # Delay refinement end
2949
2456
  ####################################################
@@ -3176,6 +2683,10 @@ def rapidtide_main(argparsingfunc):
3176
2683
  lagstrengths[np.where(fitmask > 0)], histpcts, nozero=False
3177
2684
  )
3178
2685
  thesigmapcts = tide_stats.getfracvals(lagsigma[np.where(fitmask > 0)], histpcts, nozero=False)
2686
+ if optiondict["refinedelay"]:
2687
+ therefinedtimepcts = tide_stats.getfracvals(
2688
+ lagtimesrefined[np.where(fitmask > 0)], histpcts, nozero=False
2689
+ )
3179
2690
  for i in range(len(histpcts)):
3180
2691
  optiondict[f"lagtimes_{str(int(np.round(100 * histpcts[i], 0))).zfill(2)}pct"] = (
3181
2692
  thetimepcts[i]
@@ -3186,6 +2697,10 @@ def rapidtide_main(argparsingfunc):
3186
2697
  optiondict[f"lagsigma_{str(int(np.round(100 * histpcts[i], 0))).zfill(2)}pct"] = (
3187
2698
  thesigmapcts[i]
3188
2699
  )
2700
+ if optiondict["refinedelay"]:
2701
+ optiondict[
2702
+ f"lagtimesrefined_{str(int(np.round(100 * histpcts[i], 0))).zfill(2)}pct"
2703
+ ] = therefinedtimepcts[i]
3189
2704
  optiondict["fitmasksize"] = np.sum(fitmask)
3190
2705
  optiondict["fitmaskpct"] = 100.0 * optiondict["fitmasksize"] / optiondict["corrmasksize"]
3191
2706
 
@@ -3239,55 +2754,29 @@ def rapidtide_main(argparsingfunc):
3239
2754
  ),
3240
2755
  ]
3241
2756
  if (optiondict["outputlevel"] != "min") and (optiondict["outputlevel"] != "less"):
3242
- if optiondict["refineregressderivs"] > 1:
3243
- for i in range(optiondict["refineregressderivs"]):
3244
- savelist += [
3245
- (
3246
- regressderivratios[i, :],
3247
- f"regressderivratios_{i}",
3248
- "map",
3249
- None,
3250
- f"Ratio of derivative {i + 1} of delayed sLFO to the delayed sLFO",
3251
- ),
3252
- (
3253
- medfiltregressderivratios[i, :],
3254
- f"medfiltregressderivratios_{i}",
3255
- "map",
3256
- None,
3257
- f"Median filtered version of the regressderivratios_{i} map",
3258
- ),
3259
- (
3260
- filteredregressderivratios[i, :],
3261
- f"filteredregressderivratios_{i}",
3262
- "map",
3263
- None,
3264
- f"regressderivratios_{i}, with outliers patched using median filtered data",
3265
- ),
3266
- ]
3267
- else:
3268
- savelist += [
3269
- (
3270
- regressderivratios,
3271
- "regressderivratios",
3272
- "map",
3273
- None,
3274
- "Ratio of the first derivative of delayed sLFO to the delayed sLFO",
3275
- ),
3276
- (
3277
- medfiltregressderivratios,
3278
- "medfiltregressderivratios",
3279
- "map",
3280
- None,
3281
- "Median filtered version of the regressderivratios map",
3282
- ),
3283
- (
3284
- filteredregressderivratios,
3285
- "filteredregressderivratios",
3286
- "map",
3287
- None,
3288
- "regressderivratios, with outliers patched using median filtered data",
3289
- ),
3290
- ]
2757
+ savelist += [
2758
+ (
2759
+ regressderivratios,
2760
+ "regressderivratios",
2761
+ "map",
2762
+ None,
2763
+ "Ratio of the first derivative of delayed sLFO to the delayed sLFO",
2764
+ ),
2765
+ (
2766
+ medfiltregressderivratios,
2767
+ "medfiltregressderivratios",
2768
+ "map",
2769
+ None,
2770
+ "Median filtered version of the regressderivratios map",
2771
+ ),
2772
+ (
2773
+ filteredregressderivratios,
2774
+ "filteredregressderivratios",
2775
+ "map",
2776
+ None,
2777
+ "regressderivratios, with outliers patched using median filtered data",
2778
+ ),
2779
+ ]
3291
2780
  if optiondict["calccoherence"]:
3292
2781
  savelist += [
3293
2782
  (coherencepeakval, "coherencepeakval", "map", None, "Coherence peak value"),
@@ -3549,7 +3038,13 @@ def rapidtide_main(argparsingfunc):
3549
3038
  if theinputdata.filetype != "nifti":
3550
3039
  unfiltmeanvalue = meanvalue
3551
3040
  maplist = [
3552
- (unfiltmeanvalue, "unfiltmean", "map", None, "Voxelwise mean of fmri data before smoothing"),
3041
+ (
3042
+ unfiltmeanvalue,
3043
+ "unfiltmean",
3044
+ "map",
3045
+ None,
3046
+ "Voxelwise mean of fmri data before smoothing",
3047
+ ),
3553
3048
  (meanvalue, "mean", "map", None, "Voxelwise mean of fmri data"),
3554
3049
  (stddevvalue, "std", "map", None, "Voxelwise standard deviation of fmri data"),
3555
3050
  (covvalue, "CoV", "map", None, "Voxelwise coefficient of variation of fmri data"),
@@ -3579,27 +3074,28 @@ def rapidtide_main(argparsingfunc):
3579
3074
  if optiondict["numestreps"] > 0:
3580
3075
  masklist = []
3581
3076
 
3582
- # we can only calculate this map if we have enough data for a good fit
3077
+ # we can only calculate this map if we have enough data for a good fit, and the fit succeeded
3583
3078
  if optiondict["numestreps"] >= 1000:
3584
- neglogpmax = np.log10(optiondict["numestreps"])
3585
- # generate a neglogp map
3586
- neglog10pmap = lagstrengths * 0.0
3587
- for voxel in range(neglog10pmap.shape[0]):
3588
- neglog10pmap[voxel] = tide_stats.neglog10pfromr(
3589
- lagstrengths[voxel],
3590
- sigfit,
3591
- neglogpmax=neglogpmax,
3592
- debug=optiondict["debug"],
3593
- )
3594
- masklist += [
3595
- (
3596
- neglog10pmap.copy(),
3597
- "neglog10p",
3598
- "map",
3599
- None,
3600
- f"Negative log(10) of the p value of the r at each voxel",
3601
- )
3602
- ]
3079
+ if sigfit is not None:
3080
+ neglogpmax = np.log10(optiondict["numestreps"])
3081
+ # generate a neglogp map
3082
+ neglog10pmap = lagstrengths * 0.0
3083
+ for voxel in range(neglog10pmap.shape[0]):
3084
+ neglog10pmap[voxel] = tide_stats.neglog10pfromr(
3085
+ lagstrengths[voxel],
3086
+ sigfit,
3087
+ neglogpmax=neglogpmax,
3088
+ debug=optiondict["debug"],
3089
+ )
3090
+ masklist += [
3091
+ (
3092
+ neglog10pmap.copy(),
3093
+ "neglog10p",
3094
+ "map",
3095
+ None,
3096
+ f"Negative log(10) of the p value of the r at each voxel",
3097
+ )
3098
+ ]
3603
3099
 
3604
3100
  tide_io.savemaplist(
3605
3101
  outputname,