PaIRS-UniNa 0.1.13__cp310-cp310-win_amd64.whl → 0.2.8__cp310-cp310-win_amd64.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 (292) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +331 -0
  2. PaIRS_UniNa/Changes.txt +134 -2
  3. PaIRS_UniNa/Custom_Top.py +299 -299
  4. PaIRS_UniNa/Explorer.py +3136 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +831 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +786 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3025 -0
  9. PaIRS_UniNa/Log_Tab.py +57 -14
  10. PaIRS_UniNa/Output_Tab.py +922 -0
  11. PaIRS_UniNa/PaIRS_PIV.py +111 -18
  12. PaIRS_UniNa/PaIRS_pypacks.py +698 -140
  13. PaIRS_UniNa/Process_Tab.py +1221 -1402
  14. PaIRS_UniNa/Process_Tab_CalVi.py +137 -262
  15. PaIRS_UniNa/Process_Tab_Disp.py +163 -0
  16. PaIRS_UniNa/Process_Tab_Min.py +120 -0
  17. PaIRS_UniNa/Saving_tools.py +296 -0
  18. PaIRS_UniNa/TabTools.py +863 -543
  19. PaIRS_UniNa/Vis_Tab.py +1898 -1315
  20. PaIRS_UniNa/Vis_Tab_CalVi.py +484 -356
  21. PaIRS_UniNa/Whatsnew.py +59 -10
  22. PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
  23. PaIRS_UniNa/__init__.py +4 -3
  24. PaIRS_UniNa/addwidgets_ps.py +326 -56
  25. PaIRS_UniNa/calib.py +19 -12
  26. PaIRS_UniNa/calibView.py +48 -25
  27. PaIRS_UniNa/gPaIRS.py +3902 -3461
  28. PaIRS_UniNa/gPalette.py +189 -170
  29. PaIRS_UniNa/icons/align_all.png +0 -0
  30. PaIRS_UniNa/icons/announcement.png +0 -0
  31. PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
  32. PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
  33. PaIRS_UniNa/icons/automatic_off.png +0 -0
  34. PaIRS_UniNa/icons/automatic_on.png +0 -0
  35. PaIRS_UniNa/icons/automatic_size_off.png +0 -0
  36. PaIRS_UniNa/icons/automatic_size_on.png +0 -0
  37. PaIRS_UniNa/icons/bin_off.png +0 -0
  38. PaIRS_UniNa/icons/bin_on.png +0 -0
  39. PaIRS_UniNa/icons/brush_cursor.png +0 -0
  40. PaIRS_UniNa/icons/bugfix.png +0 -0
  41. PaIRS_UniNa/icons/cal_proc.png +0 -0
  42. PaIRS_UniNa/icons/cal_proc_off.png +0 -0
  43. PaIRS_UniNa/icons/cal_step.png +0 -0
  44. PaIRS_UniNa/icons/cal_step_off.png +0 -0
  45. PaIRS_UniNa/icons/calibration_logo.png +0 -0
  46. PaIRS_UniNa/icons/change_folder.png +0 -0
  47. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  48. PaIRS_UniNa/icons/close_all.png +0 -0
  49. PaIRS_UniNa/icons/close_workspace.png +0 -0
  50. PaIRS_UniNa/icons/colormap.png +0 -0
  51. PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
  52. PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
  53. PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
  54. PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
  55. PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
  56. PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
  57. PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
  58. PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
  59. PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
  60. PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
  61. PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
  62. PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
  63. PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
  64. PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
  65. PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
  66. PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
  67. PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
  68. PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
  69. PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
  70. PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
  71. PaIRS_UniNa/icons/colormaps/binary.png +0 -0
  72. PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
  73. PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
  74. PaIRS_UniNa/icons/colormaps/bone.png +0 -0
  75. PaIRS_UniNa/icons/colormaps/brg.png +0 -0
  76. PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
  77. PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
  78. PaIRS_UniNa/icons/colormaps/cool.png +0 -0
  79. PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
  80. PaIRS_UniNa/icons/colormaps/copper.png +0 -0
  81. PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
  82. PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
  83. PaIRS_UniNa/icons/colormaps/flag.png +0 -0
  84. PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
  85. PaIRS_UniNa/icons/colormaps/gray.png +0 -0
  86. PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
  87. PaIRS_UniNa/icons/colormaps/hot.png +0 -0
  88. PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
  89. PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
  90. PaIRS_UniNa/icons/colormaps/jet.png +0 -0
  91. PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
  92. PaIRS_UniNa/icons/colormaps/magma.png +0 -0
  93. PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
  94. PaIRS_UniNa/icons/colormaps/pink.png +0 -0
  95. PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
  96. PaIRS_UniNa/icons/colormaps/prism.png +0 -0
  97. PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
  98. PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
  99. PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
  100. PaIRS_UniNa/icons/colormaps/spring.png +0 -0
  101. PaIRS_UniNa/icons/colormaps/summer.png +0 -0
  102. PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
  103. PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
  104. PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
  105. PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
  106. PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
  107. PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
  108. PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
  109. PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
  110. PaIRS_UniNa/icons/colormaps/winter.png +0 -0
  111. PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
  112. PaIRS_UniNa/icons/common_region.png +0 -0
  113. PaIRS_UniNa/icons/common_region_off.png +0 -0
  114. PaIRS_UniNa/icons/completed.png +0 -0
  115. PaIRS_UniNa/icons/contourf_off.png +0 -0
  116. PaIRS_UniNa/icons/contourf_on.png +0 -0
  117. PaIRS_UniNa/icons/copy.png +0 -0
  118. PaIRS_UniNa/icons/copy_process.png +0 -0
  119. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  120. PaIRS_UniNa/icons/cut.png +0 -0
  121. PaIRS_UniNa/icons/cut_warnings.png +0 -0
  122. PaIRS_UniNa/icons/darkmode.png +0 -0
  123. PaIRS_UniNa/icons/disp_step.png +0 -0
  124. PaIRS_UniNa/icons/disp_step_off.png +0 -0
  125. PaIRS_UniNa/icons/edit_list.png +0 -0
  126. PaIRS_UniNa/icons/example_list.png +0 -0
  127. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  128. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  129. PaIRS_UniNa/icons/flip_y_off.png +0 -0
  130. PaIRS_UniNa/icons/flip_y_on.png +0 -0
  131. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  132. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  133. PaIRS_UniNa/icons/gear.gif +0 -0
  134. PaIRS_UniNa/icons/gear.png +0 -0
  135. PaIRS_UniNa/icons/import_set.png +0 -0
  136. PaIRS_UniNa/icons/information.png +0 -0
  137. PaIRS_UniNa/icons/input_logo.png +0 -0
  138. PaIRS_UniNa/icons/issue.png +0 -0
  139. PaIRS_UniNa/icons/laser_NTR.png +0 -0
  140. PaIRS_UniNa/icons/laser_TR_double.png +0 -0
  141. PaIRS_UniNa/icons/laser_TR_single.png +0 -0
  142. PaIRS_UniNa/icons/link.png +0 -0
  143. PaIRS_UniNa/icons/linked.png +0 -0
  144. PaIRS_UniNa/icons/log_logo.png +0 -0
  145. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  146. PaIRS_UniNa/icons/measure.png +0 -0
  147. PaIRS_UniNa/icons/measure_off.png +0 -0
  148. PaIRS_UniNa/icons/min_proc.png +0 -0
  149. PaIRS_UniNa/icons/min_proc_off.png +0 -0
  150. PaIRS_UniNa/icons/min_step.png +0 -0
  151. PaIRS_UniNa/icons/min_step_off.png +0 -0
  152. PaIRS_UniNa/icons/new_workspace.png +0 -0
  153. PaIRS_UniNa/icons/open_image.png +0 -0
  154. PaIRS_UniNa/icons/open_new_window.png +0 -0
  155. PaIRS_UniNa/icons/open_result.png +0 -0
  156. PaIRS_UniNa/icons/open_workspace.png +0 -0
  157. PaIRS_UniNa/icons/output_logo.png +0 -0
  158. PaIRS_UniNa/icons/paste_above.png +0 -0
  159. PaIRS_UniNa/icons/paste_below.png +0 -0
  160. PaIRS_UniNa/icons/paused.png +0 -0
  161. PaIRS_UniNa/icons/piv_proc.png +0 -0
  162. PaIRS_UniNa/icons/piv_proc_off.png +0 -0
  163. PaIRS_UniNa/icons/piv_step.png +0 -0
  164. PaIRS_UniNa/icons/piv_step_off.png +0 -0
  165. PaIRS_UniNa/icons/process_logo.png +0 -0
  166. PaIRS_UniNa/icons/process_loop.png +0 -0
  167. PaIRS_UniNa/icons/project.png +0 -0
  168. PaIRS_UniNa/icons/pylog.png +0 -0
  169. PaIRS_UniNa/icons/python_warning.png +0 -0
  170. PaIRS_UniNa/icons/queue.png +0 -0
  171. PaIRS_UniNa/icons/read.png +0 -0
  172. PaIRS_UniNa/icons/read_list.png +0 -0
  173. PaIRS_UniNa/icons/reset.png +0 -0
  174. PaIRS_UniNa/icons/reset_levels.png +0 -0
  175. PaIRS_UniNa/icons/restore_undo.png +0 -0
  176. PaIRS_UniNa/icons/running.gif +0 -0
  177. PaIRS_UniNa/icons/running.png +0 -0
  178. PaIRS_UniNa/icons/running_warn.png +0 -0
  179. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  180. PaIRS_UniNa/icons/save_cfg.png +0 -0
  181. PaIRS_UniNa/icons/saveas_workspace.png +0 -0
  182. PaIRS_UniNa/icons/scale_all.png +0 -0
  183. PaIRS_UniNa/icons/scale_down.png +0 -0
  184. PaIRS_UniNa/icons/scale_up.png +0 -0
  185. PaIRS_UniNa/icons/scan_list.png +0 -0
  186. PaIRS_UniNa/icons/scan_path.png +0 -0
  187. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  188. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  189. PaIRS_UniNa/icons/search.png +0 -0
  190. PaIRS_UniNa/icons/showIW_off.png +0 -0
  191. PaIRS_UniNa/icons/showIW_on.png +0 -0
  192. PaIRS_UniNa/icons/show_all.png +0 -0
  193. PaIRS_UniNa/icons/sort.png +0 -0
  194. PaIRS_UniNa/icons/sort_reversed.png +0 -0
  195. PaIRS_UniNa/icons/spiv_proc.png +0 -0
  196. PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
  197. PaIRS_UniNa/icons/star.png +0 -0
  198. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  199. PaIRS_UniNa/icons/subMIN_off.png +0 -0
  200. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  201. PaIRS_UniNa/icons/unedited.png +0 -0
  202. PaIRS_UniNa/icons/uninitialized.png +0 -0
  203. PaIRS_UniNa/icons/unlink.png +0 -0
  204. PaIRS_UniNa/icons/unwrap_items.png +0 -0
  205. PaIRS_UniNa/icons/vectorColor.png +0 -0
  206. PaIRS_UniNa/icons/view.png +0 -0
  207. PaIRS_UniNa/icons/view_off.png +0 -0
  208. PaIRS_UniNa/icons/vis_logo.png +0 -0
  209. PaIRS_UniNa/icons/warning_circle.png +0 -0
  210. PaIRS_UniNa/icons/window.png +0 -0
  211. PaIRS_UniNa/icons/workspace.png +0 -0
  212. PaIRS_UniNa/icons/wrap_items.png +0 -0
  213. PaIRS_UniNa/icons/write_list.png +0 -0
  214. PaIRS_UniNa/listLib.py +303 -0
  215. PaIRS_UniNa/mtfPIV.py +8 -8
  216. PaIRS_UniNa/parForMulti.py +7 -5
  217. PaIRS_UniNa/parForWorkers.py +370 -31
  218. PaIRS_UniNa/pivParFor.py +233 -229
  219. PaIRS_UniNa/plt_util.py +141 -141
  220. PaIRS_UniNa/preProcParFor.py +153 -148
  221. PaIRS_UniNa/procTools.py +631 -178
  222. PaIRS_UniNa/readcfg.py +31 -1
  223. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  224. PaIRS_UniNa/stereoPivParFor.py +227 -0
  225. PaIRS_UniNa/tAVarie.py +215 -215
  226. PaIRS_UniNa/tabSplitter.py +612 -0
  227. PaIRS_UniNa/ui_Calibration_Tab.py +545 -0
  228. PaIRS_UniNa/ui_Custom_Top.py +5 -5
  229. PaIRS_UniNa/ui_Input_Tab.py +1101 -0
  230. PaIRS_UniNa/{ui_Import_Tab_CalVi.py → ui_Input_Tab_CalVi.py} +1282 -1275
  231. PaIRS_UniNa/ui_Log_Tab.py +262 -257
  232. PaIRS_UniNa/{ui_Export_Tab.py → ui_Output_Tab.py} +2361 -1778
  233. PaIRS_UniNa/ui_Process_Tab.py +3809 -3758
  234. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1547 -1546
  235. PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
  236. PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
  237. PaIRS_UniNa/ui_Vis_Tab.py +1626 -1208
  238. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1249 -1249
  239. PaIRS_UniNa/ui_Whatsnew.py +131 -131
  240. PaIRS_UniNa/ui_gPairs.py +876 -950
  241. PaIRS_UniNa/ui_infoPaIRS.py +550 -425
  242. PaIRS_UniNa/whatsnew.txt +6 -4
  243. {PaIRS_UniNa-0.1.13.dist-info → pairs_unina-0.2.8.dist-info}/METADATA +69 -51
  244. pairs_unina-0.2.8.dist-info/RECORD +329 -0
  245. {PaIRS_UniNa-0.1.13.dist-info → pairs_unina-0.2.8.dist-info}/WHEEL +1 -1
  246. PaIRS_UniNa/CalVi.py +0 -18
  247. PaIRS_UniNa/Export_Tab.py +0 -574
  248. PaIRS_UniNa/Import_Tab.py +0 -657
  249. PaIRS_UniNa/Import_Tab_CalVi.py +0 -861
  250. PaIRS_UniNa/Import_Tab_tools.py +0 -598
  251. PaIRS_UniNa/Tree_Tab.py +0 -543
  252. PaIRS_UniNa/gCalVi.py +0 -2024
  253. PaIRS_UniNa/icons/add.png +0 -0
  254. PaIRS_UniNa/icons/cancelled.png +0 -0
  255. PaIRS_UniNa/icons/chain.png +0 -0
  256. PaIRS_UniNa/icons/chain_broken.png +0 -0
  257. PaIRS_UniNa/icons/default_sizes.png +0 -0
  258. PaIRS_UniNa/icons/dock_tabs.png +0 -0
  259. PaIRS_UniNa/icons/done.png +0 -0
  260. PaIRS_UniNa/icons/down_arrow.png +0 -0
  261. PaIRS_UniNa/icons/export_logo.png +0 -0
  262. PaIRS_UniNa/icons/fast_delete.png +0 -0
  263. PaIRS_UniNa/icons/flip_y.png +0 -0
  264. PaIRS_UniNa/icons/ganci.png +0 -0
  265. PaIRS_UniNa/icons/import_blue.png +0 -0
  266. PaIRS_UniNa/icons/import_logo.png +0 -0
  267. PaIRS_UniNa/icons/missing.png +0 -0
  268. PaIRS_UniNa/icons/process_icon.png +0 -0
  269. PaIRS_UniNa/icons/processing.png +0 -0
  270. PaIRS_UniNa/icons/restart.png +0 -0
  271. PaIRS_UniNa/icons/right_arrow.png +0 -0
  272. PaIRS_UniNa/icons/run_piv.png +0 -0
  273. PaIRS_UniNa/icons/terminal.png +0 -0
  274. PaIRS_UniNa/icons/undock_tabs.png +0 -0
  275. PaIRS_UniNa/icons/vect_field.png +0 -0
  276. PaIRS_UniNa/icons/w0.png +0 -0
  277. PaIRS_UniNa/icons/w1.png +0 -0
  278. PaIRS_UniNa/icons/w2.png +0 -0
  279. PaIRS_UniNa/icons/w3.png +0 -0
  280. PaIRS_UniNa/icons/w4.png +0 -0
  281. PaIRS_UniNa/icons/w5.png +0 -0
  282. PaIRS_UniNa/run_CalVi.py +0 -14
  283. PaIRS_UniNa/run_gcalvi.py +0 -5
  284. PaIRS_UniNa/ui_Import_Tab.py +0 -1077
  285. PaIRS_UniNa/ui_Tree_Tab.py +0 -684
  286. PaIRS_UniNa/ui_gCalVi.py +0 -640
  287. PaIRS_UniNa/ui_infoCalVi.py +0 -428
  288. PaIRS_UniNa-0.1.13.dist-info/LICENSE +0 -19
  289. PaIRS_UniNa-0.1.13.dist-info/RECORD +0 -174
  290. /PaIRS_UniNa/icons/{clean_queue.png → clean.png} +0 -0
  291. /PaIRS_UniNa/icons/{waiting_c.png → sandglass.png} +0 -0
  292. {PaIRS_UniNa-0.1.13.dist-info → pairs_unina-0.2.8.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/Vis_Tab.py CHANGED
@@ -1,184 +1,200 @@
1
1
  from .ui_Vis_Tab import*
2
- from .Import_Tab_tools import *
3
- from .Export_Tab import outType_items
2
+ from .Input_Tab_tools import *
3
+ from .Output_Tab import outType_dict
4
4
  from .TabTools import*
5
- from .procTools import FLAG_FINALIZED
6
-
7
-
5
+ if __package__ or "." in __name__:
6
+ import PaIRS_UniNa.PaIRS_PIV as PaIRS_lib
7
+ else:
8
+ if platform.system() == "Darwin":
9
+ sys.path.append('../lib/mac')
10
+ #sys.path.append('../lib')
11
+ else:
12
+ #sys.path.append('PaIRS_PIV')
13
+ sys.path.append('../lib')
14
+ sys.path.append('TpivPython/lib')
15
+ import PaIRS_PIV as PaIRS_lib # type: ignore
16
+
17
+ spin_tips={
18
+ 'min': 'Minimum level',
19
+ 'mean': 'Mean level',
20
+ 'max': 'Maximum level',
21
+ 'range': 'Level range',
22
+ 'xmin': 'Minimum x coordinate',
23
+ 'xmax': 'Maximum x coordinate',
24
+ 'ymin': 'Minimum y coordinate',
25
+ 'ymax' : 'Maximum y coordinate',
26
+ 'nclev': 'Number of color levels',
27
+ 'vecsize': 'Size of velocity vectors',
28
+ 'vecwid': 'Width of velocity vectors',
29
+ 'vecspac': 'Spacing of velocity vectors',
30
+ 'streamdens': 'Density of streamlines',
31
+ 'img': 'Image number',
32
+ 'frame': 'Frame number',
33
+ 'cam': 'Camera number',
34
+ 'it': 'Iteration number',
35
+ }
36
+ check_tips={}
37
+ radio_tips={}
38
+ line_edit_tips={}
39
+ button_tips={
40
+ 'tool_CollapBox_PlotTools': 'Open/close plot tools box',
41
+ 'CollapBox_PlotTools': 'Open/close plot tools box',
42
+ 'ShowIW': 'Show/hide interrogation windows',
43
+ 'SubMIN': 'Subtract minimum',
44
+ 'Contourf': 'Contour plot mode',
45
+ 'cmap': 'Colormap',
46
+ 'automatic_levels': 'Automatic levels',
47
+ 'automatic_sizes': 'Automatic sizes',
48
+ 'restore': 'Restore levels',
49
+ 'resize': 'Resize',
50
+ 'invert_y': 'Invert y axis',
51
+ 'left': 'Change page setting',
52
+ 'right': 'Change page setting',
53
+ 'qt_toolbar_ext_button': 'Plot interaction',
54
+ 'unit': 'Type of unit',
55
+ 'cvec': 'Color of vectors/streamlines',
56
+ 'view': 'Inspect pre-existing results',
57
+ 'ShowCR': 'Show common region',
58
+ 'dx_left': 'View zone moved to left',
59
+ 'dx_right': 'View zone moved to right',
60
+ 'dy_down': 'View zone moved down',
61
+ 'dy_up': 'View zone moved up',
62
+ 'FocusIW': 'Resize to interrogation window size',
63
+ }
64
+ combo_tips={
65
+ 'map_var': 'Map variable',
66
+ 'field_rep': 'Field representation',
67
+ }
8
68
  Flag_VIS_DEBUG=False
9
69
 
10
- exampleFolder='../_examples/'
70
+ FlagGenerateColormaps=False
71
+ FlagVerticalColormap=True
72
+ VIS_ColorMaps = {
73
+ 'main': ['gray','jet','viridis', 'cividis', 'inferno', 'hsv','brg'],
74
+ 'Miscellaneous': ['magma','plasma',
75
+ 'terrain', 'ocean','twilight', 'rainbow','cubehelix', 'prism','flag'],
76
+ 'Sequential': ['binary', 'bone', 'pink',
77
+ 'spring', 'summer', 'autumn', 'winter', 'cool',
78
+ 'Wistia', 'hot', 'afmhot', 'gist_heat', 'copper'],
79
+ 'Diverging': ['PiYG', 'PRGn', 'BrBG', 'PuOr', 'RdGy', 'RdBu', 'RdYlBu',
80
+ 'RdYlGn', 'Spectral', 'coolwarm', 'bwr', 'seismic'],
81
+ 'Qualitative': ['Pastel1', 'Pastel2', 'Paired', 'Accent', 'Dark2',
82
+ 'Set1', 'Set2', 'Set3', 'tab10', 'tab20', 'tab20b',
83
+ 'tab20c']
84
+ }
85
+ FlagGenerateColorvectors=False
86
+ VIS_VectorColors={
87
+ 'black': (0, 0, 0),
88
+ 'red': (1, 0, 0),
89
+ 'green': (0, 1, 0),
90
+ 'blue': (0, 0, 1),
91
+ 'cyan': (0, 1, 1),
92
+ 'magenta': (1, 0, 1),
93
+ 'yellow': (1, 1, 0),
94
+ 'white': (1, 1, 1),
95
+ }
11
96
  nStepsSlider=1e5
12
- nStepsSpin=1e2
97
+ nPixelsPerVector=10 #one vector each nPixelsPerVector pixels
13
98
 
14
- class VISpar(TABpar):
15
- FlagVis=True
99
+ class NamesPIV(TABpar):
16
100
 
17
- class INP(TABpar):
18
- def __init__(self):
19
- self.pinfo=patternInfoVar()
20
- self.range_to=0
21
- self.selected=imin_im_pair
22
- self.path=''
23
- self.FlagValidPath=False
24
- self.FlagValidRoot=False
25
-
26
- super().__init__()
27
- self.name='VISpar.INP'
28
- self.surname='VIS_Tab'
29
- self.unchecked_fields+=[]
30
-
31
- class OUT(TABpar):
32
- def __init__(self):
33
- self.path=''
34
- self.subfold=''
35
- self.root=''
36
- self.x = 0
37
- self.y = 0
38
- self.w = -1
39
- self.h = -1
40
- #self.W = -1
41
- #self.H = -1
42
- self.vecop = []
43
- self.outType=0
44
-
45
- super().__init__()
46
- self.name='VISpar.OUT'
47
- self.surname='VIS_Tab'
48
- self.unchecked_fields+=[]
49
-
50
- class PRO(TABpar):
51
- def __init__(self):
52
- WSize_init=[128, 64, 32]
53
- WSpac_init=[ 32, 16, 8]
54
- self.Nit=len(WSize_init)
55
- self.Vect=[np.array(WSize_init,np.intc), np.array(WSpac_init,np.intc),\
56
- np.array(WSize_init,np.intc), np.array(WSpac_init,np.intc)]
57
- self.FlagBordo=True
58
-
59
- super().__init__()
60
- self.name='VISpar.PRO'
61
- self.surname='VIS_Tab'
62
- self.unchecked_fields+=[]
63
-
64
- class TRE(TABpar):
65
- def __init__(self):
66
- nTypeProc=3
67
- self.itemname = ''
68
- self.filename_proc = ['']*nTypeProc
69
- self.name_proc = ['']*nTypeProc
70
- self.flagRun = 0
71
- self.list_pim = []
72
-
73
- super().__init__()
74
- self.name='TREpar.PRO'
75
- self.surname='VIS_Tab'
76
- self.unchecked_fields+=[]
77
-
78
- def __init__(self):
79
- self.setup()
80
- super().__init__()
81
- self.name='VISpar'
82
- self.surname='VIS_Tab'
83
- self.unchecked_fields+=[]
84
-
85
- def setup(self):
86
- self.type=0
87
- self.nameimga=''
88
- self.nameimgb=''
89
- self.nameres=''
90
-
91
- self.flagShowIW=False
92
- self.flagMIN=False
93
- self.MapVar_type=0
94
- self.VecField_type=0
95
- self.combo_items=[]
101
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
102
+ self.setup(Process,Step)
103
+ super().__init__('OUTpar','Output')
96
104
 
97
- self.FlagYInvert=[False,False]
98
- self.FlagReset=[False,False] #XLim, CLim
99
-
100
- self.m=[0,0,{}]
101
- self.M=[0,0,{}]
102
- self.mean=[0,0,{}]
103
- self.std=[0,0,{}]
104
- self.size=[[0,0,0,0,1],[0,0,0,0,1],[0,0,0,0,1]] #xmin,xmax,ymin,ymax,max vec spacing
105
- self.xlim=[0,1]
106
- self.ylim=[0,1]
107
-
108
- self.vmin=0
109
- self.vmax=1
110
- self.vmean=0.5
111
- self.vrange=1
112
- self.nclev=30
113
- self.vecsize=1
114
- self.vecspac=1
115
- self.streamdens=1
116
-
117
- self.nfield=imin_im_pair
118
- self.Inp=self.INP()
119
- self.Out=self.OUT()
120
- self.Pro=self.PRO()
121
- self.Tre=self.TRE()
122
- #self.FlagCheck=[False]*2
123
- self.FlagExistMean=[False]*2
124
- self.FlagExistRes=[False]*2
125
- self.FlagErrRead=[True]*3
126
- self.list_Image_Files=[]
127
-
128
- class NamesPIV:
129
- def __init__(self):
130
- self.imga='imga'
131
- self.imgb='imgb'
132
- self.x='X'
133
- self.y='Y'
105
+ def setup(self,Process,Step):
106
+ self.Process = Process
107
+ self.Step = Step
108
+
109
+ self.img='img'
110
+ self.dispMap='dispMap'
111
+ self.X='X'
112
+ self.Y='Y'
113
+ self.Z='Z'
114
+ self.x='x'
115
+ self.y='y'
116
+ self.z='z'
134
117
  self.u='U'
135
118
  self.v='V'
119
+ self.w='W'
120
+ self.Mod='Mod'
136
121
  self.up='uu'
137
122
  self.vp='vv'
123
+ self.wp='ww'
138
124
  self.uvp='uv'
125
+ self.uwp='uw'
126
+ self.vwp='vw'
127
+ self.ZVort='ZVort'
128
+ self.dPar='dPar'
129
+ self.dOrt='dOrt'
139
130
  self.sn='SN'
140
131
  self.FCl='CC'
141
132
  self.Info='Info'
142
- self.Mod='Mod'
143
133
  allFields={}
144
134
  for f,v in self.__dict__.items():
145
135
  allFields[v]=f
146
136
  self.allFields=allFields
147
137
  self.combo_dict={
148
- self.imga: 'intensity (frame 0)',
149
- self.imgb: 'intensity (frame 1)',
138
+ self.img: 'image intesity',
139
+ self.dispMap: 'disparity maps',
150
140
  self.Mod: 'magnitude',
141
+ self.z: 'z',
151
142
  self.u: 'U',
152
143
  self.v: 'V',
144
+ self.w: 'W',
153
145
  self.up: "<u'u'>",
154
146
  self.vp: "<v'v'>",
147
+ self.wp: "<w'w'>",
155
148
  self.uvp: "<u'v'>",
149
+ self.uwp: "<u'w'>",
150
+ self.vwp: "<v'w'>",
151
+ self.ZVort: "z-vorticity",
152
+ self.dPar: "epipolar || disp.",
153
+ self.dOrt: "epipolar ⊥ disp.",
156
154
  self.sn: "S/N",
157
155
  self.Info: "Info",
158
156
  self.FCl: "CC"
159
157
  }
158
+ self.combo_dict_keys={}
159
+ for k,v in self.combo_dict.items(): self.combo_dict_keys[v]=k
160
160
  self.titles_dict={
161
- self.imga: 'intensity (frame 0)',
162
- self.imgb: 'intensity (frame 1)',
161
+ self.img: 'intensity',
162
+ self.dispMap: 'disparity maps',
163
163
  self.Mod: "velocity magnitude",
164
+ self.z: "z coordinate",
164
165
  self.u: "x-velocity component",
165
166
  self.v: "y-velocity component",
167
+ self.w: "z-velocity component",
166
168
  self.up: "x normal Reynolds stress",
167
169
  self.vp: "y normal Reynolds stress",
170
+ self.wp: "z normal Reynolds stress",
168
171
  self.uvp: "xy tangential Reynolds stress",
172
+ self.uwp: "xz tangential Reynolds stress",
173
+ self.vwp: "yz tangential Reynolds stress",
174
+ self.ZVort: "z-vorticity component",
175
+ self.dPar: "epipolar parallel displacement",
176
+ self.dOrt: "epipolar orthogonal displacement",
169
177
  self.sn: "signal-to-noise ratio",
170
178
  self.Info: "outlier info",
171
179
  self.FCl: "Correlation coefficient"
172
180
  }
173
181
  self.titles_cb_dict={
174
- self.imga: '',
175
- self.imgb: '',
182
+ self.img: '',
183
+ self.dispMap: '',
176
184
  self.Mod: "|Vel|",
185
+ self.z: "z",
177
186
  self.u: "U",
178
187
  self.v: "V",
188
+ self.w: "W",
179
189
  self.up: "<u'u'>",
180
190
  self.vp: "<v'v'>",
191
+ self.wp: "<w'w'>",
181
192
  self.uvp: "<u'v'>",
193
+ self.uwp: "<u'w'>",
194
+ self.vwp: "<v'w'>",
195
+ self.dPar: "d par.",
196
+ self.dOrt: "d ort.",
197
+ self.ZVort: "ωz",
182
198
  self.sn: "S/N",
183
199
  self.Info: "i",
184
200
  self.FCl: "CC"
@@ -189,90 +205,384 @@ class NamesPIV:
189
205
  self.titles_list=[self.titles_dict[f] for f in self.fields]
190
206
  self.titles_cb_list=[self.titles_cb_dict[f] for f in self.fields]
191
207
 
192
- self.img=[self.imga,self.imgb]
193
- self.img_ind=[self.fields.index(f) for f in self.img]
208
+ self.img_ind=[self.fields.index(f) for f in [self.img]]
194
209
 
195
210
  # should start with x, y ,u ,v
196
- self.instVel=[self.x,self.y,self.u,self.v,self.FCl,self.Info,self.sn]
211
+ if Step==StepTypes.disp:
212
+ self.instVel=[self.x,self.y,self.z,self.dPar,self.dOrt] #,self.FCl]
213
+ self.instVel_plot=[self.z,self.dPar,self.dOrt] #,self.FCl]
214
+ self.avgVel=copy.deepcopy(self.instVel)
215
+ self.avgVel_plot=copy.deepcopy(self.instVel_plot)
216
+ elif Step==StepTypes.spiv:
217
+ self.instVel=[self.x,self.y,self.z,self.u,self.v,self.w,self.FCl,self.Info,self.sn]
218
+ self.instVel_plot=[self.Mod,self.u,self.v,self.w,self.ZVort,self.FCl,self.Info,self.sn]
219
+ self.avgVel=[self.x,self.y,self.z,self.u,self.v,self.w,self.up,self.vp,self.wp,self.uvp,self.uwp,self.vwp,self.FCl,self.Info,self.sn]
220
+ self.avgVel_plot=[self.Mod,self.u,self.v,self.w,self.up,self.vp,self.wp,self.uvp,self.uwp,self.vwp,self.ZVort,self.FCl,self.Info,self.sn]
221
+ else: # for now should be StepTypes.piv
222
+ self.instVel=[self.x,self.y,self.u,self.v,self.FCl,self.Info,self.sn]
223
+ self.instVel_plot=[self.Mod,self.u,self.v,self.ZVort,self.FCl,self.Info,self.sn]
224
+ self.avgVel=[self.x,self.y,self.u,self.v,self.up,self.vp,self.uvp,self.FCl,self.Info,self.sn]
225
+ self.avgVel_plot=[self.Mod,self.u,self.v,self.up,self.vp,self.uvp,self.ZVort,self.FCl,self.Info,self.sn]
226
+
197
227
  self.instVelFields=[self.allFields[f] for f in self.instVel ]
198
- self.instVel_plot=[self.Mod,self.u,self.v,self.FCl,self.Info,self.sn]
199
228
  self.instVel_plot_ind=[self.fields.index(f) for f in self.instVel_plot if f in self.fields]
200
-
201
-
202
- self.avgVel=[self.x,self.y,self.u,self.v,self.up,self.vp,self.uvp,self.FCl,self.Info,self.sn]
203
229
  self.avgVelFields=[self.allFields[f] for f in self.avgVel ]
204
- self.avgVel_plot=[self.Mod,self.u,self.v,self.up,self.vp,self.uvp,self.FCl,self.Info,self.sn]
205
230
  self.avgVel_plot_ind=[self.fields.index(f) for f in self.avgVel_plot if f in self.fields]
206
231
 
207
232
  def pick(self,lista,indici):
208
233
  return [lista[i] for i in indici]
209
234
 
235
+ class VISpar(TABpar):
236
+ FlagVis=True
237
+
238
+ class OUT(TABpar):
239
+ def __init__(self):
240
+ self.x = 0
241
+ self.y = 0
242
+ self.w = None
243
+ self.h = None
244
+ self.vecop = []
245
+
246
+ self.x_min = 0.0
247
+ self.x_max = 0.0
248
+ self.y_min = 0.0
249
+ self.y_max = 0.0
250
+
251
+ self.xres = 1
252
+ self.pixAR = 1
253
+
254
+ self.zconst = 0.0
255
+ self.xterm = 0.0
256
+ self.yterm = 0.0
257
+
258
+ super().__init__('VISpar.Out','Vis')
259
+
260
+ class PRO(TABpar):
261
+ def __init__(self):
262
+ WSize_init=[128, 64, 32]
263
+ WSpac_init=[ 32, 16, 8]
264
+ self.Vect=[copy.deepcopy(WSize_init),copy.deepcopy(WSpac_init),copy.deepcopy(WSize_init),copy.deepcopy(WSpac_init)]
265
+ self.FlagBordo=False
266
+ super().__init__('VISpar.Pro','Vis')
267
+
268
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
269
+ self.setup(Process,Step)
270
+ super().__init__('VISpar','Vis')
271
+ self.unchecked_fields+=['setPage']
272
+ self.uncopied_fields+=['graphics_fields']
273
+
274
+ def setup(self,Process,Step):
275
+ self.Process = Process
276
+ self.Step = Step
277
+ self.FlagView = False
278
+
279
+ self.img=-1
280
+ self.nimg=0
281
+ self.frame=1
282
+ self.it=1
283
+ self.cam=0
284
+ self.ncam=0
285
+
286
+ self.path=''
287
+ self.imList=[[[],[]]*self.ncam]
288
+ self.image_file=''
289
+ self.fres=[] #lambda k: ''
290
+ self.outPathRoot='' #useful in procOhtName(self.VISpar)
291
+ self.name_proc=''
292
+ self.result_file=''
293
+ self.FlagResult=False
294
+
295
+ fields_noGraphics=[f for f,_ in self.__dict__.items()]
296
+ self.type = 0
297
+ self.FlagMIN = False
298
+ self.FlagTR = False
299
+ self.LaserType = 0
300
+ self.Nit = 1
301
+ self.imListMin=[[[],[]]*self.ncam]
302
+
303
+ self.image_file_Min=''
304
+ self.image_file_Disp=''
305
+ self.result_file_Mean=''
306
+ self.image_file_Current=''
307
+ self.result_file_Current=''
308
+
309
+ self.FlagShowIW=False
310
+ self.FlagShowCR=False
311
+ self.FlagSubMIN=False
312
+ self.variable=''
313
+ self.variableKey=''
314
+ self.field_rep=0
315
+
316
+ self.FlagAutoLevels=True
317
+ self.FlagAutoSizes=True
318
+ self.FlagYInvert=[False,False]
319
+ self.FlagResetLevels=True
320
+ self.FlagResetSizes=True
321
+ self.setPage=0
322
+
323
+ namesPIV=NamesPIV()
324
+ img=namesPIV.img
325
+ dispMap=namesPIV.dispMap
326
+ self.vcolorMap={img: 'gray', dispMap: 'gray'}
327
+ self.colorMap='gray'
328
+ self.vvectorColor={img: 'green', dispMap: 'green'}
329
+ self.vectorColor='green'
330
+ self.vLim={img: 1, dispMap: 1}
331
+ self.vmin_default={img: 0, dispMap: 0}
332
+ self.vmax_default={img: 1, dispMap: 0}
333
+ self.vmean_default={img: 0.5, dispMap: 0.5}
334
+ self.vrange_default={img: 1, dispMap: 1}
335
+ self.vmin={img: 0, dispMap: 0}
336
+ self.vmax={img: 1, dispMap: 1}
337
+ self.vmean={img: 0.5, dispMap: 0.5}
338
+ self.vrange={img: 1, dispMap: 1}
339
+ self.min=0
340
+ self.max=1
341
+ self.mean=0.5
342
+ self.range=1
343
+
344
+ self.unit=[False,True]
345
+ self.size_default=[[0,1,0,1,1],[0,1,0,1,1]] #xmin,xmax,ymin,ymax,max vec spacing
346
+ self.size=[[0,1,0,1,1],[0,1,0,1,1]] #xmin,xmax,ymin,ymax,max vec spacing
347
+ self.xmin=0
348
+ self.xmax=1
349
+ self.ymin=0
350
+ self.ymax=1
351
+
352
+ self.nclev=30
353
+ self.vecsize=1
354
+ self.vecwid=1
355
+ self.vecspac=1
356
+ self.streamdens=1
357
+
358
+ self.FlagContourf=True
359
+
360
+ self.graphics_fields=[f for f,_ in self.__dict__.items() if f not in fields_noGraphics]
361
+
362
+ self.Out=self.OUT()
363
+ self.Pro=self.PRO()
364
+
365
+ self.FlagCAL = Process in ProcessTypes.threeCameras
366
+ self.calList = []
367
+ self.calEx = []
368
+
369
+ #self.FlagDISP = Step==StepTypes.disp
370
+ #self.dispFile = ''
371
+
372
+ def resF(self,i,string=''):
373
+ fres=self.fres
374
+ if not fres: return ''
375
+ outPathRoot=fres[0]
376
+ if string=='dispMap':
377
+ fold=os.path.dirname(self.outPathRoot)
378
+ rad=os.path.splitext(os.path.basename(self.outPathRoot))[0]
379
+ if rad[-1]!='_': rad+='_'
380
+ return myStandardRoot(os.path.join(fold, f'dispMap_rot_{rad}{i}.png'))
381
+ ndig=fres[1]
382
+ outExt=fres[2]
383
+ if type(i)==str:
384
+ return f"{outPathRoot}{i}{outExt}"
385
+ elif type(i)==int:
386
+ return f"{outPathRoot}{i:0{ndig:d}d}{outExt}"
387
+ else:
388
+ return ''
210
389
 
211
390
  class Vis_Tab(gPaIRS_Tab):
212
391
  class VIS_Tab_Signals(gPaIRS_Tab.Tab_Signals):
213
392
  pass
214
393
 
215
- def __init__(self,*args):
216
- parent=None
217
- flagInit=True
218
- if len(args): parent=args[0]
219
- if len(args)>1: flagInit=args[1]
394
+ def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
220
395
  super().__init__(parent,Ui_VisTab,VISpar)
221
396
  self.signals=self.VIS_Tab_Signals(self)
222
397
 
223
398
  #------------------------------------- Graphical interface: widgets
399
+ self.TABname='Vis'
224
400
  self.ui: Ui_VisTab
225
- ui=self.ui
226
401
  self.Ptoolbar=None
227
402
  self.addPlotToolBar()
403
+ self.ui.plot.axes.format_coord=lambda x,y: self.custom_format_coord(x,y)
228
404
 
229
405
  self.ui.sliders=self.findChildren(QSlider)
230
- for child in self.ui.sliders:
231
- child.setMinimum(0)
232
- child.setMaximum(nStepsSlider)
406
+ for slider in (self.ui.slider_min,self.ui.slider_max,self.ui.slider_mean,self.ui.slider_range):
407
+ slider.setMinimum(0)
408
+ slider.setMaximum(nStepsSlider)
409
+ slider.setSingleStep(int(nStepsSlider/100))
410
+
411
+ #necessary to change the name and the order of the items
412
+ for g in list(globals()):
413
+ if '_items' in g or '_ord' in g or '_tips' in g:
414
+ #pri.Info.blue(f'Adding {g} to {self.name_tab}')
415
+ setattr(self,g,eval(g))
233
416
 
234
- self.setupWid() #---------------- IMPORTANT
417
+ if __name__ == "__main__":
418
+ self.app=app
419
+ setAppGuiPalette(self)
235
420
 
236
421
  #------------------------------------- Graphical interface: miscellanea
422
+ self.brush_cursor= QCursor(QPixmap(icons_path+"brush_cursor.png").scaled(24,24,mode=Qt.TransformationMode.SmoothTransformation))
423
+ self.FlagNormalCursor=True
424
+ self.CursorTimer = QTimer(self)
425
+ self.CursorTimer.setSingleShot(True)
426
+ self.CursorTimer.timeout.connect(self.forceRestoreArrowCursor)
427
+
428
+ self.img=None
429
+ self.imgshow=None
430
+ self.cb=None
237
431
  self.orect=[]
238
- self.imga=None
239
- self.imgb=None
240
- self.res=None
241
- self.nameimga=self.nameimgb=self.nameres='...'
242
- self.procimga=None
243
- self.procimgb=None
244
- self.procres=None
245
- self.nameprocimga=self.nameprocimgb=self.nameprocres=''
432
+ self.xres=self.yres=1.0
433
+
434
+ self.map=None
435
+ self.contour=None
246
436
  self.qui=None
247
437
  self.stream=None
248
- self.cb=None
249
- #self.VarNames=["Mod","U","V","Fc","info"]
438
+ self.CR=None
439
+ self.RF=None
440
+
250
441
  self.namesPIV=NamesPIV()
251
-
252
442
 
443
+ pri.Time.magenta('Colormap generation: start')
444
+ # Create the popup menu
445
+ self.colorMapMenu = QMenu(self)
446
+ # Add the colormap thumbnails to the menu
447
+ def on_colormap_selected(name):
448
+ self.VISpar.vcolorMap[self.VISpar.variableKey]=self.VISpar.colorMap=name
449
+ for k, colorMapClass in enumerate(VIS_ColorMaps):
450
+ if not k: menu=self.colorMapMenu
451
+ else: menu=self.colorMapMenu.addMenu(colorMapClass)
452
+ #for colormap in VIS_ColorMaps[colorMapClass]:
453
+ for colormap in VIS_ColorMaps[colorMapClass]:
454
+ imgMapPath=icons_path+'colormaps/'+colormap+'.png'
455
+ if os.path.exists(imgMapPath) and not FlagGenerateColormaps:
456
+ pixmap = QPixmap(imgMapPath)
457
+ else:
458
+ pixmap=create_colormap_image(colormap, 25, 50, FlagVerticalColormap, imgMapPath)
459
+ action = menu.addAction(QIcon(pixmap), ' '+colormap)
460
+ action.triggered.connect(lambda _, name=colormap: on_colormap_selected(name))
461
+ pri.Time.magenta('Colormap generation: end')
462
+
463
+ pri.Time.magenta('Vector color generation: start')
464
+ # Create the popup menu
465
+ self.vectorColorMenu = QMenu(self)
466
+ # Add the colormap thumbnails to the menu
467
+ def on_vectorcolor_selected(name):
468
+ self.VISpar.vvectorColor[self.VISpar.variableKey]=self.VISpar.vectorColor=name
469
+ for colorName, color in VIS_VectorColors.items():
470
+ menu=self.vectorColorMenu
471
+ #for colormap in VIS_ColorMaps[colorMapClass]:
472
+ imgMapPath=icons_path+'colormaps/'+colorName+'Vector.png'
473
+ if os.path.exists(imgMapPath) and not FlagGenerateColorvectors:
474
+ pixmap = QPixmap(imgMapPath)
475
+ else:
476
+ pixmap=create_arrow_pixmap(color, 50, 50, imgMapPath)
477
+ action = menu.addAction(QIcon(pixmap), ' '+colorName.lower())
478
+ action.triggered.connect(lambda _, name=colorName: on_vectorcolor_selected(name))
479
+ pri.Time.magenta('Vector color generation: end')
480
+
253
481
  #------------------------------------- Declaration of parameters
254
482
  self.VISpar_base=VISpar()
255
483
  self.VISpar:VISpar=self.TABpar
256
484
  self.VISpar_old:VISpar=self.TABpar_old
257
- self.defineSetTABpar(self.setVISpar)
258
-
259
- self.flagInitImg=False
260
- self.fRead=[lambda f,v: self.getImg([0],f,v),
261
- lambda f,v: self.getImg([1],f,v),
262
- lambda f,v: self.getRes(f,v)]
263
- self.funPlot=self.setMapVar
264
- self.fLoad=[False]*3
265
-
266
485
 
267
486
  #------------------------------------- Callbacks
268
- self.setupCallbacks()
269
- self.FlagSettingPar=False
487
+ self.defineWidgets()
488
+ self.setupWid() #---------------- IMPORTANT
489
+
490
+ FlagPreventAddPrev_Slider=False
491
+ for n in ('min','max','mean','range','nclev','vecsize','vecwid','vecspac','streamdens'):
492
+ def defineSliderCallbackSet(n):
493
+ spin:QSpinBox=getattr(self.ui,'spin_'+n)
494
+ slider:QSlider=getattr(self.ui,'slider_'+n)
495
+
496
+ if n in ('min','max','mean','range'):
497
+ changingAction=lambda: self.sliderLevels_changing(spin,slider,FlagPreventAddPrev_Slider)
498
+ callback=self.wrappedCallback(spin_tips[n],changingAction)
499
+ action=lambda: self.spinLevels_action(spin)
500
+ elif n in ('nclev','vecsize','vecwid','vecspac','streamdens'):
501
+ changingAction=lambda: self.sliderFieldRep_changing(spin,slider,FlagPreventAddPrev_Slider)
502
+ callback=self.wrappedCallback(spin_tips[n],changingAction)
503
+ action=lambda: self.spinFieldRep_action(spin)
504
+ setting=lambda: self.slider_set(spin,slider)
505
+
506
+ slider.valueChanged.connect(callback)
507
+
508
+ if n in ('nclev','streamdens'):
509
+ def sliderMessage(s:QSlider):
510
+ if self.VISpar.field_rep==2:
511
+ tip = f"Release to repaint"
512
+ else: tip=""
513
+ QToolTip.showText(s.mapToGlobal(s.rect().topLeft()), tip)
514
+ slider.sliderPressed.connect(lambda: sliderMessage(slider))
515
+
516
+ setattr(self,'slider_'+n+'_callbcak',callback)
517
+ setattr(self,'spin_'+n+'_action',action)
518
+ setattr(self,'spin_'+n+'_set',setting)
519
+
520
+ defineSliderCallbackSet(n)
521
+
522
+
523
+ for k,n in enumerate(['xmin','xmax','ymin','ymax']):
524
+ def defineXYAction(k,n):
525
+ spin=getattr(self.ui,'spin_'+n)
526
+ action=lambda: self.spin_xy_action(spin,k)
527
+ setattr(self,'spin_'+n+'_action',action)
528
+ defineXYAction(k,n)
529
+
530
+ self.plot_callback=self.wrappedCallback('Plot interaction',self.updatingPlot)
531
+ self.ui.plot.addfuncrelease['fPlotCallback']=self.plot_callback
532
+
533
+ self.button_left_action=lambda: self.leftrightCallback(-1)
534
+ self.button_right_action=lambda: self.leftrightCallback(+1)
535
+
536
+ self.QS_copy2clipboard=QShortcut(QKeySequence('Ctrl+C'), self.ui.plot)
537
+ self.QS_copy2clipboard.activated.connect(self.ui.plot.copy2clipboard)
538
+ self.QS_copy2newfig=QShortcut(QKeySequence('Ctrl+D'), self.ui.plot)
539
+ self.QS_copy2newfig.activated.connect(lambda: self.ui.plot.copy2newfig(self.ui.name_var.toolTip()))
540
+ self.load_Img_callback=self.wrappedCallback('Loading image',self.loadImg)
541
+ self.load_Res_callback=self.wrappedCallback('Loading result',self.loadRes)
542
+
543
+ self.defineCallbacks()
544
+ self.spins_valueChanged=[self.ui.spin_img,self.ui.spin_frame,self.ui.spin_cam,self.ui.spin_it]
545
+ self.connectCallbacks()
546
+
547
+ self.defineSettings()
548
+ self.TABsettings.append(self.setMapVar)
549
+
550
+ self.adjustTABpar=self.adjustVISpar
551
+ self.setTABlayout=self.setVISlayout
552
+
553
+ self.FlagReset=True
554
+ self.FlagResetLevels=False
555
+ self.FlagResetSizes =False
556
+
557
+ self.image_file=''
558
+ self.image_raw=None
559
+ self.image=None
560
+ self.image_file_Min=''
561
+ self.image_Min_raw=None
562
+ self.image_Min=None
563
+ self.image_file_Disp=''
564
+ self.image_Disp_raw=None
565
+ self.image_Disp=None
566
+ self.nbits=0
567
+ self.result_file=''
568
+ self.result=None
569
+ self.result_file_Mean=''
570
+ self.result_Mean=None
571
+ self.image_file_Load=''
572
+ self.result_file_Load=''
573
+
574
+ self.image_Current_raw=None
575
+ self.image_Current=None
576
+ self.result_Current=None
577
+
578
+ self.FlagAddPrev=False
270
579
 
271
580
  #------------------------------------- Initializing
272
581
  if flagInit:
273
582
  self.initialize()
274
- #------------------------------------- todos
275
- ui.button_showMTF.hide()
583
+ #else:
584
+ # self.adjustTABpar()
585
+ # self.setTABpar(FlagBridge=False)
276
586
 
277
587
  def addPlotToolBar(self):
278
588
  if self.Ptoolbar:
@@ -287,1056 +597,1229 @@ class Vis_Tab(gPaIRS_Tab):
287
597
  def initialize(self):
288
598
  pri.Info.yellow(f'{"*"*20} VIS initialization {"*"*20}')
289
599
  self.setExample()
290
- self.setTABpar(True) #with bridge
600
+ self.adjustVISpar()
601
+ self.setVISlayout()
602
+ self.setTABpar(FlagBridge=False) #with bridge
603
+ self.add_TABpar('initialization')
291
604
 
292
605
  def setExample(self):
293
- from .procTools import dataTreePar
294
- self.VISpar.Inp.path=exampleFolder
295
- self.VISpar.Inp.FlagValidPath=int(os.path.exists(self.VISpar.Inp.path))
296
- Pinfo=analysePath(exampleFolder)
297
- if Pinfo.nimg_tot:
298
- k=np.argmax(np.asarray(Pinfo.nimg_tot))
299
- pinfo=Pinfo.extractPinfo(k)
300
- else:
301
- pinfo=patternInfoVar()
302
- pinfo.fra==''
303
- self.VISpar.Inp.pinfo=pinfo
304
- results=createListImages(exampleFolder,pinfo,False)
305
- self.VISpar.Inp.FlagValidRoot=all(results[1])-(not all(results[1]))
306
- self.VISpar.Inp.range_to=results[4]
307
- self.VISpar.list_Image_Files=results[0]
308
-
309
- self.VISpar.Out.path=exampleFolder
310
- self.VISpar.Out.subfold='out_PaIRS/'
311
- self.VISpar.Out.root='out'
312
- self.VISpar.Out.w=results[5]
313
- self.VISpar.Out.h=results[6]
314
-
315
- minproc_name=myStandardRoot(self.VISpar.Out.path+self.VISpar.Out.subfold+self.VISpar.Out.root+outExt.min)
316
- with open(minproc_name, 'rb') as file:
317
- data:dataTreePar = pickle.load(file)
318
- self.VISpar.Tre.filename_proc[dataTreePar.typeMIN]=minproc_name
319
- self.VISpar.Tre.name_proc[dataTreePar.typeMIN]=data.name_proc[dataTreePar.typeMIN]
320
- self.VISpar.Tre.flagRun=-1
321
-
322
- pivproc_name=myStandardRoot(self.VISpar.Out.path+self.VISpar.Out.subfold+self.VISpar.Out.root+outExt.piv)
323
- with open(pivproc_name, 'rb') as file:
324
- data:dataTreePar = pickle.load(file)
325
- self.VISpar.Tre.filename_proc[dataTreePar.typePIV]=pivproc_name
326
- self.VISpar.Tre.name_proc[dataTreePar.typePIV]=data.name_proc[dataTreePar.typePIV]
327
- self.VISpar.Tre.list_pim=data.VIS.Tre.list_pim
328
-
329
- self.VISpar.FlagReset=[True,True]
330
- self.updateVisfromINP(self.VISpar)
331
-
332
- def setupCallbacks(self):
333
- #Callbacks
334
- self.defineSpinCallbacks()
335
- self.defineSliderCallbacks()
336
-
337
- slider_names=['min','max','mean','range','nclev','vecsize','vecspac','streamdens']
338
- spin_names=slider_names+['xmin','ymin','xmax','ymax']
339
- slider_tips=['Minimum level','Maximum level','Mean level','Level range','Number of contour level',
340
- 'Size of vectors','Spacing of vectors','Density of streamlines']
341
- spin_tips=slider_tips+['X minimum limit','Y minimum limit','X maximum limit','Y maximum limit']
342
- for nsp in ['xmin','ymin','xmax','ymax']:
343
- def SpinXYCallback(nsp):
344
- sp=getattr(self.ui,'spin_'+nsp)
345
- return lambda: self.setXYLimFromSpin(sp)
346
- setattr(self,'spin_'+nsp+'_callback',SpinXYCallback(nsp))
347
- self.setSpinCallbacks(spin_names,spin_tips)
348
- self.spin_frame_number_callback=self.addParWrapper(self.spin_frame_number_changing,'Frame number')
349
- self.ui.spin_frame_number.valueChanged.connect(self.spin_frame_number_callback)
350
- self.spin_field_number_callback=self.addParWrapper(self.spin_field_number_changing,'Field number')
351
- self.ui.spin_field_number.valueChanged.connect(self.spin_field_number_callback)
352
-
353
- signals=[["clicked"],
354
- ["activated"], #"currentIndexChanged" #***** rimpiazzare?
355
- ["sliderReleased"]] #"valueChanged" #***** lento
356
- fields=["button",
357
- "combo",
358
- "slider"]
359
- names=[ ['restore','showIW','subMIN','showMTF','invert_y','resize'], #button
360
- ['map_var','field_rep'], #combo
361
- slider_names+[]] #slider
362
- tips=[ ['Restore levels','Show IWs','Subtract minimum','Show MTF','Invert Y axis direction','Resize image'], #button
363
- ['Map variable to display','Type of field representation'], #combo
364
- slider_tips+[]] #slider
365
-
366
- for f,N,S,T in zip(fields,names,signals,tips):
367
- for n,t in zip(N,T):
368
- wid=getattr(self.ui,f+"_"+n)
369
- fcallback=getattr(self,f+"_"+n+"_callback")
370
- fcallbackWrapped=self.addParWrapper(fcallback,t)
371
- for s in S:
372
- sig=getattr(wid,s)
373
- sig.connect(fcallbackWrapped)
374
-
375
- self.ui.left.clicked.connect(lambda: self.leftrightCallback(-1))
376
- self.ui.right.clicked.connect(lambda: self.leftrightCallback(+1))
377
-
378
- self.fPlotCallback=self.addParWrapper(self.updatingPlot,'X-Y limits')
379
- self.ui.plot.addfuncrelease['fPlotCallback']=self.fPlotCallback
380
- self.fLoadingCallback=self.addParWrapper(lambda: None,'loading')
606
+ if not basefold_DEBUG_VIS: return
607
+ imSet=ImageSet(path=basefold_DEBUG_VIS)
608
+
609
+ k1=0
610
+ k2=imSet.link[k1][0]
611
+ self.VISpar.path=imSet.path
612
+ self.VISpar.imList,_=imSet.genListsFromFrame([k1],[k2+1],imSet.ind_in[k1],imSet.nimg[k1],1,False)
613
+
614
+ outPath=myStandardPath(os.path.dirname(imSet.outFiles[outExt.piv][0]))
615
+ outSet=ImageSet(path=outPath,exts=list(outType_dict))
616
+
617
+ im_min_a=findFiles_sorted(outPath+'*a_min.*')
618
+ if im_min_a: self.VISpar.imListMin[0].append(im_min_a[0])
619
+ im_min_b=findFiles_sorted(outPath+'*b_min.*')
620
+ if im_min_b: self.VISpar.imListMin[0].append(im_min_b[0])
621
+ self.VISpar.fres=[outPath+outSet.fname[0][0],outSet.fname[0][1],outSet.fname[0][2]] #lambda i: outPath+outSet.nameF(outSet.fname[0],i)
622
+ self.VISpar.result_file_Mean=self.VISpar.resF('*').replace('_*','')
623
+ self.VISpar.img=1
624
+ self.VISpar.Out.FlagNone=True
625
+ return
381
626
 
382
- self.QS_copy2clipboard=QShortcut(QKeySequence('Ctrl+C'), self.ui.plot)
383
- self.QS_copy2clipboard.activated.connect(self.ui.plot.copy2clipboard)
384
- self.QS_copy2newfig=QShortcut(QKeySequence('Ctrl+F'), self.ui.plot)
385
- self.QS_copy2newfig.activated.connect(lambda: self.ui.plot.copy2newfig(self.ui.name_var.toolTip()))
627
+ #*************************************************** Adjusting parameters
628
+ def adjustVISpar(self):
629
+ self.VISpar.ncam=len(self.VISpar.imList)
630
+ if self.VISpar.ncam and not self.VISpar.cam: self.VISpar.cam=1
631
+ self.VISpar.nimg=len(self.VISpar.imList[0][0]) if len(self.VISpar.imList[0]) else 0 if self.VISpar.ncam else 0
632
+ if not self.VISpar.nimg and self.VISpar.img:
633
+ FlagResults=self.image_file_Min!='' or self.result_file_Mean!='' or self.image_file_Disp!=''
634
+ self.VISpar.img=0 if FlagResults else -1
635
+
636
+ FlagNewImage, FlagNewResult = self.adjustImport()
637
+
638
+ FlagNew=(not self.VISpar.type and FlagNewImage) or (self.VISpar.type==1 and FlagNewResult)
639
+ FlagDiff=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['img','cam','frame']) or FlagNew
640
+
641
+ if (self.VISpar.FlagAutoLevels and (FlagNewImage or FlagNewResult)):
642
+ self.resetAllLevels()
643
+ if FlagDiff or self.FlagResetLevels:
644
+ self.FlagResetLevels=False
645
+ self.resetLevels()
646
+ elif self.FlagResetLevels:
647
+ self.FlagResetLevels=False
648
+ self.resetLevels()
649
+
650
+ if (self.VISpar.FlagAutoSizes and (FlagNewImage or FlagNewResult)):
651
+ self.resetAllXYLims()
652
+ if FlagDiff or self.FlagResetSizes:
653
+ self.FlagResetSizes=False
654
+ self.resetXYLims()
655
+ elif self.FlagResetSizes:
656
+ self.FlagResetSizes=False
657
+ self.resetXYLims()
386
658
 
387
- def defineSpinCallbacks(self):
388
- self.spin_min_callback=lambda: self.movingSpinMinMax(self.ui.spin_min,self.ui.spin_max,+1)
389
- self.spin_max_callback=lambda: self.movingSpinMinMax(self.ui.spin_max,self.ui.spin_min,-1)
390
- self.spin_mean_callback=lambda: self.movingSpinMeanRange(self.ui.spin_mean,1)
391
- self.spin_range_callback=lambda: self.movingSpinMeanRange(self.ui.spin_range,2)
392
-
393
- self.spin_nclev_callback=lambda: self.movingSpinContourQuiver(self.ui.spin_nclev,0)
394
- self.spin_vecsize_callback=lambda: self.movingSpinContourQuiver(self.ui.spin_vecsize,1)
395
- self.spin_vecspac_callback=lambda: self.movingSpinContourQuiver(self.ui.spin_vecspac,2)
396
- self.spin_streamdens_callback=lambda: self.movingSpinContourQuiver(self.ui.spin_streamdens,3)
397
-
398
- def defineSliderCallbacks(self):
399
- self.slider_min_callback=lambda: self.movingSliderMinMax(self.ui.slider_min,self.ui.spin_min,self.ui.spin_max,+1)
400
- self.slider_max_callback=lambda: self.movingSliderMinMax(self.ui.slider_max,self.ui.spin_max,self.ui.spin_min,-1)
401
- self.slider_mean_callback=lambda: self.movingSliderMeanRange(self.ui.slider_mean,self.ui.spin_mean,1)
402
- self.slider_range_callback=lambda: self.movingSliderMeanRange(self.ui.slider_range,self.ui.spin_range,2)
403
-
404
- self.slider_nclev_callback=lambda: self.movingSliderContourQuiver(self.ui.slider_nclev,self.ui.spin_nclev,0)
405
- self.slider_vecsize_callback=lambda: self.movingSliderContourQuiver(self.ui.slider_vecsize,self.ui.spin_vecsize,1)
406
- self.slider_vecspac_callback=lambda: self.movingSliderContourQuiver(self.ui.slider_vecspac,self.ui.spin_vecspac,2)
407
- self.slider_streamdens_callback=lambda: self.movingSliderContourQuiver(self.ui.slider_streamdens,self.ui.spin_streamdens,3)
408
-
409
- #*************************************************** Callbacks
410
- #********** Interaction with plot area
411
- def updatingPlot(self):
412
- self.VISpar.xlim=list(self.ui.plot.axes.get_xlim())
413
- self.VISpar.ylim=list(self.ui.plot.axes.get_ylim())
414
-
415
- def setValueXYLimSpin(self):
416
- self.ui.spin_xmin.setValue(self.VISpar.xlim[0])
417
- self.ui.spin_xmax.setValue(self.VISpar.xlim[1])
418
- self.ui.spin_ymin.setValue(self.VISpar.ylim[0])
419
- self.ui.spin_ymax.setValue(self.VISpar.ylim[1])
420
-
421
- def setXYLimFromSpin(self,sp):
422
- if sp.hasFocus():
423
- self.VISpar.xlim[0]=self.ui.spin_xmin.value()
424
- self.VISpar.xlim[1]=self.ui.spin_xmax.value()
425
- self.VISpar.ylim[0]=self.ui.spin_ymin.value()
426
- self.VISpar.ylim[1]=self.ui.spin_ymax.value()
427
- self.setAxisLim()
428
-
429
- #********** Buttons and image spins
430
- def button_showIW_callback(self):
431
- self.VISpar.flagShowIW=self.ui.button_showIW.isChecked()
432
- self.setDefaultXLim()
659
+ self.adjustFieldRep()
660
+
433
661
 
434
- def button_showMTF_callback(self):
435
- if self.ui.button_showMTF.isChecked():
436
- pass
662
+ def adjustImport(self):
663
+ self.VISpar.image_file=self.VISpar.image_file_Min=self.VISpar.image_file_Disp=''
664
+ if self.VISpar.img%2==0 and self.VISpar.FlagTR and not self.VISpar.LaserType:
665
+ f=[1,0][self.VISpar.frame-1]
666
+ else: f=self.VISpar.frame-1
667
+ self.VISpar.image_file_Disp=''
668
+ FlagDisparity=self.VISpar.Step==StepTypes.disp and (resultCheck(self,self.VISpar,ind=self.VISpar.ind) or self.VISpar.FlagView)
669
+ if FlagDisparity:
670
+ dispMap_filename=self.VISpar.resF(f'it{self.VISpar.it}',string='dispMap')
671
+ if os.path.exists(dispMap_filename):
672
+ self.VISpar.image_file_Disp=dispMap_filename
673
+ self.VISpar.image_file_Min=''
674
+ ITEs=self.gui.ui.Explorer.ITEsfromInd(self.VISpar.ind)
675
+ ind_min=list(ITEs[0].children).index(StepTypes.min)
676
+ FlagMinimum=(self.VISpar.FlagMIN or self.VISpar.Step==StepTypes.min) and (resultCheck(self,self.VISpar,ind=ITEs[ind_min+1].ind) or self.VISpar.FlagView)
677
+ if FlagMinimum:
678
+ if 0<=self.VISpar.cam-1<self.VISpar.ncam:
679
+ if 0<=f<len(self.VISpar.imListMin[self.VISpar.cam-1]):
680
+ self.VISpar.image_file_Min=self.VISpar.imListMin[self.VISpar.cam-1][f]
681
+ if self.VISpar.img>0:
682
+ self.VISpar.image_file=self.VISpar.path+self.VISpar.imList[self.VISpar.cam-1][self.VISpar.frame-1][self.VISpar.img-1] if len(self.VISpar.imList[self.VISpar.cam-1][self.VISpar.frame-1]) else ''
683
+ elif self.VISpar.img==0:
684
+ self.VISpar.image_file=self.VISpar.image_file_Current if self.VISpar.flagRun==-2 and self.VISpar.variableKey!=self.namesPIV.dispMap else self.VISpar.image_file_Disp if self.VISpar.variableKey==self.namesPIV.dispMap else self.VISpar.image_file_Min
437
685
  else:
438
- pass
439
-
440
- def button_subMIN_callback(self):
441
- self.VISpar.flagMIN=self.ui.button_subMIN.isChecked()
442
-
443
- def button_resize_callback(self):
444
- self.setDefaultXLim()
445
-
446
- def button_invert_y_callback(self):
447
- self.VISpar.FlagYInvert[self.VISpar.type]=self.ui.button_invert_y.isChecked()
448
-
449
- def button_restore_callback(self):
450
- self.setDefaultCLim()
451
-
452
- def leftrightCallback(self,di):
453
- i=self.ui.image_levels.currentIndex()
454
- i=i+di
455
- c=self.ctoolpages
456
- if i<0: i=c
457
- elif i>c: i=0
458
- self.ui.image_levels.setCurrentIndex(i)
459
- self.ui.label_title.setText(f"Settings ({i+1}/{c+1})")
460
-
461
- def spin_field_number_changing(self):
462
- if not self.FlagSettingPar:
463
- nfield_old=self.VISpar.nfield
464
- self.VISpar.nfield=self.ui.spin_field_number.value()
465
- if self.ui.spin_field_number.hasFocus():
466
- i=self.VISpar.nfield-imin_im_pair
467
- self.checkSavedProc(i)
468
- self.fLoad=[False]*3
469
- self.importVar()
470
- if nfield_old!=self.VISpar.nfield and (self.VISpar.nfield==imin_im_pair-1 or nfield_old==imin_im_pair-1):
471
- self.setDefaultCLim()
472
- return [1,None]
473
- else:
474
- return[-1,None]
475
-
476
- def spin_frame_number_changing(self):
477
- if not self.FlagSettingPar:
478
- self.ui.combo_map_var.setCurrentIndex(self.ui.spin_frame_number.value())
479
- if self.ui.spin_frame_number.hasFocus():
480
- self.combo_map_var_action()
481
- return [1,None]
686
+ self.VISpar.image_file=self.image_file_Load
687
+
688
+ self.VISpar.result_file=self.VISpar.result_file_Mean=''
689
+ if self.VISpar.img==-1:
690
+ self.VISpar.result_file=self.result_file_Load
691
+ elif self.VISpar.img==0 and self.VISpar.flagRun==-2:
692
+ if (self.VISpar.Step==StepTypes.disp and self.VISpar.it==self.VISpar.Nit) or self.VISpar.Step!=StepTypes.disp:
693
+ self.VISpar.result_file=self.VISpar.result_file_Current
482
694
  else:
483
- return [-1,None]
484
-
485
- #********** Combos etc.
486
- def combo_map_var_callback(self):
487
- if self.VISpar.MapVar_type!=self.mapVarType():
488
- self.combo_map_var_action()
695
+ self.VISpar.FlagResult=self.VISpar.Step!=StepTypes.min and (resultCheck(self,self.VISpar) or self.VISpar.FlagView)
696
+ if self.VISpar.FlagResult:
697
+ if self.VISpar.Step==StepTypes.disp:
698
+ self.VISpar.result_file_Mean=self.VISpar.resF(f'it{self.VISpar.it}')
699
+ else:
700
+ self.VISpar.result_file_Mean=self.VISpar.resF('*').replace('_*','')
701
+ if self.VISpar.img>0:
702
+ if self.VISpar.Step==StepTypes.disp:
703
+ self.VISpar.result_file=''
704
+ else:
705
+ self.VISpar.result_file=self.VISpar.resF(self.VISpar.img)
706
+ elif self.VISpar.img==0:
707
+ self.VISpar.result_file=self.VISpar.result_file_Mean
708
+ if not self.VISpar.FlagView:
709
+ ITE=self.gui.ui.Explorer.ITEfromInd(self.VISpar.ind)
710
+ id=ITE.procdata.name_proc
711
+ self.VISpar.FlagResult=fileIdenitifierCheck(id,self.VISpar.result_file)
712
+ if not self.VISpar.FlagResult: self.VISpar.result_file=''
489
713
 
490
- def combo_map_var_action(self):
491
- type_old=int(self.VISpar.MapVar_type>1)
492
- self.VISpar.MapVar_type=self.mapVarType()
493
- self.VISpar.type=int(self.VISpar.MapVar_type>1)
494
- if self.VISpar.type: t=2
495
- else: t=self.VISpar.MapVar_type
496
- if not self.fLoad[t]:
497
- self.importVar()
498
- if type_old!=self.VISpar.type:
499
- self.setDefaultXLim()
500
- self.setDefaultCLim()
501
- else:
502
- if self.VISpar.type==1: self.setDefaultCLim()
503
-
504
- def mapVarType(self):
505
- if self.ui.combo_map_var.currentText():
506
- ind=self.namesPIV.combo_list.index(self.ui.combo_map_var.currentText())
507
- else: ind=0
508
- return ind
509
-
510
- def setDefaultXLim(self,*args):
511
- if len(args): VISpar_prev:VISpar=args[0]
512
- else: VISpar_prev=self.VISpar
513
- mapVarType=VISpar_prev.MapVar_type
514
- """
515
- if mapVarType in (0,1):
516
- VISpar_prev.FlagYInvert[self.VISpar.type]=True
517
- else:
518
- VISpar_prev.FlagYInvert[self.VISpar.type]=False
519
- """
520
- j=mapVarType if mapVarType in (0,1) else 2
521
- VISpar_prev.xlim=VISpar_prev.size[j][0:2]
522
- VISpar_prev.ylim=VISpar_prev.size[j][2:4]
523
714
 
524
- def setDefaultCLim(self,*args):
525
- if len(args): VISpar_prev:VISpar=args[0]
526
- else: VISpar_prev=self.VISpar
527
- mapVarType=VISpar_prev.MapVar_type
528
- flagImg=mapVarType in (0,1)
529
- if flagImg:
530
- me=VISpar_prev.mean[mapVarType]
531
- st=VISpar_prev.std[mapVarType]
532
- else:
533
- j=self.namesPIV.fields[mapVarType]
534
- me=VISpar_prev.mean[2][j]
535
- st=VISpar_prev.std[2][j]
536
- VISpar_prev.vmin=me-2*st
537
- VISpar_prev.vmax=me+2*st
538
- if flagImg: VISpar_prev.vmin=max([VISpar_prev.vmin,0])
539
- self.adjustValues(0,VISpar_prev)
715
+ FlagNewImage, FlagNewResult, _=self.importFiles()
716
+ return FlagNewImage, FlagNewResult
540
717
 
541
- def adjustValues(self,flag,*args):
542
- if len(args): VISpar_prev:VISpar=args[0]
543
- else: VISpar_prev=self.VISpar
544
- #flag=0 from min/max to mean/range
545
- #flag=1 from mean/range to min/max; mean is fixed
546
- #flag=2 from mean/range to min/max; range is fixed
547
- if flag==0:
548
- mi=VISpar_prev.vmin
549
- Ma=VISpar_prev.vmax
550
- VISpar_prev.vmean=0.5*(mi+Ma)
551
- VISpar_prev.vrange=Ma-mi
552
- else:
553
- m,M,step,_,_,_=self.getmM()
554
- med_val=VISpar_prev.vmean
555
- if med_val==M-step:
556
- range_val=2*step
718
+ def importFiles(self):
719
+ if self.VISpar.image_file_Min!=self.image_file_Min or self.VISpar.FlagMIN!=self.VISpar_old.FlagMIN or self.FlagReset:
720
+ self.image_file_Min,self.image_Min_raw=self.readImageFile(self.VISpar.image_file_Min)
721
+ if self.VISpar.image_file_Disp!=self.image_file_Disp or self.FlagReset:
722
+ self.image_file_Disp,self.image_Disp_raw=self.readImageFile(self.VISpar.image_file_Disp)
723
+ if self.VISpar.result_file_Mean!=self.result_file_Mean or self.VISpar.FlagResult!=self.VISpar_old.FlagResult or self.FlagReset:
724
+ self.result_file_Mean,self.result_Mean=self.readResultFile(self.VISpar.result_file_Mean)
725
+
726
+ FlagNewImage=self.VISpar.image_file!=self.image_file or self.VISpar.ind[:-1]!=self.VISpar_old.ind[:-1]
727
+ if FlagNewImage or self.FlagReset:
728
+ self.image_file=self.VISpar.image_file
729
+ if self.VISpar.img==0:
730
+ if self.VISpar.flagRun==-2:
731
+ self.image_raw=self.image_Disp_raw if self.VISpar.variableKey==self.namesPIV.dispMap else self.image_Current_raw[self.VISpar.frame] if self.image_Current_raw else None
732
+ else:
733
+ self.image_raw=self.image_Disp_raw if self.VISpar.variableKey==self.namesPIV.dispMap else self.image_Min_raw
557
734
  else:
558
- range_val=VISpar_prev.vrange
559
- VISpar_prev.vmin=mi=max([med_val-range_val*0.5,m])
560
- if mi==m:
561
- if flag==1:
562
- VISpar_prev.vmax=Ma=2*med_val-mi
563
- VISpar_prev.vrange=Ma-mi
735
+ self.image_file,self.image_raw=self.readImageFile(self.VISpar.image_file)
736
+ mapVariableList=[]
737
+ #if self.image_raw is None and self.VISpar.img==0: mapVariableList=[]
738
+ #else:
739
+ if self.image_Disp_raw is not None and self.VISpar.img==0: mapVariableList+=[self.namesPIV.dispMap]
740
+ if (self.image_Min_raw is not None and self.VISpar.img==0) or self.VISpar.img!=0: mapVariableList+=[self.namesPIV.img]
741
+
742
+ FlagNewResult=self.VISpar.result_file!=self.result_file or self.VISpar.ind[:-1]!=self.VISpar_old.ind[:-1]
743
+ if FlagNewResult or self.FlagReset:
744
+ self.result_file=self.VISpar.result_file
745
+ if self.VISpar.img==0:
746
+ if self.VISpar.flagRun==-2:
747
+ self.result=self.result_Current
564
748
  else:
565
- VISpar_prev.vmax=Ma=mi+range_val
566
- VISpar_prev.vmean=0.5*(mi+Ma)
749
+ self.result=self.result_Mean
567
750
  else:
568
- VISpar_prev.vmax=Ma=min([med_val+range_val*0.5,M])
569
- if Ma==M:
570
- if flag==1:
571
- VISpar_prev.vmin=mi=2*med_val-Ma
572
- VISpar_prev.vrange=Ma-mi
573
- else:
574
- VISpar_prev.vmin=mi=Ma-range_val
575
- VISpar_prev.vmean=0.5*(mi+Ma)
751
+ self.result_file,self.result=self.readResultFile(self.VISpar.result_file)
576
752
 
577
- def combo_field_rep_callback(self):
578
- self.VISpar.VecField_type=self.ui.combo_field_rep.currentIndex()
579
-
580
- #********** Min-max
581
- def movingSpinMinMax(self,sp_min,sp_max,dv):
582
- if sp_min.hasFocus():
583
- self.changeSpinMinMax(sp_min,sp_max,dv)
584
-
585
- def changeSpinMinMax(self,sp_min,sp_max,dv):
586
- v=sp_min.value()
587
- if (dv>0 and v>=sp_max.value()) or \
588
- (dv<0 and v<=sp_max.value()):
589
- sp_max.setValue(v+dv*sp_min.singleStep())
590
- self.VISpar.vmin=self.ui.spin_min.value()
591
- self.VISpar.vmax=self.ui.spin_max.value()
592
- self.adjustValues(0)
593
-
594
- def movingSliderMinMax(self,sl_min,sp_min,sp_max,dv):
595
- if sl_min.hasFocus():
596
- v=sl_min.value()/(nStepsSlider-1)*(sp_min.maximum()-sp_min.minimum())+sp_min.minimum()
597
- sp_min.setValue(v)
598
- self.changeSpinMinMax(sp_min,sp_max,dv)
599
-
600
- #********** Mean-range
601
- def movingSpinMeanRange(self,sp,n):
602
- #n=1 for mean, 2 for range
603
- if sp.hasFocus():
604
- self.changeSpinMeanRange(sp,n)
605
-
606
- def changeSpinMeanRange(self,sp,n):
607
- self.VISpar.vmean=self.ui.spin_mean.value()
608
- self.VISpar.vrange=self.ui.spin_range.value()
609
- self.adjustValues(n)
610
-
611
- def movingSliderMeanRange(self,sl,sp,n):
612
- if sl.hasFocus():
613
- v=sl.value()/(nStepsSlider-1)*(sp.maximum()-sp.minimum())+sp.minimum()
614
- sp.setValue(v)
615
- self.changeSpinMeanRange(sp,n)
616
-
617
- #********** Remaining
618
- def movingSpinContourQuiver(self,sp,n):
619
- if sp.hasFocus():
620
- self.changeSpinContourQuiver(sp,n)
621
-
622
- def changeSpinContourQuiver(self,sp,n):
623
- if n==0: self.VISpar.nclev=sp.value()
624
- elif n==1: self.VISpar.vecsize=sp.value()
625
- elif n==2: self.VISpar.vecspac=sp.value()
626
- elif n==3: self.VISpar.streamdens=sp.value()
627
-
628
- def movingSliderContourQuiver(self,sl,sp,n):
629
- if sl.hasFocus():
630
- v=sl.value()/(nStepsSlider-1)*(sp.maximum()-sp.minimum())+sp.minimum()
631
- sp.setValue(v)
632
- self.changeSpinContourQuiver(sp,n)
633
-
634
- #*************************************************** Menus
635
- def contextMenuEvent(self, event):
636
- contextMenu = QMenu(self)
637
- copy2clipboard = contextMenu.addAction("Copy to clipboard ("+self.QS_copy2clipboard.key().toString(QKeySequence.NativeText)+")")
638
- copy2newfig = contextMenu.addAction("Open in new figure ("+self.QS_copy2newfig.key().toString(QKeySequence.NativeText)+")")
639
- contextMenu.addSeparator()
640
- if len(self.ui.plot.fig2)>1:
641
- showAll = contextMenu.addAction("Show all")
642
- closeAll = contextMenu.addAction("Close all")
643
- alignAll = contextMenu.addAction("Align all")
644
- contextMenu.addSeparator()
753
+ if self.image_raw is not None:
754
+ if self.VISpar.img>=0 and self.VISpar.variableKey!=self.namesPIV.dispMap:
755
+ self.image=transfIm(self.VISpar.Out,Images=[self.image_raw])[0]
756
+ else:
757
+ self.image=self.image_raw
758
+ self.getImageInfo()
645
759
  else:
646
- showAll = None
647
- closeAll= None
648
- alignAll= None
649
- loadImga = contextMenu.addAction("Load image frame 0")
650
- loadImga.setCheckable(self.fLoad[0])
651
- loadImga.setChecked(self.fLoad[0])
652
- loadImgb = contextMenu.addAction("Load image frame 1")
653
- loadImgb.setCheckable(self.fLoad[1])
654
- loadImgb.setChecked(self.fLoad[1])
655
- loadRes = contextMenu.addAction("Load result")
656
- loadRes.setCheckable(self.fLoad[2])
657
- loadRes.setChecked(self.fLoad[2])
658
- action = contextMenu.exec(self.mapToGlobal(event.pos()))
659
- if action == copy2clipboard:
660
- self.ui.plot.copy2clipboard()
661
- elif action == copy2newfig:
662
- self.ui.plot.copy2newfig(self.ui.name_var.toolTip())
663
- elif action == showAll:
664
- self.ui.plot.showAll()
665
- elif action == closeAll:
666
- self.ui.plot.closeAll()
667
- elif action == alignAll:
668
- self.ui.plot.alignAll()
669
- elif action == loadImga:
670
- self.loadImg([0])
671
- elif action == loadImgb:
672
- self.loadImg([1])
673
- elif action == loadRes:
674
- self.loadRes()
760
+ self.image=None
761
+ if self.image_Min_raw is not None:
762
+ self.image_Min=transfIm(self.VISpar.Out,Images=[self.image_Min_raw])[0]
763
+ else:
764
+ self.image_Min=None
765
+ if self.image_Disp_raw is not None:
766
+ self.image_Disp=self.image_Disp_raw #transfIm(self.VISpar.Out,Images=[self.image_Disp_raw])[0]
767
+ else:
768
+ self.image_Disp=None
769
+ if self.result is not None:
770
+ self.getResultInfo()
771
+
772
+ if self.result:
773
+ [mapVariableList.append(r) for r in list(self.result)]
774
+ self.FlagReset=False
775
+
776
+ comboItemsList=[]
777
+ if self.namesPIV.img in mapVariableList: comboItemsList+=[self.namesPIV.combo_dict[self.namesPIV.img]]
778
+ if self.namesPIV.dispMap in mapVariableList: comboItemsList+=[self.namesPIV.combo_dict[self.namesPIV.dispMap]]
779
+ for f in list(self.namesPIV.combo_dict)[2:]:
780
+ if f in mapVariableList: comboItemsList.append(self.namesPIV.combo_dict[f])
781
+ if len(comboItemsList)==0: comboItemsList=[self.namesPIV.combo_dict[self.namesPIV.img]]
782
+ if self.VISpar.variable not in comboItemsList:
783
+ self.VISpar.variable=comboItemsList[0]
784
+ self.VISpar.variableKey=self.namesPIV.combo_dict_keys[self.VISpar.variable]
785
+ if self.VISpar.variableKey==self.namesPIV.img and self.VISpar.img==0:
786
+ if self.VISpar.image_file!=self.VISpar.image_file_Min:
787
+ self.VISpar.image_file=self.VISpar.image_file_Min
788
+ self.image=self.image_Min
789
+ self.getImageInfo()
790
+ elif self.VISpar.variableKey==self.namesPIV.dispMap and self.VISpar.img==0:
791
+ if self.VISpar.image_file!=self.VISpar.image_file_Disp:
792
+ self.VISpar.image_file=self.VISpar.image_file_Disp
793
+ self.image=self.image_Disp
794
+ self.getImageInfo()
795
+ self.VISpar.type=int(self.VISpar.variableKey not in (self.namesPIV.img, self.namesPIV.dispMap) )
796
+
797
+ return FlagNewImage, FlagNewResult, comboItemsList
798
+
799
+ def checkVISTab(self,ind=None):
800
+ if ind is None: VIS:VISpar=self.VISpar
801
+ else: VIS:VISpar=self.TABpar_at(ind)
802
+ VIS.OptionDone=1 if (VIS.flagRun>0 and resultCheck(self,VIS)) or VIS.flagRun<=0 else 0
803
+
804
+ def adjustFieldRep(self):
805
+ if self.VISpar_old.field_rep!=self.VISpar.field_rep and self.result:
806
+ if not self.VISpar.unit[self.VISpar.type]:
807
+ xres,yres=self.getXYRes(type=1)
808
+ else: xres=yres=1.0
809
+ if self.namesPIV.x in self.result and self.namesPIV.y in self.result:
810
+ X=self.result[self.namesPIV.x]*xres
811
+ Y=self.result[self.namesPIV.y]*yres
812
+ elif self.namesPIV.X in self.result and self.namesPIV.Y in self.result:
813
+ X=self.result[self.namesPIV.X]*xres
814
+ Y=self.result[self.namesPIV.Y]*yres
815
+ else: return
816
+ dX=np.sqrt((X[0,1]-X[0,0])**2+(Y[1,0]-Y[0,0])**2)
817
+ dW=[X.max()-X.min(),Y.max()-Y.min()]
818
+ size_pixels=self.ui.plot.fig.get_size_inches()*self.ui.plot.fig.get_dpi()*self.ui.plot.axes.get_position().bounds[2:]
819
+ spaPixels=dX*size_pixels/dW
820
+ fac_spa=np.max(nPixelsPerVector/spaPixels).astype(int).item()
821
+ self.VISpar.vecspac=max([1,fac_spa])
822
+ self.VISpar.vecsize=5
823
+ self.VISpar.vecwid=1
824
+
825
+ #*************************************************** Layout
826
+ def setVISlayout(self):
827
+ _, _, comboItemsList=self.importFiles()
828
+ self.checkResVariables()
829
+
830
+ FlagLoad=self.image_file_Load!='' or self.result_file_Load!=''
831
+ FlagResults=self.image_file_Min!='' or self.result_file_Mean!='' or self.image_file_Disp!=''
832
+ FlagSpinsEnabled=self.VISpar.nimg or FlagLoad
833
+ FlagDispMap=self.VISpar.variableKey==self.namesPIV.dispMap
834
+ #self.ui.Plot_tools.setEnabled(FlagSpinsEnabled)
835
+
836
+ FlagIW=self.VISpar.type==0 and self.VISpar.Step in (StepTypes.piv,StepTypes.disp,StepTypes.spiv) and not FlagDispMap
837
+ self.ui.button_ShowIW.setVisible(FlagIW)
838
+ if FlagIW:
839
+ tip=f"{'Hide' if self.ui.button_ShowIW.isChecked() else 'Show'} Interrogation Window scheme"
840
+ self.ui.button_ShowIW.setToolTip(tip)
841
+ self.ui.button_ShowIW.setStatusTip(tip)
842
+
843
+ FlagCR=self.VISpar.type==0 and self.VISpar.Step in (StepTypes.disp,StepTypes.spiv) and not FlagDispMap
844
+ self.ui.button_ShowCR.setVisible(FlagCR)
845
+ if FlagCR:
846
+ tip=f"{'Hide' if self.ui.button_ShowCR.isChecked() else 'Show'} common region"
847
+ self.ui.button_ShowCR.setToolTip(tip)
848
+ self.ui.button_ShowCR.setStatusTip(tip)
849
+
850
+ FlagMIN=self.VISpar.type==0 and self.image_Min is not None and self.VISpar.img>0 #and self.VISpar.FlagMIN
851
+ self.ui.button_SubMIN.setVisible(FlagMIN)
852
+ if FlagMIN:
853
+ tip=f"{'Add' if self.ui.button_SubMIN.isChecked() else 'Subtract'} historical minimum background"
854
+ self.ui.button_SubMIN.setToolTip(tip)
855
+ self.ui.button_SubMIN.setStatusTip(tip)
856
+
857
+ self.ui.line_img.setVisible(FlagIW or FlagMIN)
858
+
859
+ FlagUnit=self.VISpar.Process==ProcessTypes.piv and (self.VISpar.Out.xres!=1.0 or self.VISpar.Out.pixAR!=1.0)
860
+ self.ui.button_unit.setVisible(FlagUnit)
861
+ if FlagUnit:
862
+ tip=f"Set {'pixel' if self.ui.button_unit.isChecked() else 'physical'} units"
863
+ self.ui.button_unit.setToolTip(tip)
864
+ self.ui.button_unit.setStatusTip(tip)
865
+
866
+ self.ui.line_unit.setVisible(FlagUnit)
867
+
868
+ self.ui.button_Contourf.setVisible(self.VISpar.type)
869
+ self.ui.line_Contourf.setVisible(self.VISpar.type==1)
675
870
 
676
- def loadImg(self,*args):
677
- if len(args): iab=args[0]
678
- else: iab=[0]
679
- filename, _ = QFileDialog.getOpenFileName(self,\
680
- "Select an image file of the sequence", filter=text_filter,\
681
- options=optionNativeDialog)
682
- if filename:
683
- if iab[0]==0:
684
- self.VISpar.nameimga=myStandardRoot('{}'.format(str(filename)))
685
- else:
686
- self.VISpar.nameimgb=myStandardRoot('{}'.format(str(filename)))
687
- self.getImg(iab,True)
688
- combo_items=self.namesPIV.combo_list[:2]
689
- curr_combo_items=self.VISpar.combo_items
690
- self.VISpar.combo_items=[]
691
- for f in self.namesPIV.combo_list:
692
- if f in curr_combo_items or f in combo_items:
693
- self.VISpar.combo_items.append(f)
694
- self.VISpar.MapVar_type=iab[0]
695
- self.VISpar.type=0
696
- self.VISpar.FlagYInvert[self.VISpar.type]=True
697
- self.VISpar.FlagExistRes[0]=[True]
698
- self.setDefaultCLim()
699
- self.setDefaultXLim()
700
- self.fLoadingCallback()
701
- self.fLoad[iab[0]]=True
871
+ self.ui.combo_map_var.clear()
872
+ self.ui.combo_map_var.addItems(comboItemsList)
702
873
 
703
- def getImg(self,iab,FlagNewRead,*args):
704
- if len(args): VISpar_prev:VISpar=args[0]
705
- else: VISpar_prev=self.VISpar
706
- pri.PlotTime.white(f'{"*"*25} Opening image - start')
707
-
708
- imgab=['imga','imgb']
709
- for i in iab:
710
- n=imgab[i]
711
- flagProc=VISpar_prev.Tre.flagRun<=-10 and VISpar_prev.nfield==imin_im_pair-1
712
- if flagProc:
713
- prefix='proc'
714
- name_VISpar=getattr(self,'name'+prefix+n)
715
- name_VISpa_old=''
716
- else:
717
- prefix=''
718
- name_VISpar=getattr(VISpar_prev,'name'+n)
719
- name_VISpa_old=getattr(self.VISpar_old,'name'+n)
720
- nameimg=name_VISpar
721
- I=None
722
- #if getattr(self,'name'+n,nameimg)==name_VISpar: continue
723
- VISpar_prev.FlagErrRead[i]=True
724
- if name_VISpar:
725
- try:
726
- if flagProc:
727
- I=getattr(self,prefix+n)
728
- VISpar_prev.FlagErrRead[i]=np.size(I)==np.size(np.zeros(1))
729
- else:
730
- if os.path.exists(name_VISpar):
731
- pri.Info.cyan(f'Opening: {name_VISpar} [<--{name_VISpa_old}]')
732
- #img=mplimage.imread(name_VISpar)
733
- imgraw=Image.open(name_VISpar)
734
- I=np.ascontiguousarray(imgraw)
735
- I=transfIm(VISpar_prev.Out,Images=[I])[0]
736
- VISpar_prev.FlagErrRead[i]=False
737
- except Exception as inst:
738
- pri.Error.red(f'Error opening image file: {name_VISpar}\n{traceback.print_exc()}\n{inst}')
739
- #else:
740
- #nameimg=f'Void image file'
741
- #if VISpar_prev.indTree==self.VISpar.indTree and VISpar_prev.indItem==self.VISpar.indItem and VISpar_prev.ind==self.VISpar.ind:
742
- setattr(self,n,I)
743
- setattr(self,'name'+n,nameimg)
744
-
745
- if FlagNewRead:
746
- self.getImgInfo(VISpar_prev,i,I)
747
- pri.Info.green(f'Setting sizes of {name_VISpar} M={VISpar_prev.M[i]} mean={VISpar_prev.mean[i]} std={VISpar_prev.std[i]}')
748
- pri.PlotTime.white(f'{"*"*25} Opening image - end')
749
-
750
- def getImgInfo(self,VISpar_prev,i,I):
751
- VISpar_prev.m[i]=0
752
- if not VISpar_prev.FlagErrRead[i]:
753
- VISpar_prev.M[i]=I.max()
754
- VISpar_prev.mean[i]=np.mean(I)
755
- VISpar_prev.std[i]=np.std(I)
756
- VISpar_prev.size[i]=[0,np.size(I,1),0,np.size(I,0),1]
757
- else:
758
- VISpar_prev.M[i]=1
759
- VISpar_prev.mean[i]=VISpar_prev.std[i]=0
760
- VISpar_prev.size[i]=[0,0,0,0,1]
874
+ FlagResult=self.result is not None and "U" in self.result and "V" in self.result and (self.VISpar.type>0 or self.VISpar.Step==StepTypes.piv)
875
+ self.ui.button_cvec.setVisible(FlagResult and self.VISpar.field_rep!=0)
876
+ self.ui.label_field_rep.setVisible(FlagResult)
877
+ self.ui.combo_field_rep.setVisible(FlagResult)
761
878
 
762
- def loadRes(self):
763
- filename, _ = QFileDialog.getOpenFileName(self,\
764
- "Select an image file of the sequence", filter="All files (*.mat *.plt);; .mat (*.mat);; .plt (*.plt)",\
765
- options=optionNativeDialog)
766
- if filename:
767
- self.VISpar.nameres=myStandardRoot('{}'.format(str(filename)))
768
- self.getRes(True)
769
- combo_items=[self.namesPIV.combo_dict[f] for f in self.namesPIV.fields if f in self.res]
770
- curr_combo_items=self.VISpar.combo_items
771
- self.VISpar.combo_items=[]
772
- for f in self.namesPIV.combo_list:
773
- if f in curr_combo_items or f in combo_items:
774
- self.VISpar.combo_items.append(f)
775
- self.VISpar.MapVar_type=2
776
- self.VISpar.type=1
777
- self.VISpar.FlagYInvert[self.VISpar.type]=False
778
- self.VISpar.FlagExistRes[1]=[True]
779
- self.setDefaultCLim()
780
- self.setDefaultXLim()
781
- self.fLoadingCallback()
782
- self.fLoad[2]=True
783
-
784
- def getRes(self,FlagNewRead,*args):
785
- if len(args): VISpar_prev:VISpar=args[0]
786
- else: VISpar_prev=self.VISpar
787
- pri.PlotTime.white(f'{"*"*25} Opening result - start')
879
+ i=self.VISpar.setPage
880
+ c=self.ui.image_levels.count()-1-int(not FlagResult or (self.VISpar.type==0 and self.VISpar.field_rep==0)) #or (not self.VISpar.FlagContourf and not self.VISpar.field_rep))
881
+ if i>c: i=0
882
+ self.ui.image_levels.setCurrentIndex(i)
883
+ self.ui.label_title.setText(f"Settings ({i+1}/{c+1})")
788
884
 
789
- i=2
790
- res=None
791
- VISpar_prev.FlagErrRead[i]=True
792
- flagMean=VISpar_prev.nfield==imin_im_pair-1
793
- flagProc=VISpar_prev.Tre.flagRun<=-10 and flagMean
794
- if flagProc:
795
- prefix='proc'
796
- nameres=getattr(self,'name'+prefix+'res')
797
- else:
798
- prefix=''
799
- nameres=getattr(VISpar_prev,'nameres')
800
- if nameres:
801
- try:
802
- if flagProc:
803
- res=self.procres
804
- VISpar_prev.FlagErrRead[i]=False
805
- else:
806
- if os.path.exists(nameres):
807
- pri.Info.cyan(f'Opening: {nameres} [<--{self.VISpar_old.nameres}]')
808
- ext=os.path.splitext(nameres)[-1]
809
- if ext=='.mat':
810
- res = scipy.io.loadmat(nameres)
811
- elif ext=='.plt':
812
- tres = readPlt(nameres)
813
- res={}
814
- for j, n in enumerate(tres[1]):
815
- res[n]=tres[0][:,:,j]
816
- res["Mod"]=np.sqrt(res["U"]**2+res["V"]**2)
817
- VISpar_prev.FlagErrRead[i]=False
818
- except Exception as inst:
819
- pri.Error.red(f'Error opening image file: {nameres}\n{traceback.print_exc()}\n{inst}')
820
-
821
- #if VISpar_prev.indTree==self.VISpar.indTree and VISpar_prev.indItem==self.VISpar.indItem and VISpar_prev.ind==self.VISpar.ind:
822
- self.res=res
823
- self.nameres=nameres
824
- #else:
825
- # self.nameres=f'Void result file'
826
- if FlagNewRead:
827
- self.getResInfo(VISpar_prev,i,res)
828
- pri.PlotTime.white(f'{"*"*25} Opening result - end')
829
-
830
- def getResInfo(self,VISpar_prev:VISpar,i,res):
831
- if not VISpar_prev.FlagErrRead[i]:
832
- VISpar_prev.m[i]={}
833
- VISpar_prev.M[i]={}
834
- for vn in list(res):
835
- if not vn in self.namesPIV.fields: continue
836
- V=res[vn]
837
- m=V.min()
838
- M=V.max()
839
- mm=1.5*max([abs(m),abs(M)])
840
- if mm<0.1: mm=1
841
- VISpar_prev.m[i][vn]=-mm
842
- VISpar_prev.M[i][vn]=+mm
843
- VISpar_prev.mean[i][vn]=np.mean(V)
844
- VISpar_prev.std[i][vn]=np.std(V)
845
- X=res["X"]
846
- Y=res["Y"]
847
- VISpar_prev.size[i]=[X.min(),X.max(),Y.min(),Y.max(),int(max([np.size(X,0),np.size(X,1)])/4)]
885
+ if self.VISpar.variableKey in self.VISpar.vLim:
886
+ Lim=self.VISpar.vLim[self.VISpar.variableKey]
848
887
  else:
849
- VISpar_prev.m[i]=VISpar_prev.M[i]={}
850
- VISpar_prev.mean[i]=VISpar_prev.std[i]={}
851
- VISpar_prev.size[i]=[0,0,0,0,1]
852
-
853
- def setMinMaxField(self):
854
- if any(self.VISpar.FlagExistMean):
855
- self.ui.spin_field_number.setMinimum(-1+imin_im_pair)
888
+ Lim=1.0
889
+ step=Lim/nStepsSlider
890
+ FlagLim= self.VISpar.type or FlagDispMap
891
+ self.ui.spin_min.setMinimum(-Lim if FlagLim else 0)
892
+ self.ui.spin_min.setMaximum(Lim-2*step)
893
+ self.ui.spin_max.setMinimum(-Lim+2*step if FlagLim else 2*step)
894
+ self.ui.spin_max.setMaximum(Lim)
895
+ self.ui.spin_mean.setMinimum(-Lim+step if FlagLim else step)
896
+ self.ui.spin_mean.setMaximum(Lim-step)
897
+ self.ui.spin_range.setMinimum(2*step)
898
+ self.ui.spin_range.setMaximum(2*Lim if FlagLim else step)
899
+ self.ui.spin_vecspac.setMaximum(self.VISpar.size[1][4])
900
+
901
+ self.ui.label_vecspac.setVisible(self.VISpar.field_rep==1)
902
+ self.ui.slider_vecspac.setVisible(self.VISpar.field_rep==1)
903
+ self.ui.spin_vecspac.setVisible(self.VISpar.field_rep==1)
904
+ self.ui.label_vecsize.setVisible(self.VISpar.field_rep==1)
905
+ self.ui.slider_vecsize.setVisible(self.VISpar.field_rep==1)
906
+ self.ui.spin_vecsize.setVisible(self.VISpar.field_rep==1)
907
+ self.ui.label_vecwid.setVisible(self.VISpar.field_rep==1)
908
+ self.ui.slider_vecwid.setVisible(self.VISpar.field_rep==1)
909
+ self.ui.spin_vecwid.setVisible(self.VISpar.field_rep==1)
910
+ self.ui.spin_vecspac.setMaximum(self.VISpar.size_default[1][-1])
911
+ self.ui.label_streamdens.setVisible(self.VISpar.field_rep==2)
912
+ self.ui.slider_streamdens.setVisible(self.VISpar.field_rep==2)
913
+ self.ui.spin_streamdens.setVisible(self.VISpar.field_rep==2)
914
+
915
+ self.ui.spin_img.setMinimum(-1)
916
+ self.ui.spin_img.setMaximum(self.VISpar.nimg if self.VISpar.nimg else 0 if FlagResults else -1)
917
+ #self.ui.spin_img.setEnabled(FlagSpinsEnabled)
918
+ self.ui.spin_frame.setEnabled(FlagSpinsEnabled)
919
+ self.ui.spin_cam.setMaximum(self.VISpar.ncam)
920
+ self.ui.spin_cam.setEnabled(FlagSpinsEnabled and self.VISpar.ncam>1)
921
+
922
+ FlagCamFrame=self.VISpar.img>-1 and self.VISpar.type==0 and not FlagDispMap
923
+ self.ui.label_frame.setVisible(FlagCamFrame)
924
+ self.ui.spin_frame.setVisible(FlagCamFrame)
925
+ self.ui.label_cam.setVisible(FlagCamFrame)
926
+ self.ui.spin_cam.setVisible(FlagCamFrame)
927
+ FlagDispResult=self.VISpar.img==0 and self.VISpar.Step==StepTypes.disp #and self.VISpar.variableKey is not self.namesPIV.img #and self.VISpar.type==1
928
+ self.ui.label_it.setVisible(FlagDispResult)
929
+ self.ui.spin_it.setVisible(FlagDispResult)
930
+ self.ui.spin_it.setMinimum(1)
931
+ self.ui.spin_it.setMaximum(self.VISpar.Nit)
932
+ self.ui.spin_it.setEnabled(self.VISpar.flagRun!=-2)
933
+ if self.VISpar.type==0:
934
+ dataType='Input'
935
+ dataName=self.image_file if self.image is not None else None
856
936
  else:
857
- self.ui.spin_field_number.setMinimum(0+imin_im_pair)
858
- if len(self.VISpar.list_Image_Files):
859
- self.ui.spin_field_number.setMaximum(self.VISpar.Inp.range_to-1+imin_im_pair)
860
- self.ui.spin_field_number.setEnabled(True)
937
+ dataType='Output'
938
+ dataName=self.result_file if self.result is not None else None
939
+ if dataName:
940
+ self.ui.name_var.setText(f'{dataType} file: {os.path.basename(dataName)}')
861
941
  else:
862
- self.ui.spin_field_number.setMaximum(self.ui.spin_field_number.minimum())
863
- self.ui.spin_field_number.setEnabled(False)
864
-
865
- #*************************************************** From Parameters to UI
866
- def readVar(self,FlagNewRead,*args):
867
- if len(args): VISpar_prev:VISpar=args[0]
868
- else: VISpar_prev=self.VISpar
869
- j=VISpar_prev.MapVar_type
870
- if j>1: j=2
871
- field=['nameimga','nameimgb','nameres'][j]
872
- if len(args): FlagNewRead=True
873
- if FlagNewRead or getattr(self,field)!=getattr(VISpar_prev,field): #\
874
- #or VISpar_prev.Out.isDifferentFrom(self.VISpar_old.Out,[],['x','y','w','h','vecop'],True):
875
- self.fRead[j](FlagNewRead,VISpar_prev)
876
- return
877
-
878
- def importVar(self,*args):
879
- if not self.VISpar.FlagVis:
880
- pri.Callback.yellow(f'{">"*30} importVar skipped (tab closed) {"<"*30}')
881
- return
882
- if len(args): VISpar_prev:VISpar=args[0]
883
- else: VISpar_prev=self.VISpar
942
+ self.ui.name_var.setText(f'{dataType} file not available!')
943
+ self.ui.name_var.setToolTip(f'{dataType} file: {dataName}')
944
+ self.ui.name_var.setStatusTip(self.ui.name_var.toolTip())
884
945
 
885
- flagExistRes=VISpar_prev.FlagExistRes
886
- if any(flagExistRes):
887
- mapVarItem=self.namesPIV.combo_list[VISpar_prev.MapVar_type]
888
- VISpar_prev.combo_items=[]
889
- if VISpar_prev.FlagExistRes[0]:
890
- VISpar_prev.combo_items+=self.namesPIV.pick(self.namesPIV.combo_list,self.namesPIV.img_ind)
891
- if VISpar_prev.FlagExistRes[1]:
892
- if VISpar_prev.nfield==imin_im_pair-1 and VISpar_prev.Tre.flagRun>-10:
893
- VISpar_prev.combo_items+=self.namesPIV.pick(self.namesPIV.combo_list,self.namesPIV.avgVel_plot_ind)
894
- else:
895
- VISpar_prev.combo_items+=self.namesPIV.pick(self.namesPIV.combo_list,self.namesPIV.instVel_plot_ind)
896
- if not mapVarItem in VISpar_prev.combo_items:
897
- mapVarItem=VISpar_prev.combo_items[0]
898
- mapVarType=self.namesPIV.combo_list.index(mapVarItem)
899
- resType=int(mapVarType>1)
900
- if resType!=VISpar_prev.type: #zoom
901
- VISpar_prev.FlagReset[0]=True
902
- VISpar_prev.type=resType
903
- if mapVarType!=VISpar_prev.MapVar_type or (): #levels
904
- VISpar_prev.FlagReset[1]=True
905
- VISpar_prev.MapVar_type=mapVarType
906
- else:
907
- VISpar_prev.combo_items=[]
908
- VISpar_prev.MapVar_type= VISpar_prev.type=-1
909
- return
910
-
911
- self.readVar(True,VISpar_prev)
912
-
913
- if not VISpar_prev.FlagErrRead[VISpar_prev.type]:
914
- if VISpar_prev.FlagReset[0]:
915
- self.setDefaultXLim(VISpar_prev)
916
- VISpar_prev.FlagReset[0]=False
917
- if VISpar_prev.FlagReset[1]:
918
- self.setDefaultCLim(VISpar_prev)
919
- VISpar_prev.FlagReset[1]=False
946
+ if self.VISpar.variableKey in self.VISpar.vcolorMap:
947
+ self.VISpar.colorMap=self.VISpar.vcolorMap[self.VISpar.variableKey]
948
+ if self.VISpar.variableKey in self.VISpar.vvectorColor:
949
+ self.VISpar.vectorColor=self.VISpar.vvectorColor[self.VISpar.variableKey]
950
+
951
+ self.ui.button_cmap.setIcon(QIcon(icons_path+'colormaps/'+self.VISpar.colorMap+'.png'))
952
+ self.ui.button_cvec.setIcon(QIcon(icons_path+'colormaps/'+self.VISpar.vectorColor+'Vector.png'))
953
+
954
+ self.setLevels()
955
+ t=self.VISpar.type
956
+ if (t==0 and self.VISpar.unit[t]) or (t==1 and not self.VISpar.unit[t]):
957
+ self.xres,self.yres=self.getXYRes()
958
+ else: self.xres=self.yres=1.0
959
+ self.VISpar.xmin=self.VISpar.size[self.VISpar.type][0]*self.xres
960
+ self.VISpar.xmax=self.VISpar.size[self.VISpar.type][1]*self.xres
961
+ self.VISpar.ymin=self.VISpar.size[self.VISpar.type][2]*self.yres
962
+ self.VISpar.ymax=self.VISpar.size[self.VISpar.type][3]*self.yres
963
+
964
+ self.checkVISTab()
965
+ self.setVISwarn()
920
966
  return
921
-
922
- def setVISpar(self):
923
- self.FlagSettingPar=True
924
- if not self.VISpar.FlagVis:
925
- pri.Callback.yellow(f'{">"*30} setVISpar skipped (tab closed) {"<"*30}')
926
- return
927
- if self.VISpar.Inp.FlagValidPath==-10 or self.VISpar.Inp.FlagValidPath==-10:
928
- self.hide()
929
- return
930
- self.setVisible(True)
931
-
932
- self.readVar(False)
933
- self.setCombos()
934
- self.setNameVar()
935
- self.setMinMaxField()
936
- self.ui.spin_field_number.setValue(self.VISpar.nfield)
937
- self.setMinMaxSpin()
938
- self.setValueSpin()
939
- self.setValueXYLimSpin()
940
- if self.VISpar.type==0:
941
- self.ui.button_showIW.show()
942
- if self.VISpar.FlagExistMean[0] and self.VISpar.nfield>imin_im_pair-1:
943
- self.ui.button_subMIN.show()
944
- else: self.ui.button_subMIN.hide()
945
- self.ui.button_showIW.setChecked(self.VISpar.flagShowIW)
946
- self.ui.button_subMIN.setChecked(self.VISpar.flagMIN)
947
- else:
948
- self.ui.button_showIW.hide()
949
- self.ui.button_subMIN.hide()
950
- self.ui.button_invert_y.setChecked(self.VISpar.FlagYInvert[self.VISpar.type])
951
-
952
- self.ui.spin_field_number.setValue(self.VISpar.nfield)
953
- if self.VISpar.type==0:
954
- self.ui.label_frame_number.show()
955
- self.ui.spin_frame_number.show()
956
- self.ui.spin_frame_number.setValue(self.VISpar.MapVar_type)
957
- else:
958
- self.ui.label_frame_number.hide()
959
- self.ui.spin_frame_number.hide()
960
-
961
- if self.VISpar.type==0: j=self.VISpar.MapVar_type
962
- else: j=2
963
- self.ui.spin_frame_number.setEnabled(True)
964
- if not self.VISpar.FlagErrRead[j]:
965
- self.funPlot()
966
- #self.setMapVar()
967
- #self.exitVISnofile(False)
967
+
968
+ def setLevels(self):
969
+ if self.VISpar.variableKey in self.VISpar.vmin:
970
+ self.VISpar.min=self.VISpar.vmin[self.VISpar.variableKey]
971
+ self.VISpar.max=self.VISpar.vmax[self.VISpar.variableKey]
972
+ self.VISpar.mean=self.VISpar.vmean[self.VISpar.variableKey]
973
+ self.VISpar.range=self.VISpar.vrange[self.VISpar.variableKey]
974
+
975
+ def resetLevels(self):
976
+ if self.VISpar.variableKey in self.VISpar.vmin_default:
977
+ self.VISpar.vmin[self.VISpar.variableKey]=self.VISpar.vmin_default[self.VISpar.variableKey]
978
+ self.VISpar.vmax[self.VISpar.variableKey]=self.VISpar.vmax_default[self.VISpar.variableKey]
979
+ self.VISpar.vmean[self.VISpar.variableKey]=self.VISpar.vmean_default[self.VISpar.variableKey]
980
+ self.VISpar.vrange[self.VISpar.variableKey]=self.VISpar.vrange_default[self.VISpar.variableKey]
981
+ #self.setLevels()
982
+
983
+ def resetAllLevels(self, ind=None):
984
+ if ind is None: VIS:VISpar=self.VISpar
985
+ else: VIS:VISpar=self.TABpar_at(ind)
986
+ for field in ('min','max','mean','range'):
987
+ v=getattr(VIS,'v'+field)
988
+ w=getattr(VIS,'v'+field+'_default')
989
+ for f in list(w):
990
+ v[f]=w[f]
991
+ #self.setLevels()
992
+
993
+ def checkResVariables(self):
994
+ for field in ('min','max','mean','range'):
995
+ v=getattr(self.VISpar,'v'+field)
996
+ w=getattr(self.VISpar,'v'+field+'_default')
997
+ for f in list(w):
998
+ if f not in list(v):
999
+ v[f]=w[f]
1000
+
1001
+ def resetXYLims(self):
1002
+ self.VISpar.size[self.VISpar.type][::]=self.VISpar.size_default[self.VISpar.type][::]
1003
+
1004
+ def resetAllXYLims(self, ind=None):
1005
+ if ind is None: VIS:VISpar=self.VISpar
1006
+ else: VIS:VISpar=self.TABpar_at(ind)
1007
+ for t in (0,1):
1008
+ VIS.size[t][::]=self.VISpar.size_default[t][::]
1009
+
1010
+ def readImageFile(self,filename):
1011
+ I=None
1012
+ if not filename: return filename, I
1013
+ try:
1014
+ if os.path.exists(filename):
1015
+ pri.Info.cyan(f'Opening: {filename} [<--{self.image_file}]')
1016
+ img=Image.open(filename)
1017
+ I=np.ascontiguousarray(img)
1018
+ self.nbits=img.getextrema()[1].bit_length()
1019
+ #I=transfIm(self.VISpar.Out,Images=[I])[0]
1020
+ except Exception as inst:
1021
+ pri.Error.red(f'Error opening image file: {filename}\n{traceback.format_exc()}\n{inst}')
1022
+ I=None
1023
+ return filename, I
1024
+
1025
+ def getImageInfo(self,image=None,ind=None):
1026
+ if image is None: I=self.image
1027
+ else: I=image
1028
+ if I is None: return
1029
+ if ind is None: VIS:VISpar=self.VISpar
1030
+ else: VIS:VISpar=self.TABpar_at(ind)
1031
+ variableKey=self.VISpar.variableKey
1032
+ if variableKey is self.namesPIV.dispMap:
1033
+ variableKey=self.namesPIV.dispMap
1034
+ if image is None:
1035
+ CC_16bit=self.image.astype(np.float64) # Convert back to float
1036
+ I=(CC_16bit / 65535.0) * 2.0 - 1.0 # Reverse the normalization
1037
+ self.image=I
1038
+ mean=np.mean(I).item()
1039
+ std=np.std(I).item()
1040
+ VIS.vLim[variableKey]=1.0
1041
+ VIS.vmin_default[variableKey]=max([mean-2*std,-1.0])
1042
+ VIS.vmax_default[variableKey]=min([mean+2*std,1.0])
968
1043
  else:
969
- self.exitVISerr(1)
970
- """
971
- if all(self.FlagErr):
972
- # self.exitVISnofile(False)
973
- self.exitVISerr(2)
1044
+ mean=np.mean(I).item()
1045
+ std=np.std(I).item()
1046
+ VIS.vLim[variableKey]=min([2*I.max().item(),2**(self.nbits+1)])
1047
+ VIS.vmin_default[variableKey]=np.round(max([mean-2*std,0])).item()
1048
+ VIS.vmax_default[variableKey]=np.round(min([mean+2*std,VIS.vLim[variableKey]])).item()
1049
+
1050
+ VIS.vmean_default[variableKey]=0.5*(VIS.vmin_default[variableKey]+VIS.vmax_default[variableKey])
1051
+ VIS.vrange_default[variableKey]=VIS.vmax_default[variableKey]-VIS.vmin_default[variableKey]
1052
+ VIS.size_default[0]=[0,np.size(I,1),0,np.size(I,0),1]
1053
+ if variableKey not in VIS.vcolorMap:
1054
+ VIS.vcolorMap[variableKey]='gray' if variableKey in ('img','dispMap') else 'jet'
1055
+ if variableKey not in VIS.vvectorColor:
1056
+ VIS.vvectorColor[variableKey]='green' if variableKey in ('img','dispMap') else 'black'
1057
+
1058
+ def readResultFile(self,filename):
1059
+ res=None
1060
+ if not filename: return filename, res
1061
+ try:
1062
+ if os.path.exists(filename):
1063
+ pri.Info.cyan(f'Opening: {filename} [<--{self.result_file}]')
1064
+ ext=os.path.splitext(filename)[-1]
1065
+ if ext=='.mat':
1066
+ res = scipy.io.loadmat(filename)
1067
+ elif ext=='.plt':
1068
+ tres = readPlt(filename)
1069
+ res={}
1070
+ for j, n in enumerate(tres[1]):
1071
+ res[n]=tres[0][:,:,j]
1072
+ if self.namesPIV.u in res and self.namesPIV.v in res:
1073
+ res=self.calcMagnitude(res)
1074
+ FlagUnit=self.VISpar.Out.xres!=1.0 or self.VISpar.Out.pixAR!=1.0
1075
+ res=self.calcZVorticity(res,FlagUnit)
1076
+ for f in list(res):
1077
+ if not f in self.namesPIV.allFields: del res[f]
1078
+ except Exception as inst:
1079
+ pri.Error.red(f'Error opening image file: {filename}\n{traceback.format_exc()}\n{inst}')
1080
+ res=None
1081
+ return filename, res
1082
+
1083
+ def calcMagnitude(self,res):
1084
+ if self.namesPIV.u in res and self.namesPIV.v in res:
1085
+ if self.namesPIV.w in res:
1086
+ res[self.namesPIV.Mod]=np.sqrt(res[self.namesPIV.u]**2+res[self.namesPIV.v]**2+res[self.namesPIV.w]**2)
974
1087
  else:
975
- self.exitVISerr(1)
976
- # self.exitVISnofile(True)
977
- """
978
- self.FlagSettingPar=False
1088
+ res[self.namesPIV.Mod]=np.sqrt(res[self.namesPIV.u]**2+res[self.namesPIV.v]**2)
1089
+ return res
979
1090
 
980
- def exitVISerr(self,flagErr):
981
- if flagErr:
982
- FlagPlot=False
983
- if flagErr==2: FlagSpin=False
984
- else: FlagSpin=True
985
- else:
986
- FlagPlot=True
987
- FlagSpin=True
988
-
989
- #if not FlagPlot:self.ui.CollapBox_PlotTools.closeBox()
990
- self.ui.CollapBox_PlotTools.setEnabled(FlagPlot)
991
- self.Ptoolbar.setVisible(FlagPlot)
992
- self.ui.Plot_tools.setEnabled(FlagPlot)
993
- for child in self.ui.plot.fig.get_children():
994
- child.set_visible(FlagPlot)
995
-
996
- if not FlagSpin:
997
- self.ui.spin_field_number.setValue(-1+imin_im_pair)
998
- self.ui.spin_field_number.setEnabled(FlagSpin)
999
- self.ui.spin_frame_number.setEnabled(FlagSpin)
1000
- #if not FlagPlot: self.plotPaIRS()
1001
-
1002
- def exitVISnofile(self,flagErr):
1003
- if flagErr:
1004
- self.ui.plot.axes.cla()
1005
- if len(self.ui.plot.fig.axes)>1:
1006
- self.ui.plot.fig.axes[1].remove()
1007
- self.ui.plot.axes.axis('off')
1008
- self.ui.plot.axes.get_xaxis().set_visible(False)
1009
- self.ui.plot.axes.get_yaxis().set_visible(False)
1010
- for s in ('top','right','bottom','left'):
1011
- self.ui.plot.axes.spines[s].set_visible(False)
1091
+ def calcZVorticity(self,res,FlagUnit=False):
1092
+ if self.namesPIV.x in res and self.namesPIV.y in res and self.namesPIV.u in res and self.namesPIV.v in res:
1093
+ if FlagUnit: xres=yres=1/1000
1094
+ else: xres=yres=1.0
1095
+ try:
1096
+ du_dy, _=np.gradient(res[self.namesPIV.u],res[self.namesPIV.y][:,0]*yres,res[self.namesPIV.x][0,:]*xres) # Derivate di u rispetto a y e x
1097
+ _, dv_dx=np.gradient(res[self.namesPIV.v],res[self.namesPIV.y][:,0]*yres,res[self.namesPIV.x][0,:]*xres) # Derivate di v rispetto a y e x
1098
+ res[self.namesPIV.ZVort]=dv_dx-du_dy
1099
+ except:
1100
+ pri.Error.red(f'Error while computing vorticity field:\n{traceback.format_exc()}\n\n')
1101
+ return res
1102
+
1103
+ def getResultInfo(self,result=None,ind=None):
1104
+ if result is None: res=self.result
1105
+ else: res=result
1106
+ if res is None: return
1107
+ if ind is None: VIS:VISpar=self.VISpar
1108
+ else: VIS:VISpar=self.TABpar_at(ind)
1109
+ for i in list(VIS.vmin_default):
1110
+ if i not in (self.namesPIV.img,self.namesPIV.dispMap):
1111
+ del VIS.vmin_default[i]
1112
+ del VIS.vmax_default[i]
1113
+ del VIS.vmean_default[i]
1114
+ del VIS.vrange_default[i]
1115
+ del VIS.vLim[i]
1116
+
1117
+ for f in list(res):
1118
+ V:np=res[f][~np.isnan(res[f])]
1119
+ #m=np.mean(V).item()
1120
+ #r=np.std(V).item()
1121
+ #VIS.vLim[f]=max([m+5*r,abs(m-5*r)])
1122
+ amax=np.max(np.abs(V))*5.0
1123
+ m=np.mean(V)
1124
+ r=(np.max(V)-np.min(V))*2.50
1125
+ rmax=np.abs(m+r)
1126
+ rmin=np.abs(m-r)
1127
+ VIS.vLim[f]=float(max([amax,rmax,rmin]))
1128
+ if VIS.vLim[f]<0.1: VIS.vLim[f]=1
1129
+ VIS.vmin_default[f]=float(np.percentile(V,1)) #np.round(m-2*r).item()
1130
+ VIS.vmax_default[f]=float(np.percentile(V,99)) #np.round(m+2*r).item()
1131
+ VIS.vmean_default[f]=0.5*(VIS.vmin_default[f]+VIS.vmax_default[f])
1132
+ VIS.vrange_default[f]=VIS.vmax_default[f]-VIS.vmin_default[f]
1133
+ if f not in VIS.vcolorMap:
1134
+ VIS.vcolorMap[f]='jet'
1135
+ if f not in VIS.vvectorColor:
1136
+ VIS.vvectorColor[f]='black'
1137
+ pass
1012
1138
 
1013
- self.ui.plot.hide()
1014
- self.Ptoolbar.hide()
1015
- self.ui.Plot_tools.setEnabled(False)
1139
+ FlagSize=False
1140
+ if "X" in list(res) and "Y" in list(res):
1141
+ X=res["X"]
1142
+ Y=res["Y"]
1143
+ FlagSize=True
1144
+ elif "x" in list(res) and "y" in list(res):
1145
+ X=res["x"]
1146
+ Y=res["y"]
1147
+ FlagSize=True
1148
+ if FlagSize:
1149
+ if np.size(X) and np.size(Y):
1150
+ VIS.size_default[1]=[X.min().item(),X.max().item(),Y.min().item(),Y.max().item(),int(max([np.size(X,0),np.size(X,1)])/4)]
1016
1151
  else:
1017
- self.ui.plot.axes.axis('on')
1018
- self.ui.plot.axes.get_xaxis().set_visible(True)
1019
- self.ui.plot.axes.get_yaxis().set_visible(True)
1020
- for s in ('top','right','bottom','left'):
1021
- self.ui.plot.axes.spines[s].set_visible(True)
1022
- self.Ptoolbar.show()
1023
- self.ui.Plot_tools.setEnabled(True)
1152
+ VIS.size_default[1]=[0,1,0,1,1]
1153
+
1154
+ def setVISwarn(self,ind=None):
1155
+ if ind is None: VIS:VISpar=self.VISpar
1156
+ else: VIS:VISpar=self.TABpar_at(ind)
1157
+ VIS.warningMessage='Result files correctly identified!' if VIS.OptionDone==1 else 'Result files corresponding to the current step appear to be missing from the specified output path.'
1158
+
1159
+ #*************************************************** Plot tools
1160
+ #******************** Actions
1161
+ def button_view_action(self):
1162
+ self.VISpar.FlagView=self.ui.button_view.isChecked()
1163
+
1164
+ def button_ShowIW_action(self):
1165
+ self.VISpar.FlagShowIW=self.ui.button_ShowIW.isChecked()
1166
+ #if self.VISpar.FlagShowIW: self.resetXYLims()
1024
1167
 
1025
- def plotPaIRS(self):
1026
- logoname=''+ icons_path +'logo_PaIRS_completo.png'
1027
- img=np.array(Image.open(logoname)) #mplimage.imread(logoname)
1028
- self.ui.plot.axes.cla()
1029
- if len(self.ui.plot.fig.axes)>1:
1030
- self.ui.plot.fig.axes[1].remove()
1031
- self.imgshow=self.ui.plot.axes.imshow(img)
1032
- self.ui.plot.axes.axis('off')
1033
- self.ui.plot.axes.get_xaxis().set_visible(False)
1034
- self.ui.plot.axes.get_yaxis().set_visible(False)
1035
- self.ui.plot.draw()
1036
-
1037
- def setCombos(self):
1038
- self.ui.combo_map_var.clear()
1039
- self.ui.combo_map_var.addItems(self.VISpar.combo_items)
1040
- if len(self.VISpar.combo_items):
1041
- field=self.namesPIV.combo_list[self.VISpar.MapVar_type]
1042
- if field in self.VISpar.combo_items:
1043
- i=self.VISpar.combo_items.index(field)
1044
- else:
1045
- i=-1
1046
- else: i=-1
1047
- self.ui.combo_map_var.setCurrentIndex(i)
1048
- if self.VISpar.type==0:
1049
- self.ui.label_field_rep.hide()
1050
- self.ui.combo_field_rep.hide()
1168
+ def button_SubMIN_action(self):
1169
+ self.VISpar.FlagSubMIN=self.ui.button_SubMIN.isChecked()
1170
+
1171
+ def button_ShowCR_action(self):
1172
+ self.VISpar.FlagShowCR=self.ui.button_ShowCR.isChecked()
1051
1173
 
1052
- self.ctoolpages=c=self.ui.image_levels.count()-2
1053
- i=self.ui.image_levels.currentIndex()
1054
- if i==c+1:
1055
- i=0
1056
- self.ui.image_levels.setCurrentIndex(i)
1057
- self.ui.label_title.setText(f"Settings ({i+1}/{c+1})")
1174
+ def button_unit_action(self):
1175
+ self.VISpar.unit[self.VISpar.type]=self.ui.button_unit.isChecked()
1058
1176
 
1059
- #self.disableImageLevels(not self.VISpar.nameimga)
1060
- else:
1061
- if not self.VISpar.nameres:
1062
- self.ui.label_field_rep.hide()
1063
- self.ui.combo_field_rep.hide()
1064
- else:
1065
- self.ui.label_field_rep.show()
1066
- self.ui.combo_field_rep.show()
1067
- self.ui.combo_field_rep.setCurrentIndex(self.VISpar.VecField_type)
1068
-
1069
- self.ctoolpages=c=self.ui.image_levels.count()-1
1070
- i=self.ui.image_levels.currentIndex()
1071
- self.ui.label_title.setText(f"Settings ({i+1}/{c+1})")
1072
- self.checkContourQuiver()
1073
-
1074
- #self.disableImageLevels(not self.VISpar.nameres)
1075
-
1076
- def checkContourQuiver(self):
1077
- wnames_all=("vecsize","vecspac","streamdens")
1078
- if self.VISpar.VecField_type==1:
1079
- wnames=("vecsize","vecspac")
1080
- elif self.VISpar.VecField_type==2:
1081
- wnames=("streamdens")
1082
- else:
1083
- wnames=()
1084
- for n in wnames_all:
1085
- flag= n in wnames
1086
- for l in ("label_","slider_","spin_"):
1087
- w=getattr(self.ui,l+n)
1088
- if flag: w.show()
1089
- else: w.hide()
1090
-
1091
- def setMinMaxSpin(self):
1092
- m,M,step,step_mean,step_range,vecspac_max=self.getmM()
1093
-
1094
- self.ui.spin_min.setMinimum(m)
1095
- self.ui.spin_min.setMaximum(M-2*step)
1096
- self.ui.spin_min.setSingleStep(step)
1097
- self.ui.spin_max.setMinimum(m+2*step)
1098
- self.ui.spin_max.setMaximum(M)
1099
- self.ui.spin_max.setSingleStep(step)
1100
-
1101
- self.ui.spin_mean.setMinimum(m+step)
1102
- self.ui.spin_mean.setMaximum(M-step)
1103
- self.ui.spin_mean.setSingleStep(step_mean)
1104
- self.ui.spin_range.setMinimum(2*step)
1105
- self.ui.spin_range.setMaximum(M-m)
1106
- self.ui.spin_range.setSingleStep(step_range)
1177
+ def button_Contourf_action(self):
1178
+ self.VISpar.FlagContourf=self.ui.button_Contourf.isChecked()
1179
+
1180
+ def button_cmap_action(self):
1181
+ # Show the popup menu
1182
+ self.colorMapMenu.exec(self.ui.button_cmap.mapToGlobal(self.ui.button_cmap.rect().bottomLeft()))
1107
1183
 
1108
- self.ui.spin_vecspac.setMaximum(vecspac_max)
1184
+ def button_cvec_action(self):
1185
+ # Show the popup menu
1186
+ self.vectorColorMenu.exec(self.ui.button_cvec.mapToGlobal(self.ui.button_cvec.rect().bottomLeft()))
1187
+
1188
+ def combo_map_var_action(self):
1189
+ self.VISpar.variable=self.ui.combo_map_var.currentText()
1190
+ self.VISpar.variableKey=self.namesPIV.combo_dict_keys[self.VISpar.variable]
1191
+ self.VISpar.type=int(self.VISpar.variable!=self.namesPIV.combo_dict[self.namesPIV.img])
1192
+ self.setLevels()
1109
1193
 
1110
- def getmM(self):
1111
- if self.VISpar.type==0:
1112
- m=self.VISpar.m[self.VISpar.MapVar_type]
1113
- M=self.VISpar.M[self.VISpar.MapVar_type]
1114
- range_max=M-m
1115
- step=1
1116
- step_mean=1
1117
- step_range=1
1118
- elif self.VISpar.type==1:
1119
- j=self.namesPIV.fields[self.VISpar.MapVar_type]
1120
- m=self.VISpar.m[2][j]
1121
- M=self.VISpar.M[2][j]
1122
- range_max=M-m
1123
- step=max([(M-1-m)/nStepsSpin,0.01])
1124
- step_mean=max([(M-m-2*step)/nStepsSpin,0.01])
1125
- step_range=(range_max-2*step)/nStepsSpin
1126
- else:
1127
- m=M=step=step_mean=step_range=0
1128
- vecspac_max=self.VISpar.size[-1][-1]
1129
- return m,M,step,step_mean,step_range,vecspac_max
1194
+ def button_automatic_levels_action(self):
1195
+ self.VISpar.FlagAutoLevels=self.ui.button_automatic_levels.isChecked()
1196
+ return True
1130
1197
 
1131
- def setValueSpin(self):
1132
- #self.ui.spin_field_number.setValue(self.VISpar.nfield)
1133
- names=["min","max","mean","range","nclev","vecsize","streamdens"]
1134
- for i,n in enumerate(names):
1135
- sp=getattr(self.ui,"spin_"+n)
1136
- if i<4: field="v"+n
1137
- else: field=n
1138
- v=getattr(self.VISpar,field)
1139
- sp.setValue(v)
1140
- self.setSlidersFromSpins()
1141
-
1142
- def setSlidersFromSpins(self):
1143
- names=["min","max","mean","range","nclev","vecsize","streamdens"]
1144
- for n in names:
1145
- sp=getattr(self.ui,"spin_"+n)
1146
- sl=getattr(self.ui,"slider_"+n)
1147
- if (sp.maximum()-sp.minimum())>0:
1148
- sl_value=int((sp.value()-sp.minimum())/(sp.maximum()-sp.minimum())*nStepsSlider)
1149
- else: sl_value=0
1150
- sl.setValue(sl_value)
1151
-
1152
- def setNameVar(self):
1153
- if self.VISpar.type==0:
1154
- if self.VISpar.FlagErrRead[self.VISpar.MapVar_type]:
1155
- self.setNameVarLabel('Input file not available!','')
1198
+ def button_automatic_sizes_action(self):
1199
+ self.VISpar.FlagAutoSizes=self.ui.button_automatic_sizes.isChecked()
1200
+ if self.VISpar.FlagAutoSizes is False and self.VISpar.Process==ProcessTypes.piv:
1201
+ type2=0 if self.VISpar.type==1 else 1
1202
+ if self.VISpar.unit[self.VISpar.type]!=self.VISpar.unit[type2]:
1203
+ xres,yres=self.getXYRes(type=self.VISpar.unit[self.VISpar.type])
1204
+ else: xres=yres=1.0
1205
+ if (type2==0 and self.VISpar.unit[type2]) or (type2==1 and not self.VISpar.unit[type2]):
1206
+ xres2,yres2=self.getXYRes(type=type2)
1207
+ else: xres2=yres2=1.0
1208
+ self.VISpar.size[type2][0:2]=[s*xres/xres2 for s in [self.VISpar.xmin, self.VISpar.xmax]]
1209
+ self.VISpar.size[type2][2:4]=[s*yres/yres2 for s in [self.VISpar.ymin, self.VISpar.ymax]]
1210
+ return True
1211
+
1212
+ def button_restore_action(self):
1213
+ self.resetLevels()
1214
+
1215
+ def button_resize_action(self):
1216
+ self.resetXYLims()
1217
+
1218
+ def button_invert_y_action(self):
1219
+ self.VISpar.FlagYInvert[self.VISpar.type]=self.ui.button_invert_y.isChecked()
1220
+
1221
+ def spinLevels_action(self,spin:MyQDoubleSpin):
1222
+ n=spin.objectName().replace('spin_','')
1223
+ spin_value=getattr(self.VISpar,n)
1224
+
1225
+ v=getattr(self.VISpar,'v'+n)
1226
+ v[self.VISpar.variableKey]=spin_value
1227
+ self.adjustSpins(spin)
1228
+
1229
+ def adjustSpins(self,spin:MyQDoubleSpin):
1230
+ nspin=spin.objectName().replace('spin_','')
1231
+ if spin in (self.ui.spin_min,self.ui.spin_max):
1232
+ if spin==self.ui.spin_min and spin.value()>=self.ui.spin_max.value():
1233
+ self.VISpar.max=self.VISpar.min+self.ui.spin_range.minimum()
1234
+ elif spin==self.ui.spin_max and spin.value()<=self.ui.spin_min.value():
1235
+ self.VISpar.min=self.VISpar.max-self.ui.spin_range.minimum()
1236
+ self.VISpar.mean=0.5*(self.VISpar.min+self.VISpar.max)
1237
+ self.VISpar.range=self.VISpar.max-self.VISpar.min
1238
+ elif spin in (self.ui.spin_mean,self.ui.spin_range):
1239
+ m=self.ui.spin_mean.value()
1240
+ r=self.ui.spin_range.value()
1241
+ if m-r*0.5<self.ui.spin_min.minimum():
1242
+ self.VISpar.min=self.ui.spin_min.minimum()
1243
+ if spin==self.ui.spin_mean:
1244
+ self.VISpar.range=2*(m-self.VISpar.min)
1245
+ self.VISpar.max=m+0.5*self.VISpar.range
1246
+ else:
1247
+ self.VISpar.max=self.VISpar.min+r
1248
+ self.VISpar.mean=0.5*(self.VISpar.min+self.VISpar.max)
1249
+ elif m+r*0.5>self.ui.spin_max.maximum():
1250
+ self.VISpar.max=self.ui.spin_max.maximum()
1251
+ if spin==self.ui.spin_mean:
1252
+ self.VISpar.range=2*(self.VISpar.max-m)
1253
+ self.VISpar.min=m-0.5*self.VISpar.range
1254
+ else:
1255
+ self.VISpar.min=self.VISpar.max-r
1256
+ self.VISpar.mean=0.5*(self.VISpar.min+self.VISpar.max)
1156
1257
  else:
1157
- name=getattr(self,['nameimga','nameimgb'][self.VISpar.MapVar_type])
1158
- self.setNameVarLabel(f'Input file: {os.path.basename(name)}',\
1159
- f'Input file: {name}')
1258
+ self.VISpar.max=m+0.5*r
1259
+ self.VISpar.min=m-0.5*r
1260
+ if spin==self.ui.spin_mean: self.VISpar.range=(self.VISpar.max-self.VISpar.min)
1261
+ else: self.VISpar.mean=0.5*(self.VISpar.min+self.VISpar.max)
1262
+
1263
+ for n in ['min','max','mean','range']:
1264
+ if n!=nspin:
1265
+ spin=getattr(self.ui,'spin_'+n)
1266
+ slider=getattr(self.ui,'slider_'+n)
1267
+ val=getattr(self.VISpar,n)
1268
+ spin.setValue(val)
1269
+ self.slider_set(spin,slider)
1270
+
1271
+ def sliderLevels_changing(self,spin:MyQDoubleSpin,slider:QSlider,Flag=False):
1272
+ self.setSpinFromSlider(spin,slider)
1273
+ self.adjustSpins(spin)
1274
+ self.sliderLevels_action()
1275
+ return Flag
1276
+
1277
+ def setSpinFromSlider(self,spin:MyQDoubleSpin,slider:QSlider):
1278
+ slider_value=slider.value()
1279
+ spin_value=spin.minimum()+(spin.maximum()-spin.minimum())/slider.maximum()*slider_value
1280
+ spin.setValue(spin_value)
1281
+ n=spin.objectName().replace('spin_','')
1282
+ if n in ('nclev','vecspac'):
1283
+ spin_value=int(spin_value)
1284
+ setattr(self.VISpar,n,spin_value)
1285
+ return spin_value
1286
+
1287
+ def sliderLevels_action(self):
1288
+ for n in ('min','max','mean','range'):
1289
+ spin_value=getattr(self.VISpar,n)
1290
+ v=getattr(self.VISpar,'v'+n)
1291
+ v[self.VISpar.variableKey]=spin_value
1292
+
1293
+ def spinFieldRep_action(self,spin:MyQDoubleSpin):
1294
+ n=spin.objectName().replace('spin_','')
1295
+ spin_value=getattr(self.VISpar,n)
1296
+ if n in ('nclev','vecspac'): spin_value=int(spin_value)
1297
+ setattr(self.VISpar,n,spin_value)
1298
+
1299
+ def sliderFieldRep_changing(self,spin:MyQDoubleSpin,slider:QSlider,Flag=False):
1300
+ self.setSpinFromSlider(spin,slider)
1301
+ self.sliderFieldRep_action()
1302
+ return Flag
1303
+
1304
+ def sliderFieldRep_action(self):
1305
+ return
1306
+
1307
+ def spin_xy_action(self,spin,k):
1308
+ n=spin.objectName().replace('spin_','')
1309
+ spin_value=getattr(self.VISpar,n)
1310
+ res=self.xres if k<2 else self.yres
1311
+ self.VISpar.size[self.VISpar.type][k]=spin_value/res
1312
+
1313
+ def button_dx_left_action(self):
1314
+ dx=(self.VISpar.xmax-self.VISpar.xmin)/self.xres
1315
+ self.VISpar.size[self.VISpar.type][0]-=dx
1316
+ self.VISpar.size[self.VISpar.type][1]-=dx
1317
+
1318
+ def button_dx_right_action(self):
1319
+ dx=(self.VISpar.xmax-self.VISpar.xmin)/self.xres
1320
+ self.VISpar.size[self.VISpar.type][0]+=dx
1321
+ self.VISpar.size[self.VISpar.type][1]+=dx
1322
+
1323
+ def button_dy_down_action(self):
1324
+ dy=(self.VISpar.ymax-self.VISpar.ymin)/self.yres
1325
+ self.VISpar.size[self.VISpar.type][2]-=dy
1326
+ self.VISpar.size[self.VISpar.type][3]-=dy
1327
+
1328
+ def button_dy_up_action(self):
1329
+ dy=(self.VISpar.ymax-self.VISpar.ymin)/self.yres
1330
+ self.VISpar.size[self.VISpar.type][2]+=dy
1331
+ self.VISpar.size[self.VISpar.type][3]+=dy
1332
+
1333
+ def button_FocusIW_action(self):
1334
+ """
1335
+ Show a popup menu with options 'H x W' and return the selected index (int) or None.
1336
+ Labels are formatted as f"{Vect[2][i]} x {Vect[0][i]}".
1337
+ """
1338
+ FlagDisp=self.VISpar.variableKey is self.namesPIV.dispMap
1339
+ if FlagDisp: it=-1
1160
1340
  else:
1161
- if self.VISpar.FlagErrRead[2]:
1162
- self.setNameVarLabel('Output file not available!','')
1163
- else:
1164
- name=self.nameres
1165
- self.setNameVarLabel(f'Output file: {os.path.basename(name)}',\
1166
- f'Output file: {name}')
1167
-
1168
- def setNameVarLabel(self,stringa,stringa2):
1169
- if stringa:
1170
- self.ui.name_var.setText(stringa)
1171
- self.ui.name_var.setToolTip(stringa2)
1172
- self.ui.name_var.setStatusTip(stringa2)
1173
- self.ui.name_var.show()
1341
+ # Ensure consistent length between lists 0 (width values) and 2 (height values)
1342
+ ve=self.VISpar.Pro.Vect if isinstance(self.VISpar.Pro.Vect[0],list) else [[v] for v in self.VISpar.Pro.Vect]
1343
+ Vect = [[val for val in v] for v in ve]
1344
+ n = min(len(Vect[0]), len(Vect[2]))
1345
+ if n == 0:
1346
+ return None
1347
+
1348
+ # Create a context menu and populate it with the available sizes
1349
+ menu = QMenu(self)
1350
+ for i in range(n):
1351
+ label = f"{Vect[2][i]} x {Vect[0][i]}"
1352
+ act = menu.addAction(label)
1353
+ act.setData(i)
1354
+
1355
+ # Display the menu at the current cursor position and wait for user selection
1356
+ chosen = menu.exec(QCursor.pos())
1357
+ it = None if chosen is None else chosen.data()
1358
+ if it is not None: self.FocusIW_it(it)
1359
+
1360
+ def FocusIW_it(self,it=-1):
1361
+ ve=self.VISpar.Pro.Vect if isinstance(self.VISpar.Pro.Vect[0],list) else [[v] for v in self.VISpar.Pro.Vect]
1362
+ Vect = [[val for val in v] for v in ve]
1363
+ if self.VISpar.unit[self.VISpar.type] and self.VISpar.type!=0:
1364
+ yres=self.VISpar.Out.xres*self.VISpar.Out.pixAR
1365
+ for k in range(2): Vect[k]=[val/self.VISpar.Out.xres for val in Vect[k]]
1366
+ for k in range(2,4): Vect[k]=[val/yres for val in Vect[k]]
1367
+ else: yres=1.0
1368
+ W=Vect[2][it]
1369
+ FlagDisp=self.VISpar.variableKey is self.namesPIV.dispMap
1370
+ if FlagDisp:
1371
+ H=self.gui.w_Process_Disp.PROpar.SemiWidth_Epipolar*2+1
1372
+ H/=yres
1373
+ FlagBordo=False
1374
+ else:
1375
+ H=Vect[0][it]
1376
+ FlagBordo=self.VISpar.Pro.FlagBordo
1377
+ if abs(self.VISpar.size[self.VISpar.type][1]-self.VISpar.size[self.VISpar.type][0]-W)<1 and abs(self.VISpar.size[self.VISpar.type][3]-self.VISpar.size[self.VISpar.type][2]-H)<1:
1378
+ dW=W if FlagDisp else Vect[3][it]
1379
+ boundDist=W/2 if not FlagBordo else dW
1380
+ x0=int((self.VISpar.size[self.VISpar.type][0]-boundDist+W/2)/dW)*dW+boundDist-W/2 if self.VISpar.size[self.VISpar.type][0]>boundDist else boundDist-W/2
1381
+ dH=H if FlagDisp else Vect[1][it]
1382
+ boundDist=H/2 if not FlagBordo else dH
1383
+ y0=int((self.VISpar.size[self.VISpar.type][2]-boundDist+H/2)/dH)*dH+boundDist-H/2 if self.VISpar.size[self.VISpar.type][2]>boundDist else boundDist-H/2
1384
+ self.VISpar.size[self.VISpar.type][0]=x0
1385
+ self.VISpar.size[self.VISpar.type][2]=y0
1386
+ self.VISpar.size[self.VISpar.type][1]=x0+W
1387
+ self.VISpar.size[self.VISpar.type][3]=y0+H
1174
1388
  else:
1175
- self.ui.name_var.hide()
1389
+ self.VISpar.size[self.VISpar.type][1]=self.VISpar.size[self.VISpar.type][0]+W
1390
+ self.VISpar.size[self.VISpar.type][3]=self.VISpar.size[self.VISpar.type][2]+H
1391
+
1392
+ #******************** Settings
1393
+ def button_view_set(self):
1394
+ self.ui.button_view.setChecked(self.VISpar.FlagView)
1395
+
1396
+ def button_ShowIW_set(self):
1397
+ self.ui.button_ShowIW.setChecked(self.VISpar.FlagShowIW)
1398
+
1399
+ def button_ShowCR_set(self):
1400
+ self.ui.button_ShowCR.setChecked(self.VISpar.FlagShowCR)
1401
+
1402
+ def button_SubMIN_set(self):
1403
+ self.ui.button_SubMIN.setChecked(self.VISpar.FlagSubMIN)
1404
+
1405
+ def button_unit_set(self):
1406
+ self.ui.button_unit.setChecked(self.VISpar.unit[self.VISpar.type])
1407
+
1408
+ def button_Contourf_set(self):
1409
+ self.ui.button_Contourf.setChecked(self.VISpar.FlagContourf)
1410
+
1411
+ def button_automatic_levels_set(self):
1412
+ self.ui.button_automatic_levels.setChecked(self.VISpar.FlagAutoLevels)
1413
+
1414
+ def button_automatic_sizes_set(self):
1415
+ self.ui.button_automatic_sizes.setChecked(self.VISpar.FlagAutoSizes)
1416
+
1417
+ def button_invert_y_set(self):
1418
+ self.ui.button_invert_y.setChecked(self.VISpar.FlagYInvert[self.VISpar.type])
1419
+
1420
+ def combo_map_var_set(self):
1421
+ self.ui.combo_map_var.setCurrentText(self.VISpar.variable)
1422
+
1423
+ def slider_set(self,spin:MyQDoubleSpin,slider:QSlider):
1424
+ spin_value=getattr(self.VISpar,spin.objectName().replace('spin_',''))
1425
+ if spin.maximum()>spin.minimum():
1426
+ slider_value=int((spin_value-spin.minimum())/(spin.maximum()-spin.minimum())*slider.maximum())
1427
+ else: slider_value=0
1428
+ slider.setValue(slider_value)
1429
+
1430
+ #******************** Layout
1431
+ def leftrightCallback(self,di):
1432
+ i=self.ui.image_levels.currentIndex()
1433
+ i=i+di
1434
+ c=self.ui.image_levels.count()-1-int(self.result is None)
1435
+ if i<0: i=c
1436
+ elif i>c: i=0
1437
+ self.VISpar.setPage=i
1438
+
1439
+ #*************************************************** Plot
1440
+ def updatingPlot(self):
1441
+ xmin,xmax=list(self.ui.plot.axes.get_xlim())
1442
+ ymin,ymax=list(self.ui.plot.axes.get_ylim())
1443
+ self.VISpar.size[self.VISpar.type][:2]=[xmin/self.xres,xmax/self.xres]
1444
+ self.VISpar.size[self.VISpar.type][2:4]=[ymin/self.yres,ymax/self.yres]
1445
+
1446
+ def forceRestoreArrowCursor(self):
1447
+ if self.CursorTimer.isActive():
1448
+ self.CursorTimer.stop()
1449
+ while QApplication.overrideCursor() is not None:
1450
+ QApplication.restoreOverrideCursor()
1451
+ self.FlagNormalCursor = True
1452
+
1453
+ def brushCursor(self):
1454
+ self.forceRestoreArrowCursor()
1455
+ self.FlagNormalCursor=False
1456
+ QApplication.setOverrideCursor(self.brush_cursor)
1457
+ self.CursorTimer.start(250)
1176
1458
 
1177
1459
  def setMapVar(self):
1178
1460
  pri.PlotTime.magenta(f'{"/"*25} Plotting image - start')
1179
- QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor)
1461
+ self.brushCursor()
1180
1462
  try:
