|
@@ -0,0 +1,533 @@
|
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
|
+"""
|
|
|
|
+Created on Mon Jul 3 17:53:21 2023
|
|
|
|
+
|
|
|
|
+@author: zilya
|
|
|
|
+"""
|
|
|
|
+
|
|
|
|
+import tkinter as tk
|
|
|
|
+from math import ceil, floor
|
|
|
|
+import numpy as np
|
|
|
|
+from types import SimpleNamespace
|
|
|
|
+from datetime import datetime
|
|
|
|
+import json
|
|
|
|
+import pickle
|
|
|
|
+
|
|
|
|
+def set_limits():
|
|
|
|
+
|
|
|
|
+ # Задание общих аппаратных характкристик
|
|
|
|
+ gamma = 42.576e6 # Hz/T Гиромагнитное отношение водорода
|
|
|
|
+ G_amp_max_mT_m = 37.8 # mT/m. Максимальный градиент
|
|
|
|
+ G_amp_max = G_amp_max_mT_m*1e-3*gamma # Hz/m. Максимальный градиент
|
|
|
|
+ G_slew_max_T_m_s = 121 # T/m/s. Максимальная скорость нарастания
|
|
|
|
+ G_slew_max = G_slew_max_T_m_s*gamma # Hz/m/s. Максимальная скорость нарастания
|
|
|
|
+ rf_raster_time = 1e-6 # s. Растр РЧ импульса
|
|
|
|
+ grad_raster_time = 10e-6 # s. Растр градиентов
|
|
|
|
+ tau_max = G_amp_max/G_slew_max # s. Максимальное время нарастания градиента с учетом макс скорости нарастания
|
|
|
|
+ tau_max = np.ceil(tau_max/ grad_raster_time)*grad_raster_time
|
|
|
|
+ tau = 250e-6 # s. Фиксированное время нарастания градиентов
|
|
|
|
+
|
|
|
|
+ # Чтение заданных в интерфэйс значений
|
|
|
|
+ sl_nb = int(textBox1.get())
|
|
|
|
+ sl_thkn = float(textBox2.get())
|
|
|
|
+ sl_gap = float(textBox3.get())
|
|
|
|
+ FoV_f = float(textBox4.get())
|
|
|
|
+ FoV_ph_image = float(textBox5.get())
|
|
|
|
+ Nf = int(textBox6.get())
|
|
|
|
+ Np_image = int(textBox7.get())
|
|
|
|
+ BW_pixel = float(textBox8.get())
|
|
|
|
+ N_TE = int(textBox9.get())
|
|
|
|
+ #TE = float(textBox9.get())
|
|
|
|
+ TR = float(textBox10.get())
|
|
|
|
+ alpha = float(textBox11.get())
|
|
|
|
+ beta = float(textBox12.get())
|
|
|
|
+ Conct = int(textBox13.get())
|
|
|
|
+ ETL = int(textBox14.get())
|
|
|
|
+ Average = int(textBox15.get())
|
|
|
|
+ ph_over = float(textBox16.get())
|
|
|
|
+
|
|
|
|
+ Np = Np_image*(1+ph_over/100)
|
|
|
|
+ Np = round(Np)
|
|
|
|
+ ph_over = (Np/Np_image-1)*100
|
|
|
|
+ FoV_ph = FoV_ph_image*(1+ph_over/100)
|
|
|
|
+
|
|
|
|
+ TR = np.ceil(TR/ grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ # --- Параметры РЧ импульса -----
|
|
|
|
+ rf_ringdown_time=20e-6
|
|
|
|
+ rf_dead_time=100e-6
|
|
|
|
+ adc_dead_time=10e-6
|
|
|
|
+
|
|
|
|
+ # - Библиотека time bandwidth products
|
|
|
|
+ t_BW_product_ex1 = 3.8
|
|
|
|
+ t_BW_product_ref1 = 4.2
|
|
|
|
+ t_BW_product_ex2 = 3.55
|
|
|
|
+ t_BW_product_ref2 = 3.55
|
|
|
|
+
|
|
|
|
+ # s. Библиотека длительностей импульсов
|
|
|
|
+ # Длительности кратны растру градиента 10 мкс
|
|
|
|
+ t_ex1 = 2.05e-3
|
|
|
|
+ t_ref1 = 2.56e-3
|
|
|
|
+ t_ex2 = 3.10e-3
|
|
|
|
+ t_ref2 = 3.88e-3
|
|
|
|
+
|
|
|
|
+ apodization = 0.27
|
|
|
|
+
|
|
|
|
+ # ----- Подбор импульсов на основе выбранной толщины среза
|
|
|
|
+ if sl_thkn > t_BW_product_ex1/(t_ex1*G_amp_max):
|
|
|
|
+ t_BW_product_ex = t_BW_product_ex1
|
|
|
|
+ t_BW_product_ref = t_BW_product_ref1
|
|
|
|
+ else:
|
|
|
|
+ t_BW_product_ex = t_BW_product_ex2
|
|
|
|
+ t_BW_product_ref = t_BW_product_ref2
|
|
|
|
+
|
|
|
|
+ if sl_thkn > t_BW_product_ex2/(t_ex1*G_amp_max):
|
|
|
|
+ t_ex = t_ex1
|
|
|
|
+ t_ref = t_ref1
|
|
|
|
+ else:
|
|
|
|
+ t_ex = t_ex2
|
|
|
|
+ t_ref = t_ref2
|
|
|
|
+
|
|
|
|
+ BW_ex_pulse = t_BW_product_ex/t_ex
|
|
|
|
+
|
|
|
|
+ # ---- Вычисление основных площадей и длительностей ------
|
|
|
|
+ A_ex = BW_ex_pulse*(t_ex+tau)/sl_thkn
|
|
|
|
+ A_read = Nf/FoV_f
|
|
|
|
+ A_ph = Np/2/FoV_ph
|
|
|
|
+ A_reph = 0.25*A_ex
|
|
|
|
+ A_pre = 1.5*A_read
|
|
|
|
+ A_crs = 0.75*A_ex
|
|
|
|
+ A_crr = A_read
|
|
|
|
+ A_sps = 4*A_ex
|
|
|
|
+
|
|
|
|
+ t_reph_min = A_reph/G_amp_max + tau
|
|
|
|
+ t_pre_min = A_pre/G_amp_max + tau
|
|
|
|
+ t_pre_min = max(t_reph_min,t_pre_min)
|
|
|
|
+ t_pre_min = np.ceil(t_pre_min / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ t_crs_min = A_crs/G_amp_max + tau
|
|
|
|
+ t_crr_min = A_crr/G_amp_max + tau
|
|
|
|
+ t_ph_min = A_ph/G_amp_max + tau
|
|
|
|
+ t_cr_min = max(t_crs_min,t_crr_min,t_ph_min)
|
|
|
|
+ t_cr_min = np.ceil(t_cr_min / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ t_read = 1/BW_pixel
|
|
|
|
+ t_read = np.ceil(t_read / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ t_sps = A_sps/G_amp_max + tau
|
|
|
|
+ t_sps = np.ceil(t_sps / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ ES_1 = t_ref + t_read + 2*t_cr_min + 4*tau
|
|
|
|
+ ES_2 = t_ref + t_ex + 2*t_cr_min + 2*t_pre_min + 4*tau
|
|
|
|
+ ES = max(ES_1,ES_2)
|
|
|
|
+ ES = np.ceil(ES/ grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ t_cr = 0.5*(ES-t_ref-t_read) - 2*tau
|
|
|
|
+ t_cr = np.ceil(t_cr / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ t_pre = 0.5*(ES-t_ref-t_ex) - 2*tau
|
|
|
|
+ t_pre = np.ceil(t_pre / grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ TE = N_TE*ES
|
|
|
|
+
|
|
|
|
+ N_TE_min = 1
|
|
|
|
+ N_TE_max = ETL
|
|
|
|
+
|
|
|
|
+ TR_min = ES*(ETL) + t_ex/2 + t_read/2 + t_sps + 2*tau
|
|
|
|
+ TR_max = 10
|
|
|
|
+ TR_min = np.ceil(TR_min/ grad_raster_time)*grad_raster_time
|
|
|
|
+
|
|
|
|
+ delay_TR = TR-TR_min
|
|
|
|
+
|
|
|
|
+ Conc_min = ceil(sl_nb*TR_min/TR)
|
|
|
|
+ Conc_max = sl_nb
|
|
|
|
+ ETL_min = 1;
|
|
|
|
+ ETL_max1 = 16;
|
|
|
|
+ ETL_max2 = floor((TR-t_ex/2-t_read/2-t_sps-2*tau)/ES)
|
|
|
|
+ ETL_max = min(ETL_max1,ETL_max2)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Nf_min = 1
|
|
|
|
+ #Nf_max1 = FoV_f*G_amp_max*(t_cr-tau)
|
|
|
|
+ Nf_max = min(FoV_f*G_amp_max*(t_read),1600)
|
|
|
|
+ #Nf_max = min(Nf_max1,Nf_max2)
|
|
|
|
+ Np_min = 1
|
|
|
|
+ Np_max1 = Nf
|
|
|
|
+ Np_max2 = 2*FoV_ph*G_amp_max*(t_cr-tau)
|
|
|
|
+ Np_max = min(Np_max1,Np_max2)
|
|
|
|
+
|
|
|
|
+ FoV_min = 25e-3
|
|
|
|
+ FoV_f_max = 450e-3
|
|
|
|
+ FoV_f_min = Nf/(G_amp_max*t_read)
|
|
|
|
+ #FoV_f_min2 = Nf/(G_amp_max*(t_cr-tau))
|
|
|
|
+ FoV_f_min = max(FoV_f_min,FoV_min)
|
|
|
|
+ FoV_p_min = FoV_f_min
|
|
|
|
+ FoV_p_max = FoV_f
|
|
|
|
+
|
|
|
|
+ Np_image_min = Np_min
|
|
|
|
+ Np_image_max = min(Np_max, Nf_max/(1+ph_over/100))
|
|
|
|
+
|
|
|
|
+ FoV_p_image_min = FoV_p_min/(1+ph_over/100)
|
|
|
|
+ FoV_p_image_max = min(FoV_p_max,FoV_f_max/(1+ph_over/100))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ # BW_pixel_min = 1/(ES-t_ref-2*t_cr_min-4*tau)
|
|
|
|
+ # BW_pixel_min = max(ceil(BW_pixel_min), 40)
|
|
|
|
+ BW_pixel_min = 40
|
|
|
|
+ BW_pixel_max1 = 1780
|
|
|
|
+ BW_pixel_max2 = FoV_f*G_amp_max/Nf
|
|
|
|
+ BW_pixel_max = min (BW_pixel_max1,BW_pixel_max2)
|
|
|
|
+
|
|
|
|
+ sl_thkn_min1 = t_BW_product_ex2/(t_ex2*G_amp_max)
|
|
|
|
+ sl_thkn_min2 = t_BW_product_ex2*(t_ex2+tau)/((t_cr-tau)*G_amp_max)
|
|
|
|
+ sl_thkn_min = max(sl_thkn_min1,sl_thkn_min2)
|
|
|
|
+ sl_thkn_max = 20e-3
|
|
|
|
+ sl_gap_min, sl_gap_max = 0, 800
|
|
|
|
+
|
|
|
|
+ Average_min, Average_max = 1, 10
|
|
|
|
+
|
|
|
|
+ ph_over_min, ph_over_max = 0, 100
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ label2_1.configure(text = "min = " + str(ceil(sl_thkn_min*10000)/10000))
|
|
|
|
+ label2_2.configure(text = "max = " + str(sl_thkn_max))
|
|
|
|
+ label3_1.configure(text = "min = " + str(sl_gap_min))
|
|
|
|
+ label3_2.configure(text = "max = " + str(sl_gap_max))
|
|
|
|
+ label4_1.configure(text = "min = " + str(ceil(FoV_f_min*1000)/1000))
|
|
|
|
+ label4_2.configure(text = "max = " + str(FoV_f_max))
|
|
|
|
+ label5_1.configure(text = "min = " + str(ceil(FoV_p_image_min*1000)/1000))
|
|
|
|
+ label5_2.configure(text = "max = " + str(ceil(FoV_p_image_max*1000)/1000))
|
|
|
|
+ label6_1.configure(text = "min = " + str(Nf_min))
|
|
|
|
+ label6_2.configure(text = "max = " + str(ceil(Nf_max)))
|
|
|
|
+ label7_1.configure(text = "min = " + str(ceil(Np_image_min*1000)/1000))
|
|
|
|
+ label7_2.configure(text = "max = " + str(ceil(Np_image_max*1000)/1000))
|
|
|
|
+ label8_1.configure(text = "min = " + str(BW_pixel_min))
|
|
|
|
+ label8_2.configure(text = "max = " + str(ceil(BW_pixel_max*1000)/1000))
|
|
|
|
+ label9_1.configure(text = "min = " + str(N_TE_min))
|
|
|
|
+ label9_2.configure(text = "max = " + str(N_TE_max))
|
|
|
|
+ label10_1.configure(text = "min = " + str(ceil(TR_min*1000)/1000))
|
|
|
|
+ label10_2.configure(text = "max = " + str(TR_max))
|
|
|
|
+ label13_1.configure(text = "min = " + str(Conc_min))
|
|
|
|
+ label13_2.configure(text = "max = " + str(Conc_max))
|
|
|
|
+ label14_1.configure(text = "min = " + str(ETL_min))
|
|
|
|
+ label14_2.configure(text = "max = " + str(ETL_max))
|
|
|
|
+ label15_1.configure(text = "min = " + str(Average_min))
|
|
|
|
+ label15_2.configure(text = "max = " + str(Average_max))
|
|
|
|
+ label16_1.configure(text = "min = " + str(ph_over_min))
|
|
|
|
+ label16_2.configure(text = "max = " + str(ph_over_max))
|
|
|
|
+
|
|
|
|
+ global param
|
|
|
|
+ param = SimpleNamespace()
|
|
|
|
+ param.G_amp_max =G_amp_max_mT_m
|
|
|
|
+ param.G_slew_max = G_slew_max_T_m_s
|
|
|
|
+ param.gamma = gamma
|
|
|
|
+ param.grad_raster_time = grad_raster_time
|
|
|
|
+ param.rf_raster_time = rf_raster_time
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ param.t_BW_product_ex = t_BW_product_ex
|
|
|
|
+ param.t_BW_product_ref = t_BW_product_ref
|
|
|
|
+ param.t_ex = t_ex
|
|
|
|
+ param.t_ref = t_ref
|
|
|
|
+ param.rf_ringdown_time = rf_ringdown_time
|
|
|
|
+ param.rf_dead_time = rf_dead_time
|
|
|
|
+ param.adc_dead_time = adc_dead_time
|
|
|
|
+ param.aapodization = apodization
|
|
|
|
+
|
|
|
|
+ param.dG = tau
|
|
|
|
+ param.sl_nb = sl_nb
|
|
|
|
+ param.sl_thkn = sl_thkn
|
|
|
|
+ param.sl_gap = sl_gap
|
|
|
|
+ param.FoV_f = FoV_f
|
|
|
|
+ param.FoV_ph = FoV_ph
|
|
|
|
+ param.Nf = Nf
|
|
|
|
+ param.Np = Np
|
|
|
|
+ param.BW_pixel = BW_pixel
|
|
|
|
+ param.TE = TE
|
|
|
|
+ param.N_TE = N_TE #то на коком номере эхо истинное время эхо(в центр к-пр)
|
|
|
|
+ param.ES = ES
|
|
|
|
+ param.TR = TR
|
|
|
|
+ param.FA = alpha
|
|
|
|
+ param.RA = beta
|
|
|
|
+ param.conct = Conct
|
|
|
|
+ param.ETL = ETL
|
|
|
|
+ param.Average = Average
|
|
|
|
+ param.ph_over = ph_over
|
|
|
|
+
|
|
|
|
+ param.delay_TR = delay_TR
|
|
|
|
+
|
|
|
|
+ # tk.Label(win, text = 't = ' + str(round(time//60)) + ':'+ str(round(time%60)) + 'min').grid(row=13, column=2,sticky = "E")
|
|
|
|
+ tk.Label(win, text = 'ES = ' + str(ceil(ES*10000)/10000) + ' s').grid(row=19, column=2,sticky = "E")
|
|
|
|
+ tk.Label(win, text = 'TE = ' + str(ceil(TE*10000)/10000) + ' s').grid(row=20, column=2,sticky = "E")
|
|
|
|
+ #tk.Label(win, text = str(ETL_max2) + 's').grid(row=18, column=2,sticky = "E")
|
|
|
|
+
|
|
|
|
+def save_param():
|
|
|
|
+
|
|
|
|
+ output_filename = str(textBox17.get())
|
|
|
|
+ # output_filename = "TSE_T1" + datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
+ file = open(output_filename + ".json", 'w')
|
|
|
|
+ json.dump(param.__dict__, file, indent = 4)
|
|
|
|
+ file.close()
|
|
|
|
+
|
|
|
|
+ # output_filename = "TSE_" + datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
+ # file = open(output_filename, 'wb')
|
|
|
|
+ # pickle.dump(param, file)
|
|
|
|
+ # file.close()
|
|
|
|
+
|
|
|
|
+def read_json():
|
|
|
|
+ filepath = tk.filedialog.askopenfilename()
|
|
|
|
+ if filepath != "":
|
|
|
|
+ with open(filepath, "r") as file:
|
|
|
|
+ params_j = json.load(file)
|
|
|
|
+ textBox2.delete(0, 'end'); textBox2.insert(0, params_j['sl_thkn'])
|
|
|
|
+ textBox3.delete(0, 'end'); textBox3.insert(0, params_j['sl_gap'])
|
|
|
|
+ textBox4.delete(0, 'end'); textBox4.insert(0, params_j['FoV_f'])
|
|
|
|
+ textBox5.delete(0, 'end'); textBox5.insert(0, params_j['FoV_ph'])
|
|
|
|
+ textBox6.delete(0, 'end'); textBox6.insert(0, params_j['Nf'])
|
|
|
|
+ textBox7.delete(0, 'end'); textBox7.insert(0, params_j['Np'])
|
|
|
|
+ textBox8.delete(0, 'end'); textBox8.insert(0, params_j['N_TE'])
|
|
|
|
+ textBox9.delete(0, 'end'); textBox9.insert(0, params_j['N_TE'])
|
|
|
|
+ textBox10.delete(0, 'end'); textBox10.insert(0, params_j['TR'])
|
|
|
|
+ textBox11.delete(0, 'end'); textBox11.insert(0, params_j['FA'])
|
|
|
|
+ textBox12.delete(0, 'end'); textBox12.insert(0, params_j['RA'])
|
|
|
|
+ textBox13.delete(0, 'end'); textBox13.insert(0, params_j['conct'])
|
|
|
|
+ textBox14.delete(0, 'end'); textBox14.insert(0, params_j['ETL'])
|
|
|
|
+ textBox15.delete(0, 'end'); textBox15.insert(0, params_j['Average'])
|
|
|
|
+ textBox16.delete(0, 'end'); textBox16.insert(0, params_j['ph_over'])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+### Defoult values ###
|
|
|
|
+# --------------------------------
|
|
|
|
+sl_nb = 1 # number of slices
|
|
|
|
+sl_thkn = 5e-3 # Slice thickness, m
|
|
|
|
+sl_gap = 100 # Slice gap, %
|
|
|
|
+
|
|
|
|
+#---------------------------------
|
|
|
|
+FoV_f = 32e-3 # FoV in freq encoding direction, m
|
|
|
|
+FoV_ph = 32e-3 # FoV in ph encoding direction, m
|
|
|
|
+Nf = 16 # Freq direction resolution
|
|
|
|
+Np = 16 # Resolution in ph encoding direction
|
|
|
|
+
|
|
|
|
+#----------------------------------
|
|
|
|
+BW_pixel = 500 # Pixel BW
|
|
|
|
+N_TE = 1 # number of echo in center of k-space
|
|
|
|
+# TE = 20e-3 # Echo time, s
|
|
|
|
+TR = 500e-3 # Repetition time, s
|
|
|
|
+alpha = 90 # Flip angle, degree
|
|
|
|
+beta = 180
|
|
|
|
+ETL = 8
|
|
|
|
+Conct = 1
|
|
|
|
+Average = 1
|
|
|
|
+ph_over = 0
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+win = tk.Tk()
|
|
|
|
+win.title('TSE')
|
|
|
|
+win.geometry("350x470+100+100")
|
|
|
|
+win.resizable(False,False)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# number of slices
|
|
|
|
+sl_nb_min,sl_nb_max = 1, 103
|
|
|
|
+tk.Label(win, text = 'Slices').grid(row=0, column=0,sticky = "E")
|
|
|
|
+textBox1 = tk.Spinbox(from_=sl_nb_min, to=sl_nb_max, width = 4)
|
|
|
|
+textBox1.grid(row=0, column=1)
|
|
|
|
+label1_1 = tk.Label(win, text = "min = " + str(sl_nb_min))
|
|
|
|
+label1_1.grid(row=0, column=2)
|
|
|
|
+label1_2 = tk.Label(win, text = "max = " + str(sl_nb_max))
|
|
|
|
+label1_2.grid(row=0, column=3)
|
|
|
|
+
|
|
|
|
+# Slice thickness, m
|
|
|
|
+tk.Label(win, text = 'Slice thickness, m').grid(row=1, column=0,sticky = "E")
|
|
|
|
+textBox2 = tk.Entry(width = 6)
|
|
|
|
+textBox2.insert(0, sl_thkn)
|
|
|
|
+textBox2.grid(row=1, column=1)
|
|
|
|
+label2_1 = tk.Label(win, text = "min = " )
|
|
|
|
+label2_1.grid(row=1, column=2)
|
|
|
|
+label2_2 = tk.Label(win, text = "max = " )
|
|
|
|
+label2_2.grid(row=1, column=3)
|
|
|
|
+
|
|
|
|
+# Slice gap, %
|
|
|
|
+tk.Label(win, text = 'Slice gap, % ').grid(row=2, column=0,sticky = "E")
|
|
|
|
+textBox3 = tk.Entry(width = 6)
|
|
|
|
+textBox3.insert(0, sl_gap)
|
|
|
|
+textBox3.grid(row=2, column=1)
|
|
|
|
+label3_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label3_1.grid(row=2, column=2)
|
|
|
|
+label3_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label3_2.grid(row=2, column=3)
|
|
|
|
+
|
|
|
|
+# FoV in freq encoding direction, m
|
|
|
|
+tk.Label(win, text = 'FoV read, m').grid(row=3, column=0,sticky = "E")
|
|
|
|
+textBox4 = tk.Entry(width = 6)
|
|
|
|
+textBox4.insert(0, FoV_f)
|
|
|
|
+textBox4.grid(row=3, column=1)
|
|
|
|
+label4_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label4_1.grid(row=3, column=2)
|
|
|
|
+label4_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label4_2.grid(row=3, column=3)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# FoV in ph encoding direction, m
|
|
|
|
+label5 = tk.Label(win, text = 'FoV phase, m')
|
|
|
|
+label5.grid(row=4, column=0,sticky = "E")
|
|
|
|
+textBox5 = tk.Entry(width = 6)
|
|
|
|
+textBox5.insert(0, FoV_f)
|
|
|
|
+textBox5.grid(row=4, column=1)
|
|
|
|
+label5_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label5_1.grid(row=4, column=2)
|
|
|
|
+label5_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label5_2.grid(row=4, column=3)
|
|
|
|
+
|
|
|
|
+# Freq direction resolution
|
|
|
|
+label6 = tk.Label(win, text = 'Read resolution')
|
|
|
|
+label6.grid(row=5, column=0,sticky = "E")
|
|
|
|
+textBox6 = tk.Entry(width = 6)
|
|
|
|
+textBox6.insert(0, Nf)
|
|
|
|
+textBox6.grid(row=5, column=1)
|
|
|
|
+label6_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label6_1.grid(row=5, column=2)
|
|
|
|
+label6_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label6_2.grid(row=5, column=3)
|
|
|
|
+
|
|
|
|
+# Ph direction resolution
|
|
|
|
+label7 = tk.Label(win, text = 'Phase resolution')
|
|
|
|
+label7.grid(row=6, column=0,sticky = "E")
|
|
|
|
+textBox7 = tk.Entry(width = 6)
|
|
|
|
+textBox7.insert(0, Np)
|
|
|
|
+textBox7.grid(row=6, column=1)
|
|
|
|
+label7_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label7_1.grid(row=6, column=2)
|
|
|
|
+label7_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label7_2.grid(row=6, column=3)
|
|
|
|
+
|
|
|
|
+# Pixel BW
|
|
|
|
+label8 = tk.Label(win, text = 'Pixel BW, Hz')
|
|
|
|
+label8.grid(row=7, column=0,sticky = "E")
|
|
|
|
+textBox8 = tk.Entry(width = 6)
|
|
|
|
+textBox8.insert(0, BW_pixel)
|
|
|
|
+textBox8.grid(row=7, column=1)
|
|
|
|
+label8_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label8_1.grid(row=7, column=2)
|
|
|
|
+label8_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label8_2.grid(row=7, column=3)
|
|
|
|
+
|
|
|
|
+# TE, s
|
|
|
|
+label9 = tk.Label(win, text = 'N_TE')
|
|
|
|
+label9.grid(row=8, column=0,sticky = "E")
|
|
|
|
+textBox9 = tk.Entry(width = 6)
|
|
|
|
+textBox9.insert(0, N_TE)
|
|
|
|
+textBox9.grid(row=8, column=1)
|
|
|
|
+label9_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label9_1.grid(row=8, column=2)
|
|
|
|
+label9_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label9_2.grid(row=8, column=3)
|
|
|
|
+
|
|
|
|
+# TR, s
|
|
|
|
+label10 = tk.Label(win, text = 'TR, s')
|
|
|
|
+label10.grid(row=9, column=0,sticky = "E")
|
|
|
|
+textBox10 = tk.Entry(width = 6)
|
|
|
|
+textBox10.insert(0, TR)
|
|
|
|
+textBox10.grid(row=9, column=1)
|
|
|
|
+label10_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label10_1.grid(row=9, column=2)
|
|
|
|
+label10_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label10_2.grid(row=9, column=3)
|
|
|
|
+
|
|
|
|
+# Flip angle, degree
|
|
|
|
+label11= tk.Label(win, text = 'Flip angle, degree')
|
|
|
|
+label11.grid(row=10, column=0,sticky = "E")
|
|
|
|
+textBox11 = tk.Entry(width = 6)
|
|
|
|
+textBox11.insert(0, alpha)
|
|
|
|
+textBox11.grid(row=10, column=1)
|
|
|
|
+angle_min, angle_max = 1, 90
|
|
|
|
+label11_1 = tk.Label(win, text = "min = "+ str(angle_min))
|
|
|
|
+label11_1.grid(row=10, column=2)
|
|
|
|
+label11_2 = tk.Label(win, text = "max = "+ str(angle_max))
|
|
|
|
+label11_2.grid(row=10, column=3)
|
|
|
|
+
|
|
|
|
+# Refocusing angle, degree
|
|
|
|
+label12= tk.Label(win, text = 'Refocusing angle, degree')
|
|
|
|
+label12.grid(row=11, column=0,sticky = "E")
|
|
|
|
+textBox12 = tk.Entry(width = 6)
|
|
|
|
+textBox12.insert(0, beta)
|
|
|
|
+textBox12.grid(row=11, column=1)
|
|
|
|
+beta_min, beta_max = 110, 180
|
|
|
|
+label12_1 = tk.Label(win, text = "min = "+ str(beta_min))
|
|
|
|
+label12_1.grid(row=11, column=2)
|
|
|
|
+label12_2 = tk.Label(win, text = "max = "+ str(beta_max))
|
|
|
|
+label12_2.grid(row=11, column=3)
|
|
|
|
+
|
|
|
|
+# Concatenations
|
|
|
|
+label13= tk.Label(win, text = 'Concatenations')
|
|
|
|
+label13.grid(row=12, column=0,sticky = "E")
|
|
|
|
+textBox13 = tk.Entry(width = 6)
|
|
|
|
+textBox13.insert(0, Conct)
|
|
|
|
+textBox13.grid(row=12, column=1)
|
|
|
|
+label13_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label13_1.grid(row=12, column=2)
|
|
|
|
+label13_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label13_2.grid(row=12, column=3)
|
|
|
|
+
|
|
|
|
+# ETL
|
|
|
|
+label14= tk.Label(win, text = 'ETL')
|
|
|
|
+label14.grid(row=13, column=0,sticky = "E")
|
|
|
|
+textBox14 = tk.Entry(width = 6)
|
|
|
|
+textBox14.insert(0, ETL)
|
|
|
|
+textBox14.grid(row=13, column=1)
|
|
|
|
+label14_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label14_1.grid(row=13, column=2)
|
|
|
|
+label14_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label14_2.grid(row=13, column=3)
|
|
|
|
+
|
|
|
|
+# Averages
|
|
|
|
+label15= tk.Label(win, text = 'Averages')
|
|
|
|
+label15.grid(row=14, column=0,sticky = "E")
|
|
|
|
+textBox15 = tk.Entry(width = 6)
|
|
|
|
+textBox15.insert(0, Average)
|
|
|
|
+textBox15.grid(row=14, column=1)
|
|
|
|
+label15_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label15_1.grid(row=14, column=2)
|
|
|
|
+label15_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label15_2.grid(row=14, column=3)
|
|
|
|
+
|
|
|
|
+# phase oversampling
|
|
|
|
+label16= tk.Label(win, text = 'Ph oversampling,%')
|
|
|
|
+label16.grid(row=15, column=0,sticky = "E")
|
|
|
|
+textBox16 = tk.Entry(width = 6)
|
|
|
|
+textBox16.insert(0, ph_over)
|
|
|
|
+textBox16.grid(row=15, column=1)
|
|
|
|
+label16_1 = tk.Label(win, text = "min = ")
|
|
|
|
+label16_1.grid(row=15, column=2)
|
|
|
|
+label16_2 = tk.Label(win, text = "max = ")
|
|
|
|
+label16_2.grid(row=15, column=3)
|
|
|
|
+
|
|
|
|
+set_limits()
|
|
|
|
+
|
|
|
|
+btn1 = tk.Button(win, text = 'Set', command = set_limits)
|
|
|
|
+btn1.grid(row=16, column=0,sticky = "E")
|
|
|
|
+
|
|
|
|
+btn1 = tk.Button(win, text = 'Save', command = save_param)
|
|
|
|
+btn1.grid(row=16, column=3)
|
|
|
|
+
|
|
|
|
+btn1 = tk.Button(win, text = 'Read json', command = read_json)
|
|
|
|
+btn1.grid(row=17, column=0,sticky = "E")
|
|
|
|
+
|
|
|
|
+# filename
|
|
|
|
+label17= tk.Label(win, text = 'File name')
|
|
|
|
+label17.grid(row=18, column=0,sticky = "E")
|
|
|
|
+textBox17 = tk.Entry(width = 27)
|
|
|
|
+textBox17.insert(0, "TSE")
|
|
|
|
+textBox17.grid(row=18, column=1, columnspan=3,sticky = "W")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+win.mainloop()
|
|
|
|
+
|
|
|
|
+
|