File size: 2,576 Bytes
5d0dc03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import os
import sys
import numpy as np
import nibabel as nib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# Add src to path
sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
from ivim_model import calculate_ivim_params, _fit_pixel

def func_qua(x, a0, a1, a2):
    return a2 * (x ** 2) + a1 * x + a0

def main():
    print("=== Debugging Single Pixel Fit ===")
    
    # Load data
    data_dir = os.path.join(os.path.dirname(__file__), 'data', 'CFIN')
    nii_file = [f for f in os.listdir(data_dir) if f.endswith('.nii') and 'DTI' in f][0]
    bval_file = [f for f in os.listdir(data_dir) if f.endswith('.bval')][0]
    
    img = nib.load(os.path.join(data_dir, nii_file))
    data = img.get_fdata()
    bvals = np.loadtxt(os.path.join(data_dir, bval_file))
    
    # Preprocess (Average)
    unique_b = np.unique(np.round(bvals, -1))
    avg_data_list = []
    for b_val in unique_b:
        idxs = np.where(np.abs(bvals - b_val) < 10)[0]
        if len(idxs) > 0:
            avg_data_list.append(np.mean(data[:, :, :, idxs], axis=3))
    avg_data = np.stack(avg_data_list, axis=3)
    
    # Pick a pixel in the brain
    # Slice 9, x=50, y=50 (approx center)
    slice_idx = 9
    x, y = 48, 48
    
    signal = avg_data[x, y, slice_idx, :]
    print(f"Pixel ({x}, {y}, {slice_idx})")
    print(f"b-values: {unique_b}")
    print(f"Signal: {signal}")
    
    # Run IVIM calculation
    print("\n--- Running calculate_ivim_params (Quadratic) ---")
    r2, D, f, D_star, K = calculate_ivim_params(unique_b, signal, model_type='quadratic', gof=0.9)
    print(f"Result: D={D}, f={f}, D*={D_star}, K={K}, R2={r2}")
    
    # Manual check of the fit
    vec_b = unique_b
    vec_S = signal / np.max(signal)
    vec_S_log = np.log(vec_S + 1e-10)
    
    # Fit high b
    limit_dif = 180
    idx = np.where(vec_b >= limit_dif)[0][0]
    b_high = vec_b[idx:]
    S_high = vec_S_log[idx:]
    
    print(f"\nHigh-b data (b >= {limit_dif}):")
    print(f"b: {b_high}")
    print(f"log(S): {S_high}")
    
    # Try fit
    bounds = ([-np.inf, -np.inf, 0], [np.inf, 0, np.inf])
    try:
        popt, _ = curve_fit(func_qua, b_high, S_high, bounds=bounds)
        print(f"Manual Curve Fit params: a0={popt[0]}, a1={popt[1]}, a2={popt[2]}")
        print(f"Implied D = {-popt[1]}")
        print(f"Implied K = {popt[2] / popt[1]**2 * 6 if popt[1]!=0 else 0}")
    except Exception as e:
        print(f"Fit failed: {e}")

if __name__ == "__main__":
    main()