PaIRS-UniNa 0.2.10__cp313-cp313-macosx_11_0_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +347 -0
  2. PaIRS_UniNa/Changes.txt +174 -0
  3. PaIRS_UniNa/Custom_Top.py +303 -0
  4. PaIRS_UniNa/Explorer.py +3322 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +829 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +787 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3026 -0
  9. PaIRS_UniNa/Log_Tab.py +110 -0
  10. PaIRS_UniNa/Output_Tab.py +922 -0
  11. PaIRS_UniNa/PaIRS.py +18 -0
  12. PaIRS_UniNa/PaIRS_PIV.py +873 -0
  13. PaIRS_UniNa/PaIRS_pypacks.py +1374 -0
  14. PaIRS_UniNa/Process_Tab.py +1761 -0
  15. PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
  16. PaIRS_UniNa/Process_Tab_Disp.py +170 -0
  17. PaIRS_UniNa/Process_Tab_Min.py +120 -0
  18. PaIRS_UniNa/ResizePopup.py +55 -0
  19. PaIRS_UniNa/SPIVCalHelp.py +155 -0
  20. PaIRS_UniNa/Saving_tools.py +298 -0
  21. PaIRS_UniNa/TabTools.py +1413 -0
  22. PaIRS_UniNa/Vis_Tab.py +2176 -0
  23. PaIRS_UniNa/Vis_Tab_CalVi.py +982 -0
  24. PaIRS_UniNa/Whatsnew.py +130 -0
  25. PaIRS_UniNa/_PaIRS_PIV.so +0 -0
  26. PaIRS_UniNa/__init__.py +6 -0
  27. PaIRS_UniNa/__main__.py +45 -0
  28. PaIRS_UniNa/addwidgets_ps.py +1633 -0
  29. PaIRS_UniNa/calib.py +1488 -0
  30. PaIRS_UniNa/calibView.py +833 -0
  31. PaIRS_UniNa/gPaIRS.py +3957 -0
  32. PaIRS_UniNa/gPalette.py +189 -0
  33. PaIRS_UniNa/icons/abort.png +0 -0
  34. PaIRS_UniNa/icons/about.png +0 -0
  35. PaIRS_UniNa/icons/align_all.png +0 -0
  36. PaIRS_UniNa/icons/announcement.png +0 -0
  37. PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
  38. PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
  39. PaIRS_UniNa/icons/automatic_off.png +0 -0
  40. PaIRS_UniNa/icons/automatic_on.png +0 -0
  41. PaIRS_UniNa/icons/automatic_size_off.png +0 -0
  42. PaIRS_UniNa/icons/automatic_size_on.png +0 -0
  43. PaIRS_UniNa/icons/axes.png +0 -0
  44. PaIRS_UniNa/icons/background.png +0 -0
  45. PaIRS_UniNa/icons/background_vectors.png +0 -0
  46. PaIRS_UniNa/icons/bin_off.png +0 -0
  47. PaIRS_UniNa/icons/bin_on.png +0 -0
  48. PaIRS_UniNa/icons/browse_file_c.png +0 -0
  49. PaIRS_UniNa/icons/browse_folder_c.png +0 -0
  50. PaIRS_UniNa/icons/brush_cursor.png +0 -0
  51. PaIRS_UniNa/icons/bugfix.png +0 -0
  52. PaIRS_UniNa/icons/cal_proc.png +0 -0
  53. PaIRS_UniNa/icons/cal_proc_off.png +0 -0
  54. PaIRS_UniNa/icons/cal_step.png +0 -0
  55. PaIRS_UniNa/icons/cal_step_off.png +0 -0
  56. PaIRS_UniNa/icons/calibrate.png +0 -0
  57. PaIRS_UniNa/icons/calibration_logo.png +0 -0
  58. PaIRS_UniNa/icons/change_folder.png +0 -0
  59. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  60. PaIRS_UniNa/icons/checklist.png +0 -0
  61. PaIRS_UniNa/icons/clean.png +0 -0
  62. PaIRS_UniNa/icons/clean_run.png +0 -0
  63. PaIRS_UniNa/icons/close.png +0 -0
  64. PaIRS_UniNa/icons/close_all.png +0 -0
  65. PaIRS_UniNa/icons/close_project.png +0 -0
  66. PaIRS_UniNa/icons/close_workspace.png +0 -0
  67. PaIRS_UniNa/icons/colormap.png +0 -0
  68. PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
  69. PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
  70. PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
  71. PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
  72. PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
  73. PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
  74. PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
  75. PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
  76. PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
  77. PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
  78. PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
  79. PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
  80. PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
  81. PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
  82. PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
  83. PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
  84. PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
  85. PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
  86. PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
  87. PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
  88. PaIRS_UniNa/icons/colormaps/binary.png +0 -0
  89. PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
  90. PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
  91. PaIRS_UniNa/icons/colormaps/bone.png +0 -0
  92. PaIRS_UniNa/icons/colormaps/brg.png +0 -0
  93. PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
  94. PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
  95. PaIRS_UniNa/icons/colormaps/cool.png +0 -0
  96. PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
  97. PaIRS_UniNa/icons/colormaps/copper.png +0 -0
  98. PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
  99. PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
  100. PaIRS_UniNa/icons/colormaps/flag.png +0 -0
  101. PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
  102. PaIRS_UniNa/icons/colormaps/gray.png +0 -0
  103. PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
  104. PaIRS_UniNa/icons/colormaps/hot.png +0 -0
  105. PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
  106. PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
  107. PaIRS_UniNa/icons/colormaps/jet.png +0 -0
  108. PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
  109. PaIRS_UniNa/icons/colormaps/magma.png +0 -0
  110. PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
  111. PaIRS_UniNa/icons/colormaps/pink.png +0 -0
  112. PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
  113. PaIRS_UniNa/icons/colormaps/prism.png +0 -0
  114. PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
  115. PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
  116. PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
  117. PaIRS_UniNa/icons/colormaps/spring.png +0 -0
  118. PaIRS_UniNa/icons/colormaps/summer.png +0 -0
  119. PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
  120. PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
  121. PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
  122. PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
  123. PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
  124. PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
  125. PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
  126. PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
  127. PaIRS_UniNa/icons/colormaps/winter.png +0 -0
  128. PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
  129. PaIRS_UniNa/icons/common_region.png +0 -0
  130. PaIRS_UniNa/icons/common_region_off.png +0 -0
  131. PaIRS_UniNa/icons/completed.png +0 -0
  132. PaIRS_UniNa/icons/contourf_off.png +0 -0
  133. PaIRS_UniNa/icons/contourf_on.png +0 -0
  134. PaIRS_UniNa/icons/copy.png +0 -0
  135. PaIRS_UniNa/icons/copy_process.png +0 -0
  136. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  137. PaIRS_UniNa/icons/copygrid.png +0 -0
  138. PaIRS_UniNa/icons/cursor_lamp.png +0 -0
  139. PaIRS_UniNa/icons/cut.png +0 -0
  140. PaIRS_UniNa/icons/cut_warnings.png +0 -0
  141. PaIRS_UniNa/icons/darkmode.png +0 -0
  142. PaIRS_UniNa/icons/debug_run.png +0 -0
  143. PaIRS_UniNa/icons/delete.png +0 -0
  144. PaIRS_UniNa/icons/deleteErr.png +0 -0
  145. PaIRS_UniNa/icons/disp_step.png +0 -0
  146. PaIRS_UniNa/icons/disp_step_off.png +0 -0
  147. PaIRS_UniNa/icons/down.png +0 -0
  148. PaIRS_UniNa/icons/edit_list.png +0 -0
  149. PaIRS_UniNa/icons/editing.png +0 -0
  150. PaIRS_UniNa/icons/example_list.png +0 -0
  151. PaIRS_UniNa/icons/find_all_planes.png +0 -0
  152. PaIRS_UniNa/icons/find_plane.png +0 -0
  153. PaIRS_UniNa/icons/flaticon_PaIRS.png +0 -0
  154. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  155. PaIRS_UniNa/icons/flaticon_PaIRS_download.png +0 -0
  156. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  157. PaIRS_UniNa/icons/flip_y_off.png +0 -0
  158. PaIRS_UniNa/icons/flip_y_on.png +0 -0
  159. PaIRS_UniNa/icons/focusErrr.png +0 -0
  160. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  161. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  162. PaIRS_UniNa/icons/gear.gif +0 -0
  163. PaIRS_UniNa/icons/gear.png +0 -0
  164. PaIRS_UniNa/icons/ger.png +0 -0
  165. PaIRS_UniNa/icons/greenv.png +0 -0
  166. PaIRS_UniNa/icons/guide.png +0 -0
  167. PaIRS_UniNa/icons/icon_CalVi.png +0 -0
  168. PaIRS_UniNa/icons/icon_PaIRS.png +0 -0
  169. PaIRS_UniNa/icons/import.png +0 -0
  170. PaIRS_UniNa/icons/import_set.png +0 -0
  171. PaIRS_UniNa/icons/information.png +0 -0
  172. PaIRS_UniNa/icons/information2.png +0 -0
  173. PaIRS_UniNa/icons/input_logo.png +0 -0
  174. PaIRS_UniNa/icons/issue.png +0 -0
  175. PaIRS_UniNa/icons/laser_NTR.png +0 -0
  176. PaIRS_UniNa/icons/laser_TR_double.png +0 -0
  177. PaIRS_UniNa/icons/laser_TR_single.png +0 -0
  178. PaIRS_UniNa/icons/link.png +0 -0
  179. PaIRS_UniNa/icons/linked.png +0 -0
  180. PaIRS_UniNa/icons/loaded.png +0 -0
  181. PaIRS_UniNa/icons/loading_2.gif +0 -0
  182. PaIRS_UniNa/icons/log_logo.png +0 -0
  183. PaIRS_UniNa/icons/logo_CalVi.png +0 -0
  184. PaIRS_UniNa/icons/logo_CalVi_completo.png +0 -0
  185. PaIRS_UniNa/icons/logo_CalVi_party.png +0 -0
  186. PaIRS_UniNa/icons/logo_PaIRS.png +0 -0
  187. PaIRS_UniNa/icons/logo_PaIRS_completo.png +0 -0
  188. PaIRS_UniNa/icons/logo_PaIRS_download.png +0 -0
  189. PaIRS_UniNa/icons/logo_PaIRS_party_rect.png +0 -0
  190. PaIRS_UniNa/icons/logo_PaIRS_rect.png +0 -0
  191. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  192. PaIRS_UniNa/icons/mask.png +0 -0
  193. PaIRS_UniNa/icons/measure.png +0 -0
  194. PaIRS_UniNa/icons/measure_off.png +0 -0
  195. PaIRS_UniNa/icons/min_proc.png +0 -0
  196. PaIRS_UniNa/icons/min_proc_off.png +0 -0
  197. PaIRS_UniNa/icons/min_step.png +0 -0
  198. PaIRS_UniNa/icons/min_step_off.png +0 -0
  199. PaIRS_UniNa/icons/minus.png +0 -0
  200. PaIRS_UniNa/icons/mirror_u.png +0 -0
  201. PaIRS_UniNa/icons/mirror_v.png +0 -0
  202. PaIRS_UniNa/icons/mirror_x.png +0 -0
  203. PaIRS_UniNa/icons/mirror_y.png +0 -0
  204. PaIRS_UniNa/icons/mtplt.png +0 -0
  205. PaIRS_UniNa/icons/new.png +0 -0
  206. PaIRS_UniNa/icons/new_workspace.png +0 -0
  207. PaIRS_UniNa/icons/news.png +0 -0
  208. PaIRS_UniNa/icons/normal_run.png +0 -0
  209. PaIRS_UniNa/icons/open.png +0 -0
  210. PaIRS_UniNa/icons/open_image.png +0 -0
  211. PaIRS_UniNa/icons/open_new_window.png +0 -0
  212. PaIRS_UniNa/icons/open_result.png +0 -0
  213. PaIRS_UniNa/icons/open_workspace.png +0 -0
  214. PaIRS_UniNa/icons/output_logo.png +0 -0
  215. PaIRS_UniNa/icons/paste_above.png +0 -0
  216. PaIRS_UniNa/icons/paste_below.png +0 -0
  217. PaIRS_UniNa/icons/pause.png +0 -0
  218. PaIRS_UniNa/icons/paused.png +0 -0
  219. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  220. PaIRS_UniNa/icons/piv_proc.png +0 -0
  221. PaIRS_UniNa/icons/piv_proc_off.png +0 -0
  222. PaIRS_UniNa/icons/piv_step.png +0 -0
  223. PaIRS_UniNa/icons/piv_step_off.png +0 -0
  224. PaIRS_UniNa/icons/plane.png +0 -0
  225. PaIRS_UniNa/icons/play.png +0 -0
  226. PaIRS_UniNa/icons/plus.png +0 -0
  227. PaIRS_UniNa/icons/process_logo.png +0 -0
  228. PaIRS_UniNa/icons/process_loop.png +0 -0
  229. PaIRS_UniNa/icons/project.png +0 -0
  230. PaIRS_UniNa/icons/pylog.png +0 -0
  231. PaIRS_UniNa/icons/python_warning.png +0 -0
  232. PaIRS_UniNa/icons/queue.png +0 -0
  233. PaIRS_UniNa/icons/quit.png +0 -0
  234. PaIRS_UniNa/icons/read.png +0 -0
  235. PaIRS_UniNa/icons/read_list.png +0 -0
  236. PaIRS_UniNa/icons/redo.png +0 -0
  237. PaIRS_UniNa/icons/redx.png +0 -0
  238. PaIRS_UniNa/icons/reset.png +0 -0
  239. PaIRS_UniNa/icons/reset_levels.png +0 -0
  240. PaIRS_UniNa/icons/resize_icon.png +0 -0
  241. PaIRS_UniNa/icons/restore.png +0 -0
  242. PaIRS_UniNa/icons/restore_undo.png +0 -0
  243. PaIRS_UniNa/icons/rotate_clock.png +0 -0
  244. PaIRS_UniNa/icons/rotate_counter.png +0 -0
  245. PaIRS_UniNa/icons/rotate_v_clock.png +0 -0
  246. PaIRS_UniNa/icons/rotate_v_counter.png +0 -0
  247. PaIRS_UniNa/icons/running.gif +0 -0
  248. PaIRS_UniNa/icons/running.png +0 -0
  249. PaIRS_UniNa/icons/running_warn.png +0 -0
  250. PaIRS_UniNa/icons/sandglass.png +0 -0
  251. PaIRS_UniNa/icons/save.png +0 -0
  252. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  253. PaIRS_UniNa/icons/save_cfg.png +0 -0
  254. PaIRS_UniNa/icons/saveas.png +0 -0
  255. PaIRS_UniNa/icons/saveas_workspace.png +0 -0
  256. PaIRS_UniNa/icons/scale_all.png +0 -0
  257. PaIRS_UniNa/icons/scale_down.png +0 -0
  258. PaIRS_UniNa/icons/scale_up.png +0 -0
  259. PaIRS_UniNa/icons/scan_list.png +0 -0
  260. PaIRS_UniNa/icons/scan_path.png +0 -0
  261. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  262. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  263. PaIRS_UniNa/icons/search.png +0 -0
  264. PaIRS_UniNa/icons/showIW_off.png +0 -0
  265. PaIRS_UniNa/icons/showIW_on.png +0 -0
  266. PaIRS_UniNa/icons/show_all.png +0 -0
  267. PaIRS_UniNa/icons/sort.png +0 -0
  268. PaIRS_UniNa/icons/sort_reversed.png +0 -0
  269. PaIRS_UniNa/icons/spiv_proc.png +0 -0
  270. PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
  271. PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
  272. PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
  273. PaIRS_UniNa/icons/star.png +0 -0
  274. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  275. PaIRS_UniNa/icons/subMIN_off.png +0 -0
  276. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  277. PaIRS_UniNa/icons/tom.png +0 -0
  278. PaIRS_UniNa/icons/trash.png +0 -0
  279. PaIRS_UniNa/icons/undo.png +0 -0
  280. PaIRS_UniNa/icons/unedited.png +0 -0
  281. PaIRS_UniNa/icons/unina_dii.png +0 -0
  282. PaIRS_UniNa/icons/uninitialized.png +0 -0
  283. PaIRS_UniNa/icons/unlink.png +0 -0
  284. PaIRS_UniNa/icons/unwrap_items.png +0 -0
  285. PaIRS_UniNa/icons/up.png +0 -0
  286. PaIRS_UniNa/icons/updating_import.gif +0 -0
  287. PaIRS_UniNa/icons/updating_pairs.gif +0 -0
  288. PaIRS_UniNa/icons/vectorColor.png +0 -0
  289. PaIRS_UniNa/icons/vettore.png +0 -0
  290. PaIRS_UniNa/icons/view.png +0 -0
  291. PaIRS_UniNa/icons/view_off.png +0 -0
  292. PaIRS_UniNa/icons/vis_logo.png +0 -0
  293. PaIRS_UniNa/icons/waiting_circle.png +0 -0
  294. PaIRS_UniNa/icons/warning.png +0 -0
  295. PaIRS_UniNa/icons/warning_circle.png +0 -0
  296. PaIRS_UniNa/icons/window.png +0 -0
  297. PaIRS_UniNa/icons/workspace.png +0 -0
  298. PaIRS_UniNa/icons/wrap_items.png +0 -0
  299. PaIRS_UniNa/icons/write_list.png +0 -0
  300. PaIRS_UniNa/listLib.py +303 -0
  301. PaIRS_UniNa/mtfPIV.py +256 -0
  302. PaIRS_UniNa/parForMulti.py +435 -0
  303. PaIRS_UniNa/parForWorkers.py +593 -0
  304. PaIRS_UniNa/pivParFor.py +235 -0
  305. PaIRS_UniNa/plt_util.py +141 -0
  306. PaIRS_UniNa/preProcParFor.py +155 -0
  307. PaIRS_UniNa/procTools.py +1439 -0
  308. PaIRS_UniNa/readcfg.py +52 -0
  309. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  310. PaIRS_UniNa/stereoPivParFor.py +227 -0
  311. PaIRS_UniNa/tAVarie.py +215 -0
  312. PaIRS_UniNa/tabSplitter.py +612 -0
  313. PaIRS_UniNa/ui_Calibration_Tab.py +578 -0
  314. PaIRS_UniNa/ui_Custom_Top.py +296 -0
  315. PaIRS_UniNa/ui_Input_Tab.py +1101 -0
  316. PaIRS_UniNa/ui_Input_Tab_CalVi.py +1283 -0
  317. PaIRS_UniNa/ui_Log_Tab.py +263 -0
  318. PaIRS_UniNa/ui_Output_Tab.py +2362 -0
  319. PaIRS_UniNa/ui_Process_Tab.py +3810 -0
  320. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1549 -0
  321. PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
  322. PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
  323. PaIRS_UniNa/ui_ResizePopup.py +204 -0
  324. PaIRS_UniNa/ui_Vis_Tab.py +1628 -0
  325. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1251 -0
  326. PaIRS_UniNa/ui_Whatsnew.py +132 -0
  327. PaIRS_UniNa/ui_gPairs.py +877 -0
  328. PaIRS_UniNa/ui_infoPaIRS.py +551 -0
  329. PaIRS_UniNa/whatsnew.txt +4 -0
  330. pairs_unina-0.2.10.dist-info/METADATA +159 -0
  331. pairs_unina-0.2.10.dist-info/RECORD +333 -0
  332. pairs_unina-0.2.10.dist-info/WHEEL +5 -0
  333. pairs_unina-0.2.10.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1761 @@
