phase-encoding-simple.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. from scipy.optimize import differential_evolution
  4. import numpy as np
  5. voxel_num = 3
  6. phase_range = np.pi/2
  7. phase_init = 0.0
  8. noise_ratio = 1e5
  9. total_periods = 50
  10. rf_samples_per_period = 10
  11. # B0=1.5T freq=64Mhz, period = 15.6 ns
  12. period = 15.6/1000/1000 #ms
  13. omega = 2.0*np.pi/period
  14. T2s_scale = 0.001 #ms # need to be 10ms
  15. T2s_min = T2s_scale/1000.0
  16. #print(period)
  17. #ms
  18. time_steps = np.linspace(0, period*total_periods, rf_samples_per_period*total_periods)
  19. voxel_amplitudes = np.random.rand(voxel_num)
  20. voxel_T2s_decay = np.random.rand(voxel_num)*(T2s_scale-T2s_min) + T2s_min
  21. print("amp/decay", voxel_amplitudes,voxel_T2s_decay)
  22. #voxel_amplitudes = [0.4, 0.8, 0]
  23. #voxel_amplitudes = [0.9, 0.092893218813452, 0.5]
  24. #voxel_amplitudes = [0.6, 0.517157287525381, 0.4]
  25. test_amplitudes = np.zeros(voxel_num)
  26. test_amplitudes = voxel_amplitudes
  27. voxel_phases = np.linspace(0,phase_range, voxel_num)
  28. #print(voxel_phases)
  29. if len(voxel_amplitudes) != len(voxel_phases):
  30. print("ERROR! Size of amplitude and phase arrays do not match!")
  31. raise
  32. def gen_rf_signal(time):
  33. signal = 0.0
  34. for i in range(voxel_num):
  35. signal += voxel_amplitudes[i]*np.sin(
  36. omega*time + voxel_phases[i] + phase_init
  37. ) * (
  38. np.exp(-time/voxel_T2s_decay[i])
  39. ) + ( 0.0
  40. + np.random.rand()/noise_ratio
  41. )
  42. return signal
  43. def assumed_signal(time, values):
  44. amplitudes = values[:voxel_num]
  45. T2s_decay = values[voxel_num:]
  46. signal = 0.0
  47. for i in range(voxel_num):
  48. signal += amplitudes[i]*np.sin(
  49. omega*time + voxel_phases[i] + phase_init
  50. ) * (
  51. np.exp(-time/T2s_decay[i])
  52. )
  53. return signal
  54. rf_signal_measured = gen_rf_signal(time_steps)
  55. def fitness(amplitudes):
  56. diff = rf_signal_measured - assumed_signal(time_steps, amplitudes)
  57. return np.sqrt(np.mean(np.square(diff)))
  58. #print(voxel_phases)
  59. #print (voxel_amplitudes)
  60. # import matplotlib.pyplot as plt
  61. # plt.plot(time_steps, rf_signal(time_steps))
  62. # plt.show()
  63. # #print(fitness(test_amplitudes))
  64. bounds = []
  65. amplitude_minmax = (0,1)
  66. T2s_minmax = (T2s_min,T2s_scale)
  67. for i in range(voxel_num):
  68. bounds.append(amplitude_minmax)
  69. for i in range(voxel_num):
  70. bounds.append(T2s_minmax)
  71. result = differential_evolution(fitness, bounds, polish=True
  72. #, maxiter = voxel_num*2*500
  73. )
  74. voxel_all = np.append(voxel_amplitudes,voxel_T2s_decay/T2s_scale)
  75. print("all ", voxel_all)
  76. result.x[voxel_num:] = result.x[voxel_num:]/T2s_scale
  77. print("eval ",result.x, result.fun)
  78. # print("Diff")
  79. # print((voxel_amplitudes-result.x))
  80. # print("percent")
  81. print("percent",(voxel_all-result.x)*100)
  82. if np.max((voxel_all-result.x)*100)>0.5:
  83. print ("============== !!!LARGE!!! ===============")
  84. print("\n")