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
@@ -0,0 +1,922 @@
1
+ from .ui_Output_Tab import*
2
+ from .TabTools import *
3
+
4
+ outType_dict={
5
+ '.mat': 'binary (.mat)',
6
+ '.plt': 'tecplot (.plt)',
7
+ #'tecplot (ASCII)': '.plt',
8
+ }
9
+ outType_items=[outType_dict[i] for i in outType_dict]
10
+
11
+ spin_tips={
12
+ 'x' : 'First column of image area to process',
13
+ 'y' : 'First row of image',
14
+ 'w' : 'Width of image area to process',
15
+ 'h' : 'Height of image area to process',
16
+ 'xres' : 'Image resolution along X',
17
+ 'pixAR' : 'Image resolution along Y',
18
+ 'dt' : 'Time delay between frames',
19
+ 'x_min' : 'Minimum x world coordinate',
20
+ 'x_max' : 'Maximum x world coordinate',
21
+ 'y_min' : 'Minimum y world coordinate',
22
+ 'y_max' : 'Maximum y world coordinate',
23
+ 'zconst' : 'Laser plane equation constant',
24
+ 'xterm' : 'Laser plane equation x-slope',
25
+ 'yterm' : 'Laser plane equation y-slope',
26
+ }
27
+ button_tips={
28
+ 'rot_counter' : 'Counterclockwise rotation of image',
29
+ 'rot_clock' : 'Clockwise rotation of image',
30
+ 'mirror_x' : 'Horizontal mirroring of image',
31
+ 'mirror_y' : 'Vertical mirroring of image',
32
+ 'rotv_counter' : 'Counterclockwise rotation of velocity field',
33
+ 'rotv_clock' : 'Clockwise rotation of velocity field',
34
+ 'flip_u' : 'Flip of velocity vectors along X',
35
+ 'flip_v' : 'Flip of velocity vectors along Y',
36
+ 'reset_rot_flip' : 'Reset of rotations and mirroring/flip',
37
+ 'path' : 'Output folder path',
38
+ 'resize' : 'Reset of image sizes',
39
+ 'tool_CollapBox_Flip' : 'Graphics',
40
+ 'CollapBox_Flip' : 'Graphics',
41
+ 'unit' : 'Type of resolution unit',
42
+ 'def_reg' : 'Reset sizes of area to process',
43
+ 'automatic_reshape' : 'Automatic resize/reshape',
44
+ 'read_disp' : 'Read .clz file',
45
+ }
46
+ radio_tips={
47
+ 'Save' : 'Save results',
48
+ 'Same_as_input' : 'Output folder path same as input',
49
+ 'Subfold' : 'Create subfolder',
50
+ }
51
+ check_tips={}
52
+ line_edit_tips={
53
+ 'root' : 'Root of output files',
54
+ 'path' : 'Output folder path',
55
+ 'subfold' : 'Output subfolder path',
56
+ }
57
+ combo_tips={
58
+ 'process' : 'Type of process',
59
+ 'outType' : 'Type of output files',
60
+ }
61
+
62
+ class OUTpar(TABpar):
63
+ FlagAutoReshape = True
64
+
65
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
66
+ self.setup(Process,Step)
67
+ super().__init__('OUTpar','Output')
68
+ self.OptionDone=0
69
+ self.unchecked_fields+=['FlagAutoReshape','OptionValidPath','OptionValidSubFold','OptionValidRoot']
70
+
71
+ def setup(self,Process,Step):
72
+ self.Process = Process
73
+ self.Step = Step
74
+ self.FlagProc = self.Process!=StepTypes.min
75
+ self.FlagCalib = self.Process not in ProcessTypes.singleCamera
76
+
77
+ self.FlagSave = True
78
+ self.root = 'out'
79
+ self.OptionValidRoot = 1
80
+ self.outType = 0
81
+ self.FlagSame_as_input = True
82
+ self.path = basefold
83
+ self.inputPath = basefold
84
+ self.OptionValidPath = 1
85
+
86
+ self.FlagSubfold = True
87
+ self.subfold = 'out_PaIRS/'
88
+ self.userSubfold = self.subfold
89
+ self.OptionValidSubFold = 1
90
+
91
+ self.imageFile = None
92
+ self.imageFileMin = None
93
+ self.OptionValidMin = 1
94
+ self.x = 0
95
+ self.y = 0
96
+ self.w = 1
97
+ self.h = 1
98
+ self.W = 1
99
+ self.H = 1
100
+
101
+ self.aimop = [0]
102
+ self.bimop = [0]
103
+ self.vecop = [0]
104
+
105
+ self.xres = float(1.000)
106
+ self.pixAR = float(1.000)
107
+ self.dt = float(1000)
108
+ self.unit = False #Step not in (StepTypes.disp,StepTypes.spiv)
109
+ self.res = float(0.0)
110
+
111
+ self.def_reg = [float(-20), float(20), float(-20), float(20)]
112
+ self.x_min = float(-50)
113
+ self.x_max = float(+50)
114
+ self.y_min = float(-50)
115
+ self.y_max = float(+50)
116
+ self.FlagWarnCR = False
117
+ self.warnCR = ''
118
+
119
+ self.zconst = 0.0
120
+ self.xterm = 0.0
121
+ self.yterm = 0.0
122
+ self.FlagDISP = Step==StepTypes.disp
123
+
124
+ class Output_Tab(gPaIRS_Tab):
125
+ class Export_Tab_signals(gPaIRS_Tab.Tab_Signals):
126
+ pass
127
+
128
+ def __init__(self,parent: QWidget =None, flagInit= __name__ == "__main__"):
129
+ super().__init__(parent,Ui_OutputTab,OUTpar)
130
+ self.signals=self.Export_Tab_signals(self)
131
+
132
+ #------------------------------------- Graphical interface: widgets
133
+ self.TABname='Output'
134
+ self.ui: Ui_OutputTab
135
+ ui=self.ui
136
+ ui.spin_x.addwid=[ui.spin_w]
137
+ ui.spin_y.addwid=[ui.spin_h]
138
+ ui.combo_outType.clear()
139
+ for item in outType_dict.values():
140
+ ui.combo_outType.addItem(item)
141
+
142
+ #necessary to change the name and the order of the items
143
+ for g in list(globals()):
144
+ if '_items' in g or '_ord' in g or '_tips' in g:
145
+ #pri.Info.blue(f'Adding {g} to {self.name_tab}')
146
+ setattr(self,g,eval(g))
147
+
148
+ if __name__ == "__main__":
149
+ self.app=app
150
+ setAppGuiPalette(self)
151
+
152
+ #------------------------------------- Graphical interface: miscellanea
153
+ self.pixmap_x = QPixmap(''+ icons_path +'redx.png')
154
+ self.pixmap_v = QPixmap(''+ icons_path +'greenv.png')
155
+ self.pixmap_wait = QPixmap(''+ icons_path +'sandglass.png')
156
+ self.pixmap_warn = QPixmap(u""+ icons_path +"warning.png")
157
+
158
+ self.aim_qtim=ImageQt(''+ icons_path +'axes.png')
159
+ self.bim_qtim=ImageQt(''+ icons_path +'background.png')
160
+ self.vim_qtim=ImageQt(''+ icons_path +'background_vectors.png')
161
+
162
+
163
+ self.aim_qtim=ImageQt(''+ icons_path +'axes.png')
164
+ self.bim_qtim=ImageQt(''+ icons_path +'background.png')
165
+ self.vim_qtim=ImageQt(''+ icons_path +'background_vectors.png')
166
+ self.image_labels=[None,ImageQt(''+ icons_path +'rotate_counter.png'),
167
+ ImageQt(''+ icons_path +'mirror_x.png'),ImageQt(''+ icons_path +'mirror_y.png'),
168
+ ImageQt(''+ icons_path +'rotate_clock.png')]
169
+ self.velocity_labels=[None,ImageQt(''+ icons_path +'rotate_v_counter.png'),
170
+ ImageQt(''+ icons_path +'mirror_u.png'),ImageQt(''+ icons_path +'mirror_v.png'),
171
+ ImageQt(''+ icons_path +'rotate_v_clock.png')]
172
+
173
+ aim,bim,vim=self.getQPixmap()
174
+ self.ui.aim.setPixmap(aim)
175
+ self.ui.aim_2.setPixmap(aim)
176
+ self.ui.aim_3.setPixmap(aim)
177
+ self.ui.bim.setPixmap(vim)
178
+ self.ui.bim_2.setPixmap(bim)
179
+ self.ui.bim_3.setPixmap(vim)
180
+
181
+ self.rotate_counter = QTransform().rotate(-90)
182
+ self.rotate_clock = QTransform().rotate(+90)
183
+ self.mirror_x = QTransform().scale(1,-1)
184
+ self.mirror_y = QTransform().scale(-1,1)
185
+
186
+ self.CollapBox_Flip_height=self.ui.CollapBox_Flip.minimumHeight()
187
+ self.w_Flip_Image_height=self.ui.w_Flip_Image.minimumHeight()
188
+
189
+ #self.ui.label_WarnCR.setPixmap( self.pixmap_warn )
190
+
191
+ #------------------------------------- Declaration of parameters
192
+ self.OUTpar_base=OUTpar()
193
+ self.OUTpar:OUTpar=self.TABpar
194
+ self.OUTpar_old:OUTpar=self.TABpar_old
195
+
196
+ #------------------------------------- Callbacks
197
+ self.defineWidgets()
198
+ self.setupWid() #---------------- IMPORTANT
199
+
200
+ #self.defineActions()
201
+ self.defineReshapeButtonActions()
202
+ self.ui.spin_xres.valueChanged.connect(lambda v: self.resLabelLayout())
203
+ self.ui.spin_pixAR.valueChanged.connect(lambda v:self.resLabelLayout())
204
+ self.ui.spin_dt.valueChanged.connect(lambda v: self.resLabelLayout())
205
+
206
+ self.defineCallbacks()
207
+ self.connectCallbacks()
208
+ #self.defineAdditionalCallbacks()
209
+
210
+ #self.defineSet()
211
+ self.defineSettings()
212
+
213
+ self.adjustTABpar=self.adjustOUTpar
214
+ self.setTABlayout=self.setOUTlayout
215
+ self.checkTABpar=self.checkOUTpar
216
+ self.setTABwarn=self.setOUTwarn
217
+
218
+ #------------------------------------- Initializing
219
+ if flagInit:
220
+ self.initialize()
221
+ #else:
222
+ # self.setTABpar(FlagBridge=False)
223
+
224
+ def initialize(self):
225
+ pri.Info.yellow(f'{"*"*20} OUTPUT initialization {"*"*20}')
226
+ self.OUTpar.Process = ProcessTypes.piv
227
+ self.OUTpar.w=self.OUTpar.h=self.OUTpar.W=self.OUTpar.H=1000
228
+ self.setTABpar(FlagBridge=False)
229
+
230
+ #*************************************************** Rotation and flip
231
+ def getQPixmap(self):
232
+ aim=QPixmap.fromImage(self.aim_qtim)
233
+ bim=QPixmap.fromImage(self.bim_qtim)
234
+ vim=QPixmap.fromImage(self.vim_qtim)
235
+ return aim, bim, vim
236
+
237
+ def RotMirror(self,addop):
238
+ if addop[0]!=0:
239
+ self.OUTpar.aimop=self.OUTpar.aimop+[addop[0]]
240
+ Itransf=np.eye(2,2)
241
+ Itransf=self.imTransf_op2I(Itransf,self.OUTpar.aimop,False)
242
+ self.OUTpar.aimop=self.imTransf_I2op(Itransf)
243
+ if addop[1]!=0:
244
+ self.OUTpar.bimop=self.OUTpar.bimop+[addop[1]]
245
+ Itransf=np.eye(2,2)
246
+ Itransf=self.imTransf_op2I(Itransf,self.OUTpar.bimop,False)
247
+ self.OUTpar.bimop=self.imTransf_I2op(Itransf)
248
+ self.OUTpar.vecop=self.OUTpar.bimop+self.OUTpar.aimop
249
+ Itransf=np.eye(2,2)
250
+ Itransf=self.imTransf_op2I(Itransf,self.OUTpar.vecop,False)
251
+ self.OUTpar.vecop=self.imTransf_I2op(Itransf)
252
+
253
+ def RotMirror_Pixmaps(self):
254
+ #aim_qtim,bim_qtim,aim_rot,bim_rot,v_rot,vmat_rot = self.allocateQPixmap()
255
+ _,bim_rot,vim_rot = self.getQPixmap()
256
+ opList=[self.OUTpar.bimop,self.OUTpar.vecop]
257
+ labList=[self.ui.bim_2,self.ui.bim_3]
258
+ imList=[bim_rot,vim_rot]
259
+
260
+ for ops,lab,im in zip(opList,labList,imList):
261
+ for _,op in enumerate(ops):
262
+ if op==1:
263
+ im=im.transformed(self.rotate_counter)
264
+ elif op==-1:
265
+ im=im.transformed(self.rotate_clock)
266
+ elif op==3:
267
+ im=im.transformed(self.mirror_x)
268
+ elif op==2:
269
+ im=im.transformed(self.mirror_y)
270
+ geom=lab.geometry()
271
+ geom.setWidth(im.width())
272
+ geom.setHeight(im.height())
273
+ geom.setY(lab.parentWidget().maximumHeight()-im.height()-5)
274
+ lab.setMinimumSize(im.width(),im.height())
275
+ lab.setMaximumSize (im.width(),im.height())
276
+ lab.setGeometry(geom)
277
+ lab.setPixmap(im)
278
+
279
+ opList=[self.OUTpar.bimop,self.OUTpar.aimop]
280
+ imageList=[self.image_labels,self.velocity_labels]
281
+ nList=[2,3]
282
+ for ops,image_labels,n in zip(opList,imageList,nList):
283
+ cont=0
284
+ for k,op in enumerate(ops):
285
+ if op:
286
+ cont+=1
287
+ lab:QLabel=getattr(self.ui,f'lab_op{k+1}_{n}')
288
+ lab.setPixmap(QPixmap.fromImage(image_labels[op]))
289
+ for j in range(cont,3):
290
+ lab:QLabel=getattr(self.ui,f'lab_op{j+1}_{n}')
291
+ lab.setPixmap(QPixmap())
292
+ if cont:
293
+ getattr(self.ui,f'lab_op{0}_{n}').hide()
294
+ else:
295
+ getattr(self.ui,f'lab_op{0}_{n}').show()
296
+ return
297
+
298
+ def imTransf_op2I(self,I,op,flagInv):
299
+ for i in range(len(op)):
300
+ if op[i]==1: #rotation counter
301
+ I=self.matRot90(I.copy(),flagInv)
302
+ elif op[i]==-1: #clock
303
+ I=self.matRot90(I.copy(), not flagInv)
304
+ elif op[i]==3 or op[i]==2:
305
+ I=self.matMirror(I.copy(),op[i]-2)
306
+ return I
307
+
308
+ def matRot90(self,I,flagInv):
309
+ #RH =(I[0,0]==I[1,1]) and (I[0,1]==-I[1,0])
310
+ #if not RH: flagInv= not flagInv
311
+ if not flagInv: #direct counter
312
+ a=I[0:np.size(I,0),0].copy()
313
+ I[0:np.size(I,0),0]=-I[0:np.size(I,0),1]
314
+ I[0:np.size(I,0),1]=+a
315
+ else:
316
+ a=I[0:np.size(I,0),0].copy()
317
+ I[0:np.size(I,0),0]=+I[0:np.size(I,0),1]
318
+ I[0:np.size(I,0),1]=-a
319
+ return I
320
+
321
+ def matMirror(self,I,ind):
322
+ #ind=1 mirror_x, ind=0 mirror_y
323
+ I[0:np.size(I,0),ind]=-I[0:np.size(I,0),ind]
324
+ return I
325
+
326
+ def imTransf_I2op(self,I):
327
+ op=[0]
328
+ RHim= I[0,0]==I[1,1] and I[1,0]==-I[0,1]
329
+ if RHim:
330
+ if I[0,0]==1: op=[0]
331
+ elif I[0,0]==-1: op=[1,1]
332
+ elif I[0,1]==1: op=[1]
333
+ elif I[0,1]==-1: op=[-1]
334
+ else:
335
+ if I[0,0]==1: op=[3]
336
+ elif I[0,0]==-1: op=[2]
337
+ elif I[0,1]==1: op=[1,2]
338
+ elif I[0,1]==-1: op=[1,3]
339
+ return op
340
+
341
+ def defineReshapeButtonActions(self):
342
+ self.button_rot_counter_action=lambda: self.RotMirror([0,1])
343
+ self.button_rot_clock_action=lambda: self.RotMirror([0,-1])
344
+ self.button_mirror_x_action=lambda: self.RotMirror([0,3])
345
+ self.button_mirror_y_action=lambda: self.RotMirror([0,2])
346
+ self.button_rotv_counter_action=lambda: self.RotMirror([1,0])
347
+ self.button_rotv_clock_action=lambda: self.RotMirror([-1,0])
348
+ self.button_flip_v_action=lambda: self.RotMirror([3,0])
349
+ self.button_flip_u_action=lambda: self.RotMirror([2,0,2])
350
+
351
+ def button_reset_rot_flip_action(self):
352
+ self.OUTpar.aimop=[0]
353
+ self.OUTpar.bimop=[0]
354
+ self.OUTpar.vecop=[0]
355
+ self.RotMirror([-2,-2,-2])
356
+
357
+ def button_automatic_reshape_action(self):
358
+ OUTpar.FlagAutoReshape=self.ui.button_automatic_reshape.isChecked()
359
+ return True
360
+
361
+ def button_automatic_reshape_set(self):
362
+ self.ui.button_automatic_reshape.setChecked(OUTpar.FlagAutoReshape)
363
+ return True
364
+
365
+ #*************************************************** Adjusting parameters
366
+ def adjustOUTpar(self):
367
+ self.OUTpar.FlagProc=self.OUTpar.Process!=ProcessTypes.min
368
+ self.OUTpar.FlagCalib=self.OUTpar.Process not in ProcessTypes.singleCamera
369
+ if self.OUTpar.FlagSame_as_input: self.OUTpar.path=self.OUTpar.inputPath
370
+
371
+ self.OUTpar.path=myStandardPath(self.OUTpar.path)
372
+ if self.OUTpar.FlagSubfold:
373
+ self.OUTpar.subfold=myStandardPath(self.OUTpar.subfold)
374
+ self.OUTpar.userSubfold=self.OUTpar.subfold
375
+ else:
376
+ self.OUTpar.subfold=''
377
+ #else:
378
+ # self.OUTpar.subfold=''
379
+ self.OUTpar.root=myStandardRoot(self.OUTpar.root)
380
+
381
+ if self.OUTpar.imageFile: self.OUTpar.W,self.OUTpar.H=self.get_image_dimensions(self.OUTpar.inputPath+self.OUTpar.imageFile)
382
+ if (self.OUTpar.isDifferentFrom(self.OUTpar_old,fields=['W','H','inputPath']) and self.OUTpar.ind[:-1]==self.OUTpar_old.ind[:-1] and OUTpar.FlagAutoReshape) or (self.OUTpar_old.imageFile is None and self.OUTpar.W>0 and self.OUTpar.H>0):
383
+ self.button_resize_action()
384
+ self.button_reset_rot_flip_action()
385
+
386
+ #if self.OUTpar.isDifferentFrom(self.OUTpar_old,fields=['x_min','x_max','y_min','y_max']) or not self.OUTpar.FlagInit:
387
+ if self.OUTpar.Step in (StepTypes.disp,StepTypes.spiv):
388
+ if self.OUTpar.unit: self.OUTpar.xres=float(1)
389
+ else: self.OUTpar.xres=self.OUTpar.res
390
+
391
+ self.checkOUTpar()
392
+ return
393
+
394
+ def checkOUTpar(self,ind=None):
395
+ if ind is None: OUT:OUTpar=self.OUTpar
396
+ else: OUT:OUTpar=self.TABpar_at(ind)
397
+ self.setOptionValidPath(ind)
398
+ self.setOptionValidSubFold(ind)
399
+ self.setOptionValidRoot(ind)
400
+ self.checkMinCompatibility(ind)
401
+ self.checkCommonRegion(ind)
402
+ OUT.OptionDone=1 if OUT.OptionValidPath==1 and OUT.OptionValidSubFold in (1,-1) and OUT.OptionValidRoot==1 and OUT.OptionValidMin==1 and not OUT.FlagWarnCR else 0 if OUT.OptionValidPath==0 or OUT.OptionValidSubFold==0 or OUT.OptionValidRoot in (0,-1) or OUT.OptionValidMin==0 or OUT.FlagWarnCR else -1
403
+ #pri.Info.blue(f'Output OptionDone = {OUT.OptionDone}')
404
+
405
+ def get_image_dimensions(self,file_name):
406
+ try:
407
+ # Attempt to open the image file
408
+ with Image.open(file_name) as img:
409
+ # Get image dimensions
410
+ width, height = img.size
411
+ return [width,height]
412
+ except IOError:
413
+ # Handle the case where the file is not a valid image
414
+ return [0,0]
415
+
416
+ def checkMinCompatibility(self,ind):
417
+ if ind is None:
418
+ OUT:OUTpar=self.OUTpar
419
+ ind=OUT.ind
420
+ else: OUT:OUTpar=self.TABpar_at(ind)
421
+
422
+ if OUT.Step!=StepTypes.min and OUT.imageFile is not None and OUT.imageFileMin is not None and self.get_image_dimensions(OUT.inputPath+OUT.imageFile)!=self.get_image_dimensions(OUT.imageFileMin):
423
+ OUT.OptionValidMin=0
424
+ else:
425
+ OUT.OptionValidMin=1
426
+
427
+ def checkCommonRegion(self,ind=None):
428
+ if ind is None:
429
+ OUT:OUTpar=self.OUTpar
430
+ if OUT.Step==StepTypes.disp:
431
+ PRO=self.gui.w_Process_Disp.PROpar
432
+ elif OUT.Step in (StepTypes.piv,StepTypes.spiv):
433
+ PRO=self.gui.w_Process.PROpar
434
+ else:
435
+ PRO=None
436
+ ind=OUT.ind
437
+ else:
438
+ OUT:OUTpar=self.TABpar_at(ind)
439
+ if OUT.Step==StepTypes.disp:
440
+ PRO=self.gui.w_Process_Disp.TABpar_at(ind)
441
+ elif OUT.Step in (StepTypes.piv,StepTypes.spiv):
442
+ PRO=self.gui.w_Process.TABpar_at(ind)
443
+ else:
444
+ PRO=None
445
+
446
+ OUT.FlagWarnCR=False
447
+ OUT.warnCR=''
448
+ if OUT.Step==StepTypes.piv:
449
+ errorString=''
450
+ Vect=[v[0] for v in PRO.Vect]
451
+
452
+ nMin=2
453
+ W=OUT.w
454
+ H=OUT.h
455
+ DueDistBordoW=Vect[2] if not PRO.FlagBordo else Vect[3]*2
456
+ DueDistBordoH=Vect[0] if not PRO.FlagBordo else Vect[1]*2
457
+ DX=W-DueDistBordoW
458
+ DY=H-DueDistBordoH
459
+ #if W*0.5<Vect[2] or H*0.5<Vect[0]:
460
+ # errorString='Processing image region too small to accommodate the selected interrogation windows! Expand the processing image region or reduce the size of the interrogation windows. The size of the interrogation window should not exceed the half of the image size in order to have at least 2 vectors in the x and/ y directions.'
461
+ if int(DX/Vect[3])<nMin-1 or int(DY/Vect[1])<nMin-1:
462
+ errorString=f'Processing image region is too small to contain at least {nMin} vectors in the x and/or y direction! Expand the processing image region or decrease the spacing of the interrogation windows! Please also notice that the "First vector at ↓" flag in the Interrogation window box of the Process tab determines the number of vectors in the computed fields.'
463
+ pass
464
+ if errorString:
465
+ errorString='Issue with processing region! ' + errorString
466
+ pri.Callback.white(errorString)
467
+ OUT.FlagWarnCR=True
468
+ OUT.warnCR=errorString
469
+ elif OUT.Step in (StepTypes.disp,StepTypes.spiv):
470
+ if hasattr(self.gui,'ui') and hasattr(self.gui.ui,'Explorer'):
471
+ OUT.res=0.0
472
+ from .procTools import dataTreePar, data2Disp, data2StereoPIV
473
+ procdata:dataTreePar=self.gui.ui.Explorer.ITEfromInd(OUT.ind).procdata
474
+ data=procdata.duplicate()
475
+ data.Process=procdata.Process
476
+ data.Step=procdata.Step
477
+ INP_ind=self.gui.w_Input.TABpar_at(ind)
478
+ OUT_ind=OUT #self.gui.w_Output.TABpar_at(ind)
479
+ PRO_ind=self.gui.w_Process.TABpar_at(ind)
480
+ PRO_Min_ind=self.gui.w_Process_Min.TABpar_at(ind)
481
+ PRO_Disp_ind=self.gui.w_Process_Disp.TABpar_at(ind)
482
+ data.setProc(INP_ind,OUT_ind,PRO_ind,PRO_Min_ind,PRO_Disp_ind)
483
+ try:
484
+ errorString='Error while setting camera calibration parameters! Check if calibration files are not correctly specified or are missing.'
485
+ if OUT.Step==StepTypes.disp: disp=data2Disp(data)
486
+ elif OUT.Step==StepTypes.spiv: disp=data2StereoPIV(data)
487
+ errorString='Error while setting the laser plane equation constants!'
488
+ ve=disp.vect
489
+ ve.PianoLaser[0]=np.float32(OUT.zconst)
490
+ ve.PianoLaser[1]=np.float32(OUT.xterm)
491
+ ve.PianoLaser[2]=np.float32(OUT.yterm)
492
+ errorString='Invalid common region'
493
+ disp.evalCommonZone()
494
+ errorString='Common region incompatible with selected interrogation windows!'
495
+ OUT.res=1./disp.dataProc.RisxRadd
496
+ if OUT.Step==StepTypes.disp:
497
+ Vect=PRO.Vect
498
+ nMin=4
499
+ FlagBordo=False
500
+ else:
501
+ Vect=[v[0] for v in PRO.Vect]
502
+ nMin=2
503
+ FlagBordo=PRO.FlagBordo
504
+
505
+ w=OUT.x_max-OUT.x_min
506
+ h=OUT.y_max-OUT.y_min
507
+ W=w/disp.dataProc.RisxRadd
508
+ H=h/disp.dataProc.RisxRadd
509
+
510
+ DueDistBordoW=Vect[2] if not FlagBordo else Vect[3]*2
511
+ DueDistBordoH=Vect[0] if not FlagBordo else Vect[1]*2
512
+ DX=W-DueDistBordoW
513
+ DY=H-DueDistBordoH
514
+
515
+ #if W*0.5<Vect[2] or H*0.5<Vect[0]:
516
+ # errorString='Common region too small to accommodate the selected interrogation windows! Expand the common region or reduce the size of the interrogation windows. The size of the interrogation window should not exceed the half of the image size in order to have at least 2 vectors in the x and/ y directions.'
517
+ # raise('Common region/IW incompatibility issue')
518
+ if int(DX/Vect[3])<nMin-1 or int(DY/Vect[1])<nMin-1:
519
+ errorString=f'Common region is too small to contain at least {nMin-1 if OUT.Step==StepTypes.disp else nMin} vectors in the x and/or y direction! Expand the common region or decrease the spacing of the interrogation windows. Please also notice that the "First vector at ↓" flag in the Interrogation window box of the Process tab determines the number of vectors in the computed fields.'
520
+ raise('Common region/IW incompatibility issue')
521
+ pass
522
+ except Exception as exc:
523
+ if errorString=='Invalid common region':
524
+ pattern = r'\*+ Error(.*?) \*+'
525
+ matches = re.findall(pattern, str(exc))
526
+ for m,ma in enumerate(matches):
527
+ matches[m]=ma.replace('camera 1','camera 2').replace('camera 0','camera 1')
528
+ if matches:
529
+ errorString+=':\n-'+'\n-'.join(matches)
530
+ if errorString=='Common region incompatible with selected interrogation windows!':
531
+ pri.Error.red(f'{errorString}\n{traceback.format_exc()}\n\n')
532
+ pass
533
+ errorString='Issue with physical region! ' + errorString
534
+ pri.Callback.white(errorString)
535
+ OUT.FlagWarnCR=True
536
+ OUT.warnCR=errorString
537
+ if not self.OUTpar.unit: OUT.xres=OUT.res
538
+
539
+ #*************************************************** Layout
540
+ def setOUTlayout(self):
541
+ self.ui.label_process.setVisible(__name__ == "__main__")
542
+ self.ui.combo_process.setVisible(__name__ == "__main__")
543
+
544
+ self.ui.w_combo_outType.setVisible(self.OUTpar.FlagProc and self.OUTpar.Step!=StepTypes.min)
545
+ FlagValidProc=self.OUTpar.FlagProc and self.OUTpar.imageFile is not None
546
+ self.ui.w_FurtherOptions.setVisible(FlagValidProc and self.OUTpar.Step!=StepTypes.min)
547
+ if FlagValidProc:
548
+ self.ui.w_Flip_Mirror.setVisible(not self.OUTpar.FlagCalib)
549
+
550
+ height=self.w_Flip_Image_height-self.ui.w_Flip_Mirror.minimumHeight()*int(self.OUTpar.FlagCalib)
551
+ self.ui.w_Flip_Image.setMinimumHeight(height)
552
+ self.ui.w_Flip_Image.setMaximumHeight(height)
553
+ height=self.CollapBox_Flip_height-self.ui.w_Flip_Mirror.minimumHeight()*int(self.OUTpar.FlagCalib)
554
+ #self.ui.CollapBox_Flip.setMinimumHeight(height)
555
+ #self.ui.CollapBox_Flip.setMaximumHeight(height)
556
+ self.ui.CollapBox_Flip.heightOpened=height
557
+ self.ui.CollapBox_Flip.heightArea=height-self.ui.CollapBox_Flip.toolHeight
558
+ self.ui.CollapBox_Flip.on_click()
559
+ #self.ui.w_Flip_Image.setEnabled(self.OUTpar.FlagDone)
560
+
561
+ self.setMinMaxSpinxywh()
562
+ self.RotMirror_Pixmaps()
563
+ self.resLabelLayout()
564
+
565
+ """
566
+ if self.OUTpar.Step==StepTypes.disp:
567
+ self.ui.w_Resolution.setVisible(False)
568
+ else:
569
+ self.ui.w_Resolution.setVisible(True)
570
+ """
571
+ self.ui.w_Resolution.setVisible(True)
572
+ self.ui.w_dt.setVisible(self.OUTpar.Step!=StepTypes.disp)
573
+ self.ui.w_Res_eff.setVisible(self.OUTpar.Step!=StepTypes.disp)
574
+ self.ui.button_unit.setVisible(self.OUTpar.FlagCalib)
575
+ self.ui.button_unit.setEnabled(self.OUTpar.Step!=StepTypes.disp)
576
+ self.ui.spin_xres.setEnabled(not self.OUTpar.FlagCalib)
577
+ self.ui.w_y_Resolution.setVisible(not self.OUTpar.FlagCalib)
578
+ self.ui.label_x_res.setText('Resolution' if self.OUTpar.FlagCalib else 'X resolution')
579
+
580
+ self.ui.g_CommonRegion.setVisible(self.OUTpar.FlagCalib)
581
+ self.ui.button_def_reg.setVisible(False)
582
+ self.ui.label_WarnCR.setVisible(self.OUTpar.FlagWarnCR)
583
+ #self.check_def_reg()
584
+
585
+ self.ui.g_laser_plane_eq.setVisible(self.OUTpar.Step in (StepTypes.disp,StepTypes.spiv))
586
+ self.ui.g_laser_plane_eq.setEnabled(not self.OUTpar.FlagDISP or self.OUTpar.Step==StepTypes.disp)
587
+
588
+ self.ui.w_SaveResults.setVisible(self.OUTpar.FlagSave)
589
+ self.ui.w_OutputFold_Button.setVisible(self.OUTpar.FlagSave)
590
+ self.ui.w_OutputSubfold.setVisible(self.OUTpar.FlagSave)
591
+ self.ui.label_path.setEnabled(not self.OUTpar.FlagSame_as_input)
592
+ self.ui.w_edit_path.setEnabled(not self.OUTpar.FlagSame_as_input)
593
+ self.ui.w_button_path.setEnabled(not self.OUTpar.FlagSame_as_input)
594
+ self.ui.w_OutputSubfold_name.setVisible(self.OUTpar.FlagSubfold)
595
+
596
+ self.setRootLabel()
597
+ self.setPathLabel()
598
+ self.setSubFoldLabel()
599
+
600
+ self.checkOUTpar()
601
+ self.setOUTwarn()
602
+ self.setTABWarnLabel()
603
+ self.ui.label_WarnCR.setToolTip(self.OUTpar.warnCR)
604
+ self.ui.label_WarnCR.setStatusTip(self.ui.label_WarnCR.toolTip())
605
+ return
606
+
607
+ def setOUTwarn(self,ind=None):
608
+ if ind is None: OUT:OUTpar=self.OUTpar
609
+ else: OUT:OUTpar=self.TABpar_at(ind)
610
+
611
+ if OUT.OptionDone==1:
612
+ OUT.warningMessage='Output paths correctly identified!'
613
+ else:
614
+ warningMessage=''
615
+ if not OUT.OptionValidPath:
616
+ warningMessage+=self.setPathLabel(ind)
617
+ if not OUT.OptionValidSubFold:
618
+ if warningMessage: warningMessage+='\n* '
619
+ warningMessage+=self.setSubFoldLabel(ind)
620
+ if not OUT.OptionValidRoot==1:
621
+ if warningMessage: warningMessage+='\n* '
622
+ warningMessage+=self.setRootLabel(ind)
623
+ if not OUT.OptionValidMin==1:
624
+ if warningMessage: warningMessage+='\n* '
625
+ warningMessage+='Sizes of historical minimum background image incompatible with current image set!'
626
+ if OUT.FlagWarnCR:
627
+ if warningMessage: warningMessage+='\n* '
628
+ warningMessage+=OUT.warnCR
629
+ if '\n* ' in warningMessage: warningMessage='* '+warningMessage
630
+ OUT.warningMessage=warningMessage
631
+
632
+ #*************************************************** Mode
633
+ #******************** Actions
634
+ def combo_process_action(self):
635
+ current_ind=self.ui.combo_process.currentIndex()
636
+ self.OUTpar.Process=list(process)[current_ind]
637
+
638
+ #******************** Set
639
+ def combo_process_set(self):
640
+ current_proc=process[self.OUTpar.Process]
641
+ self.ui.combo_process.setCurrentIndex(process_items.index(current_proc))
642
+
643
+ #*************************************************** Resolution
644
+ #******************** Actions
645
+ def button_unit_action(self):
646
+ self.OUTpar.unit=self.ui.button_unit.isChecked()
647
+
648
+ #******************** Settings
649
+ def button_unit_set(self):
650
+ self.ui.button_unit.setChecked(self.OUTpar.unit)
651
+ if not self.OUTpar.unit:
652
+ text='Physical units'
653
+ else:
654
+ text='Pixel units'
655
+ self.ui.button_unit.setText(text)
656
+
657
+ #******************** Layout
658
+ def resLabelLayout(self,FlagSet=False):
659
+ dt=self.OUTpar.dt if FlagSet else self.ui.spin_dt.value()
660
+ xres=self.OUTpar.xres if FlagSet else self.ui.spin_xres.value()
661
+ #xres=max([xres,0.0000001])
662
+ if self.OUTpar.Process==ProcessTypes.piv:
663
+
664
+ pixAR=self.OUTpar.pixAR if FlagSet else self.ui.spin_pixAR.value()
665
+
666
+ Velx=float(1000/(xres*dt)) if xres else None
667
+ Vely=float(Velx/pixAR) if xres else None
668
+ self.ui.label_Res_x.setText(f"X: {Velx:.6g} m/s" if Velx else "X: -")
669
+ self.ui.label_Res_y.setText(f"Y: {Vely:.6g} m/s" if Vely else "Y: -")
670
+ else:
671
+ Velx=float(1000/(xres*dt)) if xres else None
672
+ self.ui.label_Res_x.setText(f" {Velx:.6g} m/s" if Velx else f" -")
673
+ self.ui.label_Res_y.setText(f"")
674
+ adjustFont(self.ui.label_Res_x)
675
+ adjustFont(self.ui.label_Res_y)
676
+
677
+ #*************************************************** Common Region
678
+ #******************** Actions
679
+ def button_def_reg_action(self):
680
+ self.OUTpar.x_min=self.OUTpar.def_reg[0]
681
+ self.OUTpar.x_max=self.OUTpar.def_reg[1]
682
+ self.OUTpar.y_min=self.OUTpar.def_reg[2]
683
+ self.OUTpar.y_max=self.OUTpar.def_reg[3]
684
+
685
+ #******************** Layout
686
+ def check_def_reg(self):
687
+ FlagHidden=self.OUTpar.x_min==self.OUTpar.def_reg[0] and self.OUTpar.x_max==self.OUTpar.def_reg[1] and self.OUTpar.y_min==self.OUTpar.def_reg[2] and self.OUTpar.y_max==self.OUTpar.def_reg[3]
688
+ self.ui.button_def_reg.setVisible(not FlagHidden)
689
+
690
+ #*************************************************** Laser Plane constants
691
+ #******************** Actions
692
+ def button_read_disp_action(self):
693
+ dispName, _ = QFileDialog.getOpenFileName(self,\
694
+ "Select a laser plane equation file", filter=f'*.clz',\
695
+ dir=self.OUTpar.inputPath,\
696
+ options=optionNativeDialog)
697
+ if not dispName: return
698
+ if os.path.exists(dispName):
699
+ PianoLaser=self.readLaserPlaneConst(dispName)
700
+ self.OUTpar.zconst=PianoLaser[0]
701
+ self.OUTpar.xterm=PianoLaser[1]
702
+ self.OUTpar.yterm=PianoLaser[2]
703
+
704
+ def readLaserPlaneConst(self, filename: str):
705
+ try:
706
+ with open(filename, "r") as cfg:
707
+ lines = cfg.readlines()
708
+ planeConst = [
709
+ float(lines[3].strip().rstrip(',')),
710
+ float(lines[4].strip().rstrip(',')),
711
+ float(lines[5].strip().rstrip(','))
712
+ ]
713
+ return planeConst
714
+
715
+ except Exception as inst:
716
+ errorPrint = f"\n!!!!!!!!!! Error while reading the file:\n{str(inst)}\n"
717
+ return [0.0,0.0,0.0]
718
+
719
+ #*************************************************** Edit root
720
+ #******************** Actions
721
+ def line_edit_root_changing(self):
722
+ self.ui.label_check_root.setPixmap(QPixmap())
723
+
724
+ def line_edit_root_preaction(self):
725
+ entry=myStandardRoot(self.ui.line_edit_root.text())
726
+ self.ui.line_edit_root.setText(entry)
727
+
728
+ #******************** Settings
729
+ def setRootLabel(self,ind=None):
730
+ if ind is None: OUT:OUTpar=self.OUTpar
731
+ else: OUT:OUTpar=self.TABpar_at(ind)
732
+ #Clickable label: no need for setStatusTip
733
+ if OUT.OptionValidRoot==-2:
734
+ message="Files with the same root name already exist in the selected output folder!"
735
+ pixmap=self.pixmap_warn
736
+ elif OUT.OptionValidRoot==-1:
737
+ pixmap=self.pixmap_warn
738
+ message="It was not possible to create the specified output folder!"
739
+ elif OUT.OptionValidRoot==0:
740
+ pixmap=self.pixmap_x
741
+ message="The root of the output filenames is not admitted!"
742
+ if OUT.OptionValidRoot==1:
743
+ pixmap=self.pixmap_v
744
+ message="The root of the output filenames is admitted!"
745
+ if ind is None:
746
+ self.ui.label_check_root.setPixmap(pixmap)
747
+ self.ui.label_check_root.setToolTip(message)
748
+ return message
749
+
750
+ #******************** Layout
751
+ def setOptionValidRoot(self,ind=None):
752
+ if ind is None: OUT:OUTpar=self.OUTpar
753
+ else: OUT:OUTpar=self.TABpar_at(ind)
754
+
755
+ if OUT.Step == StepTypes.min:
756
+ ext='_min.png'
757
+ else:
758
+ ext=list(outType_dict)[OUT.outType]
759
+ FlagExistPath=False
760
+ FlagCreateSubFold=False
761
+ if OUT.OptionValidPath:
762
+ currpath=myStandardPath(OUT.path)
763
+ if OUT.OptionValidSubFold:
764
+ currpath=myStandardPath(currpath+OUT.subfold)
765
+ if OUT.OptionValidSubFold==1: FlagCreateSubFold=not os.path.exists(currpath)
766
+ elif OUT.OptionValidSubFold==-1: FlagExistPath=True
767
+ else:
768
+ currpath='./'
769
+ pattern=myStandardRoot(currpath+OUT.root)+'*'+ext
770
+ FlagExist=False
771
+ if FlagExistPath:
772
+ files=findFiles_sorted(pattern)
773
+ FlagExist=len(files)>0
774
+ if FlagExist:
775
+ OUT.OptionValidRoot=-2
776
+ else:
777
+ try:
778
+ if FlagCreateSubFold:
779
+ os.mkdir(currpath)
780
+ FlagDeleteSubFold=True
781
+ else:
782
+ FlagDeleteSubFold=False
783
+ except:
784
+ FlagDeleteSubFold=False
785
+ OUT.OptionValidRoot=-1
786
+ else:
787
+ try:
788
+ filename=pattern.replace('*','a0')+'.delmeplease'
789
+ open(filename,'w')
790
+ except:
791
+ FlagDeleteFile=False
792
+ OUT.OptionValidRoot=0
793
+ else:
794
+ FlagDeleteFile=True
795
+ OUT.OptionValidRoot=1
796
+ finally:
797
+ if FlagDeleteFile:
798
+ os.remove(filename)
799
+ finally:
800
+ if FlagDeleteSubFold:
801
+ os.rmdir(currpath)
802
+
803
+ #*************************************************** Edit path
804
+ #******************** Actions
805
+ def radio_Same_as_input_action(self):
806
+ self.OUTpar.path=self.OUTpar.inputPath
807
+
808
+ def line_edit_path_changing(self):
809
+ self.ui.label_check_path.setPixmap(QPixmap())
810
+
811
+ def line_edit_path_preaction(self):
812
+ currpath=myStandardPath(self.ui.line_edit_path.text())
813
+ currpath=relativizePath(currpath)
814
+ self.ui.line_edit_path.setText(currpath)
815
+
816
+ def button_path_action(self):
817
+ directory = str(QFileDialog.getExistingDirectory(self,\
818
+ "Choose an output folder", dir=self.OUTpar.path,options=optionNativeDialog))
819
+ currpath='{}'.format(directory)
820
+ if not currpath=='':
821
+ self.ui.line_edit_path.setText(currpath)
822
+ self.line_edit_path_preaction()
823
+ self.OUTpar.path=self.ui.line_edit_path.text()
824
+
825
+ #******************** Settings
826
+ def setPathLabel(self,ind=None):
827
+ if ind is None: OUT:OUTpar=self.OUTpar
828
+ else: OUT:OUTpar=self.TABpar_at(ind)
829
+ #Clickable label: no need for setStatusTip
830
+ if OUT.OptionValidPath:
831
+ pixmap=self.pixmap_v
832
+ message="The specified path of the output folder exists!"
833
+ else:
834
+ pixmap=self.pixmap_x
835
+ message="The specified path of the output folder does not exist!"
836
+ if ind is None:
837
+ self.ui.label_check_path.setPixmap(pixmap)
838
+ self.ui.label_check_path.setToolTip(message)
839
+ return message
840
+
841
+ #******************** Layout
842
+ def setOptionValidPath(self,ind=None):
843
+ if ind is None: OUT:OUTpar=self.OUTpar
844
+ else: OUT:OUTpar=self.TABpar_at(ind)
845
+ OUT.OptionValidPath=int(os.path.exists(OUT.path))
846
+
847
+ #*************************************************** Edit subfold
848
+ #******************** Actions
849
+ def radio_Subfold_action(self):
850
+ if not self.OUTpar.subfold and self.OUTpar.FlagSubfold:
851
+ self.OUTpar.subfold=self.OUTpar.userSubfold
852
+
853
+ def line_edit_subfold_changing(self):
854
+ self.ui.label_check_path_subfold.setPixmap(QPixmap())
855
+
856
+ def line_edit_subfold_preaction(self):
857
+ entry=myStandardPath(self.ui.line_edit_subfold.text())
858
+ self.ui.line_edit_subfold.setText(entry)
859
+
860
+ def line_edit_subfold_action(self):
861
+ self.setOptionValidSubFold()
862
+
863
+ #******************** Settings
864
+ def setSubFoldLabel(self,ind=None):
865
+ if ind is None: OUT:OUTpar=self.OUTpar
866
+ else: OUT:OUTpar=self.TABpar_at(ind)
867
+
868
+ """
869
+ if OUT.OptionValidSubFold==-1:
870
+ pixmap=self.pixmap_warn
871
+ message="Current path already exists! 😰"
872
+ """
873
+ #Clickable label: no need for setStatusTip
874
+ if OUT.OptionValidSubFold==0:
875
+ pixmap=self.pixmap_x
876
+ message="The specified path of the output subfolder is not admitted!"
877
+ elif OUT.OptionValidSubFold in (-1,1):
878
+ pixmap=self.pixmap_v
879
+ message="The specified path of the output subfolder is admitted!"
880
+ if ind is None:
881
+ self.ui.label_check_path_subfold.setPixmap(pixmap)
882
+ self.ui.label_check_path_subfold.setToolTip(message)
883
+ return message
884
+
885
+
886
+ #******************** Layout
887
+ def setOptionValidSubFold(self,ind=None):
888
+ if ind is None: OUT:OUTpar=self.OUTpar
889
+ else: OUT:OUTpar=self.TABpar_at(ind)
890
+ if OUT.OptionValidPath:
891
+ currpath=myStandardPath(OUT.path)
892
+ else:
893
+ currpath='./'
894
+ currpath=myStandardPath(currpath+OUT.subfold)
895
+ if OUT.OptionValidPath and os.path.exists(currpath):
896
+ OUT.OptionValidSubFold=-1
897
+ else:
898
+ if OUT.flagRun>0 and not os.path.exists(currpath):
899
+ OUT.OptionValidSubFold=0
900
+ else:
901
+ try:
902
+ os.mkdir(currpath)
903
+ except:
904
+ FlagDeleteFolder=False
905
+ OUT.OptionValidSubFold=0
906
+ else:
907
+ FlagDeleteFolder=True
908
+ OUT.OptionValidSubFold=1
909
+ finally:
910
+ if FlagDeleteFolder:
911
+ os.rmdir(currpath)
912
+
913
+ if __name__ == "__main__":
914
+ import sys
915
+ app=QApplication.instance()
916
+ if not app:app = QApplication(sys.argv)
917
+ app.setStyle('Fusion')
918
+ object = Output_Tab(None)
919
+ object.show()
920
+ app.exec()
921
+ app.quit()
922
+ app=None