1181
1463
  if self.VISpar.type==0:
1182
- self.showImg()
1464
+ fields=['image_file','variable','unit','FlagSubMIN','Out','colorMap']
1465
+ img=self.image
1466
+ if img is not None and self.VISpar.img>0 and self.VISpar.FlagSubMIN and self.image_Min is not None:
1467
+ img=img-self.image_Min
1468
+ self.img=img
1469
+ FlagDraw=self.showImg(fields)
1470
+
1471
+ FlagIW=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['FlagShowIW','Pro'])
1472
+ if FlagIW or FlagDraw: self.showRect()
1473
+ FlagDraw=FlagDraw or FlagIW
1474
+ if self.image is not None and self.VISpar.FlagShowCR and self.VISpar.variableKey!=self.namesPIV.dispMap:
1475
+ self.showCommonRegion()
1476
+ FlagDraw=FlagDraw or self.CR is not None
1477
+ else:
1478
+ self.cleanCommonRegion()
1183
1479
  else:
1184
- self.showRes()
1480
+ if self.orect: self.cleanRect()
1481
+ self.cleanCommonRegion()
1482
+ fields=['result_file','variable','unit','min','max','nclev','FlagContourf','colorMap']
1483
+ if self.VISpar.variableKey not in self.result: raise('Variable not found in result structure!')
1484
+ V=self.result[self.VISpar.variableKey]
1485
+ if not self.VISpar.FlagContourf:
1486
+ self.img,Ximg,Yimg,FlagInterp,size=self.calcMap(V,size_pixels=[np.size(V,0), np.size(V,1)])
1487
+ FlagDraw=self.showImg(fields,size)
1488
+ else:
1489
+ self.img,Ximg,Yimg,FlagInterp,size=self.calcMap(V)
1490
+ if FlagInterp:
1491
+ FlagDraw=self.showImg(fields,size)
1492
+ else:
1493
+ FlagDraw=self.showMap(fields)
1494
+ if self.contour is None:
1495
+ FlagDraw=self.showImg(fields,size)
1496
+ fields=['result_file','variable','FlagContourf','field_rep','unit','vectorColor']
1497
+ if self.VISpar.field_rep==1: fields+=['vecsize','vecwid','vecspac']
1498
+ elif self.VISpar.field_rep==2: fields+=['streamdens']
1499
+ if self.VISpar.Step!=StepTypes.piv: fields+=['type']
1500
+ FlagVecField=self.VISpar.isDifferentFrom(self.VISpar_old,fields=fields)
1501
+ if FlagVecField and self.result:
1502
+ self.showVecField()
1503
+ elif self.result is None: self.cleanVecField()
1504
+ FlagDraw=FlagDraw or FlagVecField
1505
+
1506
+ if FlagDraw:
1507
+ #self.ui.plot.draw()
1508
+ self.ui.plot.draw_idle()
1185
1509
  except:
1510
+ pri.Error.red(f'Error while generating plot:\n{traceback.format_exc()}\n\n')
1186
1511
  printException()
1187
- self.exitVISerr(False)
1188
- QApplication.restoreOverrideCursor()
1512
+ #self.exitVISerr(False)
1189
1513
  pri.PlotTime.magenta(f'{"%"*25} Plotting image - end')
1190
1514
 
1191
- def showImg(self):
1192
- fields=['MapVar_type','flagMIN','nfield']
1193
- flagImg=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1194
- FlagOut=self.VISpar.Out.isDifferentFrom(self.VISpar_old.Out,[],['x','y','w','h','vecop'],True)
1195
- flagImg=flagImg or FlagOut
1196
- if flagImg:
1197
- self.ui.plot.axes.cla()
1198
- if self.cb:
1199
- try:
1200
- self.cb.remove()
1201
- except:
1202
- pass
1203
- self.cb=None
1204
- img=getattr(self,['imga','imgb'][self.VISpar.MapVar_type])
1205
- if self.VISpar.flagMIN and len(self.Imin[self.VISpar.MapVar_type])>0\
1206
- and self.VISpar.nfield>-1+imin_im_pair:
1207
- img=img-self.Imin[self.VISpar.MapVar_type]
1208
- self.img=img
1209
- self.ui.plot.axes.set_title(self.ui.combo_map_var.currentText())
1210
- self.imgshow=self.ui.plot.axes.imshow(img,
1211
- origin='upper',extent=(0,np.size(img,1),np.size(img,0),0),
1212
- vmin=self.VISpar.vmin,vmax=self.VISpar.vmax)
1213
- self.imgshow.set_cmap(mpl.colormaps['gray'])
1214
- divider = make_axes_locatable(self.ui.plot.axes)
1215
- cax = divider.append_axes("right", size="5%", pad=0.05)
1216
- self.cb=self.ui.plot.fig.colorbar(self.imgshow,cax=cax)
1217
- self.cb.ax.set_title("I")
1515
+ def showImg(self,fields,size:list=None):
1516
+ img=self.img
1517
+ if img is None:
1518
+ self.cleanAxes(FlagAxis=False)
1519
+ return True #raise Exception('Invalid input image!')
1520
+
1521
+ FlagNewPlot=self.VISpar.isDifferentFrom(self.VISpar_old,fields=fields)
1522
+ FlagOut=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['Out'])
1523
+ FlagXLim=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['xmin','xmax','ymin','ymax','unit','FlagYInvert','Out'])
1524
+ FlagCMap=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['colorMap','nclev'])
1525
+ FlagCLim=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['min','max','nclev','colorMap'] if self.VISpar.type else ['min','max'])
1526
+ FlagExtent=False
1527
+
1528
+ if FlagNewPlot:
1529
+ FlagVariable=self.VISpar_old.variable!=self.VISpar.variable
1530
+
1531
+ if self.imgshow is None or self.VISpar_old.FlagContourf!=self.VISpar.FlagContourf or FlagOut:
1532
+ self.cleanAxes()
1533
+ self.imgshow=self.ui.plot.axes.imshow(img,extent=self.imgExtent(size), origin='lower', vmin=self.VISpar.min,vmax=self.VISpar.max,zorder=0)
1534
+ self.imgshow.format_cursor_data=lambda v: self.custom_format_cursor_data(v)
1535
+ cmap,_=self.colorMap()
1536
+ self.imgshow.set_cmap(cmap)
1537
+ divider = make_axes_locatable(self.ui.plot.axes)
1538
+ cax = divider.append_axes("right", size="5%", pad=0.05)
1539
+ self.cb=self.ui.plot.fig.colorbar(self.imgshow,cax=cax)
1540
+ self.setTitleLabels()
1541
+ FlagXLim=True
1542
+ else:
1543
+ self.imgshow.set_data(img)
1544
+ extent=self.imgExtent(size)
1545
+ if extent!=self.imgshow.get_extent():
1546
+ self.imgshow.set_extent(extent)
1547
+ FlagExtent=True
1548
+ if FlagCMap:
1549
+ cmap,_=self.colorMap()
1550
+ self.imgshow.set_cmap(cmap)
1551
+ if FlagCLim:
1552
+ self.imgshow.set_clim(self.VISpar.min,self.VISpar.max)
1553
+ if FlagVariable:
1554
+ self.setTitleLabels()
1218
1555
  else:
1219
- fields=['vmin','vmax']
1220
- flagCLim=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1221
- if flagCLim:
1222
- self.imgshow.set_clim(self.VISpar.vmin,self.VISpar.vmax)
1223
-
1224
-
1225
- fields=['xlim','ylim','FlagYInvert','Out']
1226
- flagXLim=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1227
- if flagXLim or flagImg:
1556
+ if FlagCMap:
1557
+ cmap,_=self.colorMap()
1558
+ self.imgshow.set_cmap(cmap)
1559
+ if FlagCLim:
1560
+ self.imgshow.set_clim(self.VISpar.min,self.VISpar.max)
1561
+ if FlagXLim:
1228
1562
  self.setAxisLim()
1229
1563
  self.Ptoolbar.update()
1230
1564
 
1231
- fields=['flagShowIW','Pro']
1232
- flagIW=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1233
- if flagIW or flagImg:
1234
- self.showRect()
1235
-
1236
- flagDraw=flagImg or flagXLim or flagIW or flagCLim
1237
- if flagDraw:
1238
- #self.ui.plot.draw()
1239
- self.ui.plot.draw_idle()
1565
+ FlagDraw=FlagNewPlot or FlagOut or FlagXLim or FlagCMap or FlagCLim or FlagExtent
1566
+ return FlagDraw
1240
1567
 