1
+ from .ui_Process_Tab import*
2
+ from .TabTools import*
3
+ from .Custom_Top import Custom_Top
4
+ #from procTools import *
5
+
6
+ Flag_type_of_DCs=False
7
+ Flag_Hart_corr=False
8
+ Flag_Nogueira=False
9
+ minNIterAdaptative=5
10
+
11
+ mode_items= ['simple', #0
12
+ 'advanced', #1
13
+ 'expert'] #2
14
+
15
+ top_items=[ 'custom', #0
16
+ 'preview', #1
17
+ 'fast', #2
18
+ 'standard',#3
19
+ 'advanced',#4
20
+ 'high resolution', #5
21
+ 'adaptative resolution'] #6
22
+
23
+ mode_init=0
24
+ top_init=3
25
+ WSize_init=[128, 64, 32]
26
+ WSpac_init=[ 64, 16, 8]
27
+
28
+ ImInt_items=( #************ do not change the order of items here!
29
+ 'none', # none
30
+ 'moving window', # moving window
31
+ 'linear revitalized', # linear revitalized
32
+ 'bilinear/biquadratic/bicubic', # bilinear/biquadratic/bicubic
33
+ 'simplex', # simplex
34
+ 'shift theorem', # shift theorem
35
+ 'sinc (Whittaker-Shannon)', # sinc (Whittaker-Shannon)
36
+ 'B-spline' # B-spline
37
+ )
38
+ ImInt_order=[i for i in range(len(ImInt_items))] #************ change here, please!
39
+
40
+ VelInt_items=( #************ do not change the order of items here!
41
+ 'bilinear', # bilinear
42
+ 'linear revitalized', # linear revitalized
43
+ 'simplex', # simplex
44
+ 'shift theorem', # shift theorem
45
+ 'shift theorem (extrapolation)', # shift theorem (extrapolation)
46
+ 'B-spline' # B-spline
47
+ )
48
+ VelInt_order=[i for i in range(len(VelInt_items))] #************ change here, please!
49
+
50
+
51
+ Wind_items=( #************ do not change the order of items here!
52
+ 'top-hat', # top-hat
53
+ 'Nogueira', # Nogueira
54
+ 'Blackman', # Blackman
55
+ 'Blackman-Harris', # Blackman-Harris
56
+ 'triangular', # Triangular
57
+ 'Hann', # Hann
58
+ 'Gaussian', # Gaussian
59
+ )
60
+ Wind_abbrev=('TH','NG','BL','BH','TR','HN','GS')
61
+ #Wind_order=[i for i in range(8)] #************ change here, please!
62
+ Wind_order=[0,2,6,3,5,1,4]
63
+
64
+ spin_tips={
65
+ 'final_iter' : 'Number of final iterations',
66
+ 'final_it' : 'Number of final iterations for different image interpolation',
67
+ 'KernMed' : 'Semi-kernel for median test',
68
+ 'SogliaMed' : 'Alpha threshold for median test',
69
+ 'ErroreMed' : 'Epsilon threshold for median test',
70
+ 'JumpMed' : 'Spacing of vectors for validation',
71
+ 'SogliaSN' : 'Threshold for S/N test',
72
+ 'SogliaCP' : 'Threshold for correlation peak test',
73
+ 'SogliaMedia' : 'Tolerance for Nogueira test',
74
+ 'SogliaNumVet' : 'Number of vectors for Nogueira test',
75
+ 'SogliaNoise' : 'Minimum allowed value for validation',
76
+ 'SogliaStd' : 'Minimum allowed st.d. value for validation',
77
+ 'Wind_halfwidth' : 'Weighting window half-width',
78
+ 'NItAdaptative' : 'Number of iterations for adaptative process',
79
+ 'MinC' : 'Minimum correlation value for adapatative process',
80
+ 'MaxC' : 'Maximum correlation value for adapatative process',
81
+ 'LarMax' : 'Maximum half-width for adapatative process',
82
+ 'LarMin' : 'Minimum half-width for adapatative process',
83
+ 'order' : 'Kernel width for image interpolation',
84
+ 'order_2' : 'Kernel width for image interpolation (final it.)',
85
+ 'VelInt_order' : 'Kernel width for velocity interpolation',
86
+ 'par_Gauss' : 'Alpha threshold for Gaussian window',
87
+ 'par_Gauss_2' : 'Half-width for Gaussian window',
88
+ 'MaxDisp_absolute' : 'Maximum displacement',
89
+ }
90
+ button_tips={
91
+ 'more_size' : 'Rectangular IW',
92
+ 'more_iter' : 'Image interpolation (final it.)',
93
+ 'edit_custom': 'Custom type of process',
94
+ 'add' : 'PIV process iterations',
95
+ 'delete' : 'PIV process iterations',
96
+ 'FinIt' : 'Final iteration box',
97
+ 'Interp' : 'Interpolation box',
98
+ 'Validation' : 'Validation box',
99
+ 'Windowing' : 'Windowing box',
100
+ 'top' : 'Type of process box',
101
+ 'save_custom': 'Save custom process',
102
+ 'mtf' : 'Plot MTF',
103
+ 'save_cfg' : 'Save of .cfg file',
104
+ 'tool_CollapBox_IntWind' : 'Graphics',
105
+ 'CollapBox_IntWind' : 'Graphics',
106
+ 'tool_CollapBox_FinIt' : 'Graphics',
107
+ 'CollapBox_FinIt' : 'Graphics',
108
+ 'tool_CollapBox_top' : 'Graphics',
109
+ 'CollapBox_top' : 'Graphics',
110
+ 'tool_CollapBox_Interp' : 'Graphics',
111
+ 'CollapBox_Interp' : 'Graphics',
112
+ 'tool_Validation' : 'Graphics',
113
+ 'CollapBox_Validation' : 'Graphics',
114
+ 'tool_Windowing' : 'Graphics',
115
+ 'CollapBox_Windowing' : 'Graphics',
116
+ }
117
+ check_tips={
118
+ 'Bordo' : 'First vector at IW spacing',
119
+ 'DC' : 'Direct correlation',
120
+ 'SecMax' : 'Second correlation peak correction',
121
+ 'CorrHart' : 'Hart''s correction',
122
+ 'DC_it' : 'DC for current iteration',
123
+ }
124
+ line_edit_tips={
125
+ 'size' : 'IW size' ,
126
+ 'spacing' : 'IW spacing',
127
+ 'size_2' : 'IW size' ,
128
+ 'spacing_2' : 'IW spacing',
129
+ 'IW' : 'IW sizes and/or spacings',
130
+ }
131
+ combo_tips ={
132
+ 'mode' : 'Process mode',
133
+ 'top' : 'Type of process',
134
+ 'custom_top' : 'Custom type of process',
135
+ 'correlation' : 'Correlation map interpolation',
136
+ 'TypeMed' : 'Median test type',
137
+ 'FlagCorrezioneVel' : 'Correction type',
138
+ 'FlagSommaProd' : 'Type of DCs',
139
+ 'ImInt' : 'Image interpolation',
140
+ 'par_pol' : 'Polynomial interpolation',
141
+ 'par_imshift' : 'Moving window',
142
+ 'ImInt_2' : 'Image interpolation (final it.)',
143
+ 'par_pol_2' : 'Polynomial interpolation (final it.)',
144
+ 'par_imshift_2' : 'Moving window (final it.)',
145
+ 'int_vel' : 'Velocity field interpolation',
146
+ 'Wind_Vel_type' : 'Velocity weighting window',
147
+ 'par_tophat' : 'Top-hat window type (vel.)',
148
+ 'par_Nog' : 'Nogueira window type (vel.)',
149
+ 'par_Bla' : 'Blackman window type (vel.)',
150
+ 'par_Har' : 'Blackman-Harris window type (vel.)',
151
+ 'Wind_Corr_type' : 'Correlation map weighting window',
152
+ 'par_tophat_2' : 'Top-hat window type (corr.)',
153
+ 'par_Nog_2' : 'Nogueira window type (corr.)',
154
+ 'par_Bla_2' : 'Blackman window type (corr.)',
155
+ 'par_Har_2' : 'Blackman-Harris window type (corr.)',
156
+ 'MaxDisp_type' : 'Maximum displacement type',
157
+ 'MaxDisp_relative' : 'Maximum displacement',
158
+ }
159
+ radio_tips={
160
+ 'MedTest' : 'Median test',
161
+ 'SNTest' : 'S/N test',
162
+ 'CPTest' : 'Correlation peak test',
163
+ 'Nogueira' : 'Nogueira test',
164
+ 'Adaptative': 'Adaptative process',
165
+ }
166
+
167
+ def cont_fields(diz):
168
+ cont=0
169
+ for f,v in diz:
170
+ if not 'fields' in f and f[0]!='_':
171
+ cont+=1
172
+ return cont
173
+
174
+ class PROpar(TABpar):
175
+ mode=mode_init
176
+
177
+ def __init__(self,top=top_init,WSize=WSize_init,WSpac=WSpac_init,Process=ProcessTypes.null,Step=StepTypes.null):
178
+ #attributes in fields
179
+ self.setup(top,WSize,WSpac,Process,Step)
180
+ super().__init__('PROpar','Process')
181
+ self.unchecked_fields+=['prev_top','mode',\
182
+ 'FlagFinIt_reset','FlagInterp_reset','FlagValidation_reset','FlagWindowing_reset','FlagCustom',\
183
+ 'IntIniz_ind_list','IntFin_ind_list',\
184
+ 'VectFlag','flag_rect_wind','row','col',\
185
+ 'FlagCalcVel','FlagWindowing','SemiDimCalcVel','MaxDisp','FlagDC_it']
186
+
187
+ def setup(self,top=top_init,WSize=WSize_init,WSpac=WSpac_init,Process=ProcessTypes.null,Step=StepTypes.null):
188
+ self.Process = Process
189
+ self.Step = Step
190
+ cont=[0]
191
+ name_fields=['']
192
+ #************* DEFAULT VALUES
193
+ #******************************* base_fields
194
+ self.FlagCustom=False
195
+ self.FlagFinIt_reset=False
196
+ self.FlagInterp_reset=False
197
+ self.FlagValidation_reset=False
198
+ self.FlagWindowing_reset=False
199
+
200
+ if not self.mode in mode_items:
201
+ self.mode=0
202
+ self.top=top
203
+ self.prev_top=top
204
+ self.custom_top_name=''
205
+
206
+ cont.append(cont_fields(self.__dict__.items()))
207
+ name_fields.append('base')
208
+
209
+ #******************************* IW_fields
210
+ self.Nit=len(WSize)
211
+ Vect=[copy.deepcopy(WSize),copy.deepcopy(WSpac),copy.deepcopy(WSize),copy.deepcopy(WSpac)]
212
+ self.Vect=Vect
213
+ self.VectFlag=[True]*4
214
+ self.flag_rect_wind=False
215
+ self.FlagBordo=1
216
+
217
+ cont.append(cont_fields(self.__dict__.items()))
218
+ name_fields.append('IW')
219
+
220
+ #******************************* FinalIt_fields
221
+ self.FlagDirectCorr=1
222
+ self.NIterazioni=0
223
+
224
+ cont.append(cont_fields(self.__dict__.items()))
225
+ name_fields.append('FinalIt')
226
+
227
+ #******************************* Int_fields
228
+ self.IntIniz=1
229
+ self.IntIniz_ind_list=[3,1,2]
230
+ self.IntFin=1
231
+ self.IntFin_ind_list=[3,1,2]
232
+ self.FlagInt=0
233
+ self.IntCorr=0
234
+ self.IntVel=1
235
+
236
+ cont.append(cont_fields(self.__dict__.items()))
237
+ name_fields.append('Int')
238
+
239
+ #******************************* Validation_fields
240
+ self.FlagMedTest=1
241
+ self.TypeMed=1
242
+ self.KernMed=1
243
+ self.SogliaMed=2.0
244
+ self.ErroreMed=0.5
245
+ self.JumpMed=1
246
+
247
+ self.FlagSNTest=0
248
+ self.SogliaSN=1.5
249
+
250
+ self.FlagCPTest=0
251
+ self.SogliaCP=0.2
252
+
253
+ self.FlagNogTest=0
254
+ self.SogliaMedia=0.25
255
+ self.SogliaNumVet=0.10
256
+
257
+ self.SogliaNoise=2.00
258
+ self.SogliaStd=3.00
259
+ self.FlagCorrezioneVel=1
260
+ self.FlagSecMax=1
261
+ self.FlagCorrHart=0
262
+
263
+ cont.append(cont_fields(self.__dict__.items()))
264
+ name_fields.append('Validation')
265
+
266
+ #******************************* Windowing_fields
267
+ self.vFlagCalcVel=[0]*self.Nit
268
+ self.vFlagWindowing=[0]*self.Nit
269
+ self.vSemiDimCalcVel=[0]*self.Nit
270
+ self.vMaxDisp=[-4]*self.Nit
271
+ if self.Nit>1:
272
+ self.vDC=[0]*(self.Nit-1)+[self.FlagDirectCorr]
273
+ else:
274
+ self.vDC=[0]
275
+
276
+
277
+ self.FlagAdaptative=0
278
+ self.NItAdaptative=2
279
+ self.MinC=0.4
280
+ self.MaxC=0.75
281
+ self.LarMin=1
282
+ self.LarMax=16
283
+ self.FlagSommaProd=0
284
+
285
+ cont.append(cont_fields(self.__dict__.items()))
286
+ name_fields.append('Wind')
287
+
288
+ self.row=0
289
+ self.col=0
290
+
291
+ if self.top==1: #preview/custom
292
+ self.IntIniz=3
293
+ self.IntFin=3
294
+ self.IntVel=1
295
+ self.NIterazioni=0
296
+ elif self.top==2: #fast
297
+ self.IntIniz=1
298
+ self.IntFin=1
299
+ self.IntVel=1
300
+ self.NIterazioni=1
301
+ elif self.top==0 or self.top==3: #standard
302
+ self.IntIniz=53
303
+ self.IntFin=53
304
+ self.IntVel=52
305
+ self.NIterazioni=2
306
+ elif self.top==4: #advanced
307
+ self.IntIniz=57
308
+ self.IntFin=57
309
+ self.IntVel=53
310
+ self.NIterazioni=2
311
+
312
+ self.vFlagCalcVel=[2]*self.Nit
313
+ self.vFlagWindowing=[2]*self.Nit
314
+ elif self.top==5: #high resolution
315
+ self.IntIniz=57
316
+ self.IntFin=57
317
+ self.IntVel=53
318
+ self.NIterazioni=10
319
+
320
+ self.vFlagCalcVel=[2]*self.Nit
321
+ self.vFlagWindowing=[2]*self.Nit
322
+ self.vSemiDimCalcVel=[3]*self.Nit
323
+ elif self.top==6: #adaptative
324
+ self.IntIniz=57
325
+ self.IntFin=57
326
+ self.IntVel=53
327
+ self.NIterazioni=20
328
+
329
+ self.FlagAdaptative=1
330
+ self.vFlagCalcVel=[2]*(self.Nit+1)
331
+ self.vFlagWindowing=[2]*(self.Nit+1)
332
+ self.vSemiDimCalcVel=[3]*self.Nit+[self.LarMax]
333
+ self.vMaxDisp+=[self.vMaxDisp[-1]]
334
+ self.vDC+=[self.vDC[-1]]
335
+
336
+ self.FlagCalcVel =self.vFlagCalcVel [self.row]
337
+ self.FlagWindowing =self.vFlagWindowing [self.row]
338
+ self.SemiDimCalcVel=self.vSemiDimCalcVel[self.row]
339
+ self.MaxDisp =self.vMaxDisp [self.row]
340
+ self.FlagDC_it =self.vDC [self.row]
341
+
342
+ for j in range(1,len(cont)):
343
+ setattr(self,name_fields[j]+"_fields",[])
344
+ d=getattr(self,name_fields[j]+"_fields")
345
+ k=-1
346
+ for f,_ in self.__dict__.items():
347
+ k+=1
348
+ if k in range(cont[j-1],cont[j]):
349
+ d.append(f)
350
+
351
+ def change_top(self,top_new):
352
+ WSize=[w for w in self.Vect[0]]
353
+ WSpac=[w for w in self.Vect[1]]
354
+ newist=PROpar(top_new,WSize,WSpac,self.Process,self.Step)
355
+ newist.copyfromfields(self,newist.parFields)
356
+ for f in self.fields:
357
+ if f not in self.IW_fields:
358
+ setattr(self,f,getattr(newist,f))
359
+
360
+ class Process_Tab(gPaIRS_Tab):
361
+ class Process_Tab_Signals(gPaIRS_Tab.Tab_Signals):
362
+ pass
363
+
364
+ def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
365
+ super().__init__(parent,Ui_ProcessTab,PROpar)
366
+ self.signals=self.Process_Tab_Signals(self)
367
+
368
+ #------------------------------------- Graphical interface: widgets
369
+ self.TABname='Process'
370
+ self.ui: Ui_ProcessTab
371
+ ui=self.ui
372
+
373
+ self.Vect_widgets=[ui.line_edit_size,\
374
+ ui.line_edit_spacing,\
375
+ ui.line_edit_size_2,\
376
+ ui.line_edit_spacing_2]
377
+ self.Vect_Lab_widgets=[ui.check_edit_size,\
378
+ ui.check_edit_spacing,\
379
+ ui.check_edit_size_2,\
380
+ ui.check_edit_spacing_2]
381
+ ui.line_edit_size.addlab=ui.check_edit_size
382
+ ui.line_edit_size.addwid=[w for w in self.Vect_widgets]
383
+ ui.line_edit_size.addwid.append(ui.spin_final_iter)
384
+ ui.line_edit_spacing.addlab=ui.check_edit_spacing
385
+ ui.line_edit_spacing.addwid=ui.line_edit_size.addwid
386
+ ui.line_edit_size_2.addlab=ui.check_edit_size_2
387
+ ui.line_edit_size_2.addwid=ui.line_edit_size.addwid
388
+ ui.line_edit_spacing_2.addlab=ui.check_edit_spacing_2
389
+ ui.line_edit_spacing_2.addwid=ui.line_edit_size.addwid
390
+ ui.table_iter.addwid.append(ui.line_edit_IW)
391
+
392
+ #necessary to change the name and the order of the items
393
+ for g in list(globals()):
394
+ if '_items' in g or '_ord' in g or '_tips' in g:
395
+ #pri.Info.blue(f'Adding {g} to {self.name_tab}')
396
+ setattr(self,g,eval(g))
397
+ self.Wind_Vel_type_items=Wind_items
398
+ self.Wind_Vel_type_order=Wind_order
399
+ self.Wind_Corr_type_items=Wind_items
400
+ self.Wind_Corr_type_order=Wind_order
401
+
402
+
403
+ if __name__ == "__main__":
404
+ self.app=app
405
+ setAppGuiPalette(self)
406
+
407
+ #------------------------------------- Graphical interface: miscellanea
408
+ self.icon_plus = QIcon()
409
+ self.icon_plus.addFile(u""+ icons_path +"plus.png", QSize(), QIcon.Normal, QIcon.Off)
410
+ self.icon_minus = QIcon()
411
+ self.icon_minus.addFile(u""+ icons_path +"minus.png", QSize(), QIcon.Normal, QIcon.Off)
412
+
413
+ self.Lab_greenv=QPixmap(u""+ icons_path +"greenv.png")
414
+ self.Lab_redx=QPixmap(u""+ icons_path +"redx.png")
415
+ self.Lab_warning=QPixmap(u""+ icons_path +"warning.png")
416
+
417
+ self.ui.button_more_size.setIconSize(self.ui.button_more_size.size()-QSize(6,6))
418
+ self.ui.button_more_iter.setIconSize(self.ui.button_more_iter.size()-QSize(6,6))
419
+
420
+ self.custom_list_file=pro_path+custom_list_file
421
+ self.setCustomTops()
422
+
423
+ self.tableHeaders =[self.ui.table_iter.horizontalHeaderItem(i).text() for i in range(self.ui.table_iter.columnCount())]
424
+ header = self.ui.table_iter.horizontalHeader()
425
+ #it, velocity, correlation, DC, Max. disp.
426
+ header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents) #it
427
+ header.setSectionResizeMode(1, QHeaderView.ResizeMode.Interactive) #velocity
428
+ header.setSectionResizeMode(2, QHeaderView.ResizeMode.Interactive) #correlation
429
+ header.setSectionResizeMode(3, QHeaderView.ResizeMode.Interactive) #Max. disp.
430
+ header.setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents) #DC
431
+ header.setSectionResizeMode(5, QHeaderView.ResizeMode.Stretch) #Info
432
+ self.ui.table_iter.setHorizontalHeaderLabels(self.tableHeaders)
433
+ #header.setMinimumSectionSize(int(self.minimumWidth()/2))
434
+ #header.setMaximumSectionSize(int(self.maximumWidth()/2))
435
+ self.ui.table_iter.InfoLabel=self.ui.label_info
436
+ self.ui.table_iter.DeleteButton=self.ui.button_delete
437
+ self.ui.label_info.hide()
438
+
439
+ #------------------------------------- obsolescences
440
+ if not Flag_type_of_DCs:
441
+ #self.ui.w_type_of_DCs.hide()
442
+ self.ui.label_type_of_DCs.hide()
443
+ self.ui.combo_FlagSommaProd.hide()
444
+ if not Flag_Hart_corr: self.ui.check_CorrHart.hide()
445
+ if not Flag_Nogueira: self.ui.w_Nogueira.hide()
446
+
447
+ #------------------------------------- Declaration of parameters
448
+ self.PROpar_base=PROpar()
449
+ self.PROpar:PROpar=self.TABpar
450
+ self.PROpar_old:PROpar=self.TABpar_old
451
+ self.PROpar_custom=PROpar(0)
452
+
453
+ #------------------------------------- Callbacks
454
+ self.defineWidgets()
455
+ self.setupWid() #---------------- IMPORTANT
456
+
457
+ self.defineActions()
458
+ self.defineCallbacks()
459
+ self.connectCallbacks()
460
+ self.defineAdditionalCallbacks()
461
+ self.defineSet()
462
+ self.defineSettings()
463
+ self.TABsettings.append(self.table_iter_set)
464
+ self.adjustTABpar=self.adjustPROpar
465
+ self.setTABlayout=self.setPROlayout
466
+
467
+ #------------------------------------- Initializing
468
+ if flagInit:
469
+ self.initialize()
470
+ #else:
471
+ # self.setTABpar(FlagBridge=False)
472
+
473
+ def initialize(self):
474
+ pri.Info.yellow(f'{"*"*20} PROCESS initialization {"*"*20}')
475
+ self.setTABpar(FlagBridge=False)
476
+ self.add_TABpar('initialization')
477
+ self.setFocus()
478
+
479
+ def defineActions(self):
480
+ self.defineIWActions()
481
+ self.defineInterpActions()
482
+ self.defineWindowingActions()
483
+ self.defineCollapBoxActions()
484
+
485
+ def defineAdditionalCallbacks(self):
486
+ #additional callbacks
487
+ self.ui.spin_final_it.addfuncout['check_more_iter']=self.spin_final_it_action
488
+ self.ui.spin_final_it.addfuncreturn['check_more_iter']=self.spin_final_it_action
489
+
490
+ #graphical callbacks
491
+ names=['size','spacing','size_2','spacing_2']
492
+ f='line_edit'
493
+ for n in names:
494
+ wid=getattr(self.ui,f+"_"+n)
495
+ fcallback=getattr(self,f+"_"+n+"_changing")
496
+ wid.textChanged.connect(fcallback)
497
+
498
+ #other functions
499
+ self.ui.line_edit_IW.addfuncin["InfoLabelIn"]=self.line_edit_IW_addfuncin
500
+ self.ui.line_edit_IW.addfuncout["InfoLabelOut"]=self.ui.table_iter.resizeInfoLabel
501
+ self.ui.table_iter.itemSelectionChanged.connect(self.wrappedCallback('Iteration table selection',self.table_iter_action))
502
+ self.ui.table_iter.contextMenuEvent=lambda e: self.tableContextMenuEvent(self.ui.table_iter,e)
503
+ self.ui.spin_LarMin.valueChanged.connect(self.spin_LarMin_changing)
504
+
505
+ def defineIWActions(self):
506
+ wtype='line_edit'
507
+ def defineIWAction(i,n):
508
+ widname=wtype+"_"+n
509
+ a1=getattr(self.ui,'line_edit'+'_'+n)
510
+ a2=getattr(self.ui,'check_edit'+'_'+n)
511
+ edit_changing=widname+'_changing'
512
+ setattr(self,edit_changing,lambda: self.edit_Wind_vectors(a1,a2))
513
+ edit_action=widname+'_action'
514
+ setattr(self,edit_action,lambda: self.set_Wind_vectors(a1,a2,i))
515
+ names=['size','spacing','size_2','spacing_2']
516
+ for i,n in enumerate(names):
517
+ defineIWAction(i,n)
518
+ return
519
+
520
+ def defineInterpActions(self):
521
+ if hasattr(self.ui,'combo_ImInt'):
522
+ self.combo_ImInt_action=lambda: Process_Tab.combo_ImInt_action_gen(self,'IntIniz',self.ui.combo_ImInt,self.ui.w_ImInt_par,self.PROpar.IntIniz_ind_list)
523
+ names=['combo_par_pol','combo_par_imshift','spin_order']
524
+ for n in names:
525
+ setattr(self,n+'_action',self.combo_ImInt_action)
526
+
527
+ if hasattr(self.ui,'combo_ImInt_2'):
528
+ self.combo_ImInt_2_action=lambda: Process_Tab.combo_ImInt_action_gen(self,'IntFin',self.ui.combo_ImInt_2,self.ui.w_ImInt_par_2,self.PROpar.IntFin_ind_list)
529
+ names=['combo_par_pol_2','combo_par_imshift_2','spin_order_2']
530
+ for n in names:
531
+ setattr(self,n+'_action',self.combo_ImInt_2_action)
532
+
533
+ if hasattr(self.ui,'combo_int_vel'):
534
+ self.combo_int_vel_action=lambda: Process_Tab.combo_int_vel_action_gen(self,'IntVel',self.ui.combo_int_vel,self.ui.w_VelInt_par)
535
+ self.spin_VelInt_order_action=self.combo_int_vel_action
536
+ return
537
+
538
+ def defineWindowingActions(self):
539
+ self.combo_Wind_Vel_type_action=lambda: self.combo_Wind_Vel_action_gen('FlagCalcVel',self.ui.combo_Wind_Vel_type,self.ui.w_Wind_par)
540
+ names=['combo_par_tophat','combo_par_Nog','combo_par_Bla','combo_par_Har','spin_par_Gauss']
541
+ for n in names:
542
+ setattr(self,n+'_action',self.combo_Wind_Vel_type_action)
543
+
544
+ self.combo_Wind_Corr_type_action=lambda: self.combo_Wind_Vel_action_gen('FlagWindowing',self.ui.combo_Wind_Corr_type,self.ui.w_Wind_par_2)
545
+ names=['combo_par_tophat_2','combo_par_Nog_2','combo_par_Bla_2','combo_par_Har_2','spin_par_Gauss_2']
546
+ for n in names:
547
+ setattr(self,n+'_action',self.combo_Wind_Corr_type_action)
548
+
549
+ self.combo_MaxDisp_relative_action=self.combo_MaxDisp_action
550
+ self.spin_MaxDisp_absolute_action=self.combo_MaxDisp_action
551
+ return
552
+
553
+ def defineCollapBoxActions(self):
554
+ self.button_CollapBox_FinIt_action=lambda: self.reset_field('FinalIt_fields')
555
+ self.button_CollapBox_Interp_action=lambda: self.reset_field('Int_fields')
556
+ self.button_CollapBox_Validation_action=lambda: self.reset_field('Validation_fields')
557
+ self.button_CollapBox_Windowing_action=lambda: self.reset_field('Wind_fields')
558
+ self.button_CollapBox_top_action=self.combo_top_action
559
+ return
560
+
561
+ def defineSet(self):
562
+ self.defineInterpSet()
563
+ self.defineWindowingSet()
564
+
565
+ def defineInterpSet(self):
566
+ if hasattr(self.ui,'combo_ImInt'):
567
+ self.combo_ImInt_set=lambda: Process_Tab.combo_ImInt_set_gen(self,'IntIniz',self.ui.combo_ImInt,self.ui.w_ImInt_par,self.PROpar.IntIniz_ind_list)
568
+ if hasattr(self.ui,'combo_ImInt_2'):
569
+ self.combo_ImInt_2_set=lambda: Process_Tab.combo_ImInt_set_gen(self,'IntFin',self.ui.combo_ImInt_2,self.ui.w_ImInt_par_2,self.PROpar.IntFin_ind_list)
570
+ if hasattr(self.ui,'combo_int_vel'):
571
+ self.combo_int_vel_set=lambda: Process_Tab.combo_int_vel_set_gen(self,'IntVel',self.ui.combo_int_vel,self.ui.w_VelInt_par)
572
+ return
573
+
574
+ def defineWindowingSet(self):
575
+ self.combo_Wind_Vel_type_set=lambda: self.combo_Wind_Vel_set_gen('FlagCalcVel',self.ui.combo_Wind_Vel_type,self.ui.w_Wind_par)
576
+ self.combo_Wind_Corr_type_set=lambda: self.combo_Wind_Vel_set_gen('FlagWindowing',self.ui.combo_Wind_Corr_type,self.ui.w_Wind_par_2)
577
+ self.MTF=None
578
+
579
+ #*************************************************** adjusting PROpars and controls
580
+ def reset_field(self,dizName):
581
+ diz=getattr(self.PROpar,dizName)
582
+ top=self.PROpar.prev_top
583
+ WSize=[w for w in self.PROpar.Vect[0]]
584
+ WSpac=[w for w in self.PROpar.Vect[1]]
585
+ PROpar_old=PROpar(top,WSize,WSpac,self.PROpar.Process,self.PROpar.Step)
586
+ self.PROpar.copyfromfields(PROpar_old,diz)
587
+ if self.PROpar.top==0:
588
+ self.setPROpar_custom()
589
+
590
+ def adjustPROpar(self):
591
+ self.check_reset()
592
+ self.check_more_iter()
593
+ self.adjustWindowingPar()
594
+
595
+ def check_reset(self):
596
+ WSize=[w for w in self.PROpar.Vect[0]]
597
+ WSpac=[w for w in self.PROpar.Vect[1]]
598
+ PROpar_old=PROpar(self.PROpar.top,WSize,WSpac,self.PROpar.Process,self.PROpar.Step)
599
+ if PROpar_old.top==0:
600
+ i=self.ui.combo_custom_top.currentIndex()
601
+ if i!=-1:
602
+ PROpar_old.copyfrom(self.PROpar_customs[i])
603
+ exc=self.PROpar.unchecked_fields+['ind']
604
+ self.PROpar.FlagFinIt_reset=not self.PROpar.isEqualTo(PROpar_old,exc,self.PROpar.FinalIt_fields)
605
+ self.PROpar.FlagInterp_reset=not self.PROpar.isEqualTo(PROpar_old,exc,self.PROpar.Int_fields)
606
+ self.PROpar.FlagValidation_reset=not self.PROpar.isEqualTo(PROpar_old,exc,self.PROpar.Validation_fields)
607
+ self.PROpar.FlagWindowing_reset=not self.PROpar.isEqualTo(PROpar_old,exc,self.PROpar.Wind_fields)
608
+ #self.PROpar.printDifferences(PROpar_old,exc)
609
+ self.PROpar.FlagCustom=self.PROpar.FlagFinIt_reset|self.PROpar.FlagInterp_reset|\
610
+ self.PROpar.FlagValidation_reset|self.PROpar.FlagWindowing_reset
611
+
612
+ def check_more_iter(self):
613
+ max_it=len(self.PROpar.Vect[0])+self.PROpar.NIterazioni
614
+ if max_it==1:
615
+ self.PROpar.FlagInt=0
616
+ else:
617
+ self.ui.spin_final_it.setMaximum(max_it-1)
618
+
619
+ def adjustWindowingPar(self):
620
+ Nit=self.PROpar.Nit
621
+ fields=['vFlagCalcVel','vFlagWindowing','vSemiDimCalcVel','vDC','vMaxDisp']
622
+ for f in fields:
623
+ v=getattr(self.PROpar,f)
624
+ nWind=len(v)
625
+ if nWind>Nit:
626
+ for k in range(nWind-1,Nit-1,-1):
627
+ v.pop(k)
628
+ elif nWind<Nit:
629
+ for k in range(nWind,Nit):
630
+ v.append(v[-1])
631
+ if self.PROpar.FlagAdaptative:
632
+ self.PROpar.vSemiDimCalcVel[-1]=self.PROpar.LarMin
633
+ self.PROpar.vFlagCalcVel+=[self.PROpar.vFlagCalcVel[-1]] #+=[2] per BL
634
+ self.PROpar.vFlagWindowing+=[self.PROpar.vFlagWindowing[-1]] #+=[2] per BL
635
+ self.PROpar.vSemiDimCalcVel+=[self.PROpar.LarMax]
636
+ self.PROpar.vMaxDisp+=[self.PROpar.vMaxDisp[-1]]
637
+ self.PROpar.vDC+=[self.PROpar.vDC[-1]]
638
+ if not self.PROpar.FlagDirectCorr:
639
+ self.PROpar.vDC=[0]*len(self.PROpar.vDC)
640
+ self.PROpar.row=len(self.PROpar.vFlagCalcVel)-1 if self.PROpar.row>=len(self.PROpar.vFlagCalcVel)-1 else self.PROpar.row if self.PROpar.row>-1 else 0
641
+ self.adjustTablePar()
642
+ if self.PROpar.FlagAdaptative and self.PROpar.row==self.PROpar.Nit-1:
643
+ self.PROpar.SemiDimCalcVel=self.PROpar.LarMin
644
+ return
645
+
646
+ def adjustTablePar(self):
647
+ self.PROpar.FlagCalcVel =self.PROpar.vFlagCalcVel [self.PROpar.row]
648
+ self.PROpar.FlagWindowing =self.PROpar.vFlagWindowing [self.PROpar.row]
649
+ self.PROpar.SemiDimCalcVel=self.PROpar.vSemiDimCalcVel[self.PROpar.row]
650
+ self.PROpar.MaxDisp=self.PROpar.vMaxDisp[self.PROpar.row]
651
+ self.PROpar.FlagDC_it=self.PROpar.vDC[self.PROpar.row]
652
+ pri.Callback.green(f'{" "*10} FlagCalcVel={self.PROpar.FlagCalcVel}, FlagWindowing={self.PROpar.FlagWindowing}, SemiDimCalcVel={self.PROpar.SemiDimCalcVel}, MaxDisp={self.PROpar.MaxDisp}, DC={self.PROpar.FlagDC_it}')
653
+
654
+ def setPushCollapBoxes(self,*args):
655
+ if len(args):
656
+ cb=args #tuple
657
+ else:
658
+ cb=('FinIt','Interp','Validation','Windowing','ToP')
659
+ for n in cb:
660
+ if n!='ToP':
661
+ flag=getattr(self.PROpar,'Flag'+n+'_reset')
662
+ push=getattr(self.ui,'button_CollapBox_'+n)
663
+ CollapBox=getattr(self.ui,'CollapBox_'+n)
664
+ if flag:
665
+ push.show()
666
+ else:
667
+ push.hide()
668
+ w=getattr(self.ui,'CollapBox_'+n)
669
+ #w.setFocus()
670
+ CollapBox.FlagPush=flag
671
+ if self.PROpar.FlagCustom:
672
+ self.ui.button_save_custom.show()
673
+ self.ui.label_top.setText("Modified from ")
674
+ self.ui.button_CollapBox_top.show()
675
+ self.ui.CollapBox_top.FlagPush=True
676
+ else:
677
+ self.ui.button_save_custom.hide()
678
+ self.ui.label_top.setText("Current")
679
+ self.ui.button_CollapBox_top.hide()
680
+ self.ui.CollapBox_top.FlagPush=False
681
+
682
+ #*************************************************** From Parameters to UI
683
+ def setPROlayout(self):
684
+ self.setPROlayout_mode()
685
+ self.setPROlayout_IW()
686
+ self.setPROlayout_ToP()
687
+ self.setPushCollapBoxes()
688
+ self.setPROlayout_Int()
689
+ self.setPROlayout_Valid()
690
+ self.setPROlayout_Wind()
691
+
692
+ #*************************************************** MODE
693
+ #******************** Actions
694
+ def combo_mode_action(self):
695
+ self.PROpar.mode=PROpar.mode=self.ui.combo_mode.currentIndex()
696
+ return
697
+
698
+ def button_save_cfg_action(self):
699
+ Title='Select location and name of the configuration file to save'
700
+ filename, _ = QFileDialog.getSaveFileName(self,Title,
701
+ filter=f'*.cfg',\
702
+ options=optionNativeDialog)
703
+ filename=myStandardRoot('{}'.format(str(filename)))
704
+ if not filename: return
705
+ if 'dataTreePar' not in list(globals()):
706
+ from .procTools import dataTreePar
707
+ data=dataTreePar(self.PROpar.Process,self.PROpar.Step)
708
+ data.setProc(PRO=self.PROpar.duplicate())
709
+ data.writeCfgProcPiv(filename,FlagWarningDialog=True)
710
+
711
+ #******************** Settings
712
+ def combo_mode_set(self):
713
+ self.ui.combo_mode.setCurrentIndex(PROpar.mode)
714
+ return
715
+
716
+ #******************** Layout
717
+ def setPROlayout_mode(self):
718
+ index=PROpar.mode
719
+ self.ui.CollapBox_Interp.setVisible(index>0)
720
+ self.ui.CollapBox_Validation.setVisible(index>1)
721
+ self.ui.CollapBox_Windowing.setVisible(index>1)
722
+
723
+ #*************************************************** INTERROGATION WINDOWS
724
+ #******************** Actions
725
+ def edit_Wind_vectors(self,wedit:QLineEdit,wlab:QLabel):
726
+ text=wedit.text()
727
+ split_text=re.split(r'(\d+)', text)[1:-1:2]
728
+ vect=[int(i) for i in split_text]
729
+ FlagEmpty=len(vect)==0
730
+ if FlagEmpty: FlagError=True
731
+ else: FlagError=not all([v>=w for v,w in zip(vect[:-1],vect[1:])])
732
+ if FlagError:
733
+ wlab.setPixmap(self.Lab_warning)
734
+ if FlagEmpty:
735
+ message="Please, insert at least one element!"
736
+ else:
737
+ message="Items must be inserted in decreasing order!"
738
+ else:
739
+ wlab.setPixmap(QPixmap())
740
+ message=""
741
+ show_mouse_tooltip(wedit,message)
742
+ wlab.setToolTip(message)
743
+ wlab.setStatusTip(message)
744
+ self.PROpar.VectFlag[self.Vect_widgets.index(wedit)]=not FlagError
745
+ return split_text, vect, FlagError
746
+
747
+ def set_Wind_vectors(self,wedit:QLineEdit,wlab:QLabel,i):
748
+ _, vect, FlagError=self.edit_Wind_vectors(wedit,wlab)
749
+ self.set_Wind_vectors_new(i,vect,FlagError)
750
+
751
+ def set_Wind_vectors_new(self,i,vect,FlagError=False):
752
+ if not FlagError:
753
+ Nit_i=len(vect)
754
+ if Nit_i>self.PROpar.Nit:
755
+ self.PROpar.Nit=Nit_i
756
+ else:
757
+ if all([v==w for v,w in zip(vect[:Nit_i],self.PROpar.Vect[i][:Nit_i])]):
758
+ self.PROpar.Nit=Nit_i
759
+ Vect2=[]
760
+ for j in range(4):
761
+ if self.PROpar.flag_rect_wind:
762
+ k=j
763
+ else:
764
+ k=j%2
765
+ if k==i:
766
+ Vect2.append(copy.deepcopy(vect))
767
+ else:
768
+ Vect2.append(copy.deepcopy(self.PROpar.Vect[k]))
769
+ self.PROpar.Vect=self.adjustVect(Vect2)
770
+ self.line_edit_size_set()
771
+
772
+ def adjustVect(self,Vect):
773
+ for i,v in enumerate(Vect):
774
+ if self.PROpar.Nit<len(v):
775
+ Vect[i]=v[:self.PROpar.Nit]
776
+ elif self.PROpar.Nit>len(v):
777
+ Vect[i]=v+[v[-1] for _ in range(self.PROpar.Nit-len(v))] #np.append(v,np.repeat(v[-1],self.PROpar.Nit-len(v)))
778
+ """
779
+ rep=np.array([0,0,0,0])
780
+ for i,v in enumerate(Vect):
781
+ if len(v)>1:
782
+ while rep[i]<len(v)-1:
783
+ if v[-1-rep[i]]==v[-2-rep[i]]: rep[i]+=1
784
+ else: break
785
+ #si potrebbe programmare meglio...
786
+ dit=np.min(rep)
787
+ if dit:
788
+ self.PROpar.Nit-=dit
789
+ for i in range(4):
790
+ Vect[i]=Vect[i][:self.PROpar.Nit]
791
+ self.ui.spin_final_iter.setValue(self.ui.spin_final_iter.value()+dit)
792
+ """
793
+ self.line_edit_size_set()
794
+ return Vect
795
+
796
+ def button_more_size_action(self):
797
+ self.PROpar.flag_rect_wind=not self.PROpar.flag_rect_wind
798
+ if not self.PROpar.flag_rect_wind:
799
+ self.PROpar.Vect[2]=copy.deepcopy(self.PROpar.Vect[0])
800
+ self.PROpar.Vect[3]=copy.deepcopy(self.PROpar.Vect[1])
801
+
802
+ def check_Bordo_action(self):
803
+ if self.ui.check_Bordo.isChecked():
804
+ self.PROpar.FlagBordo=1
805
+ else:
806
+ self.PROpar.FlagBordo=0
807
+ pass
808
+
809
+ #******************** Settings
810
+ def line_edit_size_set(self):
811
+ for i in range(len(self.Vect_widgets)):
812
+ w=self.Vect_widgets[i]
813
+ v=self.PROpar.Vect[i]
814
+ l=self.Vect_Lab_widgets[i]
815
+ text="".join([str(t)+", " for t in v[:-1]]) + str(v[-1])
816
+ w.setText(text)
817
+ if self.PROpar.VectFlag[i]:
818
+ l.setPixmap(self.Lab_greenv)
819
+ l.setToolTip('')
820
+ l.setStatusTip('')
821
+ else:
822
+ l.setPixmap(self.Lab_redx)
823
+ self.check_more_iter()
824
+
825
+ def button_more_size_set(self):
826
+ self.ui.button_more_size.setChecked(self.PROpar.flag_rect_wind)
827
+
828
+ #******************** Layout
829
+ def setPROlayout_IW(self):
830
+ if self.PROpar.flag_rect_wind:
831
+ self.ui.button_more_size.setIcon(self.icon_minus)
832
+ self.ui.w_IW_size_2.show()
833
+ #self.ui.label_size.setText("Width")
834
+ #self.ui.label_spacing.setText("Horizontal")
835
+ self.ui.label_size.setText("Height")
836
+ self.ui.label_spacing.setText("Vertical")
837
+ else:
838
+ self.ui.button_more_size.setIcon(self.icon_plus)
839
+ self.ui.w_IW_size_2.hide()
840
+ self.ui.label_size.setText("Size")
841
+ self.ui.label_spacing.setText("Spacing")
842
+
843
+ #*************************************************** FINAL ITERATIONS
844
+ #******************** Actions
845
+ def spin_final_iter_action(self):
846
+ self.PROpar.NIterazioni=self.ui.spin_final_iter.value()
847
+ self.check_more_iter()
848
+
849
+ def check_DC_action(self):
850
+ self.PROpar.FlagDirectCorr=int(self.ui.check_DC.isChecked())
851
+ self.PROpar.vDC=[self.PROpar.FlagDirectCorr]*len(self.PROpar.vDC)
852
+
853
+ #******************** Settings
854
+ def spin_final_iter_preset(self):
855
+ if self.PROpar.FlagAdaptative:
856
+ self.ui.spin_final_iter.setMinimum(minNIterAdaptative)
857
+ else:
858
+ self.ui.spin_final_iter.setMinimum(0)
859
+
860
+ def spin_final_iter_set(self):
861
+ self.ui.spin_final_iter.setValue(self.PROpar.NIterazioni)
862
+
863
+ def check_DC_set(self):
864
+ self.ui.check_DC.setChecked(self.PROpar.FlagDirectCorr)
865
+
866
+ #*************************************************** TYPE OF PROCESS
867
+ #******************** Actions
868
+ def combo_top_action(self):
869
+ self.PROpar.prev_top=self.ui.combo_top.currentIndex()
870
+ if not self.PROpar.top:
871
+ self.setPROpar_custom()
872
+ else:
873
+ self.PROpar.change_top(self.PROpar.top)
874
+ return
875
+
876
+ def setPROpar_custom(self):
877
+ fields=[f for f in self.PROpar.fields if not f in self.PROpar.IW_fields+['ind']]
878
+ i=self.combo_custom_top_ind()
879
+ if len(self.PROpar_customs) and i>-1:
880
+ self.PROpar.copyfromfields(self.PROpar_customs[i],fields)
881
+ else:
882
+ self.PROpar.copyfromfields(self.PROpar_custom,fields)
883
+
884
+ def combo_custom_top_action(self):
885
+ self.PROpar.custom_top_name=self.ui.combo_custom_top.currentText()
886
+ self.combo_top_action()
887
+
888
+ def button_save_custom_action(self):
889
+ name=self.save_as_custom()
890
+ if name!='':
891
+ if name in self.custom_top_items:
892
+ k=self.custom_top_items.index(name)
893
+ self.custom_top_items.pop(k)
894
+ self.PROpar_customs.pop(k)
895
+ self.custom_top_items.insert(0,name)
896
+ self.PROpar_customs.insert(0,self.PROpar.duplicate())
897
+ rewriteCustomList(self.custom_top_items)
898
+
899
+ self.PROpar_custom.copyfrom(self.PROpar)
900
+ self.PROpar.top=0
901
+ self.PROpar.FlagCustom=False
902
+ return True #prevent addition of redos/undos
903
+
904
+ def save_as_custom(self):
905
+ title="Save custom type of process"
906
+ label="Enter the name of the custom type of process:"
907
+ ok,text=inputDialog(self,title,label,completer_list=self.custom_top_items)
908
+
909
+ if ok and text!='':
910
+ filename=pro_path+text+outExt.pro
911
+ if os.path.exists(filename):
912
+ Message=f'Process "{text}" already exists.\nDo you want to overwrite it?'
913
+ flagOverwrite=questionDialog(self,Message)
914
+ if not flagOverwrite: return
915
+ OptionValidRoot=True
916
+ else:
917
+ dummyfilename=pro_path+text+outExt.dum
918
+ try:
919
+ open(dummyfilename,'w')
920
+ except:
921
+ OptionValidRoot=False
922
+ else:
923
+ OptionValidRoot=True
924
+ finally:
925
+ if os.path.exists(dummyfilename):
926
+ os.remove(dummyfilename)
927
+ if not OptionValidRoot:
928
+ warningDialog(self,'Invalid root name! Please, retry.')
929
+ return
930
+
931
+ try:
932
+ with open(filename,'wb') as file:
933
+
934
+ self.PROpar.top=0
935
+ self.PROpar.FlagCustom=False
936
+ self.PROpar.name=text
937
+
938
+ pickle.dump(self.PROpar,file)
939
+ pri.Info.blue(f'Saving custom process file {filename}')
940
+ except Exception as inst:
941
+ pri.Error.red(f'Error while saving custom process file {filename}:\n{traceback.format_exc()}\n\n{inst}')
942
+ text=''
943
+ return text
944
+
945
+ def button_edit_custom_action(self):
946
+ self.edit_dlg = Custom_Top(self.custom_top_items)
947
+ self.edit_dlg.close=lambda: self.edit_dlg.done(0)
948
+ self.edit_dlg.exec()
949
+
950
+ self.edit_dlg.close()
951
+ self.setCustomTops()
952
+ self.combo_custom_top_preset()
953
+ self.combo_top_action()
954
+ return
955
+
956
+ def setCustomTops(self):
957
+ self.PROpar_customs=[]
958
+ self.custom_top_items=setCustomList(lambda var,name: self.PROpar_customs.append(var))
959
+
960
+ #******************** Settings
961
+ def combo_custom_top_preset(self):
962
+ custom_list=[self.ui.combo_custom_top.itemText(i) for i in range(self.ui.combo_custom_top.count())]
963
+ if custom_list!=self.custom_top_items:
964
+ self.ui.combo_custom_top.clear()
965
+ self.ui.combo_custom_top.addItems(self.custom_top_items)
966
+
967
+ def combo_custom_top_set(self):
968
+ self.ui.combo_custom_top.setCurrentIndex(self.combo_custom_top_ind())
969
+
970
+ def combo_custom_top_ind(self):
971
+ if self.PROpar.custom_top_name in self.custom_top_items:
972
+ ind=self.custom_top_items.index(self.PROpar.custom_top_name)
973
+ else:
974
+ ind=0
975
+ return ind
976
+
977
+ #******************** Layout
978
+ def setPROlayout_ToP(self):
979
+ #Type of process
980
+ flagCustomTop=self.PROpar.top==0
981
+ self.ui.w_custom_top.setVisible(flagCustomTop)
982
+ if flagCustomTop:
983
+ flagEn=bool(len(self.custom_top_items))
984
+ if flagEn:
985
+ self.ui.label_custom_top.setText('Custom types')
986
+ else:
987
+ self.ui.label_custom_top.setText('No custom types available')
988
+ self.ui.combo_custom_top.setEnabled(flagEn)
989
+ #self.ui.button_edit_custom.setEnabled(flagEn)
990
+ if flagEn:
991
+ i=-1
992
+ fields=['name']+self.PROpar.FinalIt_fields+self.PROpar.Int_fields+self.PROpar.Validation_fields+self.PROpar.Wind_fields
993
+ for k,p in enumerate(self.PROpar_customs):
994
+ if p.isEqualTo(self.PROpar,[],fields): i=k
995
+ if i>-1:
996
+ self.ui.combo_custom_top.setCurrentIndex(i)
997
+
998
+ #*************************************************** INTERPOLATION
999
+ #******************** Actions
1000
+ def combo_ImInt_action_gen(self,par:str,w:QComboBox,p:QStackedWidget,ImInt_ind_list:list):
1001
+ ind_old=getattr(self.PROpar,par)
1002
+ if w.currentText()==ImInt_items[0]: #none
1003
+ ind=0
1004
+ elif w.currentText()==ImInt_items[4]: #Quad4Simplex
1005
+ ind=1
1006
+ elif w.currentText()==ImInt_items[1]: #Moving S, aS
1007
+ q=p.widget(1)
1008
+ qcombo:QComboBox=q.findChild(QComboBox)
1009
+ ind=qcombo.currentIndex()+3
1010
+ elif w.currentText()==ImInt_items[3]: #BiLinear, BiQuad, BiCubic, BiCubic Matlab
1011
+ q=p.widget(2)
1012
+ qcombo=q.findChild(QComboBox)
1013
+ indeff=(5,2,7,6)
1014
+ ind=indeff[qcombo.currentIndex()]
1015
+ elif w.currentText()==ImInt_items[2]: #Linear revitalized
1016
+ ind=10
1017
+ elif w.currentText()==ImInt_items[5]: #Shift
1018
+ q=p.widget(3)
1019
+ qspin:QSpinBox=q.findChild(QSpinBox)
1020
+ if ind_old>=23 and ind_old<=40:
1021
+ ind=qspin.value()+20
1022
+ else:
1023
+ ind=ImInt_ind_list[0]+20
1024
+ elif w.currentText()==ImInt_items[6]: #Sinc
1025
+ q=p.widget(p.currentIndex())
1026
+ qspin=q.findChild(QSpinBox)
1027
+ if ind_old>=41 and ind_old<=50:
1028
+ ind=qspin.value()+40
1029
+ else:
1030
+ ind=ImInt_ind_list[1]+40
1031
+ elif w.currentText()==ImInt_items[7]: #BSpline
1032
+ q=p.widget(p.currentIndex())
1033
+ qspin=q.findChild(QSpinBox)
1034
+ if ind_old>=52 and ind_old<=70:
1035
+ ind=qspin.value()+50
1036
+ else:
1037
+ ind=ImInt_ind_list[2]+50
1038
+ setattr(self.PROpar,par,ind)
1039
+ return
1040
+
1041
+ def button_more_iter_action(self):
1042
+ self.PROpar.FlagInt=1 if self.PROpar.FlagInt==0 else 0
1043
+
1044
+ def spin_final_it_action(self):
1045
+ self.PROpar.FlagInt=self.ui.spin_final_it.value()
1046
+
1047
+ def combo_int_vel_action_gen(self,par:str,w:QComboBox,p:QStackedWidget):
1048
+ for j in range(5):
1049
+ if w.currentText()==VelInt_items[j]: #none
1050
+ indeff=(1,5,2,3,4)
1051
+ ind=indeff[j]
1052
+ break
1053
+ if w.currentText()==VelInt_items[5]: #BSpline
1054
+ q=p.widget(1)
1055
+ qspin:QSpinBox=q.findChild(QSpinBox)
1056
+ ind=qspin.value()+50
1057
+ setattr(self.PROpar,par,ind)
1058
+ return
1059
+
1060
+ #******************** Settings
1061
+ def combo_ImInt_set_gen(self,par:str,w:QComboBox,p:QStackedWidget,ImInt_ind_list:list):
1062
+ ind=getattr(self.PROpar,par)
1063
+ if ind==0:
1064
+ w.setCurrentIndex(w.findText(ImInt_items[0])) #none #così se scelgo un nome diverso è automatico
1065
+ p.setCurrentIndex(0)
1066
+ elif ind==1: #Quad4Simplex
1067
+ w.setCurrentIndex(w.findText(ImInt_items[4]))
1068
+ p.setCurrentIndex(0)
1069
+ elif ind in (3,4): #Moving S, aS
1070
+ w.setCurrentIndex(w.findText(ImInt_items[1]))
1071
+ p.setCurrentIndex(1)
1072
+ q=p.widget(p.currentIndex())
1073
+ qcombo:QComboBox=q.findChild(QComboBox)
1074
+ qcombo.setCurrentIndex(ind-3)
1075
+ elif ind in (5,2,7,6): #BiLinear, BiQuad, BiCubic, BiCubic Matlab
1076
+ w.setCurrentIndex(w.findText(ImInt_items[3]))
1077
+ p.setCurrentIndex(2)
1078
+ q=p.widget(p.currentIndex())
1079
+ qcombo=q.findChild(QComboBox)
1080
+ indeff=(-1,-1, 1 ,-1,-1, 0,3,2)
1081
+ qcombo.setCurrentIndex(indeff[ind])
1082
+ elif ind==10: #Linear revitalized
1083
+ w.setCurrentIndex(w.findText(ImInt_items[2]))
1084
+ p.setCurrentIndex(0)
1085
+ elif ind>=23 and ind<=40: #Shift
1086
+ w.setCurrentIndex(w.findText(ImInt_items[5]))
1087
+ p.setCurrentIndex(3)
1088
+ q=p.widget(p.currentIndex())
1089
+ qlabel:QLabel=q.findChild(QLabel)
1090
+ qlabel.setText('Kernel width')
1091
+ qspin:MyQSpin=q.findChild(MyQSpin)
1092
+ qspin.setMinimum(3)
1093
+ qspin.setMaximum(20)
1094
+ qspin.setValue(ind-20)
1095
+ ImInt_ind_list[0]=ind-20
1096
+ elif ind>=41 and ind<=50: #Sinc
1097
+ w.setCurrentIndex(w.findText(ImInt_items[6]))
1098
+ p.setCurrentIndex(3)
1099
+ q=p.widget(p.currentIndex())
1100
+ qlabel=q.findChild(QLabel)
1101
+ qlabel.setText('Kernel half-width')
1102
+ qspin=q.findChild(MyQSpin)
1103
+ qspin.setMinimum(1)
1104
+ qspin.setMaximum(10)
1105
+ qspin.setValue(ind-40)
1106
+ ImInt_ind_list[1]=ind-40
1107
+ elif ind>=52 and ind<=70: #BSpline
1108
+ w.setCurrentIndex(w.findText(ImInt_items[7]))
1109
+ p.setCurrentIndex(3)
1110
+ q=p.widget(p.currentIndex())
1111
+ qlabel=q.findChild(QLabel)
1112
+ qlabel.setText('Order (=Kernel width-1)')
1113
+ qspin=q.findChild(MyQSpin)
1114
+ qspin.setMinimum(2)
1115
+ qspin.setMaximum(20)
1116
+ qspin.setValue(ind-50)
1117
+ ImInt_ind_list[2]=ind-50
1118
+
1119
+ def spin_final_it_set(self):
1120
+ self.ui.spin_final_it.setValue(self.PROpar.FlagInt)
1121
+
1122
+ def combo_int_vel_set_gen(self,par:str,w:QComboBox,p:QStackedWidget):
1123
+ ind=getattr(self.PROpar,par)
1124
+ if ind>=1 and ind<=5:
1125
+ indeff=(-1, 0,2,3,4,1)
1126
+ w.setCurrentIndex(w.findText(VelInt_items[indeff[ind]])) #così se scelgo un nome diverso è automatico
1127
+ p.setCurrentIndex(0)
1128
+ elif ind>=52 and ind<=70: #BSpline
1129
+ w.setCurrentIndex(w.findText(VelInt_items[5]))
1130
+ p.setCurrentIndex(1)
1131
+ q=p.widget(p.currentIndex())
1132
+ qspin:QSpinBox=q.findChild(QSpinBox)
1133
+ qspin.setMinimum(2)
1134
+ qspin.setMaximum(20)
1135
+ qspin.setValue(ind-50)
1136
+
1137
+ #******************** Layout
1138
+ def setPROlayout_Int(self):
1139
+ max_it=len(self.PROpar.Vect[0])+self.PROpar.NIterazioni
1140
+ if max_it==1:
1141
+ self.ui.button_more_iter.hide()
1142
+ else:
1143
+ self.ui.label_max_it.setText("of " +str(max_it)+ " iterations")
1144
+ self.ui.button_more_iter.show()
1145
+ if self.PROpar.FlagInt:
1146
+ self.ui.button_more_iter.setIcon(self.icon_minus)
1147
+ self.ui.w_ImInt_2.show()
1148
+ self.ui.w_ImInt_par_2.show()
1149
+ else:
1150
+ self.ui.button_more_iter.setIcon(self.icon_plus)
1151
+ self.ui.w_ImInt_2.hide()
1152
+ self.ui.w_ImInt_par_2.hide()
1153
+
1154
+ #*************************************************** VALIDATION
1155
+ #******************** Actions
1156
+ def radio_MedTest_action(self):
1157
+ if self.ui.radio_MedTest.isChecked():
1158
+ self.PROpar.FlagNogTest=0
1159
+
1160
+ def radio_SNTest_action(self):
1161
+ if self.ui.radio_SNTest.isChecked():
1162
+ self.PROpar.FlagNogTest=0
1163
+
1164
+ def radio_CPTest_action(self):
1165
+ if self.ui.radio_CPTest.isChecked():
1166
+ self.PROpar.FlagNogTest=0
1167
+
1168
+ def radio_Nogueira_action(self):
1169
+ if self.ui.radio_Nogueira.isChecked():
1170
+ self.PROpar.FlagMedTest=0
1171
+ self.PROpar.FlagSNTest=0
1172
+ self.PROpar.FlagCPTest=0
1173
+
1174
+ #******************** Settings
1175
+ def combo_TypeMed_set(self):
1176
+ self.ui.w_MedTest_eps.setVisible(self.PROpar.TypeMed==1 and self.PROpar.FlagMedTest)
1177
+
1178
+ #******************** Layout
1179
+ def setPROlayout_Valid(self):
1180
+ self.showMedTestwid()
1181
+ self.showSNTestwid()
1182
+ self.showCPTestwid()
1183
+ self.showNogTestwid()
1184
+
1185
+ def showMedTestwid(self):
1186
+ self.ui.label_MedTest_box.setVisible(self.PROpar.FlagMedTest)
1187
+ self.ui.w_MedTest_type.setVisible(self.PROpar.FlagMedTest)
1188
+ self.ui.w_MedTest_ker.setVisible(self.PROpar.FlagMedTest)
1189
+ self.ui.w_MedTest_alfa.setVisible(self.PROpar.FlagMedTest)
1190
+ self.ui.w_MedTest_jump.setVisible(self.PROpar.FlagMedTest)
1191
+ self.ui.w_MedTest_eps.setVisible(self.PROpar.TypeMed==1 and self.PROpar.FlagMedTest)
1192
+
1193
+ def showSNTestwid(self):
1194
+ self.ui.label_SNTest.setVisible(self.PROpar.FlagSNTest)
1195
+ self.ui.w_SNTest_thres.setVisible(self.PROpar.FlagSNTest)
1196
+
1197
+ def showCPTestwid(self):
1198
+ self.ui.label_CPTest.setVisible(self.PROpar.FlagCPTest)
1199
+ self.ui.w_CPTest_thres.setVisible(self.PROpar.FlagCPTest)
1200
+
1201
+ def showNogTestwid(self):
1202
+ self.ui.label_Nogueira.setVisible(self.PROpar.FlagNogTest)
1203
+ self.ui.w_Nog_tol.setVisible(self.PROpar.FlagNogTest)
1204
+ self.ui.w_Nog_numvec.setVisible(self.PROpar.FlagNogTest)
1205
+
1206
+ #*************************************************** WINDOWING
1207
+ #******************** Actions
1208
+ def combo_Wind_Vel_action_gen(self,par:str,w:QComboBox,p:QStackedWidget):
1209
+ if w.currentText()==Wind_items[0]: # top-hat/rectangular
1210
+ q=p.widget(1)
1211
+ qcombo:QComboBox=q.findChild(QComboBox)
1212
+ indeff=(0,3,4)
1213
+ ind=indeff[qcombo.currentIndex()]
1214
+ elif w.currentText()==Wind_items[1]: # Nogueira
1215
+ q=p.widget(2)
1216
+ qcombo=q.findChild(QComboBox)
1217
+ indeff=(1,21)
1218
+ ind=indeff[qcombo.currentIndex()]
1219
+ elif w.currentText()==Wind_items[2]: # Blackman
1220
+ """
1221
+ #Blackman options
1222
+ q=p.widget(3)
1223
+ qcombo=q.findChild(QComboBox)
1224
+ indeff=(5,2,6)
1225
+ ind=indeff[qcombo.currentIndex()]
1226
+ """
1227
+ ind=2
1228
+ elif w.currentText()==Wind_items[3]: # Blackman-Harris
1229
+ q=p.widget(4)
1230
+ qcombo=q.findChild(QComboBox)
1231
+ indeff=(7,8,9,10)
1232
+ ind=indeff[qcombo.currentIndex()]
1233
+ elif w.currentText()==Wind_items[4]: # Triangular
1234
+ ind=22
1235
+ elif w.currentText()==Wind_items[5]: # Hann
1236
+ ind=23
1237
+ elif w.currentText()==Wind_items[6]: # Gaussian
1238
+ q=p.widget(5)
1239
+ qspin:MyQDoubleSpin=q.findChild(MyQDoubleSpin)
1240
+ ind=int(qspin.value()*10+100)
1241
+ setattr(self.PROpar,par,ind)
1242
+ if w.objectName()=='combo_Wind_Corr_type':
1243
+ self.PROpar.vFlagWindowing[self.PROpar.row]=self.PROpar.FlagWindowing
1244
+ self.PROpar.col=1
1245
+ else:
1246
+ self.PROpar.vFlagCalcVel[self.PROpar.row]=self.PROpar.FlagCalcVel
1247
+ self.PROpar.col=2
1248
+ return
1249
+
1250
+ def spin_Wind_halfwidth_action(self):
1251
+ self.PROpar.SemiDimCalcVel=self.ui.spin_Wind_halfwidth.value()
1252
+ self.PROpar.vSemiDimCalcVel[self.PROpar.row]=self.PROpar.SemiDimCalcVel
1253
+ self.PROpar.col=2
1254
+
1255
+ def combo_MaxDisp_type_action(self):
1256
+ ind=self.ui.combo_MaxDisp_type.currentIndex()
1257
+ k=min([self.PROpar.row,self.PROpar.Nit-1])
1258
+ if self.PROpar.MaxDisp<0 and ind==1:
1259
+ self.PROpar.MaxDisp=int(1/(-self.PROpar.MaxDisp)*min( [self.PROpar.Vect[0][k], self.PROpar.Vect[2][k]] ))
1260
+ elif self.PROpar.MaxDisp>0 and ind==0:
1261
+ maxDisp=round(min( [self.PROpar.Vect[0][k], self.PROpar.Vect[2][k]] )/self.PROpar.MaxDisp)
1262
+ if maxDisp in [2,3,4,5]:
1263
+ self.PROpar.MaxDisp=-maxDisp
1264
+ elif maxDisp<2:
1265
+ self.PROpar.MaxDisp=-2
1266
+ else:
1267
+ self.PROpar.MaxDisp=-5
1268
+ self.PROpar.vMaxDisp[self.PROpar.row]=self.PROpar.MaxDisp
1269
+ self.PROpar.col=3
1270
+
1271
+ def combo_MaxDisp_action(self):
1272
+ ind=self.ui.combo_MaxDisp_type.currentIndex()
1273
+ if ind:
1274
+ self.PROpar.MaxDisp=self.ui.spin_MaxDisp_absolute.value()
1275
+ else:
1276
+ self.PROpar.MaxDisp=-[2,3,4,5][self.ui.combo_MaxDisp_relative.currentIndex()]
1277
+ self.PROpar.vMaxDisp[self.PROpar.row]=self.PROpar.MaxDisp
1278
+ self.PROpar.col=3
1279
+
1280
+ def check_DC_it_action(self):
1281
+ self.PROpar.vDC[self.PROpar.row]=int(self.ui.check_DC_it.isChecked())
1282
+ self.PROpar.col=4
1283
+
1284
+ def radio_Adaptative_action(self):
1285
+ self.PROpar.NIterazioni=minNIterAdaptative if self.PROpar.NIterazioni<minNIterAdaptative else self.PROpar.NIterazioni
1286
+
1287
+ def spin_LarMin_changing(self):
1288
+ if self.PROpar.FlagAdaptative and self.PROpar.row==self.PROpar.Nit-1:
1289
+ self.ui.spin_Wind_halfwidth.setValue(self.ui.spin_LarMin.value())
1290
+
1291
+ def line_edit_IW_action(self):
1292
+ text=self.ui.line_edit_IW.text()
1293
+ split_text=re.split(r'(\d+)', text)[1:-1:2]
1294
+ if len(split_text)!=4:
1295
+ message="Please insert four distinct values to edit the current PIV process iteration!"
1296
+ show_mouse_tooltip(self,message)
1297
+ self.line_edit_IW_set()
1298
+ else:
1299
+ vect=[int(split_text[i]) for i in (0,2,1,3)]
1300
+ k=self.PROpar.row
1301
+ FlagValid=True
1302
+ if k>0: FlagValid=FlagValid and all([vect[i]<=self.PROpar.Vect[i][k-1] for i in range(4)])
1303
+ if k<self.PROpar.Nit-1 and FlagValid: FlagValid=FlagValid and all([vect[i]>=self.PROpar.Vect[i][k+1] for i in range(4)])
1304
+ if FlagValid:
1305
+ message=""
1306
+ show_mouse_tooltip(self,message)
1307
+ for i in range(4):
1308
+ self.PROpar.Vect[i][k]=vect[i] #np.array([vect[i]])
1309
+ else:
1310
+ message='IW sizes or spacings were assigned inconsistently! They must be inserted in decreasing order across iterations. Please, retry!'
1311
+ show_mouse_tooltip(self,message)
1312
+ self.line_edit_IW_set()
1313
+ self.PROpar.flag_rect_wind=any([v!=w for v,w in zip(self.PROpar.Vect[0],self.PROpar.Vect[2])]) or any([v!=w for v,w in zip(self.PROpar.Vect[1],self.PROpar.Vect[3])])
1314
+ return
1315
+
1316
+ def line_edit_IW_addfuncin(self):
1317
+ k=self.PROpar.row
1318
+ label=[]
1319
+ if k<self.PROpar.Nit-1:
1320
+ label.append('min. = ['+",".join([str(self.PROpar.Vect[i][k+1]) for i in (0,2,1,3)])+']')
1321
+ if k>0:
1322
+ label.append('max. = ['+",".join([str(self.PROpar.Vect[i][k-1]) for i in (0,2,1,3)])+']')
1323
+ if label: label=', '.join(label)
1324
+ else: label='Select arbitrary sizes and spacings'
1325
+ rowInfo=self.ui.table_iter.RowInfo[self.PROpar.row]
1326
+ tip="<br>".join([label,rowInfo])
1327
+ self.ui.table_iter.InfoLabel.setText(tip)
1328
+
1329
+ def table_iter_action(self):
1330
+ self.PROpar.row=self.ui.table_iter.currentRow()
1331
+ self.PROpar.col=self.ui.table_iter.currentColumn()
1332
+ pri.Callback.green(f'{"*"*10} Table selection: r={self.PROpar.row}, c={self.PROpar.col}')
1333
+
1334
+ def tableContextMenuEvent(self, table_iter:QTableWidget, event):
1335
+ item=table_iter.currentItem()
1336
+ if not item: return
1337
+ menu=QMenu(table_iter)
1338
+ menu.setStyleSheet(self.gui.ui.menu.styleSheet())
1339
+ buttons=['add', 'delete']
1340
+ name=[]
1341
+ tips=['Add new iteration to the PIV process','Delete current iteration from the PIV process']
1342
+ act=[]
1343
+ fun=[]
1344
+ for k,nb in enumerate(buttons):
1345
+ if type(nb)==str:
1346
+ b:QPushButton=getattr(self.ui,'button_'+nb)
1347
+ if b.isVisible() and b.isEnabled():
1348
+ if hasattr(self,'button_'+nb+'_callback'):
1349
+ name.append(nb)
1350
+ act.append(QAction(b.icon(),toPlainText(b.toolTip().split('.')[0]),table_iter))
1351
+ menu.addAction(act[-1])
1352
+ callback=getattr(self,'button_'+nb+'_callback')
1353
+ fcallback=self.addParWrapper(callback,tips[k])
1354
+ fun.append(fcallback)
1355
+ else:
1356
+ if len(act): menu.addSeparator()
1357
+
1358
+ if len(act):
1359
+ pri.Callback.yellow(f'||| Opening image list context menu |||')
1360
+ action = menu.exec_(table_iter.mapToGlobal(event.pos()))
1361
+ for nb,a,f in zip(name,act,fun):
1362
+ if a==action:
1363
+ f()
1364
+ break
1365
+ else:
1366
+ toolTip=item.toolTip()
1367
+ item.setToolTip('')
1368
+ item.setStatusTip('')
1369
+
1370
+ message='No context menu available! Please, pause processing.'
1371
+ show_mouse_tooltip(self,message)
1372
+ item.setToolTip(toolTip)
1373
+ item.setStatusTip(toolTip)
1374
+
1375
+ def button_mtf_action(self):
1376
+ self.fig_MTF, self.ax_MTF= plt.subplots()
1377
+ self.ax_MTF.grid()
1378
+ line_NIt=self.ax_MTF.plot(self.MTF[0],self.MTF[1][:,0],color='k',label=f'{self.PROpar.NIterazioni+1:d} iterations')
1379
+ line_inf=self.ax_MTF.plot(self.MTF[0],self.MTF[1][:,1],color='r',linestyle='--',label='∞ iterations')
1380
+ lgnd=self.ax_MTF.legend(loc='lower right')
1381
+ self.ax_MTF.set(xlim=(1, np.max(self.MTF[0])),ylim=(-.30, 1.1))
1382
+ self.ax_MTF.set_title(self.MTF[2])
1383
+ self.ax_MTF.set_xlabel("wavelength (pixels)")
1384
+ self.ax_MTF.set_ylabel("Modulation Transfer Function (MTF)")
1385
+
1386
+ self.ax_MTF.grid(which='minor', linestyle='-', alpha=0.25)
1387
+ self.ax_MTF.minorticks_on()
1388
+
1389
+ if self.MTF[3]:
1390
+ def forward(x):
1391
+ return x/self.MTF[3]
1392
+ def inverse(x):
1393
+ return x*self.MTF[3]
1394
+
1395
+ secax = self.ax_MTF.secondary_xaxis('top', functions=(forward, inverse))
1396
+ secax.set_xlabel('wavelength (mm)')
1397
+ addTexts=[secax.xaxis.label]+secax.get_xticklabels()
1398
+ else:
1399
+ addTexts=[]
1400
+
1401
+ for item in ([self.ax_MTF.title, self.ax_MTF.xaxis.label, self.ax_MTF.yaxis.label] +self.ax_MTF.get_xticklabels() + self.ax_MTF.get_yticklabels()+addTexts+lgnd.get_texts()):
1402
+ item.set_fontsize(self.font().pixelSize())
1403
+ self.fig_MTF.tight_layout()
1404
+
1405
+ self.gui.setEnabled(False)
1406
+ self.fig_MTF.canvas.mpl_connect('close_event', lambda e: self.gui.setEnabled(True))
1407
+ self.fig_MTF.canvas.manager.set_window_title('Modulation Transfer Function')
1408
+ self.fig_MTF.canvas.manager.window.setWindowIcon(self.windowIcon())
1409
+ self.fig_MTF.show()
1410
+ return
1411
+
1412
+ def button_add_action(self):
1413
+ k=self.PROpar.row
1414
+ for i in range(4):
1415
+ self.PROpar.Vect[i].insert(k,self.PROpar.Vect[i][k]) #=np.insert(self.PROpar.Vect[i],k,self.PROpar.Vect[i][k].copy())
1416
+ self.PROpar.Nit+=1
1417
+ fields=['vFlagCalcVel','vFlagWindowing','vSemiDimCalcVel','vDC','vMaxDisp']
1418
+ for f in fields:
1419
+ v=getattr(self.PROpar,f)
1420
+ v.insert(k,v[k])
1421
+ self.PROpar.row=k+1
1422
+
1423
+ def button_delete_action(self):
1424
+ k=self.PROpar.row
1425
+ if k<self.PROpar.Nit:
1426
+ for i in range(4):
1427
+ self.PROpar.Vect[i].pop(k) #=np.delete(self.PROpar.Vect[i],k)
1428
+ self.PROpar.Nit-=1
1429
+ fields=['vFlagCalcVel','vFlagWindowing','vSemiDimCalcVel','vDC','vMaxDisp']
1430
+ for f in fields:
1431
+ v=getattr(self.PROpar,f)
1432
+ v.pop(k)
1433
+ self.PROpar.row=k-1
1434
+ else:
1435
+ self.PROpar.FlagAdaptative=0
1436
+
1437
+ #******************** Settings
1438
+ def combo_Wind_Vel_set_gen(self,par:str,w:QComboBox,p:QStackedWidget):
1439
+ ind=getattr(self.PROpar,par)
1440
+ if Flag_type_of_DCs:
1441
+ if w.objectName()=='combo_Wind_Corr_type':
1442
+ if w.currentText()==Wind_items[0]:
1443
+ self.ui.w_type_of_DCs.hide()
1444
+ else:
1445
+ self.ui.w_type_of_DCs.show()
1446
+ if ind in (0,3,4): # top-hat
1447
+ w.setCurrentIndex(w.findText(Wind_items[0]))
1448
+ p.setCurrentIndex(1)
1449
+ p.show()
1450
+ q=p.widget(p.currentIndex())
1451
+ qcombo:QComboBox=q.findChild(QComboBox)
1452
+ indeff=(0, -1,-1, 1, 2)
1453
+ qcombo.setCurrentIndex(indeff[ind])
1454
+ elif ind in (1,21): # Nogueira
1455
+ w.setCurrentIndex(w.findText(Wind_items[1]))
1456
+ p.setCurrentIndex(2)
1457
+ p.show()
1458
+ q=p.widget(p.currentIndex())
1459
+ qcombo=q.findChild(QComboBox)
1460
+ if ind==1:
1461
+ qcombo.setCurrentIndex(0)
1462
+ else:
1463
+ qcombo.setCurrentIndex(1)
1464
+ elif ind in (5,2,6): # Blackman
1465
+ w.setCurrentIndex(w.findText(Wind_items[2]))
1466
+ p.hide()
1467
+ """
1468
+ #Blackman options
1469
+ p.setCurrentIndex(3)
1470
+ q=p.widget(p.currentIndex())
1471
+ qcombo=q.findChild(QComboBox)
1472
+ indeff=(-1,-1, 1, -1,-1, 0,2)
1473
+ qcombo.setCurrentIndex(indeff[ind])
1474
+ """
1475
+ elif ind in (7,8,9,10): # Blackman-Harris
1476
+ w.setCurrentIndex(w.findText(Wind_items[3]))
1477
+ p.setCurrentIndex(4)
1478
+ p.show()
1479
+ q=p.widget(p.currentIndex())
1480
+ qcombo=q.findChild(QComboBox)
1481
+ qcombo.setCurrentIndex(ind-7)
1482
+ elif ind==22: # Triangular
1483
+ w.setCurrentIndex(w.findText(Wind_items[4]))
1484
+ p.hide()
1485
+ elif ind==23: # Hann
1486
+ w.setCurrentIndex(w.findText(Wind_items[5]))
1487
+ p.hide()
1488
+ elif ind>100 and ind<=200: #Gaussian
1489
+ w.setCurrentIndex(w.findText(Wind_items[6]))
1490
+ p.setCurrentIndex(5)
1491
+ p.show()
1492
+ q=p.widget(p.currentIndex())
1493
+ qspin:MyQDoubleSpin=q.findChild(MyQDoubleSpin)
1494
+ qspin.setValue(float(ind-100)/10)
1495
+
1496
+ def combo_Wind_Vel_acr_optionText(self,ind):
1497
+ optionText=''
1498
+ if ind in (0,3,4): # top-hat
1499
+ acr=Wind_abbrev[0]
1500
+ optionText+=Wind_items[0]
1501
+ qcombo=self.ui.combo_par_tophat
1502
+ indeff=(0, -1,-1, 1, 2)
1503
+ optionText+=f' [{qcombo.itemText(indeff[ind])}]'
1504
+ elif ind in (1,21):
1505
+ acr=Wind_abbrev[1]
1506
+ optionText+=Wind_items[1]
1507
+ qcombo=self.ui.combo_par_Nog
1508
+ if ind==1: optionText+=f' [{qcombo.itemText(0)}]'
1509
+ else: optionText+=f' [{qcombo.itemText(1)}]'
1510
+ elif ind in (5,2,6):
1511
+ acr=Wind_abbrev[2]
1512
+ optionText+=Wind_items[2]
1513
+ elif ind in (7,8,9,10): # Blackman-Harris
1514
+ acr=Wind_abbrev[3]
1515
+ optionText+=Wind_items[3]
1516
+ qcombo=self.ui.combo_par_Har
1517
+ optionText+=f' [{qcombo.itemText(ind-7)}]'
1518
+ elif ind==22: # Triangular
1519
+ acr=Wind_abbrev[4]
1520
+ optionText+=Wind_items[4]
1521
+ elif ind==23: # Hann
1522
+ acr=Wind_abbrev[5]
1523
+ optionText+=Wind_items[5]
1524
+ elif ind>100 and ind<=200: #Gaussian
1525
+ acr=Wind_abbrev[6]
1526
+ optionText+=Wind_items[6]
1527
+ alpha=float(ind-100)/10
1528
+ optionText+=f' [α thresh.={alpha}]'
1529
+ return acr,optionText
1530
+
1531
+ def spin_Wind_halfwidth_set(self):
1532
+ self.ui.spin_Wind_halfwidth.setValue(self.PROpar.SemiDimCalcVel)
1533
+
1534
+ def combo_MaxDisp_type_set(self):
1535
+ ind=0 if self.PROpar.MaxDisp<0 else 1
1536
+ self.ui.combo_MaxDisp_type.setCurrentIndex(ind)
1537
+ self.ui.w_MaxDisp_par.setCurrentIndex(ind)
1538
+ if not ind:
1539
+ ind_rel=[2,3,4,5].index(-self.PROpar.MaxDisp)
1540
+ self.ui.combo_MaxDisp_relative.setCurrentIndex(ind_rel)
1541
+ else:
1542
+ k=min([self.PROpar.row,self.PROpar.Nit-1])
1543
+ maxVal=int( 0.5*min( [self.PROpar.Vect[0][k], self.PROpar.Vect[2][k]] ) )
1544
+ self.ui.spin_MaxDisp_absolute.setMaximum(maxVal)
1545
+ self.PROpar.MaxDisp=self.PROpar.vMaxDisp[self.PROpar.row]=maxVal if self.PROpar.MaxDisp>maxVal else self.PROpar.MaxDisp
1546
+ self.ui.spin_MaxDisp_absolute.setValue(self.PROpar.MaxDisp)
1547
+
1548
+ def spin_MaxC_preset(self):
1549
+ self.ui.spin_MaxC.setMinimum(self.PROpar.MinC+0.01)
1550
+
1551
+ def spin_MinC_preset(self):
1552
+ self.ui.spin_MinC.setMaximum(self.PROpar.MaxC-0.01)
1553
+
1554
+ def spin_LarMax_preset(self):
1555
+ self.ui.spin_LarMax.setMinimum(self.PROpar.LarMin+1)
1556
+
1557
+ def spin_LarMin_preset(self):
1558
+ self.ui.spin_LarMin.setMaximum(self.PROpar.LarMax-1)
1559
+
1560
+ def line_edit_IW_set(self):
1561
+ r=self.PROpar.row
1562
+ #c=self.PROpar.col
1563
+
1564
+ kVect=min([r,self.PROpar.Nit-1])
1565
+ vect=[f'{self.PROpar.Vect[i][kVect]}' for i in (0,2,1,3)]
1566
+ vectStr=', '.join(vect)
1567
+ self.ui.line_edit_IW.setText(vectStr)
1568
+
1569
+ def table_iter_set(self):
1570
+ nRow=self.ui.table_iter.rowCount()
1571
+ for k in range(len(self.PROpar.vFlagCalcVel),nRow):
1572
+ self.ui.table_iter.removeRow(self.ui.table_iter.rowAt(k))
1573
+
1574
+ nWind=len(self.PROpar.vFlagCalcVel)
1575
+ Nit=self.PROpar.Nit
1576
+ NIterazioni=self.PROpar.NIterazioni
1577
+ self.ui.table_iter.RowInfo=['']*nWind
1578
+
1579
+ flagFocus=not self.ui.line_edit_IW.hasFocus()
1580
+
1581
+ def genTableCell(item_name,tooltip,c,cc):
1582
+ if c<0: return cc
1583
+ item=QTableWidgetItem(item_name)
1584
+ item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
1585
+ item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
1586
+ item.setToolTip(tooltip)
1587
+ item.setStatusTip(tooltip)
1588
+ cc+=1
1589
+ self.ui.table_iter.setItem(c, cc, item)
1590
+ if self.PROpar.row==c and self.PROpar.col==cc:
1591
+ item.setSelected(True)
1592
+ self.ui.table_iter.setCurrentItem(item)
1593
+ return cc
1594
+
1595
+ for k in range(nWind):
1596
+ if k==self.ui.table_iter.rowCount():
1597
+ self.ui.table_iter.insertRow(k)
1598
+ c=k
1599
+ cc=-1
1600
+
1601
+ it=k-Nit+1
1602
+ if k==Nit-1 and it!=NIterazioni:
1603
+ item_name=f'{it}:{NIterazioni}'
1604
+ tooltip=f'iterations from {it} to {NIterazioni}'
1605
+ str_adapt=''
1606
+ elif k==Nit:
1607
+ item_name=f'{NIterazioni+1}:{NIterazioni+self.PROpar.NItAdaptative}'
1608
+ tooltip=f'iterations from {NIterazioni+1} to {NIterazioni+self.PROpar.NItAdaptative}'
1609
+ str_adapt=' (adaptative)'
1610
+ else:
1611
+ item_name=f'{it}'
1612
+ tooltip=f'iteration {it}'
1613
+ str_adapt=''
1614
+ kVect=min([k,self.PROpar.Nit-1])
1615
+ IWSize=f'{self.PROpar.Vect[0][kVect]} x {self.PROpar.Vect[2][kVect]}'
1616
+ IWSize_max=max([self.PROpar.Vect[0][kVect],self.PROpar.Vect[2][kVect]])
1617
+ IWSpac=f'{self.PROpar.Vect[1][kVect]} x {self.PROpar.Vect[3][kVect]}'
1618
+ self.ui.table_iter.RowInfo[k]=f'{item_name} Window size: {IWSize}, grid distance: {IWSpac}'+str_adapt
1619
+
1620
+ cc=genTableCell(item_name,tooltip,c,cc)
1621
+
1622
+ """
1623
+ item_name=IWSize
1624
+ tooltip=f'Window size: {IWSize}'
1625
+ cc=genTableCell(item_name,tooltip,c,cc)
1626
+
1627
+ item_name=IWSpac
1628
+ tooltip=f'Window size: {IWSize}'
1629
+ cc=genTableCell(item_name,tooltip,c,cc)
1630
+ """
1631
+
1632
+ acr,optionText=self.combo_Wind_Vel_acr_optionText(self.PROpar.vFlagWindowing[k])
1633
+ item_name=CorrWin=f'{acr}{IWSize_max:d}'
1634
+ tooltip=f'{optionText} window'
1635
+ cc=genTableCell(item_name,tooltip,c,cc)
1636
+
1637
+ acr,optionText=self.combo_Wind_Vel_acr_optionText(self.PROpar.vFlagCalcVel[k])
1638
+ if k==Nit:
1639
+ CorrWinWidth0=self.PROpar.vSemiDimCalcVel[k-1]*2+IWSize_max%2 if self.PROpar.vSemiDimCalcVel[k-1] else IWSize_max
1640
+ CorrWinWidth1=self.PROpar.vSemiDimCalcVel[k]*2+IWSize_max%2 if self.PROpar.vSemiDimCalcVel[k] else IWSize_max
1641
+ item_name=f'{acr}{CorrWinWidth0:d}-{CorrWinWidth1:d}'
1642
+ tooltip=f'{optionText} window; half-width = {self.PROpar.vSemiDimCalcVel[k-1]:d}-{self.PROpar.vSemiDimCalcVel[k]:d}'
1643
+ else:
1644
+ CorrWinWidth=self.PROpar.vSemiDimCalcVel[k]*2+IWSize_max%2 if self.PROpar.vSemiDimCalcVel[k] else IWSize_max
1645
+ item_name=VelWin=f'{acr}{CorrWinWidth:d}'
1646
+ tooltip=f'{optionText} window; size = {CorrWinWidth:d}'
1647
+ cc=genTableCell(item_name,tooltip,c,cc)
1648
+
1649
+ maxDisp=self.PROpar.vMaxDisp[k]
1650
+ if maxDisp<0:
1651
+ item_name=f'1/{-maxDisp:d} IW'
1652
+ tooltip=f'Maximum allowed displacement = 1/{-maxDisp:d} of the interrogation window size'
1653
+ else:
1654
+ item_name=f'{maxDisp} pix'
1655
+ tooltip=f'Maximum allowed displacement = {maxDisp:d} pixels'
1656
+ cc=genTableCell(item_name,tooltip,c,cc)
1657
+
1658
+ item_name=f'{"❌✅"[self.PROpar.vDC[k]]}'
1659
+ tooltip=f'Direct correlations: {["disactivated","activated"][self.PROpar.vDC[k]]}'
1660
+ cc=genTableCell(item_name,tooltip,c,cc)
1661
+
1662
+ item_name, tooltip=self.calcStability(k,VelWin,CorrWin)
1663
+ if k==Nit-1: item_name+='⭐'
1664
+ cc=genTableCell(item_name,tooltip,c,cc)
1665
+
1666
+ continue
1667
+
1668
+ def calcStability(self,k,VelWin,CorrWin):
1669
+ kVect=min([k,self.PROpar.Nit-1])
1670
+ FlagStable=True
1671
+ flagLambda=True
1672
+ #FlagIntVel=(self.PROpar.IntVel==1) or (52<=self.PROpar.IntVel<=70)
1673
+ #if FlagIntVel:
1674
+ for j in range(2):
1675
+ Niter=np.array([self.PROpar.NIterazioni, np.inf])
1676
+ nPointPlot=1000
1677
+ # A correlation window
1678
+ Wa=self.PROpar.Vect[j*2][kVect]
1679
+ WBase=1.5*Wa
1680
+ FlagWindowing=self.PROpar.vFlagWindowing[k] # Weighting window for the correlation map (0=TopHat 1= Nogueira 2=Blackman 3=top hat at 50#).
1681
+ # B weighted average
1682
+ FlagCalcVel=self.PROpar.vFlagCalcVel[k] # Weighting window for absolute velocity (0=TopHat, 1=Nogueira, 2=Blackman,...)
1683
+ hWb=self.PROpar.vSemiDimCalcVel[k]# Half-width of the filtering window (0=window dimension).
1684
+ # C dense predictor
1685
+ IntVel=self.PROpar.IntVel # Type of interpolation of the velocity (1=bilinear, 52-70 Bspline)
1686
+ Wc=self.PROpar.Vect[1+j*2][kVect]# Grid distance (overlap)
1687
+ # end input *********************************************
1688
+ oMax=0.5 # frequenza massima per c (legata all'overlap ov/lambda) non penso che abbia senso oltre 0,5 perchè
1689
+ # andremmo oltre Nyquist
1690
+
1691
+ (_,_,_,_,_,_,_,_,_,flagUnstable,_,lam,MTF,_,_,_)= mtfPIV1(Wa,FlagWindowing,hWb, FlagCalcVel,Wc, IntVel, oMax, WBase,nPointPlot,Niter,flagLambda)
1692
+ FlagStable=FlagStable and not flagUnstable
1693
+ if k==self.PROpar.Nit-1:
1694
+ if j==0:
1695
+ if self.father and hasattr(self.father,'w_Output'): Res=self.father.w_Output.OUTpar.xres
1696
+ else: Res=0
1697
+ self.MTF=[lam,MTF.T,f'IW size-spacing: {Wa:d}-{Wc:d}. Vel.-correl. windowing: {VelWin}-{CorrWin}.',Res]
1698
+
1699
+ else:
1700
+ if self.PROpar.Vect[j*2][kVect]>self.PROpar.Vect[(j-1)*2][kVect]:
1701
+ if self.father: Res=self.father.w_Output.OUTpar.xres*self.father.w_Output.OUTpar.pixAR
1702
+ else: Res=0
1703
+ self.MTF=[lam,MTF.T,f'IW size-spacing: {Wa:d}-{Wc:d}. Vel.-correl. windowing: {VelWin}-{CorrWin}.',Res]
1704
+ if FlagStable:
1705
+ name='stable'
1706
+ tooltip='Stable process through an infinite number of iterations'
1707
+ else:
1708
+ name='⚠ unstable'
1709
+ tooltip='Unstable process through an infinite number of iterations'
1710
+ #else:
1711
+ # name='-'
1712
+ # tooltip='No information on stability available'
1713
+ return name, tooltip
1714
+
1715
+ #******************** Layout
1716
+ def setPROlayout_Wind(self):
1717
+ self.ui.w_adaptative_iter.setVisible(self.PROpar.FlagAdaptative)
1718
+ self.ui.w_Adaptative.setVisible(self.PROpar.FlagAdaptative)
1719
+
1720
+ self.ui.table_iter.resizeInfoLabel()
1721
+ r=self.PROpar.row
1722
+ #c=self.PROpar.col
1723
+ self.ui.button_mtf.setVisible(r==self.PROpar.Nit-1)
1724
+
1725
+ FlagAdaptativeNotSelected=self.PROpar.row<self.PROpar.Nit
1726
+ self.ui.edit_IW.setEnabled(FlagAdaptativeNotSelected)
1727
+ self.ui.button_add.setEnabled(FlagAdaptativeNotSelected)
1728
+ FlagDeleteEnabled=(FlagAdaptativeNotSelected and self.PROpar.Nit>1) or self.PROpar.row>=self.PROpar.Nit
1729
+ self.ui.button_delete.setEnabled(FlagDeleteEnabled)
1730
+
1731
+ self.ui.combo_Wind_Vel_type.setEnabled(FlagAdaptativeNotSelected)
1732
+ self.ui.w_Wind_par.setEnabled(FlagAdaptativeNotSelected)
1733
+ self.ui.combo_Wind_Corr_type.setEnabled(FlagAdaptativeNotSelected)
1734
+ self.ui.w_Wind_par_2.setEnabled(FlagAdaptativeNotSelected)
1735
+ self.ui.spin_Wind_halfwidth.setEnabled(FlagAdaptativeNotSelected and not(self.PROpar.FlagAdaptative and self.PROpar.row==self.PROpar.Nit-1))
1736
+ self.ui.combo_MaxDisp_type.setEnabled(FlagAdaptativeNotSelected)
1737
+ self.ui.combo_MaxDisp_relative.setEnabled(FlagAdaptativeNotSelected)
1738
+ self.ui.spin_MaxDisp_absolute.setEnabled(FlagAdaptativeNotSelected)
1739
+ self.ui.check_DC_it.setEnabled(FlagAdaptativeNotSelected and self.PROpar.FlagDirectCorr)
1740
+ self.ui.w_Adaptative.setVisible(self.PROpar.FlagAdaptative)
1741
+ self.ui.w_adaptative_iter.setVisible(self.PROpar.FlagAdaptative)
1742
+
1743
+ nWind=len(self.PROpar.vFlagCalcVel)
1744
+ self.ui.table_iter.setMinimumHeight((nWind+1)*22)
1745
+ self.ui.table_iter.setMaximumHeight((nWind+1)*22)
1746
+ self.ui.CollapBox_Windowing.heightArea=(nWind+1)*22+200
1747
+ self.ui.CollapBox_Windowing.heightOpened=self.ui.CollapBox_Windowing.heightArea+20
1748
+ self.ui.CollapBox_Windowing.on_click()
1749
+ return
1750
+
1751
+
1752
+ if __name__ == "__main__":
1753
+ import sys
1754
+ app=QApplication.instance()
1755
+ if not app:app = QApplication(sys.argv)
1756
+ app.setStyle('Fusion')
1757
+ object = Process_Tab(None)
1758
+ object.show()
1759
+ app.exec()
1760
+ app.quit()
1761
+ app=None