gui_TSE.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Mon Jul 3 17:53:21 2023
  4. @author: zilya
  5. """
  6. import tkinter as tk
  7. from math import ceil, floor
  8. import numpy as np
  9. from types import SimpleNamespace
  10. from datetime import datetime
  11. import json
  12. import pickle
  13. def set_limits():
  14. # Задание общих аппаратных характкристик
  15. gamma = 42.576e6 # Hz/T Гиромагнитное отношение водорода
  16. G_amp_max_mT_m = 37.8 # mT/m. Максимальный градиент
  17. G_amp_max = G_amp_max_mT_m*1e-3*gamma # Hz/m. Максимальный градиент
  18. G_slew_max_T_m_s = 121 # T/m/s. Максимальная скорость нарастания
  19. G_slew_max = G_slew_max_T_m_s*gamma # Hz/m/s. Максимальная скорость нарастания
  20. rf_raster_time = 1e-6 # s. Растр РЧ импульса
  21. grad_raster_time = 10e-6 # s. Растр градиентов
  22. tau_max = G_amp_max/G_slew_max # s. Максимальное время нарастания градиента с учетом макс скорости нарастания
  23. tau_max = np.ceil(tau_max/ grad_raster_time)*grad_raster_time
  24. tau = 250e-6 # s. Фиксированное время нарастания градиентов
  25. # Чтение заданных в интерфэйс значений
  26. sl_nb = int(textBox1.get())
  27. sl_thkn = float(textBox2.get())
  28. sl_gap = float(textBox3.get())
  29. FoV_f = float(textBox4.get())
  30. FoV_ph_image = float(textBox5.get())
  31. Nf = int(textBox6.get())
  32. Np_image = int(textBox7.get())
  33. BW_pixel = float(textBox8.get())
  34. N_TE = int(textBox9.get())
  35. #TE = float(textBox9.get())
  36. TR = float(textBox10.get())
  37. alpha = float(textBox11.get())
  38. beta = float(textBox12.get())
  39. Conct = int(textBox13.get())
  40. ETL = int(textBox14.get())
  41. Average = int(textBox15.get())
  42. ph_over = float(textBox16.get())
  43. Np = Np_image*(1+ph_over/100)
  44. Np = round(Np)
  45. ph_over = (Np/Np_image-1)*100
  46. FoV_ph = FoV_ph_image*(1+ph_over/100)
  47. TR = np.ceil(TR/ grad_raster_time)*grad_raster_time
  48. # --- Параметры РЧ импульса -----
  49. rf_ringdown_time=20e-6
  50. rf_dead_time=100e-6
  51. adc_dead_time=10e-6
  52. # - Библиотека time bandwidth products
  53. t_BW_product_ex1 = 3.8
  54. t_BW_product_ref1 = 4.2
  55. t_BW_product_ex2 = 3.55
  56. t_BW_product_ref2 = 3.55
  57. # s. Библиотека длительностей импульсов
  58. # Длительности кратны растру градиента 10 мкс
  59. t_ex1 = 2.05e-3
  60. t_ref1 = 2.56e-3
  61. t_ex2 = 3.10e-3
  62. t_ref2 = 3.88e-3
  63. apodization = 0.27
  64. # ----- Подбор импульсов на основе выбранной толщины среза
  65. if sl_thkn > t_BW_product_ex1/(t_ex1*G_amp_max):
  66. t_BW_product_ex = t_BW_product_ex1
  67. t_BW_product_ref = t_BW_product_ref1
  68. else:
  69. t_BW_product_ex = t_BW_product_ex2
  70. t_BW_product_ref = t_BW_product_ref2
  71. if sl_thkn > t_BW_product_ex2/(t_ex1*G_amp_max):
  72. t_ex = t_ex1
  73. t_ref = t_ref1
  74. else:
  75. t_ex = t_ex2
  76. t_ref = t_ref2
  77. BW_ex_pulse = t_BW_product_ex/t_ex
  78. # ---- Вычисление основных площадей и длительностей ------
  79. A_ex = BW_ex_pulse*(t_ex+tau)/sl_thkn
  80. A_read = Nf/FoV_f
  81. A_ph = Np/2/FoV_ph
  82. A_reph = 0.25*A_ex
  83. A_pre = 1.5*A_read
  84. A_crs = 0.75*A_ex
  85. A_crr = A_read
  86. A_sps = 4*A_ex
  87. t_reph_min = A_reph/G_amp_max + tau
  88. t_pre_min = A_pre/G_amp_max + tau
  89. t_pre_min = max(t_reph_min,t_pre_min)
  90. t_pre_min = np.ceil(t_pre_min / grad_raster_time)*grad_raster_time
  91. t_crs_min = A_crs/G_amp_max + tau
  92. t_crr_min = A_crr/G_amp_max + tau
  93. t_ph_min = A_ph/G_amp_max + tau
  94. t_cr_min = max(t_crs_min,t_crr_min,t_ph_min)
  95. t_cr_min = np.ceil(t_cr_min / grad_raster_time)*grad_raster_time
  96. t_read = 1/BW_pixel
  97. t_read = np.ceil(t_read / grad_raster_time)*grad_raster_time
  98. t_sps = A_sps/G_amp_max + tau
  99. t_sps = np.ceil(t_sps / grad_raster_time)*grad_raster_time
  100. ES_1 = t_ref + t_read + 2*t_cr_min + 4*tau
  101. ES_2 = t_ref + t_ex + 2*t_cr_min + 2*t_pre_min + 4*tau
  102. ES = max(ES_1,ES_2)
  103. ES = np.ceil(ES/ grad_raster_time)*grad_raster_time
  104. t_cr = 0.5*(ES-t_ref-t_read) - 2*tau
  105. t_cr = np.ceil(t_cr / grad_raster_time)*grad_raster_time
  106. t_pre = 0.5*(ES-t_ref-t_ex) - 2*tau
  107. t_pre = np.ceil(t_pre / grad_raster_time)*grad_raster_time
  108. TE = N_TE*ES
  109. N_TE_min = 1
  110. N_TE_max = ETL
  111. TR_min = ES*(ETL) + t_ex/2 + t_read/2 + t_sps + 2*tau
  112. TR_max = 10
  113. TR_min = np.ceil(TR_min/ grad_raster_time)*grad_raster_time
  114. delay_TR = TR-TR_min
  115. Conc_min = ceil(sl_nb*TR_min/TR)
  116. Conc_max = sl_nb
  117. ETL_min = 1;
  118. ETL_max1 = 16;
  119. ETL_max2 = floor((TR-t_ex/2-t_read/2-t_sps-2*tau)/ES)
  120. ETL_max = min(ETL_max1,ETL_max2)
  121. Nf_min = 1
  122. #Nf_max1 = FoV_f*G_amp_max*(t_cr-tau)
  123. Nf_max = min(FoV_f*G_amp_max*(t_read),1600)
  124. #Nf_max = min(Nf_max1,Nf_max2)
  125. Np_min = 1
  126. Np_max1 = Nf
  127. Np_max2 = 2*FoV_ph*G_amp_max*(t_cr-tau)
  128. Np_max = min(Np_max1,Np_max2)
  129. FoV_min = 25e-3
  130. FoV_f_max = 450e-3
  131. FoV_f_min = Nf/(G_amp_max*t_read)
  132. #FoV_f_min2 = Nf/(G_amp_max*(t_cr-tau))
  133. FoV_f_min = max(FoV_f_min,FoV_min)
  134. FoV_p_min = FoV_f_min
  135. FoV_p_max = FoV_f
  136. Np_image_min = Np_min
  137. Np_image_max = min(Np_max, Nf_max/(1+ph_over/100))
  138. FoV_p_image_min = FoV_p_min/(1+ph_over/100)
  139. FoV_p_image_max = min(FoV_p_max,FoV_f_max/(1+ph_over/100))
  140. # BW_pixel_min = 1/(ES-t_ref-2*t_cr_min-4*tau)
  141. # BW_pixel_min = max(ceil(BW_pixel_min), 40)
  142. BW_pixel_min = 40
  143. BW_pixel_max1 = 1780
  144. BW_pixel_max2 = FoV_f*G_amp_max/Nf
  145. BW_pixel_max = min (BW_pixel_max1,BW_pixel_max2)
  146. sl_thkn_min1 = t_BW_product_ex2/(t_ex2*G_amp_max)
  147. sl_thkn_min2 = t_BW_product_ex2*(t_ex2+tau)/((t_cr-tau)*G_amp_max)
  148. sl_thkn_min = max(sl_thkn_min1,sl_thkn_min2)
  149. sl_thkn_max = 20e-3
  150. sl_gap_min, sl_gap_max = 0, 800
  151. Average_min, Average_max = 1, 10
  152. ph_over_min, ph_over_max = 0, 100
  153. label2_1.configure(text = "min = " + str(ceil(sl_thkn_min*10000)/10000))
  154. label2_2.configure(text = "max = " + str(sl_thkn_max))
  155. label3_1.configure(text = "min = " + str(sl_gap_min))
  156. label3_2.configure(text = "max = " + str(sl_gap_max))
  157. label4_1.configure(text = "min = " + str(ceil(FoV_f_min*1000)/1000))
  158. label4_2.configure(text = "max = " + str(FoV_f_max))
  159. label5_1.configure(text = "min = " + str(ceil(FoV_p_image_min*1000)/1000))
  160. label5_2.configure(text = "max = " + str(ceil(FoV_p_image_max*1000)/1000))
  161. label6_1.configure(text = "min = " + str(Nf_min))
  162. label6_2.configure(text = "max = " + str(ceil(Nf_max)))
  163. label7_1.configure(text = "min = " + str(ceil(Np_image_min*1000)/1000))
  164. label7_2.configure(text = "max = " + str(ceil(Np_image_max*1000)/1000))
  165. label8_1.configure(text = "min = " + str(BW_pixel_min))
  166. label8_2.configure(text = "max = " + str(ceil(BW_pixel_max*1000)/1000))
  167. label9_1.configure(text = "min = " + str(N_TE_min))
  168. label9_2.configure(text = "max = " + str(N_TE_max))
  169. label10_1.configure(text = "min = " + str(ceil(TR_min*1000)/1000))
  170. label10_2.configure(text = "max = " + str(TR_max))
  171. label13_1.configure(text = "min = " + str(Conc_min))
  172. label13_2.configure(text = "max = " + str(Conc_max))
  173. label14_1.configure(text = "min = " + str(ETL_min))
  174. label14_2.configure(text = "max = " + str(ETL_max))
  175. label15_1.configure(text = "min = " + str(Average_min))
  176. label15_2.configure(text = "max = " + str(Average_max))
  177. label16_1.configure(text = "min = " + str(ph_over_min))
  178. label16_2.configure(text = "max = " + str(ph_over_max))
  179. global param
  180. param = SimpleNamespace()
  181. param.G_amp_max =G_amp_max_mT_m
  182. param.G_slew_max = G_slew_max_T_m_s
  183. param.gamma = gamma
  184. param.grad_raster_time = grad_raster_time
  185. param.rf_raster_time = rf_raster_time
  186. param.t_BW_product_ex = t_BW_product_ex
  187. param.t_BW_product_ref = t_BW_product_ref
  188. param.t_ex = t_ex
  189. param.t_ref = t_ref
  190. param.rf_ringdown_time = rf_ringdown_time
  191. param.rf_dead_time = rf_dead_time
  192. param.adc_dead_time = adc_dead_time
  193. param.aapodization = apodization
  194. param.dG = tau
  195. param.sl_nb = sl_nb
  196. param.sl_thkn = sl_thkn
  197. param.sl_gap = sl_gap
  198. param.FoV_f = FoV_f
  199. param.FoV_ph = FoV_ph
  200. param.Nf = Nf
  201. param.Np = Np
  202. param.BW_pixel = BW_pixel
  203. param.TE = TE
  204. param.N_TE = N_TE #то на коком номере эхо истинное время эхо(в центр к-пр)
  205. param.ES = ES
  206. param.TR = TR
  207. param.FA = alpha
  208. param.RA = beta
  209. param.conct = Conct
  210. param.ETL = ETL
  211. param.Average = Average
  212. param.ph_over = ph_over
  213. param.delay_TR = delay_TR
  214. # tk.Label(win, text = 't = ' + str(round(time//60)) + ':'+ str(round(time%60)) + 'min').grid(row=13, column=2,sticky = "E")
  215. tk.Label(win, text = 'ES = ' + str(ceil(ES*10000)/10000) + ' s').grid(row=19, column=2,sticky = "E")
  216. tk.Label(win, text = 'TE = ' + str(ceil(TE*10000)/10000) + ' s').grid(row=20, column=2,sticky = "E")
  217. #tk.Label(win, text = str(ETL_max2) + 's').grid(row=18, column=2,sticky = "E")
  218. def save_param():
  219. output_filename = str(textBox17.get())
  220. # output_filename = "TSE_T1" + datetime.now().strftime("%Y%m%d_%H%M%S")
  221. file = open(output_filename + ".json", 'w')
  222. json.dump(param.__dict__, file, indent = 4)
  223. file.close()
  224. # output_filename = "TSE_" + datetime.now().strftime("%Y%m%d_%H%M%S")
  225. # file = open(output_filename, 'wb')
  226. # pickle.dump(param, file)
  227. # file.close()
  228. def read_json():
  229. filepath = tk.filedialog.askopenfilename()
  230. if filepath != "":
  231. with open(filepath, "r") as file:
  232. params_j = json.load(file)
  233. textBox2.delete(0, 'end'); textBox2.insert(0, params_j['sl_thkn'])
  234. textBox3.delete(0, 'end'); textBox3.insert(0, params_j['sl_gap'])
  235. textBox4.delete(0, 'end'); textBox4.insert(0, params_j['FoV_f'])
  236. textBox5.delete(0, 'end'); textBox5.insert(0, params_j['FoV_ph'])
  237. textBox6.delete(0, 'end'); textBox6.insert(0, params_j['Nf'])
  238. textBox7.delete(0, 'end'); textBox7.insert(0, params_j['Np'])
  239. textBox8.delete(0, 'end'); textBox8.insert(0, params_j['N_TE'])
  240. textBox9.delete(0, 'end'); textBox9.insert(0, params_j['N_TE'])
  241. textBox10.delete(0, 'end'); textBox10.insert(0, params_j['TR'])
  242. textBox11.delete(0, 'end'); textBox11.insert(0, params_j['FA'])
  243. textBox12.delete(0, 'end'); textBox12.insert(0, params_j['RA'])
  244. textBox13.delete(0, 'end'); textBox13.insert(0, params_j['conct'])
  245. textBox14.delete(0, 'end'); textBox14.insert(0, params_j['ETL'])
  246. textBox15.delete(0, 'end'); textBox15.insert(0, params_j['Average'])
  247. textBox16.delete(0, 'end'); textBox16.insert(0, params_j['ph_over'])
  248. ### Defoult values ###
  249. # --------------------------------
  250. sl_nb = 1 # number of slices
  251. sl_thkn = 5e-3 # Slice thickness, m
  252. sl_gap = 100 # Slice gap, %
  253. #---------------------------------
  254. FoV_f = 32e-3 # FoV in freq encoding direction, m
  255. FoV_ph = 32e-3 # FoV in ph encoding direction, m
  256. Nf = 16 # Freq direction resolution
  257. Np = 16 # Resolution in ph encoding direction
  258. #----------------------------------
  259. BW_pixel = 500 # Pixel BW
  260. N_TE = 1 # number of echo in center of k-space
  261. # TE = 20e-3 # Echo time, s
  262. TR = 500e-3 # Repetition time, s
  263. alpha = 90 # Flip angle, degree
  264. beta = 180
  265. ETL = 8
  266. Conct = 1
  267. Average = 1
  268. ph_over = 0
  269. win = tk.Tk()
  270. win.title('TSE')
  271. win.geometry("350x470+100+100")
  272. win.resizable(False,False)
  273. # number of slices
  274. sl_nb_min,sl_nb_max = 1, 103
  275. tk.Label(win, text = 'Slices').grid(row=0, column=0,sticky = "E")
  276. textBox1 = tk.Spinbox(from_=sl_nb_min, to=sl_nb_max, width = 4)
  277. textBox1.grid(row=0, column=1)
  278. label1_1 = tk.Label(win, text = "min = " + str(sl_nb_min))
  279. label1_1.grid(row=0, column=2)
  280. label1_2 = tk.Label(win, text = "max = " + str(sl_nb_max))
  281. label1_2.grid(row=0, column=3)
  282. # Slice thickness, m
  283. tk.Label(win, text = 'Slice thickness, m').grid(row=1, column=0,sticky = "E")
  284. textBox2 = tk.Entry(width = 6)
  285. textBox2.insert(0, sl_thkn)
  286. textBox2.grid(row=1, column=1)
  287. label2_1 = tk.Label(win, text = "min = " )
  288. label2_1.grid(row=1, column=2)
  289. label2_2 = tk.Label(win, text = "max = " )
  290. label2_2.grid(row=1, column=3)
  291. # Slice gap, %
  292. tk.Label(win, text = 'Slice gap, % ').grid(row=2, column=0,sticky = "E")
  293. textBox3 = tk.Entry(width = 6)
  294. textBox3.insert(0, sl_gap)
  295. textBox3.grid(row=2, column=1)
  296. label3_1 = tk.Label(win, text = "min = ")
  297. label3_1.grid(row=2, column=2)
  298. label3_2 = tk.Label(win, text = "max = ")
  299. label3_2.grid(row=2, column=3)
  300. # FoV in freq encoding direction, m
  301. tk.Label(win, text = 'FoV read, m').grid(row=3, column=0,sticky = "E")
  302. textBox4 = tk.Entry(width = 6)
  303. textBox4.insert(0, FoV_f)
  304. textBox4.grid(row=3, column=1)
  305. label4_1 = tk.Label(win, text = "min = ")
  306. label4_1.grid(row=3, column=2)
  307. label4_2 = tk.Label(win, text = "max = ")
  308. label4_2.grid(row=3, column=3)
  309. # FoV in ph encoding direction, m
  310. label5 = tk.Label(win, text = 'FoV phase, m')
  311. label5.grid(row=4, column=0,sticky = "E")
  312. textBox5 = tk.Entry(width = 6)
  313. textBox5.insert(0, FoV_f)
  314. textBox5.grid(row=4, column=1)
  315. label5_1 = tk.Label(win, text = "min = ")
  316. label5_1.grid(row=4, column=2)
  317. label5_2 = tk.Label(win, text = "max = ")
  318. label5_2.grid(row=4, column=3)
  319. # Freq direction resolution
  320. label6 = tk.Label(win, text = 'Read resolution')
  321. label6.grid(row=5, column=0,sticky = "E")
  322. textBox6 = tk.Entry(width = 6)
  323. textBox6.insert(0, Nf)
  324. textBox6.grid(row=5, column=1)
  325. label6_1 = tk.Label(win, text = "min = ")
  326. label6_1.grid(row=5, column=2)
  327. label6_2 = tk.Label(win, text = "max = ")
  328. label6_2.grid(row=5, column=3)
  329. # Ph direction resolution
  330. label7 = tk.Label(win, text = 'Phase resolution')
  331. label7.grid(row=6, column=0,sticky = "E")
  332. textBox7 = tk.Entry(width = 6)
  333. textBox7.insert(0, Np)
  334. textBox7.grid(row=6, column=1)
  335. label7_1 = tk.Label(win, text = "min = ")
  336. label7_1.grid(row=6, column=2)
  337. label7_2 = tk.Label(win, text = "max = ")
  338. label7_2.grid(row=6, column=3)
  339. # Pixel BW
  340. label8 = tk.Label(win, text = 'Pixel BW, Hz')
  341. label8.grid(row=7, column=0,sticky = "E")
  342. textBox8 = tk.Entry(width = 6)
  343. textBox8.insert(0, BW_pixel)
  344. textBox8.grid(row=7, column=1)
  345. label8_1 = tk.Label(win, text = "min = ")
  346. label8_1.grid(row=7, column=2)
  347. label8_2 = tk.Label(win, text = "max = ")
  348. label8_2.grid(row=7, column=3)
  349. # TE, s
  350. label9 = tk.Label(win, text = 'N_TE')
  351. label9.grid(row=8, column=0,sticky = "E")
  352. textBox9 = tk.Entry(width = 6)
  353. textBox9.insert(0, N_TE)
  354. textBox9.grid(row=8, column=1)
  355. label9_1 = tk.Label(win, text = "min = ")
  356. label9_1.grid(row=8, column=2)
  357. label9_2 = tk.Label(win, text = "max = ")
  358. label9_2.grid(row=8, column=3)
  359. # TR, s
  360. label10 = tk.Label(win, text = 'TR, s')
  361. label10.grid(row=9, column=0,sticky = "E")
  362. textBox10 = tk.Entry(width = 6)
  363. textBox10.insert(0, TR)
  364. textBox10.grid(row=9, column=1)
  365. label10_1 = tk.Label(win, text = "min = ")
  366. label10_1.grid(row=9, column=2)
  367. label10_2 = tk.Label(win, text = "max = ")
  368. label10_2.grid(row=9, column=3)
  369. # Flip angle, degree
  370. label11= tk.Label(win, text = 'Flip angle, degree')
  371. label11.grid(row=10, column=0,sticky = "E")
  372. textBox11 = tk.Entry(width = 6)
  373. textBox11.insert(0, alpha)
  374. textBox11.grid(row=10, column=1)
  375. angle_min, angle_max = 1, 90
  376. label11_1 = tk.Label(win, text = "min = "+ str(angle_min))
  377. label11_1.grid(row=10, column=2)
  378. label11_2 = tk.Label(win, text = "max = "+ str(angle_max))
  379. label11_2.grid(row=10, column=3)
  380. # Refocusing angle, degree
  381. label12= tk.Label(win, text = 'Refocusing angle, degree')
  382. label12.grid(row=11, column=0,sticky = "E")
  383. textBox12 = tk.Entry(width = 6)
  384. textBox12.insert(0, beta)
  385. textBox12.grid(row=11, column=1)
  386. beta_min, beta_max = 110, 180
  387. label12_1 = tk.Label(win, text = "min = "+ str(beta_min))
  388. label12_1.grid(row=11, column=2)
  389. label12_2 = tk.Label(win, text = "max = "+ str(beta_max))
  390. label12_2.grid(row=11, column=3)
  391. # Concatenations
  392. label13= tk.Label(win, text = 'Concatenations')
  393. label13.grid(row=12, column=0,sticky = "E")
  394. textBox13 = tk.Entry(width = 6)
  395. textBox13.insert(0, Conct)
  396. textBox13.grid(row=12, column=1)
  397. label13_1 = tk.Label(win, text = "min = ")
  398. label13_1.grid(row=12, column=2)
  399. label13_2 = tk.Label(win, text = "max = ")
  400. label13_2.grid(row=12, column=3)
  401. # ETL
  402. label14= tk.Label(win, text = 'ETL')
  403. label14.grid(row=13, column=0,sticky = "E")
  404. textBox14 = tk.Entry(width = 6)
  405. textBox14.insert(0, ETL)
  406. textBox14.grid(row=13, column=1)
  407. label14_1 = tk.Label(win, text = "min = ")
  408. label14_1.grid(row=13, column=2)
  409. label14_2 = tk.Label(win, text = "max = ")
  410. label14_2.grid(row=13, column=3)
  411. # Averages
  412. label15= tk.Label(win, text = 'Averages')
  413. label15.grid(row=14, column=0,sticky = "E")
  414. textBox15 = tk.Entry(width = 6)
  415. textBox15.insert(0, Average)
  416. textBox15.grid(row=14, column=1)
  417. label15_1 = tk.Label(win, text = "min = ")
  418. label15_1.grid(row=14, column=2)
  419. label15_2 = tk.Label(win, text = "max = ")
  420. label15_2.grid(row=14, column=3)
  421. # phase oversampling
  422. label16= tk.Label(win, text = 'Ph oversampling,%')
  423. label16.grid(row=15, column=0,sticky = "E")
  424. textBox16 = tk.Entry(width = 6)
  425. textBox16.insert(0, ph_over)
  426. textBox16.grid(row=15, column=1)
  427. label16_1 = tk.Label(win, text = "min = ")
  428. label16_1.grid(row=15, column=2)
  429. label16_2 = tk.Label(win, text = "max = ")
  430. label16_2.grid(row=15, column=3)
  431. set_limits()
  432. btn1 = tk.Button(win, text = 'Set', command = set_limits)
  433. btn1.grid(row=16, column=0,sticky = "E")
  434. btn1 = tk.Button(win, text = 'Save', command = save_param)
  435. btn1.grid(row=16, column=3)
  436. btn1 = tk.Button(win, text = 'Read json', command = read_json)
  437. btn1.grid(row=17, column=0,sticky = "E")
  438. # filename
  439. label17= tk.Label(win, text = 'File name')
  440. label17.grid(row=18, column=0,sticky = "E")
  441. textBox17 = tk.Entry(width = 27)
  442. textBox17.insert(0, "TSE")
  443. textBox17.grid(row=18, column=1, columnspan=3,sticky = "W")
  444. win.mainloop()