| import numpy as np
|
| import matplotlib.pyplot as plt
|
| import sys
|
| import os
|
|
|
|
|
| sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
|
|
|
| from ivim_model import calculate_ivim_params
|
|
|
| def generate_synthetic_signal(b_values, D, f, D_star, K=0, noise_level=0.02):
|
| """
|
| Generates synthetic IVIM-Kurtosis signal.
|
| S(b) = S0 * [ f * exp(-b*D*) + (1-f) * exp(-b*D + 1/6 * b^2 * D^2 * K) ]
|
| """
|
| S0 = 1000
|
| b = np.array(b_values)
|
|
|
|
|
|
|
|
|
|
|
| term_diff = np.exp(-b * D + (1/6) * (b**2) * (D**2) * K)
|
| term_perf = np.exp(-b * D_star)
|
|
|
| signal = S0 * (f * term_perf + (1 - f) * term_diff)
|
|
|
|
|
| noise = np.random.normal(0, noise_level * S0, size=len(b))
|
| signal_noisy = signal + noise
|
| signal_noisy[signal_noisy < 0] = 0
|
|
|
| return signal_noisy
|
|
|
| def main():
|
| print("=== IVIM-DKI Estimation Demo ===")
|
|
|
|
|
| D_true = 0.001
|
| f_true = 0.15
|
| D_star_true = 0.01
|
| K_true = 0.8
|
|
|
| print(f"Ground Truth: D={D_true}, f={f_true}, D*={D_star_true}, K={K_true}")
|
|
|
|
|
| b_values = [0, 10, 20, 30, 50, 80, 100, 200, 400, 800, 1000, 1500, 2000]
|
| print(f"b-values: {b_values}")
|
|
|
|
|
| signal = generate_synthetic_signal(b_values, D_true, f_true, D_star_true, K_true)
|
|
|
|
|
| print("\nFitting model...")
|
|
|
|
|
| r2, D_est, f_est, D_star_est, K_est = calculate_ivim_params(b_values, signal, gof=0.999, model_type='quadratic')
|
|
|
|
|
| print("\n--- Results ---")
|
| print(f"Estimated D: {D_est:.6f} (Error: {abs(D_est - D_true)/D_true*100:.2f}%)")
|
| print(f"Estimated f: {f_est:.6f} (Error: {abs(f_est - f_true)/f_true*100:.2f}%)")
|
| print(f"Estimated D*: {D_star_est:.6f} (Error: {abs(D_star_est - D_star_true)/D_star_true*100:.2f}%)")
|
| print(f"Estimated K: {K_est:.6f} (Error: {abs(K_est - K_true)/K_true*100:.2f}%)")
|
| print(f"Goodness of fit (R2): {r2:.4f}")
|
|
|
|
|
| plt.figure(figsize=(10, 6))
|
| plt.plot(b_values, signal, 'o', label='Noisy Data')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| b_smooth = np.linspace(0, max(b_values), 100)
|
| term_diff_est = np.exp(-b_smooth * D_est + (1/6) * (b_smooth**2) * (D_est**2) * K_est)
|
| term_perf_est = np.exp(-b_smooth * D_star_est)
|
| S0_est = np.max(signal)
|
| signal_est = S0_est * (f_est * term_perf_est + (1 - f_est) * term_diff_est)
|
|
|
| plt.plot(b_smooth, signal_est, '-', label='Fitted Curve')
|
| plt.xlabel('b-value (s/mm^2)')
|
| plt.ylabel('Signal Intensity')
|
| plt.title('IVIM-DKI Fit Demo')
|
| plt.legend()
|
| plt.grid(True)
|
|
|
|
|
| output_plot = 'demo_fit.png'
|
| plt.savefig(output_plot)
|
| print(f"\nPlot saved to {output_plot}")
|
|
|
| if __name__ == "__main__":
|
| main()
|
|
|