| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- # Demonstrates usage of py2jemris functionalities
- # May be used for quick testing
- # Gehua Tong
- # May 18, 2020
- from coil2xml import coil2xml
- from seq2xml import seq2xml
- from sim_jemris import sim_jemris
- from pulseq_jemris_simulator import simulate_pulseq_jemris, create_and_save_phantom
- from recon_jemris import recon_jemris
- import phantom as pht
- from pulseq_library import make_pulseq_irse, make_pulseq_se_oblique
- import numpy as np
- import matplotlib.pyplot as plt
- from pypulseq.Sequence.sequence import Sequence
- from scipy.io import loadmat, savemat
- #from virtualscanner.utils.constants import SERVER_SIM_BLOCH_PY2JEMRIS_PATH
- import os
- import h5py
- utest_path = 'sim/utest_outputs'
- sim_path = 'sim'
- def utest_coil2xml():
- # Example on using coil2xml
- # Generate coil using B1 maps and plot
- # 4 channels with different B1 maps
- b1 = np.ones((32,32))
- XY = np.meshgrid(np.linspace(0,1,32), np.linspace(0,1,32))
- X = XY[0]
- Y = XY[1]
- # Define coil sensitivity maps (complex arrays, in general)
- b1_ch1 = np.sqrt(X**2 + Y**2)
- b1_ch2 = np.rot90(b1_ch1)
- b1_ch3 = np.rot90(b1_ch2)
- b1_ch4 = np.rot90(b1_ch3)
- coil2xml(b1maps=[b1_ch1, b1_ch2, b1_ch3, b1_ch4], fov=200, name='test_coil', out_folder=utest_path)
- # Generate sensmaps.h5 using JEMRIS command
- os.chdir(utest_path)
- print(os.system('dir'))
- out = os.system('jemris test_coil.xml')
- os.chdir('../..')
- print(out)
- # Load sensmaps.h5 and plot coil
- a = h5py.File(utest_path + '/sensmaps.h5', 'r')
- maps_magnitude = a['maps/magnitude']
- maps_phase = a['maps/phase']
- plt.figure(1)
- plt.title('Coil sensitivity maps')
- for u in range(4):
- plt.subplot(2,4,u+1)
- plt.gray()
- plt.imshow(maps_magnitude[f'0{u}'])
- plt.title(f'Magnitude Ch #{u+1}')
- plt.subplot(2,4,u+5)
- plt.gray()
- plt.imshow(maps_phase[f'0{u}'])
- plt.title(f'Phase Ch #{u+1}')
- plt.show()
- return
- def utest_seq2xml():
- # Make a sequence
- seq = make_pulseq_irse(fov=0.256, n=16, thk=0.01, fa=15, tr=150, te=30, ti=10,
- enc='xyz', slice_locs=None, write=False)
- # Convert to .xml format
- seq2xml(seq, seq_name='irse16_pulseq', out_folder=utest_path)
- # Use JEMRIS to generate sequence diagrams from .xml sequence
- os.chdir(utest_path)
- print(os.system('dir'))
- out = os.system(f'jemris -x -d id=1 -f irse16_pulseq irse16_pulseq.xml')
- print(out)
- os.chdir('../..')
- # Read sequence diagram and plot
- data = h5py.File(utest_path + '/irse16_pulseq.h5','r')
- diag = data['seqdiag']
- t = diag['T']
- gx = diag['GX']
- gy = diag['GY']
- gz = diag['GZ']
- rxp = diag['RXP']
- txm = diag['TXM']
- txp = diag['TXP']
- ylist = [txm, txp, gx, gy, gz, rxp]
- title_list = ['RF Tx magnitude', 'RF Tx phase', 'Gx', 'Gy', 'Gz', 'RF Rx phase']
- styles = ['r-', 'g-', 'k-', 'k-', 'k-', 'bx']
- plt.figure(1)
- for v in range(6):
- plt.subplot(6,1,v+1)
- plt.plot(t, ylist[v], styles[v])
- plt.title(title_list[v])
- plt.xlabel('Time')
- plt.show()
- return
- def utest_sim_jemris():
- # Copy helping files in
- os.chdir(sim_path)
- out = os.system('copy uniform.xml utest_outputs')
- print(out)
- os.chdir('..')
- utest_phantom_output_h5()
- list_sim_orig = {'seq_xml': 'gre32.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
- 'rx_xml': 'uniform.xml'}
- out = sim_jemris(list_sim_orig, working_folder = utest_path)
- os.chdir(utest_path)
- savemat('data32_orig.mat',out)
- print('Data is saved in py2jemris/sim/utest_outputs/data32_orig.mat')
- os.chdir('../..')
- return
- def utest_pulseq_sim():
- # TODO this !
- # Demonstrates simulation pipeline using pulseq inputs
- # Define the same phantom
- phantom_info = {'fov': 0.256, 'N': 15, 'type': 'cylindrical', 'dim': 2, 'dir': 'z', 'loc': 0}
- sps = 'sim/utest_outputs/se_fov256mm_Nf15_Np15_TE50ms_TR200ms_FA90deg.seq'
- sim_name = 'utest_outputs'
- # Make sequence
- os.chdir(utest_path)
- make_pulseq_se_oblique(fov=0.256,n=15, thk=0.005, tr=0.2, te=0.05, fa=90,
- enc='xyz', slice_locs=[0], write=True)
- os.chdir('../..')
- simulate_pulseq_jemris(seq_path=sps, phantom_info=phantom_info, sim_name=sim_name,
- coil_fov=0.256)
- kk, im, images = recon_jemris(file='sim/' + sim_name + '/signals.h5', dims=[15, 15])
- savemat('sim/' + sim_name + '/utest_pulseq_sim_output.mat', {'images': images, 'kspace': kk, 'imspace': im})
- print('Simulation result is in py2jemris/sim/utest_outputs/utest_pulseq_sim_output.mat')
- # Plot results
- plt.figure(1)
- plt.gray()
- plt.imshow(np.squeeze(images))
- plt.show()
- return
- def utest_phantom_output_h5():
- # Creates a virtual scanner phantom and save it as an .h5 file (per JEMRIS standard)
- phantom_info = {'fov': 0.256, 'N': 32, 'type': 'cylindrical', 'dim': 2, 'dir': 'z', 'loc': 0}
- create_and_save_phantom(phantom_info, out_folder=utest_path)
- return
- if __name__ == '__main__':
- # Run all "utests"
- #utest_coil2xml() # Converts B1 map into .h5 and .xml files for JEMRIS
- #utest_phantom_output_h5() # Makes a virtual scanner phantom and converts it into .h5 format for JEMRIS
- #utest_seq2xml() # Makes a pypulseq sequence and converts it into .xml and .h5 files for JEMRIS
- #utest_sim_jemris() # Calls JEMRIS on command line using pre-made files
- utest_pulseq_sim() # Calls pipeline (INPUT: seq + phantom info + FOV ; OUTPUT: complex image space & k-space, images)
|