utest_py2jemris_script.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # Demonstrates usage of py2jemris functionalities
  2. # May be used for quick testing
  3. # Gehua Tong
  4. # May 18, 2020
  5. from coil2xml import coil2xml
  6. from seq2xml import seq2xml
  7. from sim_jemris import sim_jemris
  8. from pulseq_jemris_simulator import simulate_pulseq_jemris, create_and_save_phantom
  9. from recon_jemris import recon_jemris
  10. import phantom as pht
  11. from pulseq_library import make_pulseq_irse, make_pulseq_se_oblique
  12. import numpy as np
  13. import matplotlib.pyplot as plt
  14. from pypulseq.Sequence.sequence import Sequence
  15. from scipy.io import loadmat, savemat
  16. #from virtualscanner.utils.constants import SERVER_SIM_BLOCH_PY2JEMRIS_PATH
  17. import os
  18. import h5py
  19. utest_path = 'sim/utest_outputs'
  20. sim_path = 'sim'
  21. def utest_coil2xml():
  22. # Example on using coil2xml
  23. # Generate coil using B1 maps and plot
  24. # 4 channels with different B1 maps
  25. b1 = np.ones((32,32))
  26. XY = np.meshgrid(np.linspace(0,1,32), np.linspace(0,1,32))
  27. X = XY[0]
  28. Y = XY[1]
  29. # Define coil sensitivity maps (complex arrays, in general)
  30. b1_ch1 = np.sqrt(X**2 + Y**2)
  31. b1_ch2 = np.rot90(b1_ch1)
  32. b1_ch3 = np.rot90(b1_ch2)
  33. b1_ch4 = np.rot90(b1_ch3)
  34. coil2xml(b1maps=[b1_ch1, b1_ch2, b1_ch3, b1_ch4], fov=200, name='test_coil', out_folder=utest_path)
  35. # Generate sensmaps.h5 using JEMRIS command
  36. os.chdir(utest_path)
  37. print(os.system('dir'))
  38. out = os.system('jemris test_coil.xml')
  39. os.chdir('../..')
  40. print(out)
  41. # Load sensmaps.h5 and plot coil
  42. a = h5py.File(utest_path + '/sensmaps.h5', 'r')
  43. maps_magnitude = a['maps/magnitude']
  44. maps_phase = a['maps/phase']
  45. plt.figure(1)
  46. plt.title('Coil sensitivity maps')
  47. for u in range(4):
  48. plt.subplot(2,4,u+1)
  49. plt.gray()
  50. plt.imshow(maps_magnitude[f'0{u}'])
  51. plt.title(f'Magnitude Ch #{u+1}')
  52. plt.subplot(2,4,u+5)
  53. plt.gray()
  54. plt.imshow(maps_phase[f'0{u}'])
  55. plt.title(f'Phase Ch #{u+1}')
  56. plt.show()
  57. return
  58. def utest_seq2xml():
  59. # Make a sequence
  60. seq = make_pulseq_irse(fov=0.256, n=16, thk=0.01, fa=15, tr=150, te=30, ti=10,
  61. enc='xyz', slice_locs=None, write=False)
  62. # Convert to .xml format
  63. seq2xml(seq, seq_name='irse16_pulseq', out_folder=utest_path)
  64. # Use JEMRIS to generate sequence diagrams from .xml sequence
  65. os.chdir(utest_path)
  66. print(os.system('dir'))
  67. out = os.system(f'jemris -x -d id=1 -f irse16_pulseq irse16_pulseq.xml')
  68. print(out)
  69. os.chdir('../..')
  70. # Read sequence diagram and plot
  71. data = h5py.File(utest_path + '/irse16_pulseq.h5','r')
  72. diag = data['seqdiag']
  73. t = diag['T']
  74. gx = diag['GX']
  75. gy = diag['GY']
  76. gz = diag['GZ']
  77. rxp = diag['RXP']
  78. txm = diag['TXM']
  79. txp = diag['TXP']
  80. ylist = [txm, txp, gx, gy, gz, rxp]
  81. title_list = ['RF Tx magnitude', 'RF Tx phase', 'Gx', 'Gy', 'Gz', 'RF Rx phase']
  82. styles = ['r-', 'g-', 'k-', 'k-', 'k-', 'bx']
  83. plt.figure(1)
  84. for v in range(6):
  85. plt.subplot(6,1,v+1)
  86. plt.plot(t, ylist[v], styles[v])
  87. plt.title(title_list[v])
  88. plt.xlabel('Time')
  89. plt.show()
  90. return
  91. def utest_sim_jemris():
  92. # Copy helping files in
  93. os.chdir(sim_path)
  94. out = os.system('copy uniform.xml utest_outputs')
  95. print(out)
  96. os.chdir('..')
  97. utest_phantom_output_h5()
  98. list_sim_orig = {'seq_xml': 'gre32.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
  99. 'rx_xml': 'uniform.xml'}
  100. out = sim_jemris(list_sim_orig, working_folder = utest_path)
  101. os.chdir(utest_path)
  102. savemat('data32_orig.mat',out)
  103. print('Data is saved in py2jemris/sim/utest_outputs/data32_orig.mat')
  104. os.chdir('../..')
  105. return
  106. def utest_pulseq_sim():
  107. # TODO this !
  108. # Demonstrates simulation pipeline using pulseq inputs
  109. # Define the same phantom
  110. phantom_info = {'fov': 0.256, 'N': 15, 'type': 'cylindrical', 'dim': 2, 'dir': 'z', 'loc': 0}
  111. sps = 'sim/utest_outputs/se_fov256mm_Nf15_Np15_TE50ms_TR200ms_FA90deg.seq'
  112. sim_name = 'utest_outputs'
  113. # Make sequence
  114. os.chdir(utest_path)
  115. make_pulseq_se_oblique(fov=0.256,n=15, thk=0.005, tr=0.2, te=0.05, fa=90,
  116. enc='xyz', slice_locs=[0], write=True)
  117. os.chdir('../..')
  118. simulate_pulseq_jemris(seq_path=sps, phantom_info=phantom_info, sim_name=sim_name,
  119. coil_fov=0.256)
  120. kk, im, images = recon_jemris(file='sim/' + sim_name + '/signals.h5', dims=[15, 15])
  121. savemat('sim/' + sim_name + '/utest_pulseq_sim_output.mat', {'images': images, 'kspace': kk, 'imspace': im})
  122. print('Simulation result is in py2jemris/sim/utest_outputs/utest_pulseq_sim_output.mat')
  123. # Plot results
  124. plt.figure(1)
  125. plt.gray()
  126. plt.imshow(np.squeeze(images))
  127. plt.show()
  128. return
  129. def utest_phantom_output_h5():
  130. # Creates a virtual scanner phantom and save it as an .h5 file (per JEMRIS standard)
  131. phantom_info = {'fov': 0.256, 'N': 32, 'type': 'cylindrical', 'dim': 2, 'dir': 'z', 'loc': 0}
  132. create_and_save_phantom(phantom_info, out_folder=utest_path)
  133. return
  134. if __name__ == '__main__':
  135. # Run all "utests"
  136. #utest_coil2xml() # Converts B1 map into .h5 and .xml files for JEMRIS
  137. #utest_phantom_output_h5() # Makes a virtual scanner phantom and converts it into .h5 format for JEMRIS
  138. #utest_seq2xml() # Makes a pypulseq sequence and converts it into .xml and .h5 files for JEMRIS
  139. #utest_sim_jemris() # Calls JEMRIS on command line using pre-made files
  140. utest_pulseq_sim() # Calls pipeline (INPUT: seq + phantom info + FOV ; OUTPUT: complex image space & k-space, images)