1241
- if not self.flagInitImg: self.flagInitImg=True
1242
- return flagDraw
1243
-
1244
- def showRes(self):
1245
- flagContour=self.showContMap()
1246
- fields=['VecField_type']
1247
- if self.VISpar.VecField_type==1: fields+=['vecsize','vecspac']
1248
- elif self.VISpar.VecField_type==2: fields+=['streamdens']
1249
- flagVecField=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1250
- flagVecField=flagVecField or flagContour
1251
- self.showVecField(flagVecField)
1252
- if flagVecField:
1253
- #self.ui.plot.draw()
1254
- self.ui.plot.draw_idle()
1255
-
1256
- def showContMap(self):
1257
- fields=['MapVar_type','nfield','vmin','vmax','nclev']
1258
- flagContour=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1259
- if flagContour:
1260
- self.ui.plot.axes.cla()
1261
- self.contour=None
1262
- if self.cb:
1263
- try:
1264
- self.cb.remove()
1265
- except:
1266
- pass
1267
- self.cb=None
1268
- X=self.res[self.namesPIV.x]
1269
- Y=self.res[self.namesPIV.y]
1270
- #infoPrint.white(VarNames[self.VISpar.MapVar_type-2])
1271
- var_field=self.namesPIV.fields[self.VISpar.MapVar_type]
1272
- self.ui.plot.axes.set_title(self.namesPIV.titles_list[self.VISpar.MapVar_type])
1273
- V=self.res[var_field]
1274
- self.map=V
1275
- if self.VISpar.vmin<self.VISpar.vmax:
1276
- levs=np.linspace(self.VISpar.vmin,self.VISpar.vmax,self.VISpar.nclev)
1568
+ def colorMap(self):
1569
+ if self.VISpar.type==0:
1570
+ cmap=mpl.colormaps[self.VISpar.colorMap]
1571
+ levs=np.linspace(self.VISpar.min,self.VISpar.max,int(self.VISpar.max-self.VISpar.min))
1572
+ else:
1573
+ if self.VISpar.min<self.VISpar.max:
1574
+ levs=np.linspace(self.VISpar.min,self.VISpar.max,self.VISpar.nclev)
1277
1575
  else:
