| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- import json
- import h5py
- import sys
- # sys.path.append("C:/Users/iuliia/recoUI/serv")
- from traj import *
- from reco import *
- from seqData import SequenceDataFrame
- from service import ReconstructionService
- class ReconstructionApp():
- def __init__(self, name, digit, shift):
- super().__init__()
- self.name = name # type seq (linear|non|epi|radial)
- # print("self.name", self.name)
- self.digit = digit # 2|3 d
- self.phase_shift = shift # bool
- def start_reconstruction(self, path_raw_data, path_np_data_json, path_order_json):
- try:
- service = ReconstructionService()
- nX, nY, nZ, d_scans, nContr, spoil, ETL, N_TE, phi_wing, N_wings = self.read_consts(path_np_data_json)
- # print(nX, nY, nZ, d_scans, nContr, spoil)
- service.path_raw_data = path_raw_data
- raw_data = service.read_mat_file()
- sequence_data = SequenceDataFrame()
- sequence_data.read_raw_data(raw_data)
- sequence_data.read_dots(int(nX))
- sequence_name = self.name # Получаем введенное имя последовательности
- # print(sequence_name, path_order_json)
- if sequence_name == 'nonlinear_decart(tse)' or sequence_name == 'radial_propeller':
- print(path_order_json)
- k_space_order = self.read_order_from_json(path_order_json)
- print(f"Загружен порядок k-space: {k_space_order}")
- self.k_space_order = k_space_order
- arr_mat = np.array(sequence_data.mat_df['dot'])
- # print("len_arr_raw_data: ", len(arr_mat))
- # print(sequence_name)
- digit = self.digit # Получаем 2d или 3d
- # print("digit:", self.digit)
- if not path_raw_data or not path_np_data_json:
- raise ValueError("Пожалуйста, выберите файлы и введите данные перед началом реконструкции.")
- else:
- json_data = path_np_data_json
- if digit == '2d':
- # print("@ @ 2d @ @")
- self.reconstruct_2d(sequence_name, arr_mat, json_data)
- elif digit == '3d':
- # print("@ @ 3d @ @")
- self.reconstruct_3d(sequence_name, arr_mat, json_data)
- except ValueError as ve:
- raise ValueError(str(ve))
- except NotImplementedError as nie:
- raise NotImplementedError(str(nie))
- except Exception as e:
- raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")
- def read_order_from_json(self, path_order_json):
- with open(path_order_json, 'r') as f:
- data = json.load(f)
- # Извлечение массива из ключа "k_space_order"
- k_space_order = data.get("k_space_order", [])
- return k_space_order
- def read_mat_file(self, path):
- with h5py.File(path, 'r') as f:
- key = list(f.keys())[0]
- with h5py.File(path, 'r') as f:
- data = f[key][:]
- data = np.array(data)
- return data
- def get_value_or_default(self, json_obj, key, default_value=1):
- return int(json_obj.get(key, default_value))
- def read_consts(self, path):
- with open(path, 'r') as file:
- data = json.load(file)
- # d_scans = int(data['D_scans'])
- d_scans = self.get_value_or_default(data, "D_scans", 1)
- Np = int(data['Np'])
- Nf = int(data['Nf'])
- sl_nb = int(data['sl_nb'])
- # nContrast = int(data['contrasts'])
- nContrast = self.get_value_or_default(data, "contrasts", 1)
- # spoil = float(data['RF_spoil'])
- spoil = self.get_value_or_default(data, "RF_spoil", 0)
- ETL = self.get_value_or_default(data, 'ETL', 0) # TSE
- N_TE = self.get_value_or_default(data, 'N_TE', 0) # TSE
- phi_wing = self.get_value_or_default(data, "phi_wing", 0) # radial
- N_wings = self.get_value_or_default(data, "N_wings", 0) # radial
- return Np, Nf, sl_nb, d_scans, nContrast, spoil, ETL, N_TE, phi_wing, N_wings
- def read_consts_3d(self, path):
- with open(path, 'r') as file:
- data = json.load(file)
- d_scans = self.get_value_or_default(data, "D_scans", 1)
- # d_scans = int(data['D_scans'])
- Np = int(data['Np'])
- Nf = int(data['Nf'])
- # sl_nb = self.get_value_or_default(data, "Nss", 1)
- sl_nb = int(data['Nss'])
- if sl_nb % 2 == 1:
- sl_nb -= 1
- # nContrast = int(data['contrasts'])
- nContrast = self.get_value_or_default(data, "contrasts", 1)
- # spoil = float(data['RF_spoil'])
- spoil = self.get_value_or_default(data, "RF_spoil", 0)
- return Np, Nf, sl_nb, d_scans, nContrast, spoil
- def reconstruct_2d(self, sequence_name, mat_data, json_data):
- try:
- nX, nY, nZ, d_scans, nContr, spoil, ETL, N_TE, phi_wing, N_wings = self.read_consts(json_data)
- # print(spoil)
- if self.phase_shift == False:
- spoil = 0
- '''
- all_data = k_space[x, y, z, contrast, coil] - собрано в правильном порядке
- '''
- if sequence_name == "linear_decart":
- # print("ll")
- all_data = gather_data_along_trajectory(mat_data, nX, nY, nZ, nContr)
- # print("all_data")
- save_ffft(all_data, spoil)
- elif sequence_name == "nonlinear_decart(tse)":
- all_data = gather_data_along_trajectory_nonlinear(mat_data, self.k_space_order, nX, nY, nZ, nContr)
- save_ffft(all_data, spoil)
- elif sequence_name == "linear_epi":
- all_data = gather_data_along_trajectory_linear_epi(mat_data, nX, nY, nZ, nContr)
- save_ffft(all_data, spoil)
- elif sequence_name == "radial_propeller":
- print("RADIAL")
- all_data = gather_data_along_trajectory_radial(mat_data, self.k_space_order, nX, nY, nZ, phi_wing,
- N_wings)
- save_ffft(all_data, spoil)
- else:
- raise NotImplementedError("Для данного типа ИП еще не добавлена функция.")
- # QMessageBox.critical(self, "Ошибка: для данного типа ИП еще не добавлена функция")
- except ValueError as ve:
- raise ValueError(str(ve))
- except NotImplementedError as nie:
- raise NotImplementedError(str(nie))
- except Exception as e:
- raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")
- def reconstruct_3d(self, sequence_name, mat_data, json_data):
- try:
- nX, nY, nZ, d_scans, nContr, spoil = self.read_consts_3d(json_data) # Nss = nSlice
- if self.phase_shift == False:
- spoil = 0
- '''
- all_data = [x, y, z, contrast, coil]
- '''
- if sequence_name == "linear_decart":
- all_data = gather_data_along_trajectory(mat_data, nX, nY, nZ, nContr)
- save_ffft_3d(all_data, spoil)
- elif sequence_name == "nonlinear_decart(tse)":
- all_data = gather_data_along_trajectory_nonlinear(mat_data, self.k_space_order, nX, nY, nZ, nContr)
- save_ffft_3d(all_data, spoil)
- else:
- raise NotImplementedError(
- "Для данного типа ИП еще не добавлена функция.") # TODO уже можно добавлять функцию, так как она работает
- # QMessageBox.critical(self, "Ошибка: для данного типа ИП еще не добавлена функция")
- except ValueError as ve:
- raise ValueError(str(ve))
- except NotImplementedError as nie:
- raise NotImplementedError(str(nie))
- except Exception as e:
- raise RuntimeError(f"Произошла ошибка в процессе реконструкции: {e}")
|