|
|
import os
|
|
|
import sys
|
|
|
import numpy as np
|
|
|
import nibabel as nib
|
|
|
import matplotlib.pyplot as plt
|
|
|
from scipy.optimize import curve_fit
|
|
|
|
|
|
|
|
|
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 ===")
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
|
|
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}")
|
|
|
|
|
|
|
|
|
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}")
|
|
|
|
|
|
|
|
|
vec_b = unique_b
|
|
|
vec_S = signal / np.max(signal)
|
|
|
vec_S_log = np.log(vec_S + 1e-10)
|
|
|
|
|
|
|
|
|
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}")
|
|
|
|
|
|
|
|
|
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()
|
|
|
|