1278
- levs=np.linspace(self.VISpar.vmax-self.ui.spin_min.singleStep(),\
1279
- self.VISpar.vmax,self.VISpar.nclev)
1280
- colormap = pyplt.get_cmap('jet')
1576
+ levs=np.linspace(self.VISpar.max-self.ui.spin_min.singleStep(),\
1577
+ self.VISpar.max,self.VISpar.nclev)
1578
+ colormap = pyplt.get_cmap(self.VISpar.colorMap)
1281
1579
  colors=colormap(np.linspace(0, 1, len(levs)))
1282
- cmap = mpl.colors.ListedColormap(colors)
1283
- self.contour=self.ui.plot.axes.contourf(X, Y, V, levs, \
1284
- cmap=cmap, origin='lower', extend='both')
1580
+ cmap = mpl.colors.ListedColormap(colors)
1581
+ return cmap, levs
1582
+
1583
+ def getXYRes(self,type=None):
1584
+ if type is None: type=self.VISpar.type
1585
+ xres=yres=1.0
1586
+ if self.VISpar.Process==ProcessTypes.piv and not self.VISpar.Out.FlagNone:
1587
+ if type==0: #mm/pixels
1588
+ xres =1.0/self.VISpar.Out.xres
1589
+ yres=1.0/(self.VISpar.Out.xres*self.VISpar.Out.pixAR)
1590
+ elif type==1: #pixels/mm
1591
+ xres=self.VISpar.Out.xres
1592
+ yres=self.VISpar.Out.xres*self.VISpar.Out.pixAR
1593
+ return xres, yres
1594
+
1595
+ def imgExtent(self,size=None):
1596
+ if size is None: size=self.VISpar.size_default[self.VISpar.type]
1597
+ return [k*self.xres for k in size[:2]]+[k*self.yres for k in size[2:4]]
1598
+
1599
+ def setAxisLim(self):
1600
+ self.ui.plot.axes.set_xlim(self.VISpar.xmin,self.VISpar.xmax)
1601
+ ylim=[self.VISpar.ymin,self.VISpar.ymax]
1602
+ if self.VISpar.FlagYInvert[self.VISpar.type]:
1603
+ self.ui.plot.axes.set_ylim(max(ylim),min(ylim))
1604
+ else:
1605
+ self.ui.plot.axes.set_ylim(min(ylim),max(ylim))
1606
+ self.ui.plot.axes.set_aspect('equal', adjustable='box')
1607
+
1608
+ def setTitleLabels(self):
1609
+ self.ui.plot.axes.set_title(self.namesPIV.titles_dict[self.VISpar.variableKey])
1610
+ self.cb.ax.set_title(self.namesPIV.titles_cb_dict[self.VISpar.variableKey])
1611
+ self.ui.plot.axes.set_xlabel("x" if self.VISpar.type else "")
1612
+ self.ui.plot.axes.set_ylabel("y" if self.VISpar.type else "")
1613
+
1614
+ def showMap(self,fields):
1615
+ result=self.result
1616
+ if result is None:
1617
+ self.cleanAxes(FlagAxis=False)
1618
+ return True #raise Exception('Invalid output image!')
1619
+
1620
+ FlagNewPlot=self.VISpar.isDifferentFrom(self.VISpar_old,fields=fields)
1621
+ FlagXLim=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['xmin','xmax','ymin','ymax','unit','FlagYInvert','Out'])
1622
+ FlagCMap=self.VISpar_old.colorMap!=self.VISpar.colorMap
1623
+ FlagCLim=self.VISpar.isDifferentFrom(self.VISpar_old,fields=['min','max'])
1624
+
1625
+ if FlagNewPlot or self.VISpar_old.FlagContourf!=self.VISpar.FlagContourf or self.VISpar_old.nclev!=self.VISpar.nclev:
1626
+ self.cleanAxes()
1627
+ if not self.VISpar.unit[self.VISpar.type]:
1628
+ xres,yres=self.getXYRes(type=1)
1629
+ else: xres=yres=1.0
1630
+ X=result[self.namesPIV.x]*xres
1631
+ Y=result[self.namesPIV.y]*yres
1632
+ if self.VISpar.variableKey not in self.result: raise('Variable not found in result structure!')
1633
+ V=result[self.VISpar.variableKey]
1634
+ self.map=[X,Y,V]
1635
+
1636
+ cmap,levs=self.colorMap()
1637
+ try:
1638
+ self.contour=self.ui.plot.axes.contourf(X, Y, V, levs, \
1639
+ cmap=cmap, origin='lower', extend='both', zorder=0)
1640
+ self.contour.format_cursor_data=lambda v: self.custom_format_cursor_data(v)
1641
+ except:
1642
+ pri.Error.red(f'Error while generating contour lines:\n{traceback.format_exc()}\n\n')
1643
+ self.contour=None
1644
+ return
1285
1645
  self.contour.set_clim(levs[0],levs[-1])
