sim_jemris.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # Caller script for executing a simulation with JEMRIS (prior installation required)
  2. # Gehua Tong, April 2020
  3. from seq2xml import seq2xml
  4. from sim2xml import sim2xml
  5. from recon_jemris import read_jemris_output
  6. from coil2xml import coil2xml
  7. import subprocess
  8. import tkinter as tk
  9. from tkinter.filedialog import askopenfilename
  10. #from virtualscanner.utils import constants
  11. import h5py
  12. import os
  13. # Paths
  14. #PY2JEMRIS_SIM_PATH = constants.SERVER_SIM_BLOCH_PY2JEMRIS_PATH / 'sim'
  15. from scipy.io import savemat
  16. import time
  17. def ask_for_sim_files():
  18. """Helper function for sim_jemris;
  19. Asks the user for simulation files through file system selection
  20. Returns
  21. -------
  22. files_list : list
  23. A dictionary indicating paths to the files required to construct simu.xml
  24. """
  25. files_list = {}
  26. names = ['seq_xml', 'pht_h5', 'tx_xml', 'rx_xml']
  27. prompt_list = ['sequence file (.xml)', 'phantom file (.h5)','Tx file (.xml)', 'Rx file (.xml)']
  28. for u in range(len(prompt_list)-1):
  29. print(f"Pick your {prompt_list[u]}.")
  30. tk.Tk().withdraw()
  31. filename = askopenfilename()
  32. files_list[names[u]] = filename
  33. return files_list
  34. def run_jemris(working_folder = None):
  35. """Runs JEMRIS simulation on system command line
  36. Assumes that the working folder contains all required files and
  37. that JEMRIS is installed and added to PATH on the operating system
  38. Simply, the command "jemris simu.xml" is run and the path to signals.h5 is returned
  39. Inputs
  40. ------
  41. working_folder : str
  42. Working folder where the simulation is performed
  43. Returns
  44. -------
  45. signal path : str or pathlib Path object
  46. Path to JEMRIS simulation output data file (this file is always called signals.h5)
  47. """
  48. print("Simulating using JEMRIS ...")
  49. # Always run from the py2jemris/sim directory
  50. if working_folder is None:
  51. working_folder = 'sim'
  52. original_wd = os.getcwd()
  53. os.chdir(working_folder)
  54. print(os.system('dir'))
  55. out = os.system('jemris simu.xml')
  56. print(out)
  57. os.chdir(original_wd)
  58. # Find signal.h5
  59. if isinstance(working_folder, str):
  60. signal_path = working_folder + '/signals.h5'
  61. else:
  62. signal_path = working_folder / 'signals.h5' # Return the absolute signal path here
  63. return signal_path
  64. def sim_jemris(list_sim_files=None, working_folder=None):
  65. """Runs a JEMRIS MR simulation using given .xml and .h5 files
  66. based on custom file inputs. Returns complex signal data.
  67. Inputs
  68. ------
  69. list_sim_files : dict
  70. Dictionary of paths to relevant simulation files
  71. working_folder : str
  72. Working folder where the simulation is performed
  73. Returns
  74. -------
  75. output : dict
  76. Complex signal data with 3 fields
  77. 'Mxy' : Complex representation of transverse magnetization
  78. 'M_vec' : 3D representation of magnetization (Mx, My, Mz)
  79. 'T' : Timing of readout points
  80. """
  81. # Use interactive option if there is no dictionary input
  82. all_files_exist = False
  83. while not all_files_exist:
  84. try:
  85. seq_xml = list_sim_files['seq_xml']
  86. pht_h5 = list_sim_files['pht_h5']
  87. tx_xml = list_sim_files['tx_xml']
  88. rx_xml = list_sim_files['rx_xml']
  89. all_files_exist = True
  90. except:
  91. list_sim_files = ask_for_sim_files()
  92. # Extract sequence and phantom name
  93. seq_name = seq_xml[seq_xml.rfind('/')+1:seq_xml.rfind('.xml')]
  94. pht_name = pht_h5[pht_h5.rfind('/')+1:pht_h5.rfind('.h5')]
  95. # Make simu.xml
  96. sim2xml(sim_name='simu', seq=seq_xml, phantom=pht_h5, Tx=tx_xml, Rx=rx_xml,
  97. seq_name=seq_name, sample_name=pht_name, out_folder_name=str(working_folder))
  98. # Rum JEMRIS on command line
  99. signal_path = run_jemris(working_folder)
  100. print(signal_path)
  101. file_discovered = False
  102. print((os.path.abspath(signal_path)))
  103. while not file_discovered:
  104. file_discovered = os.path.exists(os.path.abspath(signal_path))
  105. print(file_discovered)
  106. time.sleep(2)
  107. Mxy_out, M_vec_out, times_out = read_jemris_output(signal_path)
  108. output = {'Mxy': Mxy_out, "M_vec": M_vec_out, 'T': times_out}
  109. return output
  110. from recon_jemris import *
  111. if __name__ == '__main__':
  112. # JEMRIS seq.h5
  113. #T = h5read('seq.h5','/seqdiag/T'); % temporal sampling points
  114. #RXP = h5read('seq.h5','/seqdiag/RXP'); % RF Receiver phase; unit: radiants; if negative, the TPOI was not an ADC
  115. #TXM = h5read('seq.h5','/seqdiag/TXM'); % RF Transmitter magnitude
  116. #TXP = h5read('seq.h5','/seqdiag/TXP'); % RF Transmitter phase; unit: radiants
  117. #GX = h5read('seq.h5','/seqdiag/GX'); % physical X-Gradient
  118. #GY = h5read('seq.h5','/seqdiag/GY'); % physical Y-Gradient
  119. #GZ = h5read('seq.h5','/seqdiag/GZ'); % physical Z-Gradient
  120. #['seq_xml', 'pht_h5', 'tx_xml', 'rx_xml', 'working_path'
  121. #output = sim_jemris()
  122. # print(output)
  123. # sim2xml(seq="gre.xml", phantom="sample.h5", Tx="uniform.xml", Rx="uniform.xml",
  124. # seq_name="Sequence", sample_name="Sample", out_folder_name="sim")
  125. # "Sim test" April 17 for seq2xml
  126. # First, sim using original gre
  127. list_sim_orig = {'seq_xml': 'gre32.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
  128. 'rx_xml': 'uniform.xml'}
  129. out = sim_jemris(list_sim_orig, working_folder = 'sim/test0504')
  130. savemat('sim/test0504/data32_orig.mat',out)
  131. # Second, use twice converted (.xml output of seq2xml)
  132. list_sim_twice = {'seq_xml': 'gre32_twice.xml', 'pht_h5': 'cylindrical.h5', 'tx_xml':'uniform.xml',
  133. 'rx_xml': 'uniform.xml'}
  134. # out = sim_jemris(list_sim_twice, working_folder = 'sim/test0504')
  135. # savemat('sim/test0504/data32_twice.mat',out)