reconsrtuctionApp.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import json
  2. import h5py
  3. import sys
  4. # sys.path.append("C:/Users/iuliia/recoUI/serv")
  5. from traj import *
  6. from reco import *
  7. from seqData import SequenceDataFrame
  8. from service import ReconstructionService
  9. class ReconstructionApp():
  10. def __init__(self, name, digit, shift):
  11. super().__init__()
  12. self.name = name # type seq (linear|non|epi|radial)
  13. # print("self.name", self.name)
  14. self.digit = digit # 2|3 d
  15. self.phase_shift = shift # bool
  16. def start_reconstruction(self, path_raw_data, path_np_data_json, path_order_json):
  17. try:
  18. service = ReconstructionService()
  19. nX, nY, nZ, d_scans, nContr, spoil, ETL, N_TE, phi_wing, N_wings = self.read_consts(path_np_data_json)
  20. # print(nX, nY, nZ, d_scans, nContr, spoil)
  21. service.path_raw_data = path_raw_data
  22. raw_data = service.read_mat_file()
  23. sequence_data = SequenceDataFrame()
  24. sequence_data.read_raw_data(raw_data)
  25. sequence_data.read_dots(int(nX))
  26. sequence_name = self.name # Получаем введенное имя последовательности
  27. # print(sequence_name, path_order_json)
  28. if sequence_name == 'nonlinear_decart(tse)' or sequence_name == 'radial_propeller':
  29. print(path_order_json)
  30. k_space_order = self.read_order_from_json(path_order_json)
  31. print(f"Загружен порядок k-space: {k_space_order}")
  32. self.k_space_order = k_space_order
  33. arr_mat = np.array(sequence_data.mat_df['dot'])
  34. # print("len_arr_raw_data: ", len(arr_mat))
  35. # print(sequence_name)
  36. digit = self.digit # Получаем 2d или 3d
  37. # print("digit:", self.digit)
  38. if not path_raw_data or not path_np_data_json:
  39. raise ValueError("Пожалуйста, выберите файлы и введите данные перед началом реконструкции.")
  40. else:
  41. json_data = path_np_data_json
  42. if digit == '2d':
  43. # print("@ @ 2d @ @")
  44. self.reconstruct_2d(sequence_name, arr_mat, json_data)
  45. elif digit == '3d':
  46. # print("@ @ 3d @ @")
  47. self.reconstruct_3d(sequence_name, arr_mat, json_data)
  48. except ValueError as ve:
  49. raise ValueError(str(ve))
  50. except NotImplementedError as nie:
  51. raise NotImplementedError(str(nie))
  52. except Exception as e:
  53. raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")
  54. def read_order_from_json(self, path_order_json):
  55. with open(path_order_json, 'r') as f:
  56. data = json.load(f)
  57. # Извлечение массива из ключа "k_space_order"
  58. k_space_order = data.get("k_space_order", [])
  59. return k_space_order
  60. def read_mat_file(self, path):
  61. with h5py.File(path, 'r') as f:
  62. key = list(f.keys())[0]
  63. with h5py.File(path, 'r') as f:
  64. data = f[key][:]
  65. data = np.array(data)
  66. return data
  67. def get_value_or_default(self, json_obj, key, default_value=1):
  68. return int(json_obj.get(key, default_value))
  69. def read_consts(self, path):
  70. with open(path, 'r') as file:
  71. data = json.load(file)
  72. # d_scans = int(data['D_scans'])
  73. d_scans = self.get_value_or_default(data, "D_scans", 1)
  74. Np = int(data['Np'])
  75. Nf = int(data['Nf'])
  76. sl_nb = int(data['sl_nb'])
  77. # nContrast = int(data['contrasts'])
  78. nContrast = self.get_value_or_default(data, "contrasts", 1)
  79. # spoil = float(data['RF_spoil'])
  80. spoil = self.get_value_or_default(data, "RF_spoil", 0)
  81. ETL = self.get_value_or_default(data, 'ETL', 0) # TSE
  82. N_TE = self.get_value_or_default(data, 'N_TE', 0) # TSE
  83. phi_wing = self.get_value_or_default(data, "phi_wing", 0) # radial
  84. N_wings = self.get_value_or_default(data, "N_wings", 0) # radial
  85. return Np, Nf, sl_nb, d_scans, nContrast, spoil, ETL, N_TE, phi_wing, N_wings
  86. def read_consts_3d(self, path):
  87. with open(path, 'r') as file:
  88. data = json.load(file)
  89. d_scans = self.get_value_or_default(data, "D_scans", 1)
  90. # d_scans = int(data['D_scans'])
  91. Np = int(data['Np'])
  92. Nf = int(data['Nf'])
  93. # sl_nb = self.get_value_or_default(data, "Nss", 1)
  94. sl_nb = int(data['Nss'])
  95. if sl_nb % 2 == 1:
  96. sl_nb -= 1
  97. # nContrast = int(data['contrasts'])
  98. nContrast = self.get_value_or_default(data, "contrasts", 1)
  99. # spoil = float(data['RF_spoil'])
  100. spoil = self.get_value_or_default(data, "RF_spoil", 0)
  101. return Np, Nf, sl_nb, d_scans, nContrast, spoil
  102. def reconstruct_2d(self, sequence_name, mat_data, json_data):
  103. try:
  104. nX, nY, nZ, d_scans, nContr, spoil, ETL, N_TE, phi_wing, N_wings = self.read_consts(json_data)
  105. # print(spoil)
  106. if self.phase_shift == False:
  107. spoil = 0
  108. '''
  109. all_data = k_space[x, y, z, contrast, coil] - собрано в правильном порядке
  110. '''
  111. if sequence_name == "linear_decart":
  112. # print("ll")
  113. all_data = gather_data_along_trajectory(mat_data, nX, nY, nZ, nContr)
  114. # print("all_data")
  115. save_ffft(all_data, spoil)
  116. elif sequence_name == "nonlinear_decart(tse)":
  117. all_data = gather_data_along_trajectory_nonlinear(mat_data, self.k_space_order, nX, nY, nZ, nContr)
  118. save_ffft(all_data, spoil)
  119. elif sequence_name == "linear_epi":
  120. all_data = gather_data_along_trajectory_linear_epi(mat_data, nX, nY, nZ, nContr)
  121. save_ffft(all_data, spoil)
  122. elif sequence_name == "radial_propeller":
  123. print("RADIAL")
  124. all_data = gather_data_along_trajectory_radial(mat_data, self.k_space_order, nX, nY, nZ, phi_wing,
  125. N_wings)
  126. save_ffft(all_data, spoil)
  127. else:
  128. raise NotImplementedError("Для данного типа ИП еще не добавлена функция.")
  129. # QMessageBox.critical(self, "Ошибка: для данного типа ИП еще не добавлена функция")
  130. except ValueError as ve:
  131. raise ValueError(str(ve))
  132. except NotImplementedError as nie:
  133. raise NotImplementedError(str(nie))
  134. except Exception as e:
  135. raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")
  136. def reconstruct_3d(self, sequence_name, mat_data, json_data):
  137. try:
  138. nX, nY, nZ, d_scans, nContr, spoil = self.read_consts_3d(json_data) # Nss = nSlice
  139. if self.phase_shift == False:
  140. spoil = 0
  141. '''
  142. all_data = [x, y, z, contrast, coil]
  143. '''
  144. if sequence_name == "linear_decart":
  145. all_data = gather_data_along_trajectory(mat_data, nX, nY, nZ, nContr)
  146. save_ffft_3d(all_data, spoil)
  147. elif sequence_name == "nonlinear_decart(tse)":
  148. all_data = gather_data_along_trajectory_nonlinear(mat_data, self.k_space_order, nX, nY, nZ, nContr)
  149. save_ffft_3d(all_data, spoil)
  150. else:
  151. raise NotImplementedError(
  152. "Для данного типа ИП еще не добавлена функция.") # TODO уже можно добавлять функцию, так как она работает
  153. # QMessageBox.critical(self, "Ошибка: для данного типа ИП еще не добавлена функция")
  154. except ValueError as ve:
  155. raise ValueError(str(ve))
  156. except NotImplementedError as nie:
  157. raise NotImplementedError(str(nie))
  158. except Exception as e:
  159. raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")