1286
1646
  divider = make_axes_locatable(self.ui.plot.axes)
1287
1647
  cax = divider.append_axes("right", size="5%", pad=0.05)
1288
1648
  self.cb=self.ui.plot.fig.colorbar(self.contour,cax=cax)
1289
-
1290
- self.ui.plot.fig.get_axes()[1].set_title(self.namesPIV.titles_cb_list[self.VISpar.MapVar_type])
1291
- self.ui.plot.axes.set_xlabel("x")
1292
- self.ui.plot.axes.set_ylabel("y")
1293
-
1294
- fields=['xlim','ylim','FlagYInvert']
1295
- flagXLim=self.VISpar.isDifferentFrom(self.VISpar_old,[],fields,True)
1296
- if flagXLim or flagContour:
1649
+ self.setTitleLabels()
1650
+ FlagXLim=True
1651
+ else:
1652
+ if FlagCMap:
1653
+ cmap,_=self.colorMap()
1654
+ self.contour.set_cmap(cmap)
1655
+ if FlagCLim:
1656
+ self.contour.set_clim(self.VISpar.min,self.VISpar.max)
1657
+ if FlagXLim:
1297
1658
  self.setAxisLim()
1298
1659
  self.Ptoolbar.update()
1299
1660
 
1300
- flagContour=flagContour or flagXLim
1301
- if not self.flagInitImg: self.flagInitImg=True
1302
- return flagContour
1661
+ FlagDraw=FlagNewPlot or FlagXLim or FlagCMap or FlagCLim
1662
+ return FlagDraw
1303
1663
 
1304
- def setAxisLim(self):
1305
- self.ui.plot.axes.set_xlim(self.VISpar.xlim[0],self.VISpar.xlim[1])
1306
- ylim=self.VISpar.ylim
1307
- if self.VISpar.FlagYInvert[self.VISpar.type]:
1308
- self.ui.plot.axes.set_ylim(max(ylim),min(ylim))
1664
+ def calcMap(self,V,size_pixels=[1000]*2):
1665
+ #size_pixels=self.ui.plot.fig.get_size_inches()*self.ui.plot.fig.get_dpi()
1666
+ #size_pixels=np.minimum(np.round(0.5*size_pixels).astype(int),1000)
1667
+ FlagSize=False
1668
+ if "X" in list(self.result) and "Y" in list(self.result):
1669
+ X=self.result["X"]
1670
+ Y=self.result["Y"]
1671
+ FlagSize=True
1672
+ elif "x" in list(self.result) and "y" in list(self.result):
1673
+ X=self.result["x"]
1674
+ Y=self.result["y"]
1675
+ FlagSize=True
1676
+ if FlagSize:
1677
+ xmin,xmax,ymin,ymax=[X.min(),X.max(),Y.min(),Y.max()]
1309
1678
  else:
1310
- self.ui.plot.axes.set_ylim(min(ylim),max(ylim))
1311
- self.ui.plot.axes.set_aspect('equal', adjustable='box')
1312
-
1313
- def showVecField(self,flagVecField):
1314
- if flagVecField:
1315
- ind=self.VISpar.VecField_type
1316
- if self.qui!=None:
1317
- self.qui.remove()
1318
- self.qui=None
1319
- if self.stream!=None:
1320
- self.stream.lines.remove()
1321
- for ax in self.ui.plot.axes.get_children():
1322
- if isinstance(ax, mpl.patches.FancyArrowPatch):
1323
- ax.remove()
1324
- self.stream=None
1325
- if ind in (1,2):
1326
- X=self.res["X"]
1327
- Y=self.res["Y"]
1328
- U=self.res["U"]
1329
- V=self.res["V"]
1330
- if ind==1:
1331
- fac=np.abs(X[0,1]-X[0,0])/np.amax(self.res["Mod"])
1332
- spa=self.VISpar.vecspac
1333
- self.qui=self.ui.plot.axes.quiver(
1334
- X[::spa,::spa],Y[::spa,::spa],U[::spa,::spa]*fac,V[::spa,::spa]*fac,
1335
- angles='xy',scale_units='xy',scale=1/self.VISpar.vecsize,
1336
- width=0.005,headwidth=5,headaxislength=5)
1337
- elif ind==2:
1338
- self.stream=self.ui.plot.axes.streamplot(X,Y,U,V,color='k',\
1339
- density=self.VISpar.streamdens)
1679
+ xmin,xmax,ymin,ymax=[0,np.size(V,1),0,np.size(V,0)]
1680
+ xstep_half=(xmax-xmin)/(np.size(V,1)-1)*0.5
1681
+ x = self.mylinspace(xmin,xmax, np.size(V,1))
1682
+ ystep_half=(ymax-ymin)/(np.size(V,0)-1)*0.5
1683
+ y = self.mylinspace(ymin,ymax, np.size(V,0))
1684
+ FlagInterp=False
1685
+ if (np.size(V,1)<size_pixels[1] or np.size(V,0)<size_pixels[0]) and not bool(np.any(np.isnan(V))):
1686
+ x_new = self.mylinspace(xmin, xmax, size_pixels[0])
1687
+ y_new = self.mylinspace(ymin, ymax, size_pixels[1])
1688
+ try:
1689
+ f = scipy.interpolate.RectBivariateSpline(y, x, V)
1690
+ V_new = f(y_new, x_new)
1691
+ FlagInterp=True
1692
+ except:
1693
+ try:
1694
+ x_flat, y_flat = np.meshgrid(x, y) # Griglia 2D
1695
+ points = np.column_stack((x_flat.ravel(), y_flat.ravel())) # Punti 2D
1696
+ X_new, Y_new = np.meshgrid(x_new, y_new)
1697
+ V_new = scipy.interpolate.griddata(points, V.ravel(), (X_new, Y_new), method='cubic') #'nearest', 'linear', 'cubic'
1698
+ FlagInterp=True
1699
+ pass
1700
+ except:
1701
+ pri.Error.red(f'Error while interpolating map variable field for contour representation:\n{traceback.format_exc()}\n\n')
1702
+ x_new=x
1703
+ y_new=y
1704
+ V_new=V
1705
+ FlagInterp=False
1706
+ pass
1707
+ else:
1708
+ x_new=x
1709
+ y_new=y
1710
+ V_new=V
1711
+ FlagInterp=not bool(np.any(np.isnan(V)))
1712
+ X_new, Y_new = np.meshgrid(x_new, y_new)
1713
+ return V_new, X_new, Y_new, FlagInterp, (xmin-xstep_half,xmax+ystep_half,ymin-ystep_half,ymax+ystep_half)
1714
+
1715
+ def mylinspace(self,xmin,xmax,N):
1716
+ step=(xmax-xmin)/(N-1)
1717
+ return xmin+np.arange(0,N,1)*step
1718
+
1719
+ def cleanVecField(self):
1720
+ if self.qui!=None:
1721
+ self.qui.remove()
1722
+ self.qui=None
1723
+ if self.stream is not None:
1724
+ self.stream.lines.remove()
1725
+ for ax in self.ui.plot.axes.get_children():
1726
+ if isinstance(ax, mpl.patches.FancyArrowPatch):
1727
+ ax.remove()
1728
+ self.stream=None
1729
+
1730
+ def showVecField(self):
1731
+ ind=self.VISpar.field_rep
1732
+ self.cleanVecField()
1733
+ if self.qui!=None:
1734
+ self.qui.remove()
1735
+ self.qui=None
1736
+ if self.stream is not None:
1737
+ self.stream.lines.remove()
1738
+ for ax in self.ui.plot.axes.get_children():
1739
+ if isinstance(ax, mpl.patches.FancyArrowPatch):
1740
+ ax.remove()
1741
+ self.stream=None
1742
+ if ind in (1,2) and (self.VISpar.type>0 or self.VISpar.Step==StepTypes.piv):
1743
+ if not self.VISpar.unit[self.VISpar.type]:
1744
+ xres,yres=self.getXYRes(type=1)
1745
+ else: xres=yres=1.0
1746
+ if self.namesPIV.x in self.result and self.namesPIV.y in self.result:
1747
+ X=self.result[self.namesPIV.x]*xres
1748
+ Y=self.result[self.namesPIV.y]*yres
1749
+ elif self.namesPIV.X in self.result and self.namesPIV.Y in self.result:
1750
+ X=self.result[self.namesPIV.X]*xres
1751
+ Y=self.result[self.namesPIV.Y]*yres
1752
+ U=self.result[self.namesPIV.u]
1753
+ V=self.result[self.namesPIV.v]
1754
+ Mod=np.sqrt(U**2+V**2)
1755
+ if ind==1:
1756
+ dX=np.sqrt((X[0,1]-X[0,0])**2+(Y[1,0]-Y[0,0])**2)
1757
+ spa=self.VISpar.vecspac
1758
+ vecsize=self.VISpar.vecsize
1759
+ fac=dX*vecsize*spa
1760
+ Modq= Mod[::spa,::spa]
1761
+ Uq=np.divide(U[::spa,::spa], Modq, where=Modq!=0)*fac
1762
+ Vq=np.divide(V[::spa,::spa], Modq, where=Modq!=0)*fac
1763
+ w=0.15*fac
1764
+ n=3
1765
+ wmax=min([X.max()-X.min(),Y.max()-Y.min()])*0.001
1766
+ qwidth=min([w,wmax])*self.VISpar.vecwid**2
1767
+ hwidth=4 if vecsize<4 else vecsize
1768
+ self.qui=self.ui.plot.axes.quiver(
1769
+ X[::spa,::spa],Y[::spa,::spa],Uq,Vq, color=VIS_VectorColors[self.VISpar.vectorColor], clip_on=True,
1770
+ angles='xy',scale_units='xy',scale=1.0,
1771
+ units='xy',width=qwidth,headwidth=hwidth,headlength=1.25*hwidth,headaxislength=0.75*hwidth,zorder=10)
1772
+ elif ind==2:
1773
+ size_pixels=np.shape(U)
1774
+ Up,_,_,_,_=self.calcMap(U,size_pixels=size_pixels)
1775
+ Vp,Xp,Yp,_,_=self.calcMap(V,size_pixels=size_pixels)
1776
+ Xp=Xp*xres
1777
+ Yp=Yp*yres
1778
+ self.stream=self.ui.plot.axes.streamplot(Xp,Yp,Up,Vp,color=VIS_VectorColors[self.VISpar.vectorColor],density=self.VISpar.streamdens,zorder=10)
1779
+
1780
+ def cleanAxes(self,FlagAxis=True):
1781
+ self.imgshow=self.contour=self.CR=self.RF=None
1782
+ self.orect=[]
1783
+ self.qui=self.stream=None
1784
+ """
1785
+ self.cleanCommonRegion()
1786
+ self.cleanReferenceFrame()
1787
+ self.cleanRect()
1788
+ self.cleanVecField()
1789
+ if self.contour:
1790
+ for coll in self.contour.collections:
1791
+ coll.remove()
1792
+ """
1793
+ if self.cb:
1794
+ self.cb.remove()
1795
+ self.cb=None
1796
+ self.ui.plot.axes.cla()
1797
+ self.ui.plot.axes.axis('on' if FlagAxis else 'off')
1798
+ #self.ui.Plot_tools.setEnabled(FlagAxis)
1799
+
1800
+ def custom_format_coord(self,x,y):
1801
+ if self.contour is not None:
1802
+ X=self.map[0]
1803
+ Y=self.map[1]
1804
+
1805
+ if X.min() <= x <= X.max() and Y.min() <= y <= Y.max():
1806
+ # Trova l'indice più vicino nella matrice
1807
+ col = np.searchsorted(X[0,:],x) - 1
1808
+ row = np.searchsorted(Y[:,0],y) - 1
1809
+ Z=self.map[2]
1810
+
1811
+ # Estrai il valore dal dato Z
1812
+ if 0 <= row < Z.shape[0] and 0 <= col < Z.shape[1]:
1813
+ value = Z[row, col]
1814
+ formatted_value = f"{value:.4f}".rstrip('0').rstrip('.')
1815
+ return f"(x, y)=({x:.2f}, {y:.2f})\n[{formatted_value}]"
1816
+ return f"(x, y)=({x:.2f}, {y:.2f})"
1817
+ else:
1818
+ return f"(x, y)=({x:.2f}, {y:.2f})"
1819
+
1820
+ def custom_format_cursor_data(self,value):
1821
+ formatted_value = f"{value:.4f}".rstrip('0').rstrip('.')
1822
+ return f"[{formatted_value}]"
1340
1823
 
