phase-encoding-method-of-moments-Pade.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. #from scipy.special import gamma, binom
  4. import numpy as np
  5. import matplotlib.pyplot as plt
  6. import scipy.sparse as sparse
  7. from scipy.sparse.linalg import eigsh
  8. from numpy.linalg import eig
  9. from mpmath import mp, mpf
  10. mp.dps = 2000
  11. voxel_num = 5
  12. phase_range = np.pi/2 *0.0
  13. phase_init = np.pi/2 #(0.0)
  14. U_points = voxel_num * 3000
  15. noise_ratio = 0.0*(1.2e-16) #(1.2e-16) #1e8
  16. total_periods=10#DO NOT CHANGE to fit T2s_scale autoscale
  17. rf_samples_per_period = 4
  18. # max polynomial order equals rf_samples_per_period * total_periods
  19. # B0=1.5T freq=64Mhz, period = 15.6 ns
  20. period = (10.0) #ms
  21. omega = 2.0*np.pi/period
  22. #T2s_scale = 0.01 #ms # need to be 10ms
  23. T2s_scale = total_periods*period/rf_samples_per_period/voxel_num*8 #ms # need to be 10ms
  24. T2s_min = T2s_scale/20.0
  25. #ms
  26. total_steps = rf_samples_per_period*total_periods
  27. if total_steps % 2 != 0: total_steps -= 1
  28. time_steps = np.array(mp.linspace((0), (period*total_periods), total_steps))
  29. tmp = [np.random.rand()*0.0+(1.0) for n in range(voxel_num)]
  30. voxel_amplitudes = np.array(tmp)
  31. tmp = [np.random.rand() for n in range(voxel_num)]
  32. voxel_T2s_decay = np.sort(np.array(tmp))*(T2s_scale-2*T2s_min) + T2s_min
  33. voxel_all = np.append(voxel_amplitudes,voxel_T2s_decay/T2s_scale)
  34. if voxel_num == 5:
  35. # voxel_all = np.array([mpf(0.2),(0.6),(0.02),(0.1)])
  36. voxel_all = np.array([(0.822628),(0.691376),(0.282906),(0.226013),(0.90703),(0.144985),(0.228563),(0.340353),(0.462462),(0.720518)])
  37. #voxel_all = np.array([(0.592606),(0.135168),(0.365712),(0.667536),(0.437378),(0.918822),(0.943879),(0.590338),(0.685997),(0.658839)])
  38. voxel_amplitudes = voxel_all[:voxel_num]
  39. voxel_T2s_decay = voxel_all[voxel_num:]*T2s_scale
  40. # a_i = np.array([(0.3),(0.1),(0.15),(0.1)])
  41. # d_i = np.array([(0.7),(0.9),(0.2),(0.67)])
  42. # voxel_num = len(a_i)
  43. voxel_phases = np.array(np.linspace(0,phase_range, voxel_num))
  44. # if len(voxel_amplitudes) != len(voxel_phases):
  45. # print("ERROR! Size of amplitude and phase arrays do not match!")
  46. # raise
  47. ampl = []
  48. def gen_rf_signal(time):
  49. '''Generates demodulated signal at radio frequence using voxels
  50. amplitudes, T2s decays, and phases.
  51. '''
  52. tmp = [mpf(0.0) for n in range(len(time))]
  53. mag_sin = np.array(tmp)
  54. mag_cos = np.array(tmp)
  55. for t in range(len(time)):
  56. for i in range(voxel_num):
  57. # mag_sin[t] += a_i[i]*(
  58. # (d_i[i] + np.random.rand()*noise_ratio)**time[t]
  59. # )
  60. amp = voxel_amplitudes[i] * (
  61. mp.exp(-time[t]/voxel_T2s_decay[i])
  62. ) + ( 0.0
  63. # + np.random.rand()*noise_ratio
  64. )
  65. # if t == 0:
  66. #print("a_{:d}".format(i),float(voxel_amplitudes[i]* np.sin(voxel_phases[i] + phase_init)))
  67. #print("d_{:d}".format(i),float( np.exp(-(period/rf_samples_per_period)/voxel_T2s_decay[i]) ))
  68. mag_sin[t] += amp * np.sin((voxel_phases[i] + phase_init))
  69. mag_cos[t] += amp * np.cos((voxel_phases[i] + phase_init))
  70. mag_sin[t] *= (1 + (np.random.rand()-0.5)*noise_ratio)
  71. #mag_cos[t] += np.random.rand()*noise_ratio
  72. return mag_sin, mag_cos
  73. mag_sin_0, mag_cos_0 = gen_rf_signal(time_steps)
  74. mag_sin = np.copy(mag_sin_0)
  75. mag_cos = np.copy(mag_cos_0)
  76. print("N = ",len(mag_sin))
  77. print("Noise = ", noise_ratio )
  78. # print("c_n =",["%0.8f"%(x) for x in mag_sin])
  79. sign = ""
  80. # for i in range(voxel_num):
  81. # if i%5 == 0:
  82. # sign+="\n"
  83. # sign = sign + '{:3.2g}'.format(float(a_i[i]))+"/"+'{:3.2g}'.format(float(d_i[i]))+", "
  84. #
  85. # # print(mp.exp(-1.0/voxel_T2s_decay[i]))
  86. x = np.linspace(0,1, U_points)
  87. import time
  88. time1 = time.time()
  89. time2 = time.time()
  90. print( 'It took %0.5f s' % ((time2-time1)))
  91. sign =""
  92. for i in range(voxel_num):
  93. sign+="{:4.3g}, ".format(float( mp.exp(-(period/rf_samples_per_period)/voxel_T2s_decay[i]) ))
  94. #print(sign)
  95. # x = np.linspace(0,1, U_points)
  96. # mag_x = np.linspace(0,1, len(mag_sin))
  97. # import matplotlib as matplotlib
  98. # matplotlib.rcParams.update({'font.size': 28})
  99. # plt.figure(figsize=(30, 20))
  100. # plt.plot(x,U, lw=0.2)
  101. # plt.title(r"$\sum^M \lambda_i L_i(x)$", y=1.02)
  102. # plt.xlim(0,1)
  103. # plt.xlabel(sign, fontsize=28)
  104. # plt.savefig("plt.pdf")
  105. # plt.clf()
  106. plt.plot(mag_sin, ls=' ', marker='o')
  107. plt.title("Signal to restore amp/decay_T:"+sign)
  108. plt.savefig("signal.pdf")
  109. plt.clf()