rapidtide 3.0.10__py3-none-any.whl → 3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rapidtide/Colortables.py +492 -27
- rapidtide/OrthoImageItem.py +1053 -47
- rapidtide/RapidtideDataset.py +1533 -86
- rapidtide/_version.py +3 -3
- rapidtide/calccoherence.py +196 -29
- rapidtide/calcnullsimfunc.py +191 -40
- rapidtide/calcsimfunc.py +245 -42
- rapidtide/correlate.py +1210 -393
- rapidtide/data/examples/src/testLD +56 -0
- rapidtide/data/examples/src/testalign +1 -1
- rapidtide/data/examples/src/testdelayvar +0 -1
- rapidtide/data/examples/src/testfmri +19 -1
- rapidtide/data/examples/src/testglmfilt +5 -5
- rapidtide/data/examples/src/testhappy +30 -1
- rapidtide/data/examples/src/testppgproc +17 -0
- rapidtide/data/examples/src/testrolloff +11 -0
- rapidtide/data/models/model_cnn_pytorch/best_model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.png +0 -0
- rapidtide/data/models/model_cnn_pytorch/loss.txt +1 -0
- rapidtide/data/models/model_cnn_pytorch/model.pth +0 -0
- rapidtide/data/models/model_cnn_pytorch/model_meta.json +68 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm.nii.gz +0 -0
- rapidtide/data/reference/JHU-ArterialTerritoriesNoVent-LVL1_space-MNI152NLin2009cAsym_2mm_mask.nii.gz +0 -0
- rapidtide/decorators.py +91 -0
- rapidtide/dlfilter.py +2225 -108
- rapidtide/dlfiltertorch.py +4843 -0
- rapidtide/externaltools.py +327 -12
- rapidtide/fMRIData_class.py +79 -40
- rapidtide/filter.py +1899 -810
- rapidtide/fit.py +2004 -574
- rapidtide/genericmultiproc.py +93 -18
- rapidtide/happy_supportfuncs.py +2044 -171
- rapidtide/helper_classes.py +584 -43
- rapidtide/io.py +2363 -370
- rapidtide/linfitfiltpass.py +341 -75
- rapidtide/makelaggedtcs.py +211 -20
- rapidtide/maskutil.py +423 -53
- rapidtide/miscmath.py +827 -121
- rapidtide/multiproc.py +210 -22
- rapidtide/patchmatch.py +234 -33
- rapidtide/peakeval.py +32 -30
- rapidtide/ppgproc.py +2203 -0
- rapidtide/qualitycheck.py +352 -39
- rapidtide/refinedelay.py +422 -57
- rapidtide/refineregressor.py +498 -184
- rapidtide/resample.py +671 -185
- rapidtide/scripts/applyppgproc.py +28 -0
- rapidtide/simFuncClasses.py +1052 -77
- rapidtide/simfuncfit.py +260 -46
- rapidtide/stats.py +540 -238
- rapidtide/tests/happycomp +9 -0
- rapidtide/tests/test_dlfiltertorch.py +627 -0
- rapidtide/tests/test_findmaxlag.py +24 -8
- rapidtide/tests/test_fullrunhappy_v1.py +0 -2
- rapidtide/tests/test_fullrunhappy_v2.py +0 -2
- rapidtide/tests/test_fullrunhappy_v3.py +1 -0
- rapidtide/tests/test_fullrunhappy_v4.py +2 -2
- rapidtide/tests/test_fullrunrapidtide_v7.py +1 -1
- rapidtide/tests/test_simroundtrip.py +8 -8
- rapidtide/tests/utils.py +9 -8
- rapidtide/tidepoolTemplate.py +142 -38
- rapidtide/tidepoolTemplate_alt.py +165 -44
- rapidtide/tidepoolTemplate_big.py +189 -52
- rapidtide/util.py +1217 -118
- rapidtide/voxelData.py +684 -37
- rapidtide/wiener.py +19 -12
- rapidtide/wiener2.py +113 -7
- rapidtide/wiener_doc.py +255 -0
- rapidtide/workflows/adjustoffset.py +105 -3
- rapidtide/workflows/aligntcs.py +85 -2
- rapidtide/workflows/applydlfilter.py +87 -10
- rapidtide/workflows/applyppgproc.py +522 -0
- rapidtide/workflows/atlasaverage.py +210 -47
- rapidtide/workflows/atlastool.py +100 -3
- rapidtide/workflows/calcSimFuncMap.py +294 -64
- rapidtide/workflows/calctexticc.py +201 -9
- rapidtide/workflows/ccorrica.py +97 -4
- rapidtide/workflows/cleanregressor.py +168 -29
- rapidtide/workflows/delayvar.py +163 -10
- rapidtide/workflows/diffrois.py +81 -3
- rapidtide/workflows/endtidalproc.py +144 -4
- rapidtide/workflows/fdica.py +195 -15
- rapidtide/workflows/filtnifti.py +70 -3
- rapidtide/workflows/filttc.py +74 -3
- rapidtide/workflows/fitSimFuncMap.py +206 -48
- rapidtide/workflows/fixtr.py +73 -3
- rapidtide/workflows/gmscalc.py +113 -3
- rapidtide/workflows/happy.py +813 -201
- rapidtide/workflows/happy2std.py +144 -12
- rapidtide/workflows/happy_parser.py +149 -8
- rapidtide/workflows/histnifti.py +118 -2
- rapidtide/workflows/histtc.py +84 -3
- rapidtide/workflows/linfitfilt.py +117 -4
- rapidtide/workflows/localflow.py +328 -28
- rapidtide/workflows/mergequality.py +79 -3
- rapidtide/workflows/niftidecomp.py +322 -18
- rapidtide/workflows/niftistats.py +174 -4
- rapidtide/workflows/pairproc.py +88 -2
- rapidtide/workflows/pairwisemergenifti.py +85 -2
- rapidtide/workflows/parser_funcs.py +1421 -40
- rapidtide/workflows/physiofreq.py +137 -11
- rapidtide/workflows/pixelcomp.py +208 -5
- rapidtide/workflows/plethquality.py +103 -21
- rapidtide/workflows/polyfitim.py +151 -11
- rapidtide/workflows/proj2flow.py +75 -2
- rapidtide/workflows/rankimage.py +111 -4
- rapidtide/workflows/rapidtide.py +272 -15
- rapidtide/workflows/rapidtide2std.py +98 -2
- rapidtide/workflows/rapidtide_parser.py +109 -9
- rapidtide/workflows/refineDelayMap.py +143 -33
- rapidtide/workflows/refineRegressor.py +682 -93
- rapidtide/workflows/regressfrommaps.py +152 -31
- rapidtide/workflows/resamplenifti.py +85 -3
- rapidtide/workflows/resampletc.py +91 -3
- rapidtide/workflows/retrolagtcs.py +98 -6
- rapidtide/workflows/retroregress.py +165 -9
- rapidtide/workflows/roisummarize.py +173 -5
- rapidtide/workflows/runqualitycheck.py +71 -3
- rapidtide/workflows/showarbcorr.py +147 -4
- rapidtide/workflows/showhist.py +86 -2
- rapidtide/workflows/showstxcorr.py +160 -3
- rapidtide/workflows/showtc.py +159 -3
- rapidtide/workflows/showxcorrx.py +184 -4
- rapidtide/workflows/showxy.py +185 -15
- rapidtide/workflows/simdata.py +262 -36
- rapidtide/workflows/spatialfit.py +77 -2
- rapidtide/workflows/spatialmi.py +251 -27
- rapidtide/workflows/spectrogram.py +305 -32
- rapidtide/workflows/synthASL.py +154 -3
- rapidtide/workflows/tcfrom2col.py +76 -2
- rapidtide/workflows/tcfrom3col.py +74 -2
- rapidtide/workflows/tidepool.py +2972 -133
- rapidtide/workflows/utils.py +19 -14
- rapidtide/workflows/utils_doc.py +293 -0
- rapidtide/workflows/variabilityizer.py +116 -3
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/METADATA +10 -9
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/RECORD +141 -122
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/entry_points.txt +1 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/WHEEL +0 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/licenses/LICENSE +0 -0
- {rapidtide-3.0.10.dist-info → rapidtide-3.1.dist-info}/top_level.txt +0 -0
rapidtide/stats.py
CHANGED
|
@@ -17,9 +17,13 @@
|
|
|
17
17
|
#
|
|
18
18
|
#
|
|
19
19
|
import warnings
|
|
20
|
+
from typing import Any, Callable, Optional, Tuple, Union
|
|
20
21
|
|
|
21
22
|
import matplotlib.pyplot as plt
|
|
22
23
|
import numpy as np
|
|
24
|
+
from numpy.typing import ArrayLike, NDArray
|
|
25
|
+
|
|
26
|
+
from rapidtide.decorators import conditionaljit, conditionaljit2
|
|
23
27
|
|
|
24
28
|
with warnings.catch_warnings():
|
|
25
29
|
warnings.simplefilter("ignore")
|
|
@@ -32,6 +36,7 @@ with warnings.catch_warnings():
|
|
|
32
36
|
|
|
33
37
|
import scipy as sp
|
|
34
38
|
from scipy.stats import johnsonsb, kurtosis, kurtosistest, skew, skewtest
|
|
39
|
+
from statsmodels.robust import mad
|
|
35
40
|
|
|
36
41
|
import rapidtide.fit as tide_fit
|
|
37
42
|
import rapidtide.io as tide_io
|
|
@@ -44,73 +49,55 @@ if pyfftwpresent:
|
|
|
44
49
|
# ---------------------------------------- Global constants -------------------------------------------
|
|
45
50
|
defaultbutterorder = 6
|
|
46
51
|
MAXLINES = 10000000
|
|
47
|
-
donotbeaggressive = True
|
|
48
|
-
|
|
49
|
-
# ----------------------------------------- Conditional imports ---------------------------------------
|
|
50
|
-
try:
|
|
51
|
-
from numba import jit
|
|
52
|
-
except ImportError:
|
|
53
|
-
donotusenumba = True
|
|
54
|
-
else:
|
|
55
|
-
donotusenumba = False
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def disablenumba():
|
|
59
|
-
global donotusenumba
|
|
60
|
-
donotusenumba = True
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def conditionaljit():
|
|
64
|
-
def resdec(f):
|
|
65
|
-
if donotusenumba:
|
|
66
|
-
return f
|
|
67
|
-
return jit(f, nopython=True)
|
|
68
|
-
|
|
69
|
-
return resdec
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def conditionaljit2():
|
|
73
|
-
def resdec(f):
|
|
74
|
-
if donotusenumba or donotbeaggressive:
|
|
75
|
-
return f
|
|
76
|
-
return jit(f, nopython=True)
|
|
77
|
-
|
|
78
|
-
return resdec
|
|
79
52
|
|
|
80
53
|
|
|
81
54
|
# --------------------------- probability functions -------------------------------------------------
|
|
82
|
-
def printthresholds(pcts, thepercentiles, labeltext):
|
|
83
|
-
"""
|
|
55
|
+
def printthresholds(pcts: ArrayLike, thepercentiles: ArrayLike, labeltext: str) -> None:
|
|
56
|
+
"""Print significance thresholds with formatted output.
|
|
84
57
|
|
|
85
58
|
Parameters
|
|
86
59
|
----------
|
|
87
|
-
pcts
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
60
|
+
pcts : array-like
|
|
61
|
+
Percentile threshold values
|
|
62
|
+
thepercentiles : array-like
|
|
63
|
+
Percentile levels (0-1)
|
|
64
|
+
labeltext : str
|
|
65
|
+
Label to print before thresholds
|
|
94
66
|
"""
|
|
95
67
|
print(labeltext)
|
|
96
68
|
for i in range(0, len(pcts)):
|
|
97
69
|
print(f"\tp <{1.0 - thepercentiles[i]:.3f}: {pcts[i]:.3f}")
|
|
98
70
|
|
|
99
71
|
|
|
100
|
-
def fitgausspdf(
|
|
101
|
-
|
|
72
|
+
def fitgausspdf(
|
|
73
|
+
thehist: Tuple,
|
|
74
|
+
histlen: int,
|
|
75
|
+
thedata: NDArray,
|
|
76
|
+
displayplots: bool = False,
|
|
77
|
+
nozero: bool = False,
|
|
78
|
+
debug: bool = False,
|
|
79
|
+
) -> NDArray:
|
|
80
|
+
"""Fit a Gaussian probability density function to histogram data.
|
|
102
81
|
|
|
103
82
|
Parameters
|
|
104
83
|
----------
|
|
105
|
-
thehist
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
84
|
+
thehist : tuple
|
|
85
|
+
Histogram tuple from np.histogram containing (counts, bin_edges)
|
|
86
|
+
histlen : int
|
|
87
|
+
Length of histogram
|
|
88
|
+
thedata : array-like
|
|
89
|
+
Original data used to create histogram
|
|
90
|
+
displayplots : bool, optional
|
|
91
|
+
If True, display fit visualization. Default: False
|
|
92
|
+
nozero : bool, optional
|
|
93
|
+
If True, ignore zero values. Default: False
|
|
94
|
+
debug : bool, optional
|
|
95
|
+
Enable debug output. Default: False
|
|
110
96
|
|
|
111
97
|
Returns
|
|
112
98
|
-------
|
|
113
|
-
|
|
99
|
+
array-like
|
|
100
|
+
Array containing (peakheight, peakloc, peakwidth, zeroterm)
|
|
114
101
|
"""
|
|
115
102
|
thestore = np.zeros((2, histlen), dtype="float64")
|
|
116
103
|
thestore[0, :] = thehist[1][:-1]
|
|
@@ -170,20 +157,35 @@ def fitgausspdf(thehist, histlen, thedata, displayplots=False, nozero=False, deb
|
|
|
170
157
|
return np.append(params, np.array([zeroterm]))
|
|
171
158
|
|
|
172
159
|
|
|
173
|
-
def fitjsbpdf(
|
|
174
|
-
|
|
160
|
+
def fitjsbpdf(
|
|
161
|
+
thehist: Tuple,
|
|
162
|
+
histlen: int,
|
|
163
|
+
thedata: NDArray,
|
|
164
|
+
displayplots: bool = False,
|
|
165
|
+
nozero: bool = False,
|
|
166
|
+
debug: bool = False,
|
|
167
|
+
) -> NDArray:
|
|
168
|
+
"""Fit a Johnson SB probability density function to histogram data.
|
|
175
169
|
|
|
176
170
|
Parameters
|
|
177
171
|
----------
|
|
178
|
-
thehist
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
172
|
+
thehist : tuple
|
|
173
|
+
Histogram tuple from np.histogram containing (counts, bin_edges)
|
|
174
|
+
histlen : int
|
|
175
|
+
Length of histogram
|
|
176
|
+
thedata : array-like
|
|
177
|
+
Original data used to create histogram
|
|
178
|
+
displayplots : bool, optional
|
|
179
|
+
If True, display fit visualization. Default: False
|
|
180
|
+
nozero : bool, optional
|
|
181
|
+
If True, ignore zero values. Default: False
|
|
182
|
+
debug : bool, optional
|
|
183
|
+
Enable debug output. Default: False
|
|
183
184
|
|
|
184
185
|
Returns
|
|
185
186
|
-------
|
|
186
|
-
|
|
187
|
+
array-like
|
|
188
|
+
Array containing (a, b, loc, scale, zeroterm) parameters of Johnson SB fit
|
|
187
189
|
"""
|
|
188
190
|
thestore = np.zeros((2, histlen), dtype="float64")
|
|
189
191
|
thestore[0, :] = thehist[1][:-1]
|
|
@@ -222,49 +224,65 @@ def fitjsbpdf(thehist, histlen, thedata, displayplots=False, nozero=False, debug
|
|
|
222
224
|
return np.append(params, np.array([zeroterm]))
|
|
223
225
|
|
|
224
226
|
|
|
225
|
-
def getjohnsonppf(percentile, params, zeroterm):
|
|
226
|
-
"""
|
|
227
|
+
def getjohnsonppf(percentile: float, params: ArrayLike, zeroterm: float) -> None:
|
|
228
|
+
"""Get percent point function (inverse CDF) for Johnson SB distribution.
|
|
229
|
+
|
|
230
|
+
Note: This function is incomplete and only initializes variables.
|
|
227
231
|
|
|
228
232
|
Parameters
|
|
229
233
|
----------
|
|
230
|
-
percentile
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
percentile : float
|
|
235
|
+
Percentile value (0-1)
|
|
236
|
+
params : array-like
|
|
237
|
+
Johnson SB distribution parameters (a, b, loc, scale)
|
|
238
|
+
zeroterm : float
|
|
239
|
+
Zero term correction factor
|
|
237
240
|
"""
|
|
238
241
|
johnsonfunc = johnsonsb(params[0], params[1], params[2], params[3])
|
|
239
242
|
corrfac = 1.0 - zeroterm
|
|
240
243
|
|
|
241
244
|
|
|
242
245
|
def sigFromDistributionData(
|
|
243
|
-
vallist,
|
|
244
|
-
histlen,
|
|
245
|
-
thepercentiles,
|
|
246
|
-
similaritymetric="correlation",
|
|
247
|
-
displayplots=False,
|
|
248
|
-
twotail=False,
|
|
249
|
-
nozero=False,
|
|
250
|
-
dosighistfit=True,
|
|
251
|
-
debug=False,
|
|
252
|
-
):
|
|
253
|
-
"""
|
|
246
|
+
vallist: NDArray,
|
|
247
|
+
histlen: int,
|
|
248
|
+
thepercentiles: ArrayLike,
|
|
249
|
+
similaritymetric: str = "correlation",
|
|
250
|
+
displayplots: bool = False,
|
|
251
|
+
twotail: bool = False,
|
|
252
|
+
nozero: bool = False,
|
|
253
|
+
dosighistfit: bool = True,
|
|
254
|
+
debug: bool = False,
|
|
255
|
+
) -> Tuple[Optional[list], Optional[list], Optional[NDArray]]:
|
|
256
|
+
"""Calculate significance thresholds from distribution data.
|
|
257
|
+
|
|
258
|
+
Fits a probability distribution to data and calculates percentile thresholds
|
|
259
|
+
for significance testing.
|
|
254
260
|
|
|
255
261
|
Parameters
|
|
256
262
|
----------
|
|
257
|
-
vallist
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
263
|
+
vallist : array-like
|
|
264
|
+
List of similarity/correlation values
|
|
265
|
+
histlen : int
|
|
266
|
+
Length of histogram
|
|
267
|
+
thepercentiles : array-like
|
|
268
|
+
Percentile values to compute (0-1)
|
|
269
|
+
similaritymetric : str, optional
|
|
270
|
+
Type of similarity metric ("correlation" or "mutualinfo"). Default: "correlation"
|
|
271
|
+
displayplots : bool, optional
|
|
272
|
+
If True, display diagnostic plots. Default: False
|
|
273
|
+
twotail : bool, optional
|
|
274
|
+
If True, calculate two-tailed thresholds. Default: False
|
|
275
|
+
nozero : bool, optional
|
|
276
|
+
If True, exclude zero values. Default: False
|
|
277
|
+
dosighistfit : bool, optional
|
|
278
|
+
If True, fit distribution to data. Default: True
|
|
279
|
+
debug : bool, optional
|
|
280
|
+
Enable debug output. Default: False
|
|
264
281
|
|
|
265
282
|
Returns
|
|
266
283
|
-------
|
|
267
|
-
|
|
284
|
+
tuple
|
|
285
|
+
(pcts_data, pcts_fit, histfit) - percentiles from data, fitted distribution, and fit parameters
|
|
268
286
|
"""
|
|
269
287
|
# check to make sure there are nonzero values first
|
|
270
288
|
if len(np.where(vallist != 0.0)[0]) == 0:
|
|
@@ -313,8 +331,38 @@ maxrforneglogp = None
|
|
|
313
331
|
|
|
314
332
|
|
|
315
333
|
def neglog10pfromr(
|
|
316
|
-
rval
|
|
317
|
-
|
|
334
|
+
rval: float,
|
|
335
|
+
histfit: ArrayLike,
|
|
336
|
+
lutlen: int = 3000,
|
|
337
|
+
initialize: bool = False,
|
|
338
|
+
neglogpmin: float = 0.0,
|
|
339
|
+
neglogpmax: float = 3.0,
|
|
340
|
+
debug: bool = False,
|
|
341
|
+
) -> float:
|
|
342
|
+
"""Convert correlation value to negative log10 p-value using histogram fit.
|
|
343
|
+
|
|
344
|
+
Parameters
|
|
345
|
+
----------
|
|
346
|
+
rval : float
|
|
347
|
+
Correlation value to convert
|
|
348
|
+
histfit : array-like
|
|
349
|
+
Histogram fit parameters from fitjsbpdf
|
|
350
|
+
lutlen : int, optional
|
|
351
|
+
Length of lookup table. Default: 3000
|
|
352
|
+
initialize : bool, optional
|
|
353
|
+
Force reinitialization of interpolator. Default: False
|
|
354
|
+
neglogpmin : float, optional
|
|
355
|
+
Minimum negative log10 p-value. Default: 0.0
|
|
356
|
+
neglogpmax : float, optional
|
|
357
|
+
Maximum negative log10 p-value. Default: 3.0
|
|
358
|
+
debug : bool, optional
|
|
359
|
+
Enable debug output. Default: False
|
|
360
|
+
|
|
361
|
+
Returns
|
|
362
|
+
-------
|
|
363
|
+
float
|
|
364
|
+
Negative log10 p-value corresponding to the input correlation value
|
|
365
|
+
"""
|
|
318
366
|
global neglogpfromr_interpolator, minrforneglogp, maxrforneglogp
|
|
319
367
|
if neglogpfromr_interpolator is None or initialize:
|
|
320
368
|
neglogparray = np.linspace(neglogpmin, neglogpmax, lutlen, endpoint=True)
|
|
@@ -340,37 +388,52 @@ def neglog10pfromr(
|
|
|
340
388
|
return np.float64(neglogpfromr_interpolator(np.asarray([rval], dtype=float))[0])
|
|
341
389
|
|
|
342
390
|
|
|
343
|
-
def rfromp(fitfile, thepercentiles):
|
|
344
|
-
"""
|
|
391
|
+
def rfromp(fitfile: str, thepercentiles: ArrayLike) -> NDArray:
|
|
392
|
+
"""Get correlation values from p-values using a saved distribution fit.
|
|
345
393
|
|
|
346
394
|
Parameters
|
|
347
395
|
----------
|
|
348
|
-
fitfile
|
|
349
|
-
|
|
396
|
+
fitfile : str
|
|
397
|
+
Path to file containing distribution fit parameters
|
|
398
|
+
thepercentiles : array-like
|
|
399
|
+
Percentile values to calculate (0-1)
|
|
350
400
|
|
|
351
401
|
Returns
|
|
352
402
|
-------
|
|
353
|
-
|
|
403
|
+
array-like
|
|
404
|
+
Correlation values corresponding to the percentiles
|
|
354
405
|
"""
|
|
355
406
|
thefit = np.array(tide_io.readvecs(fitfile)[0]).astype("float64")
|
|
356
407
|
print(f"thefit = {thefit}")
|
|
357
408
|
return getfracvalsfromfit(thefit, thepercentiles)
|
|
358
409
|
|
|
359
410
|
|
|
360
|
-
def tfromr(
|
|
361
|
-
|
|
411
|
+
def tfromr(
|
|
412
|
+
r: float,
|
|
413
|
+
nsamps: int,
|
|
414
|
+
dfcorrfac: float = 1.0,
|
|
415
|
+
oversampfactor: float = 1.0,
|
|
416
|
+
returnp: bool = False,
|
|
417
|
+
) -> Union[float, Tuple[float, float]]:
|
|
418
|
+
"""Convert correlation to t-statistic.
|
|
362
419
|
|
|
363
420
|
Parameters
|
|
364
421
|
----------
|
|
365
|
-
r
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
422
|
+
r : float
|
|
423
|
+
Correlation coefficient
|
|
424
|
+
nsamps : int
|
|
425
|
+
Number of samples
|
|
426
|
+
dfcorrfac : float, optional
|
|
427
|
+
Degrees of freedom correction factor. Default: 1.0
|
|
428
|
+
oversampfactor : float, optional
|
|
429
|
+
Oversampling factor for DOF adjustment. Default: 1.0
|
|
430
|
+
returnp : bool, optional
|
|
431
|
+
If True, also return p-value. Default: False
|
|
370
432
|
|
|
371
433
|
Returns
|
|
372
434
|
-------
|
|
373
|
-
|
|
435
|
+
float or tuple
|
|
436
|
+
T-statistic, or (t-statistic, p-value) if returnp=True
|
|
374
437
|
"""
|
|
375
438
|
if r >= 1.0:
|
|
376
439
|
tval = float("inf")
|
|
@@ -385,7 +448,21 @@ def tfromr(r, nsamps, dfcorrfac=1.0, oversampfactor=1.0, returnp=False):
|
|
|
385
448
|
return tval
|
|
386
449
|
|
|
387
450
|
|
|
388
|
-
def pfromz(z, twotailed=True):
|
|
451
|
+
def pfromz(z: float, twotailed: bool = True) -> float:
|
|
452
|
+
"""Calculate p-value from z-score.
|
|
453
|
+
|
|
454
|
+
Parameters
|
|
455
|
+
----------
|
|
456
|
+
z : float
|
|
457
|
+
Z-score value
|
|
458
|
+
twotailed : bool, optional
|
|
459
|
+
If True, calculate two-tailed p-value. Default: True
|
|
460
|
+
|
|
461
|
+
Returns
|
|
462
|
+
-------
|
|
463
|
+
float
|
|
464
|
+
P-value corresponding to the z-score
|
|
465
|
+
"""
|
|
389
466
|
# importing packages
|
|
390
467
|
import scipy.stats
|
|
391
468
|
|
|
@@ -396,20 +473,32 @@ def pfromz(z, twotailed=True):
|
|
|
396
473
|
return scipy.stats.norm.sf(abs(z))
|
|
397
474
|
|
|
398
475
|
|
|
399
|
-
def zfromr(
|
|
400
|
-
|
|
476
|
+
def zfromr(
|
|
477
|
+
r: float,
|
|
478
|
+
nsamps: int,
|
|
479
|
+
dfcorrfac: float = 1.0,
|
|
480
|
+
oversampfactor: float = 1.0,
|
|
481
|
+
returnp: bool = False,
|
|
482
|
+
) -> Union[float, Tuple[float, float]]:
|
|
483
|
+
"""Convert correlation to z-statistic.
|
|
401
484
|
|
|
402
485
|
Parameters
|
|
403
486
|
----------
|
|
404
|
-
r
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
487
|
+
r : float
|
|
488
|
+
Correlation coefficient
|
|
489
|
+
nsamps : int
|
|
490
|
+
Number of samples
|
|
491
|
+
dfcorrfac : float, optional
|
|
492
|
+
Degrees of freedom correction factor. Default: 1.0
|
|
493
|
+
oversampfactor : float, optional
|
|
494
|
+
Oversampling factor for DOF adjustment. Default: 1.0
|
|
495
|
+
returnp : bool, optional
|
|
496
|
+
If True, also return p-value. Default: False
|
|
409
497
|
|
|
410
498
|
Returns
|
|
411
499
|
-------
|
|
412
|
-
|
|
500
|
+
float or tuple
|
|
501
|
+
Z-statistic, or (z-statistic, p-value) if returnp=True
|
|
413
502
|
"""
|
|
414
503
|
if r >= 1.0:
|
|
415
504
|
zval = float("inf")
|
|
@@ -424,29 +513,79 @@ def zfromr(r, nsamps, dfcorrfac=1.0, oversampfactor=1.0, returnp=False):
|
|
|
424
513
|
return zval
|
|
425
514
|
|
|
426
515
|
|
|
427
|
-
def zofcorrdiff(r1, r2, n1, n2):
|
|
516
|
+
def zofcorrdiff(r1: float, r2: float, n1: int, n2: int) -> float:
|
|
517
|
+
"""Calculate z-statistic for the difference between two correlations.
|
|
518
|
+
|
|
519
|
+
Parameters
|
|
520
|
+
----------
|
|
521
|
+
r1 : float
|
|
522
|
+
First correlation coefficient
|
|
523
|
+
r2 : float
|
|
524
|
+
Second correlation coefficient
|
|
525
|
+
n1 : int
|
|
526
|
+
Sample size for first correlation
|
|
527
|
+
n2 : int
|
|
528
|
+
Sample size for second correlation
|
|
529
|
+
|
|
530
|
+
Returns
|
|
531
|
+
-------
|
|
532
|
+
float
|
|
533
|
+
Z-statistic for the difference between the two correlations
|
|
534
|
+
"""
|
|
428
535
|
return (fisher(r1) - fisher(r2)) / stderrofdiff(n1, n2)
|
|
429
536
|
|
|
430
537
|
|
|
431
|
-
def stderrofdiff(n1, n2):
|
|
432
|
-
|
|
538
|
+
def stderrofdiff(n1: int, n2: int) -> float:
|
|
539
|
+
"""Calculate standard error of difference between two Fisher-transformed correlations.
|
|
433
540
|
|
|
541
|
+
Parameters
|
|
542
|
+
----------
|
|
543
|
+
n1 : int
|
|
544
|
+
Sample size for first correlation
|
|
545
|
+
n2 : int
|
|
546
|
+
Sample size for second correlation
|
|
434
547
|
|
|
435
|
-
|
|
548
|
+
Returns
|
|
549
|
+
-------
|
|
550
|
+
float
|
|
551
|
+
Standard error of the difference
|
|
436
552
|
"""
|
|
553
|
+
return np.sqrt(1.0 / (n1 - 3) + 1.0 / (n2 - 3))
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
def fisher(r: float) -> float:
|
|
557
|
+
"""Apply Fisher's r-to-z transformation to correlation coefficient.
|
|
437
558
|
|
|
438
559
|
Parameters
|
|
439
560
|
----------
|
|
440
|
-
r
|
|
561
|
+
r : float
|
|
562
|
+
Correlation coefficient
|
|
441
563
|
|
|
442
564
|
Returns
|
|
443
565
|
-------
|
|
444
|
-
|
|
566
|
+
float
|
|
567
|
+
Fisher-transformed z-value
|
|
445
568
|
"""
|
|
446
569
|
return 0.5 * np.log((1 + r) / (1 - r))
|
|
447
570
|
|
|
448
571
|
|
|
449
|
-
def permute_phase(time_series):
|
|
572
|
+
def permute_phase(time_series: NDArray) -> NDArray:
|
|
573
|
+
"""Generate phase-randomized surrogate time series.
|
|
574
|
+
|
|
575
|
+
Creates a surrogate time series with the same power spectrum as the input
|
|
576
|
+
but with randomized phases. Useful for generating null distributions in
|
|
577
|
+
time series analysis.
|
|
578
|
+
|
|
579
|
+
Parameters
|
|
580
|
+
----------
|
|
581
|
+
time_series : array-like
|
|
582
|
+
Input time series
|
|
583
|
+
|
|
584
|
+
Returns
|
|
585
|
+
-------
|
|
586
|
+
array-like
|
|
587
|
+
Phase-randomized surrogate time series with same length as input
|
|
588
|
+
"""
|
|
450
589
|
# Compute the Fourier transform of the time series
|
|
451
590
|
freq_domain = np.fft.rfft(time_series)
|
|
452
591
|
|
|
@@ -460,37 +599,71 @@ def permute_phase(time_series):
|
|
|
460
599
|
return permuted_time_series
|
|
461
600
|
|
|
462
601
|
|
|
463
|
-
def skewnessstats(timecourse):
|
|
464
|
-
"""
|
|
602
|
+
def skewnessstats(timecourse: NDArray) -> Tuple[float, float, float]:
|
|
603
|
+
"""Calculate skewness and statistical test for timecourse.
|
|
465
604
|
|
|
466
605
|
Parameters
|
|
467
606
|
----------
|
|
468
|
-
timecourse: array
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
:return:
|
|
607
|
+
timecourse : array-like
|
|
608
|
+
Input time series
|
|
472
609
|
|
|
610
|
+
Returns
|
|
611
|
+
-------
|
|
612
|
+
tuple
|
|
613
|
+
(skewness, z-statistic, p-value) from skewness test
|
|
473
614
|
"""
|
|
474
615
|
testres = skewtest(timecourse)
|
|
475
616
|
return skew(timecourse), testres[0], testres[1]
|
|
476
617
|
|
|
477
618
|
|
|
478
|
-
def kurtosisstats(timecourse):
|
|
479
|
-
"""
|
|
619
|
+
def kurtosisstats(timecourse: NDArray) -> Tuple[float, float, float]:
|
|
620
|
+
"""Calculate kurtosis and statistical test for timecourse.
|
|
480
621
|
|
|
481
622
|
Parameters
|
|
482
623
|
----------
|
|
483
|
-
timecourse: array
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
:return:
|
|
624
|
+
timecourse : array-like
|
|
625
|
+
Input time series
|
|
487
626
|
|
|
627
|
+
Returns
|
|
628
|
+
-------
|
|
629
|
+
tuple
|
|
630
|
+
(kurtosis, z-statistic, p-value) from kurtosis test
|
|
488
631
|
"""
|
|
489
632
|
testres = kurtosistest(timecourse)
|
|
490
633
|
return kurtosis(timecourse), testres[0], testres[1]
|
|
491
634
|
|
|
492
635
|
|
|
493
|
-
def
|
|
636
|
+
def fmristats(
|
|
637
|
+
fmridata: NDArray,
|
|
638
|
+
) -> Tuple[NDArray, NDArray, NDArray, NDArray, NDArray, NDArray, NDArray, NDArray]:
|
|
639
|
+
"""Calculate comprehensive statistics for fMRI data along time axis.
|
|
640
|
+
|
|
641
|
+
Parameters
|
|
642
|
+
----------
|
|
643
|
+
fmridata : ndarray
|
|
644
|
+
2D array where rows are voxels and columns are timepoints
|
|
645
|
+
|
|
646
|
+
Returns
|
|
647
|
+
-------
|
|
648
|
+
tuple
|
|
649
|
+
(min, max, mean, std, median, mad, skew, kurtosis) - each as 1D array
|
|
650
|
+
with length equal to number of voxels, calculated along timepoints
|
|
651
|
+
"""
|
|
652
|
+
return (
|
|
653
|
+
np.min(fmridata, axis=1),
|
|
654
|
+
np.max(fmridata, axis=1),
|
|
655
|
+
np.mean(fmridata, axis=1),
|
|
656
|
+
np.std(fmridata, axis=1),
|
|
657
|
+
np.median(fmridata, axis=1),
|
|
658
|
+
mad(fmridata, axis=1),
|
|
659
|
+
skew(fmridata, axis=1),
|
|
660
|
+
kurtosis(fmridata, axis=1),
|
|
661
|
+
)
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
def fast_ICC_rep_anova(
|
|
665
|
+
Y: NDArray, nocache: bool = False, debug: bool = False
|
|
666
|
+
) -> Tuple[float, float, float, float, int, int]:
|
|
494
667
|
"""
|
|
495
668
|
the data Y are entered as a 'table' ie subjects are in rows and repeated
|
|
496
669
|
measures in columns
|
|
@@ -577,26 +750,34 @@ def fast_ICC_rep_anova(Y, nocache=False, debug=False):
|
|
|
577
750
|
|
|
578
751
|
# --------------------------- histogram functions -------------------------------------------------
|
|
579
752
|
def gethistprops(
|
|
580
|
-
indata,
|
|
581
|
-
histlen,
|
|
582
|
-
refine=False,
|
|
583
|
-
therange=None,
|
|
584
|
-
pickleft=False,
|
|
585
|
-
peakthresh=0.33,
|
|
586
|
-
):
|
|
587
|
-
"""
|
|
753
|
+
indata: NDArray,
|
|
754
|
+
histlen: int,
|
|
755
|
+
refine: bool = False,
|
|
756
|
+
therange: Optional[Tuple[float, float]] = None,
|
|
757
|
+
pickleft: bool = False,
|
|
758
|
+
peakthresh: float = 0.33,
|
|
759
|
+
) -> Tuple[float, float, float]:
|
|
760
|
+
"""Extract histogram peak properties from data.
|
|
588
761
|
|
|
589
762
|
Parameters
|
|
590
763
|
----------
|
|
591
|
-
indata
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
764
|
+
indata : array-like
|
|
765
|
+
Input data array
|
|
766
|
+
histlen : int
|
|
767
|
+
Number of histogram bins
|
|
768
|
+
refine : bool, optional
|
|
769
|
+
If True, refine peak estimates using Gaussian fit. Default: False
|
|
770
|
+
therange : tuple, optional
|
|
771
|
+
(min, max) range for histogram. If None, use data range. Default: None
|
|
772
|
+
pickleft : bool, optional
|
|
773
|
+
If True, pick leftmost peak above threshold. Default: False
|
|
774
|
+
peakthresh : float, optional
|
|
775
|
+
Threshold for peak detection (fraction of max). Default: 0.33
|
|
596
776
|
|
|
597
777
|
Returns
|
|
598
778
|
-------
|
|
599
|
-
|
|
779
|
+
tuple
|
|
780
|
+
(peakloc, peakheight, peakwidth) - peak location, height, and width
|
|
600
781
|
"""
|
|
601
782
|
thestore = np.zeros((2, histlen), dtype="float64")
|
|
602
783
|
if therange is None:
|
|
@@ -638,13 +819,35 @@ def gethistprops(
|
|
|
638
819
|
|
|
639
820
|
|
|
640
821
|
def prochistogram(
|
|
641
|
-
thehist,
|
|
642
|
-
refine=False,
|
|
643
|
-
pickleft=False,
|
|
644
|
-
peakthresh=0.33,
|
|
645
|
-
ignorefirstpoint=False,
|
|
646
|
-
debug=False,
|
|
647
|
-
):
|
|
822
|
+
thehist: Tuple,
|
|
823
|
+
refine: bool = False,
|
|
824
|
+
pickleft: bool = False,
|
|
825
|
+
peakthresh: float = 0.33,
|
|
826
|
+
ignorefirstpoint: bool = False,
|
|
827
|
+
debug: bool = False,
|
|
828
|
+
) -> Tuple[float, float, float, float]:
|
|
829
|
+
"""Process histogram data to extract peak properties.
|
|
830
|
+
|
|
831
|
+
Parameters
|
|
832
|
+
----------
|
|
833
|
+
thehist : tuple
|
|
834
|
+
Histogram tuple from np.histogram containing (counts, bin_edges)
|
|
835
|
+
refine : bool, optional
|
|
836
|
+
If True, refine peak estimates using Gaussian fit. Default: False
|
|
837
|
+
pickleft : bool, optional
|
|
838
|
+
If True, pick leftmost peak above threshold. Default: False
|
|
839
|
+
peakthresh : float, optional
|
|
840
|
+
Threshold for peak detection (fraction of max). Default: 0.33
|
|
841
|
+
ignorefirstpoint : bool, optional
|
|
842
|
+
If True, ignore first histogram bin. Default: False
|
|
843
|
+
debug : bool, optional
|
|
844
|
+
Enable debug output. Default: False
|
|
845
|
+
|
|
846
|
+
Returns
|
|
847
|
+
-------
|
|
848
|
+
tuple
|
|
849
|
+
(peakheight, peakloc, peakwidth, centerofmass) - peak properties
|
|
850
|
+
"""
|
|
648
851
|
thestore = np.zeros((2, len(thehist[0])), dtype="float64")
|
|
649
852
|
histlen = len(thehist[1])
|
|
650
853
|
thestore[0, :] = (thehist[1][1:] + thehist[1][0:-1]) / 2.0
|
|
@@ -696,7 +899,23 @@ def prochistogram(
|
|
|
696
899
|
return peakheight, peakloc, peakwidth, centerofmass
|
|
697
900
|
|
|
698
901
|
|
|
699
|
-
def percentilefromloc(indata, peakloc, nozero=False):
|
|
902
|
+
def percentilefromloc(indata: NDArray, peakloc: float, nozero: bool = False) -> float:
|
|
903
|
+
"""Calculate the percentile corresponding to a given value location.
|
|
904
|
+
|
|
905
|
+
Parameters
|
|
906
|
+
----------
|
|
907
|
+
indata : array-like
|
|
908
|
+
Input data array
|
|
909
|
+
peakloc : float
|
|
910
|
+
Value location to find percentile for
|
|
911
|
+
nozero : bool, optional
|
|
912
|
+
If True, exclude zero values from calculation. Default: False
|
|
913
|
+
|
|
914
|
+
Returns
|
|
915
|
+
-------
|
|
916
|
+
float
|
|
917
|
+
Percentile (0-100) corresponding to the given value location
|
|
918
|
+
"""
|
|
700
919
|
order = indata.argsort()
|
|
701
920
|
orderedvalues = indata[order]
|
|
702
921
|
if nozero:
|
|
@@ -707,31 +926,46 @@ def percentilefromloc(indata, peakloc, nozero=False):
|
|
|
707
926
|
|
|
708
927
|
|
|
709
928
|
def makehistogram(
|
|
710
|
-
indata,
|
|
711
|
-
histlen,
|
|
712
|
-
binsize=None,
|
|
713
|
-
therange=None,
|
|
714
|
-
pickleft=False,
|
|
715
|
-
peakthresh=0.33,
|
|
716
|
-
refine=False,
|
|
717
|
-
normalize=False,
|
|
718
|
-
ignorefirstpoint=False,
|
|
719
|
-
debug=False,
|
|
720
|
-
):
|
|
721
|
-
"""
|
|
929
|
+
indata: NDArray,
|
|
930
|
+
histlen: Optional[int],
|
|
931
|
+
binsize: Optional[float] = None,
|
|
932
|
+
therange: Optional[Tuple[float, float]] = None,
|
|
933
|
+
pickleft: bool = False,
|
|
934
|
+
peakthresh: float = 0.33,
|
|
935
|
+
refine: bool = False,
|
|
936
|
+
normalize: bool = False,
|
|
937
|
+
ignorefirstpoint: bool = False,
|
|
938
|
+
debug: bool = False,
|
|
939
|
+
) -> Tuple[Tuple, float, float, float, float, float]:
|
|
940
|
+
"""Create histogram and extract peak properties from data.
|
|
722
941
|
|
|
723
942
|
Parameters
|
|
724
943
|
----------
|
|
725
|
-
indata
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
944
|
+
indata : array-like
|
|
945
|
+
Input data array
|
|
946
|
+
histlen : int or None
|
|
947
|
+
Number of histogram bins. If None, binsize must be specified
|
|
948
|
+
binsize : float, optional
|
|
949
|
+
Bin size for histogram. If specified, overrides histlen. Default: None
|
|
950
|
+
therange : tuple, optional
|
|
951
|
+
(min, max) range for histogram. If None, use data range. Default: None
|
|
952
|
+
pickleft : bool, optional
|
|
953
|
+
If True, pick leftmost peak above threshold. Default: False
|
|
954
|
+
peakthresh : float, optional
|
|
955
|
+
Threshold for peak detection (fraction of max). Default: 0.33
|
|
956
|
+
refine : bool, optional
|
|
957
|
+
If True, refine peak estimates using Gaussian fit. Default: False
|
|
958
|
+
normalize : bool, optional
|
|
959
|
+
If True, normalize histogram to unit area. Default: False
|
|
960
|
+
ignorefirstpoint : bool, optional
|
|
961
|
+
If True, ignore first histogram bin. Default: False
|
|
962
|
+
debug : bool, optional
|
|
963
|
+
Enable debug output. Default: False
|
|
731
964
|
|
|
732
965
|
Returns
|
|
733
966
|
-------
|
|
734
|
-
|
|
967
|
+
tuple
|
|
968
|
+
(histogram, peakheight, peakloc, peakwidth, centerofmass, peakpercentile)
|
|
735
969
|
"""
|
|
736
970
|
if therange is None:
|
|
737
971
|
therange = [indata.min(), indata.max()]
|
|
@@ -761,7 +995,27 @@ def makehistogram(
|
|
|
761
995
|
return thehist, peakheight, peakloc, peakwidth, centerofmass, peakpercentile
|
|
762
996
|
|
|
763
997
|
|
|
764
|
-
def echoloc(indata, histlen, startoffset=5.0):
|
|
998
|
+
def echoloc(indata: NDArray, histlen: int, startoffset: float = 5.0) -> Tuple[float, float]:
|
|
999
|
+
"""Detect and analyze echo peak in histogram data.
|
|
1000
|
+
|
|
1001
|
+
Identifies a secondary (echo) peak in histogram data that occurs after
|
|
1002
|
+
the primary peak, useful for analyzing echo patterns in imaging data.
|
|
1003
|
+
|
|
1004
|
+
Parameters
|
|
1005
|
+
----------
|
|
1006
|
+
indata : array-like
|
|
1007
|
+
Input data array
|
|
1008
|
+
histlen : int
|
|
1009
|
+
Number of histogram bins
|
|
1010
|
+
startoffset : float, optional
|
|
1011
|
+
Offset from primary peak to start echo search. Default: 5.0
|
|
1012
|
+
|
|
1013
|
+
Returns
|
|
1014
|
+
-------
|
|
1015
|
+
tuple
|
|
1016
|
+
(echo_lag, echo_ratio) where echo_lag is the distance between primary
|
|
1017
|
+
and echo peaks, and echo_ratio is the ratio of echo to primary peak areas
|
|
1018
|
+
"""
|
|
765
1019
|
thehist, peakheight, peakloc, peakwidth, centerofmass, peakpercentile = makehistogram(
|
|
766
1020
|
indata, histlen, refine=True
|
|
767
1021
|
)
|
|
@@ -790,43 +1044,56 @@ def echoloc(indata, histlen, startoffset=5.0):
|
|
|
790
1044
|
|
|
791
1045
|
|
|
792
1046
|
def makeandsavehistogram(
|
|
793
|
-
indata,
|
|
794
|
-
histlen,
|
|
795
|
-
endtrim,
|
|
796
|
-
outname,
|
|
797
|
-
binsize=None,
|
|
798
|
-
saveimfile=False,
|
|
799
|
-
displaytitle="histogram",
|
|
800
|
-
displayplots=False,
|
|
801
|
-
refine=False,
|
|
802
|
-
therange=None,
|
|
803
|
-
normalize=False,
|
|
804
|
-
dictvarname=None,
|
|
805
|
-
thedict=None,
|
|
806
|
-
append=False,
|
|
807
|
-
debug=False,
|
|
808
|
-
):
|
|
809
|
-
"""
|
|
1047
|
+
indata: NDArray,
|
|
1048
|
+
histlen: int,
|
|
1049
|
+
endtrim: int,
|
|
1050
|
+
outname: str,
|
|
1051
|
+
binsize: Optional[float] = None,
|
|
1052
|
+
saveimfile: bool = False,
|
|
1053
|
+
displaytitle: str = "histogram",
|
|
1054
|
+
displayplots: bool = False,
|
|
1055
|
+
refine: bool = False,
|
|
1056
|
+
therange: Optional[Tuple[float, float]] = None,
|
|
1057
|
+
normalize: bool = False,
|
|
1058
|
+
dictvarname: Optional[str] = None,
|
|
1059
|
+
thedict: Optional[dict] = None,
|
|
1060
|
+
append: bool = False,
|
|
1061
|
+
debug: bool = False,
|
|
1062
|
+
) -> None:
|
|
1063
|
+
"""Create histogram, extract properties, and save results to file.
|
|
810
1064
|
|
|
811
1065
|
Parameters
|
|
812
1066
|
----------
|
|
813
|
-
indata
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1067
|
+
indata : array-like
|
|
1068
|
+
Input data array
|
|
1069
|
+
histlen : int
|
|
1070
|
+
Number of histogram bins
|
|
1071
|
+
endtrim : int
|
|
1072
|
+
Number of bins to trim from end when plotting
|
|
1073
|
+
outname : str
|
|
1074
|
+
Output file path (without extension)
|
|
1075
|
+
binsize : float, optional
|
|
1076
|
+
Bin size for histogram. If specified, overrides histlen. Default: None
|
|
1077
|
+
saveimfile : bool, optional
|
|
1078
|
+
Unused parameter. Default: False
|
|
1079
|
+
displaytitle : str, optional
|
|
1080
|
+
Title for display plots. Default: "histogram"
|
|
1081
|
+
displayplots : bool, optional
|
|
1082
|
+
If True, display histogram plot. Default: False
|
|
1083
|
+
refine : bool, optional
|
|
1084
|
+
If True, refine peak estimates using Gaussian fit. Default: False
|
|
1085
|
+
therange : tuple, optional
|
|
1086
|
+
(min, max) range for histogram. If None, use data range. Default: None
|
|
1087
|
+
normalize : bool, optional
|
|
1088
|
+
If True, normalize histogram to unit area. Default: False
|
|
1089
|
+
dictvarname : str, optional
|
|
1090
|
+
Variable name for dictionary storage. If None, use outname. Default: None
|
|
1091
|
+
thedict : dict, optional
|
|
1092
|
+
Dictionary to store results in. If None, write to file. Default: None
|
|
1093
|
+
append : bool, optional
|
|
1094
|
+
If True, append to existing file. Default: False
|
|
1095
|
+
debug : bool, optional
|
|
1096
|
+
Enable debug output. Default: False
|
|
830
1097
|
"""
|
|
831
1098
|
thehist, peakheight, peakloc, peakwidth, centerofmass, peakpercentile = makehistogram(
|
|
832
1099
|
indata,
|
|
@@ -908,18 +1175,22 @@ def makeandsavehistogram(
|
|
|
908
1175
|
plt.show()
|
|
909
1176
|
|
|
910
1177
|
|
|
911
|
-
def symmetrize(a, antisymmetric=False, zerodiagonal=False):
|
|
912
|
-
"""
|
|
1178
|
+
def symmetrize(a: NDArray, antisymmetric: bool = False, zerodiagonal: bool = False) -> NDArray:
|
|
1179
|
+
"""Symmetrize a matrix.
|
|
913
1180
|
|
|
914
1181
|
Parameters
|
|
915
1182
|
----------
|
|
916
|
-
a
|
|
917
|
-
|
|
918
|
-
|
|
1183
|
+
a : ndarray
|
|
1184
|
+
Input matrix
|
|
1185
|
+
antisymmetric : bool, optional
|
|
1186
|
+
If True, create antisymmetric matrix (a - a.T) / 2. Default: False
|
|
1187
|
+
zerodiagonal : bool, optional
|
|
1188
|
+
If True, set diagonal elements to zero. Default: False
|
|
919
1189
|
|
|
920
1190
|
Returns
|
|
921
1191
|
-------
|
|
922
|
-
|
|
1192
|
+
ndarray
|
|
1193
|
+
Symmetrized matrix
|
|
923
1194
|
"""
|
|
924
1195
|
if antisymmetric:
|
|
925
1196
|
intermediate = (a - a.T) / 2.0
|
|
@@ -931,19 +1202,24 @@ def symmetrize(a, antisymmetric=False, zerodiagonal=False):
|
|
|
931
1202
|
return intermediate
|
|
932
1203
|
|
|
933
1204
|
|
|
934
|
-
def makepmask(rvals, pval, sighistfit, onesided=True):
|
|
935
|
-
"""
|
|
1205
|
+
def makepmask(rvals: NDArray, pval: float, sighistfit: NDArray, onesided: bool = True) -> NDArray:
|
|
1206
|
+
"""Create significance mask from p-value threshold and distribution fit.
|
|
936
1207
|
|
|
937
1208
|
Parameters
|
|
938
1209
|
----------
|
|
939
|
-
rvals
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1210
|
+
rvals : array-like
|
|
1211
|
+
Array of correlation or similarity values
|
|
1212
|
+
pval : float
|
|
1213
|
+
P-value threshold (0-1)
|
|
1214
|
+
sighistfit : array-like
|
|
1215
|
+
Distribution fit parameters from fitjsbpdf
|
|
1216
|
+
onesided : bool, optional
|
|
1217
|
+
If True, use one-sided test. If False, use two-sided test. Default: True
|
|
943
1218
|
|
|
944
1219
|
Returns
|
|
945
1220
|
-------
|
|
946
|
-
|
|
1221
|
+
ndarray
|
|
1222
|
+
Binary mask (int16) with 1 for significant values, 0 otherwise
|
|
947
1223
|
"""
|
|
948
1224
|
if onesided:
|
|
949
1225
|
return np.where(
|
|
@@ -958,35 +1234,49 @@ def makepmask(rvals, pval, sighistfit, onesided=True):
|
|
|
958
1234
|
|
|
959
1235
|
|
|
960
1236
|
# Find the image intensity value which thefrac of the non-zero voxels in the image exceed
|
|
961
|
-
def getfracval(datamat, thefrac, nozero=False):
|
|
962
|
-
"""
|
|
1237
|
+
def getfracval(datamat: NDArray, thefrac: float, nozero: bool = False) -> float:
|
|
1238
|
+
"""Get data value at a specific fractional position in sorted data.
|
|
963
1239
|
|
|
964
1240
|
Parameters
|
|
965
1241
|
----------
|
|
966
|
-
datamat
|
|
967
|
-
|
|
1242
|
+
datamat : array-like
|
|
1243
|
+
Input data array
|
|
1244
|
+
thefrac : float
|
|
1245
|
+
Fractional position (0-1) to find value at
|
|
1246
|
+
nozero : bool, optional
|
|
1247
|
+
If True, exclude zero values. Default: False
|
|
968
1248
|
|
|
969
1249
|
Returns
|
|
970
1250
|
-------
|
|
971
|
-
|
|
1251
|
+
float
|
|
1252
|
+
Value at the specified fractional position
|
|
972
1253
|
"""
|
|
973
1254
|
return getfracvals(datamat, [thefrac], nozero=nozero)[0]
|
|
974
1255
|
|
|
975
1256
|
|
|
976
|
-
def getfracvals(
|
|
977
|
-
|
|
1257
|
+
def getfracvals(
|
|
1258
|
+
datamat: NDArray, thefracs: ArrayLike, nozero: bool = False, debug: bool = False
|
|
1259
|
+
) -> list:
|
|
1260
|
+
"""Get data values at multiple fractional positions in sorted data.
|
|
1261
|
+
|
|
1262
|
+
Finds the intensity values that correspond to specified fractional positions
|
|
1263
|
+
when data is sorted in ascending order. Useful for percentile calculations.
|
|
978
1264
|
|
|
979
1265
|
Parameters
|
|
980
1266
|
----------
|
|
981
|
-
datamat
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1267
|
+
datamat : array-like
|
|
1268
|
+
Input data array
|
|
1269
|
+
thefracs : array-like
|
|
1270
|
+
List of fractional positions (0-1) to find values at
|
|
1271
|
+
nozero : bool, optional
|
|
1272
|
+
If True, exclude zero values. Default: False
|
|
1273
|
+
debug : bool, optional
|
|
1274
|
+
Enable debug output. Default: False
|
|
986
1275
|
|
|
987
1276
|
Returns
|
|
988
1277
|
-------
|
|
989
|
-
|
|
1278
|
+
list
|
|
1279
|
+
Values at the specified fractional positions
|
|
990
1280
|
"""
|
|
991
1281
|
thevals = []
|
|
992
1282
|
|
|
@@ -1014,17 +1304,23 @@ def getfracvals(datamat, thefracs, nozero=False, debug=False):
|
|
|
1014
1304
|
return thevals
|
|
1015
1305
|
|
|
1016
1306
|
|
|
1017
|
-
def getfracvalsfromfit(histfit, thefracs):
|
|
1018
|
-
"""
|
|
1307
|
+
def getfracvalsfromfit(histfit: ArrayLike, thefracs: ArrayLike) -> NDArray:
|
|
1308
|
+
"""Get data values at fractional positions from a Johnson SB distribution fit.
|
|
1309
|
+
|
|
1310
|
+
Uses the fitted Johnson SB distribution to calculate values corresponding
|
|
1311
|
+
to specified percentiles.
|
|
1019
1312
|
|
|
1020
1313
|
Parameters
|
|
1021
1314
|
----------
|
|
1022
|
-
histfit
|
|
1023
|
-
|
|
1315
|
+
histfit : array-like
|
|
1316
|
+
Johnson SB distribution fit parameters (a, b, loc, scale, zeroterm) from fitjsbpdf
|
|
1317
|
+
thefracs : array-like
|
|
1318
|
+
List of fractional positions/percentiles (0-1) to calculate values for
|
|
1024
1319
|
|
|
1025
1320
|
Returns
|
|
1026
1321
|
-------
|
|
1027
|
-
|
|
1322
|
+
array-like
|
|
1323
|
+
Values corresponding to the specified percentiles from the fitted distribution
|
|
1028
1324
|
"""
|
|
1029
1325
|
# print('entering getfracvalsfromfit: histfit=',histfit, ' thefracs=', thefracs)
|
|
1030
1326
|
thedist = johnsonsb(histfit[0], histfit[1], histfit[2], histfit[3])
|
|
@@ -1032,7 +1328,13 @@ def getfracvalsfromfit(histfit, thefracs):
|
|
|
1032
1328
|
return thevals
|
|
1033
1329
|
|
|
1034
1330
|
|
|
1035
|
-
def makemask(
|
|
1331
|
+
def makemask(
|
|
1332
|
+
image: NDArray,
|
|
1333
|
+
threshpct: float = 25.0,
|
|
1334
|
+
verbose: bool = False,
|
|
1335
|
+
nozero: bool = False,
|
|
1336
|
+
noneg: bool = False,
|
|
1337
|
+
) -> NDArray:
|
|
1036
1338
|
"""
|
|
1037
1339
|
|
|
1038
1340
|
Parameters
|
|
@@ -1072,7 +1374,7 @@ def makemask(image, threshpct=25.0, verbose=False, nozero=False, noneg=False):
|
|
|
1072
1374
|
return themask
|
|
1073
1375
|
|
|
1074
1376
|
|
|
1075
|
-
def getmasksize(themask):
|
|
1377
|
+
def getmasksize(themask: NDArray) -> int:
|
|
1076
1378
|
"""
|
|
1077
1379
|
|
|
1078
1380
|
Parameters
|