1341
1824
  def cleanRect(self):
1342
1825
  if len(self.orect):
@@ -1352,14 +1835,22 @@ class Vis_Tab(gPaIRS_Tab):
1352
1835
  def showRect(self):
1353
1836
  if not len(self.VISpar.Pro.Vect): return
1354
1837
  self.cleanRect()
1355
- if not self.VISpar.flagShowIW: return
1838
+ if not self.VISpar.FlagShowIW: return
1356
1839
  colors='rgbymc'
1357
1840
  lwidth=1
1358
1841
  nov_hor=3
1359
1842
  nov_vert=3
1360
1843
 
1361
- H=self.VISpar.size[self.VISpar.MapVar_type][1]
1362
- Vect = self.VISpar.Pro.Vect
1844
+ H=self.VISpar.size[self.VISpar.type][1]
1845
+ ve=self.VISpar.Pro.Vect if isinstance(self.VISpar.Pro.Vect[0],list) else [[v] for v in self.VISpar.Pro.Vect]
1846
+ Vect = [[val for val in v] for v in ve]
1847
+ dxin=dyin=5
1848
+ if self.VISpar.unit[self.VISpar.type]:
1849
+ xres,yres=self.getXYRes(type=0)
1850
+ for k in range(2): Vect[k]=[val*xres for val in Vect[k]]
1851
+ for k in range(2,4): Vect[k]=[val*yres for val in Vect[k]]
1852
+ dxin=dxin*xres
1853
+ dyin=dyin*yres
1363
1854
  nw=len(Vect[0])
1364
1855
  xin0=yin0=0
1365
1856
  xmax=ymax=0
@@ -1397,7 +1888,7 @@ class Vis_Tab(gPaIRS_Tab):
1397
1888
  if not kk:
1398
1889
  if self.VISpar.FlagYInvert[self.VISpar.type]: va='top'
1399
1890
  else: va='bottom'
1400
- text=self.ui.plot.axes.text(xin+5,yin+5,str(k),\
1891
+ text=self.ui.plot.axes.text(xin+dxin,yin+dyin,str(k),\
1401
1892
  horizontalalignment='left',verticalalignment=va,\
1402
1893
  fontsize='large',color='w',fontweight='bold')
1403
1894
  self.orect=self.orect+[rect,rect2,points,text]
@@ -1413,125 +1904,256 @@ class Vis_Tab(gPaIRS_Tab):
1413
1904
  else:
1414
1905
  yin0=0
1415
1906
  xin0=xmax
1416
- xlim=self.ui.plot.axes.get_xlim()
1417
- xlim_min=min([xlim[0],xlim_min])
1418
- xlim_max=max([xlim[1],xlim_max])
1419
- self.ui.plot.axes.set_xlim(xlim_min,xlim_max)
1420
- if self.VISpar.FlagYInvert[self.VISpar.type]:
1421
- ylim=self.ui.plot.axes.get_ylim()
1422
- ylim_max=min([ylim[1],ylim_min])
1423
- ylim_min=max([ylim[0],ylim_max])
1424
- else:
1425
- ylim=self.ui.plot.axes.get_ylim()
1426
- ylim_min=min([ylim[0],ylim_min])
1427
- ylim_max=max([ylim[1],ylim_max])
1428
- self.ui.plot.axes.set_ylim(ylim_min,ylim_max)
1429
- self.VISpar.xlim=list(self.ui.plot.axes.get_xlim())
1430
- self.VISpar.ylim=list(self.ui.plot.axes.get_ylim())
1431
-
1432
- #*************************************************** Displaying images
1433
- def updateVisfromINP(self,*args):
1434
- if len(args): VISpar_prev:VISpar=args[0]
1435
- else: VISpar_prev=self.VISpar
1436
-
1437
- self.checkSavedProc(-1,VISpar_prev)
1438
- VISpar_prev.nfield=VISpar_prev.Inp.selected
1439
- if VISpar_prev.nfield==imin_im_pair-1 and not any(VISpar_prev.FlagExistMean):
1440
- VISpar_prev.nfield+=1
1441
-
1442
- i=VISpar_prev.nfield-imin_im_pair
1443
- self.checkSavedProc(i,VISpar_prev)
1444
- self.fLoad=[False]*3
1445
- self.importVar(VISpar_prev)
1446
-
1907
+ if self.VISpar.FlagShowIW and self.VISpar.isDifferentFrom(self.VISpar_old,fields=['FlagShowIW']):
1908
+ xlim=self.ui.plot.axes.get_xlim()
1909
+ xlim_min=min([xlim[0],xlim_min])
1910
+ xlim_max=max([xlim[1],xlim_max])
1911
+ self.ui.plot.axes.set_xlim(xlim_min,xlim_max)
1912
+ if self.VISpar.FlagYInvert[self.VISpar.type]:
1913
+ ylim=self.ui.plot.axes.get_ylim()
1914
+ ylim_max=min([ylim[1],ylim_min])
1915
+ ylim_min=max([ylim[0],ylim_max])
1916
+ else:
1917
+ ylim=self.ui.plot.axes.get_ylim()
1918
+ ylim_min=min([ylim[0],ylim_min])
1919
+ ylim_max=max([ylim[1],ylim_max])
1920
+ self.ui.plot.axes.set_ylim(ylim_min,ylim_max)
1921
+ self.VISpar.xmin,self.VISpar.xmax=list(self.ui.plot.axes.get_xlim())
1922
+ self.VISpar.ymin,self.VISpar.ymax=list(self.ui.plot.axes.get_ylim())
1923
+
1924
+ def cleanCommonRegion(self):
1925
+ if self.CR:
1926
+ self.CR.remove()
1927
+ self.CR=None
1928
+ self.ui.plot.draw_idle()
1929
+ self.cleanReferenceFrame()
1447
1930
 
1448
- def checkSavedProc(self,i,*args):
1449
- if len(args): VISpar_prev:VISpar=args[0]
1450
- else: VISpar_prev=self.VISpar
1451
- INP=VISpar_prev.Inp
1452
- OUT=VISpar_prev.Out
1453
- TRE=VISpar_prev.Tre
1931
+ def showCommonRegion(self):
1932
+ self.cleanCommonRegion()
1933
+ try:
1934
+ mapFun=PaIRS_lib.MappingFunction()
1935
+ mapFun.readCal(self.VISpar.calList)
1454
1936
 
1455
- if i<0 and TRE.flagRun:
1456
- if TRE.flagRun<-1:
1457
- VISpar_prev.FlagExistMean=[TRE.flagRun in (-10,-11),TRE.flagRun in (-11,-12)] #flagRun=-10: solo min, -11:min+PIV, -12:solo PIV
1458
- else:
1459
- fnames=TRE.filename_proc[1:3]
1460
- dnames=TRE.name_proc[1:3]
1461
- VISpar_prev.FlagExistMean=[False,False]
1462
- for k,f in enumerate(fnames):
1463
- if not f:
1464
- VISpar_prev.FlagExistMean[k]=False
1465
- continue
1466
- try:
1467
- with open(f, 'rb') as file:
1468
- data = pickle.load(file)
1469
- VISpar_prev.FlagExistMean[k]=dnames[k]==data.name_proc[k+1]
1470
- except Exception as inst:
1471
- pri.Error.red(f"VIS: error opening result files {f}:\n {traceback.format_exc()}, {inst}")
1472
- VISpar_prev.FlagExistMean[k]=False
1473
- elif i<0 and not TRE.flagRun:
1474
- VISpar_prev.FlagExistMean=[False,False]
1475
-
1476
- VISpar_prev.nameimga=VISpar_prev.nameimgb=VISpar_prev.nameres=''
1477
- currpath=myStandardPath(OUT.path+OUT.subfold)
1478
- root=OUT.root
1479
- outExt=list(outType_items)[OUT.outType]
1480
- if INP.pinfo.ndig!=[]:
1481
- ndig=INP.pinfo.ndig
1937
+ #if self.VISpar.Step==StepTypes.spiv:
1938
+ # planeConst=self.readLaserPlaneConst(self.VISpar.dispFile)
1939
+ #else:
1940
+ # planeConst=[0.0,0.0,0.0]
1941
+ planeConst=[self.VISpar.Out.zconst,self.VISpar.Out.xterm,self.VISpar.Out.yterm]
1942
+
1943
+ o=self.VISpar.Out
1944
+ points=[ [o.x_min, o.y_min], [o.x_max, o.y_min], [o.x_max, o.y_max], [o.x_min, o.y_max]]
1945
+ zLaser=lambda xy: self.zLaser(xy[0],xy[1],planeConst)
1946
+ for p in points: p.append(zLaser(p))
1947
+ points_array=np.array(points,dtype=np.float64,order='C')
1948
+ cam=self.VISpar.cam-1
1949
+ X=mapFun.worldToImg(points_array,cam,None)# In output X1 is equal to X if correctly allocated
1950
+
1951
+ x_values = [Xp[0] for Xp in X]+[X[0][0]]
1952
+ y_values = [Xp[1] for Xp in X]+[X[0][1]]
1953
+ self.CR,=self.ui.plot.axes.plot(x_values, y_values, 'b-',clip_on=False)
1954
+ self.showReferenceFrame(mapFun=mapFun)
1955
+ except Exception as exc:
1956
+ pri.Error.red(f"[VIS] Error while plotting common zone!\n{traceback.format_exc()}\n")
1957
+ return
1958
+
1959
+ def zLaser(self,x,y,planeConst):
1960
+ return planeConst[0]+planeConst[1]*x+planeConst[2]*y
1961
+
1962
+ def cleanReferenceFrame(self):
1963
+ if self.RF:
1964
+ for p in self.RF:
1965
+ p.remove()
1966
+ self.RF=None
1967
+ self.ui.plot.draw_idle()
1968
+
1969
+ def showReferenceFrame(self,mapFun=None):
1970
+ self.cleanReferenceFrame()
1971
+ try:
1972
+ if mapFun is None:
1973
+ mapFun=PaIRS_lib.MappingFunction()
1974
+ mapFun.readCal(self.VISpar.calList)
1975
+
1976
+ labels=['O','x','y','z']
1977
+ unit=1
1978
+
1979
+ points=[ [0, 0, 0], [unit, 0, 0], [0, unit, 0], [0, 0, unit]]
1980
+ points_array=np.array(points,dtype=np.float64,order='C')
1981
+ cam=self.VISpar.cam-1
1982
+ X=mapFun.worldToImg(points_array,cam,None)# In output X1 is equal to X if correctly allocated
1983
+
1984
+ self.RF=[]
1985
+ origin=X[0]
1986
+ hp,=self.ui.plot.axes.plot(origin[0], origin[1], 'o', color='darkblue') # 'ko' indica un pallino nero
1987
+ self.RF.append(hp)
1988
+ length=0.25*min([q for q in self.image.shape])
1989
+ qwidth=length/25
1990
+ hwidth=4
1991
+ vnorm = np.linalg.norm(X[2]-origin)
1992
+ #colors=['darkred','darkgreen','darkmagenta']
1993
+ for k in range(1,len(X)-1): #-1 exclude z
1994
+ P=X[k]
1995
+ v=P-origin
1996
+ if vnorm!=0: v=v/vnorm*length
1997
+ hp=self.ui.plot.axes.quiver(origin[0], origin[1], v[0], v[1],
1998
+ color='darkblue',#color=colors[k-1],
1999
+ angles='xy',scale_units='xy',scale=1.0,
2000
+ units='xy',width=qwidth,headwidth=hwidth,headlength=1.25*hwidth,headaxislength=0.75*hwidth,zorder=10)
2001
+ self.RF.append(hp)
2002
+ T=origin+v*1.2
2003
+ ha=self.ui.plot.axes.text(T[0], T[1], f'{labels[k]}', color='darkblue', fontsize=fontPixelSize)
2004
+ self.RF.append(ha)
2005
+ """
2006
+ X[k]=T
2007
+ T=0.5*(X[1]+X[2])
2008
+ T=origin-0.1*(T-origin)
2009
+ ha=self.ui.plot.axes.text(T[0], T[1], f'{labels[0]}', color='darkblue', fontsize=fontPixelSize)
2010
+ self.RF.append(ha)
2011
+ """
2012
+ except Exception as exc:
2013
+ pri.Error.red(f"[VIS] Error while plotting reference frame!\n{traceback.format_exc()}\n")
2014
+ return
2015
+
2016
+ """
2017
+ def getZonaCom(self,c:int):
2018
+ return (min (self.disp.vect.Xinf[c],self.disp.vect.Xsup[c]),
2019
+ min (self.disp.vect.Yinf[c],self.disp.vect.Ysup[c]),
2020
+ max (self.disp.vect.Xinf[c],self.disp.vect.Xsup[c]),
2021
+ max (self.disp.vect.Yinf[c],self.disp.vect.Ysup[c]))
2022
+ """
2023
+
2024
+ #*************************************************** Menus
2025
+ def contextMenuEvent(self, event):
2026
+ contextMenu = QMenu(self)
2027
+ copy2clipboard = contextMenu.addAction("Copy to clipboard ("+self.QS_copy2clipboard.key().toString(QKeySequence.NativeText)+")")
2028
+ copy2clipboard.setIcon(self.ui.plot.copyIcon)
2029
+ copy2newfig = contextMenu.addAction("Open in new figure ("+self.QS_copy2newfig.key().toString(QKeySequence.NativeText)+")")
2030
+ copy2newfig.setIcon(self.ui.plot.openNewWindowIcon)
2031
+ contextMenu.addSeparator()
2032
+ if len(self.ui.plot.fig2)>0:
2033
+ showAll = contextMenu.addAction("Show all")
2034
+ showAll.setIcon(self.ui.plot.showAllIcon)
2035
+ alignAll = contextMenu.addAction("Align all")
2036
+ alignAll.setIcon(self.ui.plot.alignAllIcon)
2037
+ closeAll = contextMenu.addAction("Close all")
2038
+ closeAll.setIcon(self.ui.plot.closeAllIcon)
2039
+ contextMenu.addSeparator()
1482
2040
  else:
1483
- ndig=0
1484
- if i<0:
1485
- if VISpar_prev.FlagExistMean[0]:
1486
- root_min=myStandardRoot(OUT.path+OUT.subfold+OUT.root)+"_"
1487
- VISpar_prev.nameimga=root_min+"a_min"+INP.pinfo.ext
1488
- VISpar_prev.nameimgb=root_min+"b_min"+INP.pinfo.ext
1489
- VISpar_prev.FlagExistRes[0]=os.path.exists(VISpar_prev.nameimga) or os.path.exists(VISpar_prev.nameimgb)
1490
- else:
1491
- VISpar_prev.FlagExistRes[0]=False
2041
+ showAll = None
2042
+ closeAll= None
2043
+ alignAll= None
2044
+ loadImg = contextMenu.addAction("Load image")
2045
+ loadImg.setIcon(self.ui.plot.loadImageIcon)
2046
+ loadRes = contextMenu.addAction("Load result")
2047
+ loadRes.setIcon(self.ui.plot.loadResultIcon)
1492
2048
 
1493
- if VISpar_prev.FlagExistMean[1]:
1494
- VISpar_prev.nameres=os.path.join(f"{currpath}{root}{outExt}")
1495
- VISpar_prev.FlagExistRes[1]=os.path.exists(VISpar_prev.nameres)
1496
- else:
1497
- VISpar_prev.FlagExistRes[1]=False
2049
+ action = contextMenu.exec(self.mapToGlobal(event.pos()))
2050
+ if action == copy2clipboard:
2051
+ self.ui.plot.copy2clipboard()
2052
+ elif action == copy2newfig:
2053
+ self.ui.plot.copy2newfig(self.ui.name_var.toolTip())
2054
+ elif action == showAll:
2055
+ self.ui.plot.showAll()
2056
+ elif action == closeAll:
2057
+ self.ui.plot.closeAll()
2058
+ elif action == alignAll:
2059
+ self.ui.plot.alignAll()
2060
+ elif action == loadImg:
2061
+ self.load_Img_callback()
2062
+ elif action == loadRes:
2063
+ self.load_Res_callback()
2064
+
2065
+ def loadImg(self,filename=None):
2066
+ if filename is None:
2067
+ filename, _ = QFileDialog.getOpenFileName(self,\
2068
+ "Select an image file of the sequence", filter=text_filter,\
2069
+ options=optionNativeDialog)
1498
2070
  else:
1499
- if len(VISpar_prev.list_Image_Files):
1500
- VISpar_prev.nameimga=INP.path+VISpar_prev.list_Image_Files[i*2]
1501
- VISpar_prev.nameimgb=INP.path+VISpar_prev.list_Image_Files[i*2+1]
1502
- VISpar_prev.FlagExistRes[0]=os.path.exists(VISpar_prev.nameimga) or os.path.exists(VISpar_prev.nameimgb)
1503
- else:
1504
- VISpar_prev.FlagExistRes[0]=False
2071
+ if os.path.exists(filename): filename=None
2072
+ if filename:
2073
+ self.image_file_Load=filename
2074
+ self.image_raw=None
2075
+ self.image=None
1505
2076
 
1506
- if len(VISpar_prev.Tre.list_pim):
1507
- if VISpar_prev.FlagExistMean[1] and VISpar_prev.Tre.list_pim[i]&FLAG_FINALIZED[0]:
1508
- VISpar_prev.nameres=os.path.join(f"{currpath}{root}_{i:0{ndig:d}d}{outExt}")
1509
- VISpar_prev.FlagExistRes[1]=os.path.exists(VISpar_prev.nameres)
1510
- else:
1511
- VISpar_prev.FlagExistRes[1]=False
1512
- else:
1513
- VISpar_prev.FlagExistRes[1]=False
1514
-
1515
- if i<0:
1516
- #self.setMinMaxField()
1517
-
1518
- if VISpar_prev.FlagExistMean[0]:
1519
- Imin=[np.zeros(0),np.zeros(0)]
1520
- currpath=myStandardPath(VISpar_prev.Out.path+VISpar_prev.Out.subfold)
1521
- root=myStandardRoot(VISpar_prev.Out.root)
1522
- ext=VISpar_prev.Inp.pinfo.ext
1523
- for j,f in enumerate('ab'):
1524
- nameout=f"{currpath}{root}_{f}_min{ext}"
1525
- if os.path.exists(nameout):
1526
- try:
1527
- Imin[j]=np.array(Image.open(nameout))
1528
- except Exception as inst:
1529
- pri.Error.red(f"VIS: error opening minimum image {nameout}:\n {traceback.format_exc()}, {inst}")
1530
- self.Imin=Imin
1531
- else:
1532
- self.Imin=[np.zeros(0),np.zeros(0)]
2077
+ self.ui.spin_img.setMinimum(-1)
2078
+ self.VISpar.image_file=''
2079
+ self.VISpar.img=-1
2080
+ self.VISpar.type=0
2081
+ self.VISpar.variable=self.namesPIV.combo_dict[self.namesPIV.img]
2082
+ self.VISpar.variableKey=self.namesPIV.combo_dict_keys[self.VISpar.variable]
1533
2083
 
2084
+ self.FlagResetLevels=self.FlagResetSizes=True
2085
+ self.cleanAxes()
2086
+
2087
+ def loadRes(self):
2088
+ filename, _ = QFileDialog.getOpenFileName(self,\
2089
+ "Select an image file of the sequence", filter="All files (*.mat *.plt);; .mat (*.mat);; .plt (*.plt)",\
2090
+ options=optionNativeDialog)
2091
+ if filename:
2092
+ self.result_file_Load=filename
2093
+ self.result=None
2094
+ self.ui.spin_img.setMinimum(-1)
2095
+ self.VISpar.result_file=''
2096
+ self.VISpar.img=-1
2097
+ self.VISpar.variable=self.namesPIV.combo_dict[self.namesPIV.Mod]
2098
+ self.VISpar.variableKey=self.namesPIV.combo_dict_keys[self.VISpar.variable]
2099
+ self.FlagResetLevels=self.FlagResetSizes=True
2100
+ self.VISpar.type=1
2101
+ self.cleanAxes()
2102
+
2103
+ def create_colormap_image(colormap, width, height, FlagVerticalColormap, imgMapPath):
2104
+ # Create an empty image
2105
+ img = np.zeros((height, width, 3), dtype=np.uint8)
2106
+ # Get the Matplotlib colormap
2107
+ cmap = plt.get_cmap(colormap)
2108
+ # Calculate the colors of the colormap and assign them to the image
2109
+ for y in range(height):
2110
+ for x in range(width):
2111
+ if FlagVerticalColormap:
2112
+ normalized_y = (height-y)/ height
2113
+ color = cmap(normalized_y)
2114
+ else:
2115
+ normalized_x = x / width
2116
+ color = cmap(normalized_x)
2117
+ img[y, x] = [int(c * 255) for c in color[:3]] # Convert colors to range 0-255
2118
+ plt.imsave(imgMapPath, img)
2119
+ pixmap=numpy_to_qpixmap(img)
2120
+ return pixmap
2121
+
2122
+ def numpy_to_qpixmap(img):
2123
+ height, width, channel = img.shape
2124
+ bytes_per_line = 3 * width
2125
+ qimage = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888)
2126
+ qpixmap = QPixmap.fromImage(qimage)
2127
+ return qpixmap
2128
+
2129
+ def create_arrow_pixmap(rgb_color, width, height, path):
2130
+ fig, ax = plt.subplots(figsize=(width / 100, height / 100), dpi=100)
2131
+ ax.axis('off')
2132
+
2133
+ # Calcola la posizione e la direzione della freccia
2134
+ x = width / 8
2135
+ y = height / 2
2136
+ u = width *3/4
2137
+ v = 0
2138
+
2139
+ # Disegna la freccia con quiver
2140
+ ax.quiver(x, y, u, v, color=rgb_color, angles='xy', scale_units='xy', scale=1, width=0.002*width, headwidth=5, headlength=5,headaxislength=3)
2141
+
2142
+ ax.set_xlim(0, width)
2143
+ ax.set_ylim(0, height)
2144
+
2145
+ # Salva l'immagine in un buffer
2146
+ buf = io.BytesIO()
2147
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0, transparent=True)
2148
+ plt.close(fig)
2149
+ buf.seek(0)
2150
+
2151
+ image = Image.open(buf)
2152
+ image.save(path)
2153
+ pixmap=QPixmap(path)
2154
+ return pixmap
1534
2155
 
2156
+
1535
2157
  if __name__ == "__main__":
1536
2158
  import sys
1537
2159
  app=QApplication.instance()
@@ -1543,44 +2165,5 @@ if __name__ == "__main__":
1543
2165
  app.quit()
1544
2166
  app=None
1545
2167
 
1546
- async def plotImg(self,flagImg,flagCLim,flagXLim,flagIW,flagDraw):
1547
- pax=self.ui.plot.axes
1548
-
1549
- if flagImg:
1550
- pax.cla()
1551
- if len(pax.figure.axes)>1:
1552
- try:
1553
- pax.figure.axes[1].remove()
1554
- except:
1555
- pass
1556
- img=getattr(self,['imga','imgb'][self.VISpar.MapVar_type])
1557
- if self.VISpar.flagMIN and len(self.Imin[self.VISpar.MapVar_type])>0\
1558
- and self.VISpar.nfield>-1+imin_im_pair:
1559
- img=img-self.Imin[self.VISpar.MapVar_type]
1560
- self.img=img
1561
- pax.set_title(self.ui.combo_map_var.currentText())
1562
- self.imgshow=pax.imshow(img,
1563
- origin='upper',extent=(0,np.size(img,1),np.size(img,0),0),
1564
- vmin=self.VISpar.vmin,vmax=self.VISpar.vmax)
1565
- self.imgshow.set_cmap(mpl.colormaps['gray'])
1566
- divider = make_axes_locatable(pax)
1567
- cax = divider.append_axes("right", size="5%", pad=0.05)
1568
- cb=pax.figure.colorbar(self.imgshow,cax=cax)
1569
- cb.ax.set_title("I")
1570
-
1571
- if flagCLim:
1572
- self.imgshow.set_clim(self.VISpar.vmin,self.VISpar.vmax)
1573
-
1574
- if flagXLim:
1575
- self.setAxisLim(pax)
1576
- self.Ptoolbar.update()
1577
-
1578
- if flagIW or flagImg:
1579
- self.showRect(pax)
1580
-
1581
- if flagDraw:
1582
- #self.ui.plot.draw()
1583
- self.ui.plot.draw_idle()
1584
2168
 
1585
- if not self.flagInitImg: self.flagInitImg=True
1586
- return self.ui.plot
2169
+