PaIRS-UniNa 0.2.10__cp313-cp313-macosx_11_0_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. PaIRS_UniNa/Calibration_Tab.py +347 -0
  2. PaIRS_UniNa/Changes.txt +174 -0
  3. PaIRS_UniNa/Custom_Top.py +303 -0
  4. PaIRS_UniNa/Explorer.py +3322 -0
  5. PaIRS_UniNa/FolderLoop.py +562 -0
  6. PaIRS_UniNa/Input_Tab.py +829 -0
  7. PaIRS_UniNa/Input_Tab_CalVi.py +787 -0
  8. PaIRS_UniNa/Input_Tab_tools.py +3026 -0
  9. PaIRS_UniNa/Log_Tab.py +110 -0
  10. PaIRS_UniNa/Output_Tab.py +922 -0
  11. PaIRS_UniNa/PaIRS.py +18 -0
  12. PaIRS_UniNa/PaIRS_PIV.py +873 -0
  13. PaIRS_UniNa/PaIRS_pypacks.py +1374 -0
  14. PaIRS_UniNa/Process_Tab.py +1761 -0
  15. PaIRS_UniNa/Process_Tab_CalVi.py +313 -0
  16. PaIRS_UniNa/Process_Tab_Disp.py +170 -0
  17. PaIRS_UniNa/Process_Tab_Min.py +120 -0
  18. PaIRS_UniNa/ResizePopup.py +55 -0
  19. PaIRS_UniNa/SPIVCalHelp.py +155 -0
  20. PaIRS_UniNa/Saving_tools.py +298 -0
  21. PaIRS_UniNa/TabTools.py +1413 -0
  22. PaIRS_UniNa/Vis_Tab.py +2176 -0
  23. PaIRS_UniNa/Vis_Tab_CalVi.py +982 -0
  24. PaIRS_UniNa/Whatsnew.py +130 -0
  25. PaIRS_UniNa/_PaIRS_PIV.so +0 -0
  26. PaIRS_UniNa/__init__.py +6 -0
  27. PaIRS_UniNa/__main__.py +45 -0
  28. PaIRS_UniNa/addwidgets_ps.py +1633 -0
  29. PaIRS_UniNa/calib.py +1488 -0
  30. PaIRS_UniNa/calibView.py +833 -0
  31. PaIRS_UniNa/gPaIRS.py +3957 -0
  32. PaIRS_UniNa/gPalette.py +189 -0
  33. PaIRS_UniNa/icons/abort.png +0 -0
  34. PaIRS_UniNa/icons/about.png +0 -0
  35. PaIRS_UniNa/icons/align_all.png +0 -0
  36. PaIRS_UniNa/icons/announcement.png +0 -0
  37. PaIRS_UniNa/icons/automatic_levels_off.png +0 -0
  38. PaIRS_UniNa/icons/automatic_levels_on.png +0 -0
  39. PaIRS_UniNa/icons/automatic_off.png +0 -0
  40. PaIRS_UniNa/icons/automatic_on.png +0 -0
  41. PaIRS_UniNa/icons/automatic_size_off.png +0 -0
  42. PaIRS_UniNa/icons/automatic_size_on.png +0 -0
  43. PaIRS_UniNa/icons/axes.png +0 -0
  44. PaIRS_UniNa/icons/background.png +0 -0
  45. PaIRS_UniNa/icons/background_vectors.png +0 -0
  46. PaIRS_UniNa/icons/bin_off.png +0 -0
  47. PaIRS_UniNa/icons/bin_on.png +0 -0
  48. PaIRS_UniNa/icons/browse_file_c.png +0 -0
  49. PaIRS_UniNa/icons/browse_folder_c.png +0 -0
  50. PaIRS_UniNa/icons/brush_cursor.png +0 -0
  51. PaIRS_UniNa/icons/bugfix.png +0 -0
  52. PaIRS_UniNa/icons/cal_proc.png +0 -0
  53. PaIRS_UniNa/icons/cal_proc_off.png +0 -0
  54. PaIRS_UniNa/icons/cal_step.png +0 -0
  55. PaIRS_UniNa/icons/cal_step_off.png +0 -0
  56. PaIRS_UniNa/icons/calibrate.png +0 -0
  57. PaIRS_UniNa/icons/calibration_logo.png +0 -0
  58. PaIRS_UniNa/icons/change_folder.png +0 -0
  59. PaIRS_UniNa/icons/change_folder_off.png +0 -0
  60. PaIRS_UniNa/icons/checklist.png +0 -0
  61. PaIRS_UniNa/icons/clean.png +0 -0
  62. PaIRS_UniNa/icons/clean_run.png +0 -0
  63. PaIRS_UniNa/icons/close.png +0 -0
  64. PaIRS_UniNa/icons/close_all.png +0 -0
  65. PaIRS_UniNa/icons/close_project.png +0 -0
  66. PaIRS_UniNa/icons/close_workspace.png +0 -0
  67. PaIRS_UniNa/icons/colormap.png +0 -0
  68. PaIRS_UniNa/icons/colormaps/Accent.png +0 -0
  69. PaIRS_UniNa/icons/colormaps/BrBG.png +0 -0
  70. PaIRS_UniNa/icons/colormaps/Dark2.png +0 -0
  71. PaIRS_UniNa/icons/colormaps/PRGn.png +0 -0
  72. PaIRS_UniNa/icons/colormaps/Paired.png +0 -0
  73. PaIRS_UniNa/icons/colormaps/Pastel1.png +0 -0
  74. PaIRS_UniNa/icons/colormaps/Pastel2.png +0 -0
  75. PaIRS_UniNa/icons/colormaps/PiYG.png +0 -0
  76. PaIRS_UniNa/icons/colormaps/PuOr.png +0 -0
  77. PaIRS_UniNa/icons/colormaps/RdBu.png +0 -0
  78. PaIRS_UniNa/icons/colormaps/RdGy.png +0 -0
  79. PaIRS_UniNa/icons/colormaps/RdYlBu.png +0 -0
  80. PaIRS_UniNa/icons/colormaps/RdYlGn.png +0 -0
  81. PaIRS_UniNa/icons/colormaps/Set1.png +0 -0
  82. PaIRS_UniNa/icons/colormaps/Set2.png +0 -0
  83. PaIRS_UniNa/icons/colormaps/Set3.png +0 -0
  84. PaIRS_UniNa/icons/colormaps/Spectral.png +0 -0
  85. PaIRS_UniNa/icons/colormaps/Wistia.png +0 -0
  86. PaIRS_UniNa/icons/colormaps/afmhot.png +0 -0
  87. PaIRS_UniNa/icons/colormaps/autumn.png +0 -0
  88. PaIRS_UniNa/icons/colormaps/binary.png +0 -0
  89. PaIRS_UniNa/icons/colormaps/blackVector.png +0 -0
  90. PaIRS_UniNa/icons/colormaps/blueVector.png +0 -0
  91. PaIRS_UniNa/icons/colormaps/bone.png +0 -0
  92. PaIRS_UniNa/icons/colormaps/brg.png +0 -0
  93. PaIRS_UniNa/icons/colormaps/bwr.png +0 -0
  94. PaIRS_UniNa/icons/colormaps/cividis.png +0 -0
  95. PaIRS_UniNa/icons/colormaps/cool.png +0 -0
  96. PaIRS_UniNa/icons/colormaps/coolwarm.png +0 -0
  97. PaIRS_UniNa/icons/colormaps/copper.png +0 -0
  98. PaIRS_UniNa/icons/colormaps/cubehelix.png +0 -0
  99. PaIRS_UniNa/icons/colormaps/cyanVector.png +0 -0
  100. PaIRS_UniNa/icons/colormaps/flag.png +0 -0
  101. PaIRS_UniNa/icons/colormaps/gist_heat.png +0 -0
  102. PaIRS_UniNa/icons/colormaps/gray.png +0 -0
  103. PaIRS_UniNa/icons/colormaps/greenVector.png +0 -0
  104. PaIRS_UniNa/icons/colormaps/hot.png +0 -0
  105. PaIRS_UniNa/icons/colormaps/hsv.png +0 -0
  106. PaIRS_UniNa/icons/colormaps/inferno.png +0 -0
  107. PaIRS_UniNa/icons/colormaps/jet.png +0 -0
  108. PaIRS_UniNa/icons/colormaps/magentaVector.png +0 -0
  109. PaIRS_UniNa/icons/colormaps/magma.png +0 -0
  110. PaIRS_UniNa/icons/colormaps/ocean.png +0 -0
  111. PaIRS_UniNa/icons/colormaps/pink.png +0 -0
  112. PaIRS_UniNa/icons/colormaps/plasma.png +0 -0
  113. PaIRS_UniNa/icons/colormaps/prism.png +0 -0
  114. PaIRS_UniNa/icons/colormaps/rainbow.png +0 -0
  115. PaIRS_UniNa/icons/colormaps/redVector.png +0 -0
  116. PaIRS_UniNa/icons/colormaps/seismic.png +0 -0
  117. PaIRS_UniNa/icons/colormaps/spring.png +0 -0
  118. PaIRS_UniNa/icons/colormaps/summer.png +0 -0
  119. PaIRS_UniNa/icons/colormaps/tab10.png +0 -0
  120. PaIRS_UniNa/icons/colormaps/tab20.png +0 -0
  121. PaIRS_UniNa/icons/colormaps/tab20b.png +0 -0
  122. PaIRS_UniNa/icons/colormaps/tab20c.png +0 -0
  123. PaIRS_UniNa/icons/colormaps/terrain.png +0 -0
  124. PaIRS_UniNa/icons/colormaps/twilight.png +0 -0
  125. PaIRS_UniNa/icons/colormaps/viridis.png +0 -0
  126. PaIRS_UniNa/icons/colormaps/whiteVector.png +0 -0
  127. PaIRS_UniNa/icons/colormaps/winter.png +0 -0
  128. PaIRS_UniNa/icons/colormaps/yellowVector.png +0 -0
  129. PaIRS_UniNa/icons/common_region.png +0 -0
  130. PaIRS_UniNa/icons/common_region_off.png +0 -0
  131. PaIRS_UniNa/icons/completed.png +0 -0
  132. PaIRS_UniNa/icons/contourf_off.png +0 -0
  133. PaIRS_UniNa/icons/contourf_on.png +0 -0
  134. PaIRS_UniNa/icons/copy.png +0 -0
  135. PaIRS_UniNa/icons/copy_process.png +0 -0
  136. PaIRS_UniNa/icons/copy_process_off.png +0 -0
  137. PaIRS_UniNa/icons/copygrid.png +0 -0
  138. PaIRS_UniNa/icons/cursor_lamp.png +0 -0
  139. PaIRS_UniNa/icons/cut.png +0 -0
  140. PaIRS_UniNa/icons/cut_warnings.png +0 -0
  141. PaIRS_UniNa/icons/darkmode.png +0 -0
  142. PaIRS_UniNa/icons/debug_run.png +0 -0
  143. PaIRS_UniNa/icons/delete.png +0 -0
  144. PaIRS_UniNa/icons/deleteErr.png +0 -0
  145. PaIRS_UniNa/icons/disp_step.png +0 -0
  146. PaIRS_UniNa/icons/disp_step_off.png +0 -0
  147. PaIRS_UniNa/icons/down.png +0 -0
  148. PaIRS_UniNa/icons/edit_list.png +0 -0
  149. PaIRS_UniNa/icons/editing.png +0 -0
  150. PaIRS_UniNa/icons/example_list.png +0 -0
  151. PaIRS_UniNa/icons/find_all_planes.png +0 -0
  152. PaIRS_UniNa/icons/find_plane.png +0 -0
  153. PaIRS_UniNa/icons/flaticon_PaIRS.png +0 -0
  154. PaIRS_UniNa/icons/flaticon_PaIRS_beta.png +0 -0
  155. PaIRS_UniNa/icons/flaticon_PaIRS_download.png +0 -0
  156. PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
  157. PaIRS_UniNa/icons/flip_y_off.png +0 -0
  158. PaIRS_UniNa/icons/flip_y_on.png +0 -0
  159. PaIRS_UniNa/icons/focusErrr.png +0 -0
  160. PaIRS_UniNa/icons/folder_loop_cleanup.png +0 -0
  161. PaIRS_UniNa/icons/folder_loop_cleanup_off.png +0 -0
  162. PaIRS_UniNa/icons/gear.gif +0 -0
  163. PaIRS_UniNa/icons/gear.png +0 -0
  164. PaIRS_UniNa/icons/ger.png +0 -0
  165. PaIRS_UniNa/icons/greenv.png +0 -0
  166. PaIRS_UniNa/icons/guide.png +0 -0
  167. PaIRS_UniNa/icons/icon_CalVi.png +0 -0
  168. PaIRS_UniNa/icons/icon_PaIRS.png +0 -0
  169. PaIRS_UniNa/icons/import.png +0 -0
  170. PaIRS_UniNa/icons/import_set.png +0 -0
  171. PaIRS_UniNa/icons/information.png +0 -0
  172. PaIRS_UniNa/icons/information2.png +0 -0
  173. PaIRS_UniNa/icons/input_logo.png +0 -0
  174. PaIRS_UniNa/icons/issue.png +0 -0
  175. PaIRS_UniNa/icons/laser_NTR.png +0 -0
  176. PaIRS_UniNa/icons/laser_TR_double.png +0 -0
  177. PaIRS_UniNa/icons/laser_TR_single.png +0 -0
  178. PaIRS_UniNa/icons/link.png +0 -0
  179. PaIRS_UniNa/icons/linked.png +0 -0
  180. PaIRS_UniNa/icons/loaded.png +0 -0
  181. PaIRS_UniNa/icons/loading_2.gif +0 -0
  182. PaIRS_UniNa/icons/log_logo.png +0 -0
  183. PaIRS_UniNa/icons/logo_CalVi.png +0 -0
  184. PaIRS_UniNa/icons/logo_CalVi_completo.png +0 -0
  185. PaIRS_UniNa/icons/logo_CalVi_party.png +0 -0
  186. PaIRS_UniNa/icons/logo_PaIRS.png +0 -0
  187. PaIRS_UniNa/icons/logo_PaIRS_completo.png +0 -0
  188. PaIRS_UniNa/icons/logo_PaIRS_download.png +0 -0
  189. PaIRS_UniNa/icons/logo_PaIRS_party_rect.png +0 -0
  190. PaIRS_UniNa/icons/logo_PaIRS_rect.png +0 -0
  191. PaIRS_UniNa/icons/logo_opaco.png +0 -0
  192. PaIRS_UniNa/icons/mask.png +0 -0
  193. PaIRS_UniNa/icons/measure.png +0 -0
  194. PaIRS_UniNa/icons/measure_off.png +0 -0
  195. PaIRS_UniNa/icons/min_proc.png +0 -0
  196. PaIRS_UniNa/icons/min_proc_off.png +0 -0
  197. PaIRS_UniNa/icons/min_step.png +0 -0
  198. PaIRS_UniNa/icons/min_step_off.png +0 -0
  199. PaIRS_UniNa/icons/minus.png +0 -0
  200. PaIRS_UniNa/icons/mirror_u.png +0 -0
  201. PaIRS_UniNa/icons/mirror_v.png +0 -0
  202. PaIRS_UniNa/icons/mirror_x.png +0 -0
  203. PaIRS_UniNa/icons/mirror_y.png +0 -0
  204. PaIRS_UniNa/icons/mtplt.png +0 -0
  205. PaIRS_UniNa/icons/new.png +0 -0
  206. PaIRS_UniNa/icons/new_workspace.png +0 -0
  207. PaIRS_UniNa/icons/news.png +0 -0
  208. PaIRS_UniNa/icons/normal_run.png +0 -0
  209. PaIRS_UniNa/icons/open.png +0 -0
  210. PaIRS_UniNa/icons/open_image.png +0 -0
  211. PaIRS_UniNa/icons/open_new_window.png +0 -0
  212. PaIRS_UniNa/icons/open_result.png +0 -0
  213. PaIRS_UniNa/icons/open_workspace.png +0 -0
  214. PaIRS_UniNa/icons/output_logo.png +0 -0
  215. PaIRS_UniNa/icons/paste_above.png +0 -0
  216. PaIRS_UniNa/icons/paste_below.png +0 -0
  217. PaIRS_UniNa/icons/pause.png +0 -0
  218. PaIRS_UniNa/icons/paused.png +0 -0
  219. PaIRS_UniNa/icons/pencil_bw.png +0 -0
  220. PaIRS_UniNa/icons/piv_proc.png +0 -0
  221. PaIRS_UniNa/icons/piv_proc_off.png +0 -0
  222. PaIRS_UniNa/icons/piv_step.png +0 -0
  223. PaIRS_UniNa/icons/piv_step_off.png +0 -0
  224. PaIRS_UniNa/icons/plane.png +0 -0
  225. PaIRS_UniNa/icons/play.png +0 -0
  226. PaIRS_UniNa/icons/plus.png +0 -0
  227. PaIRS_UniNa/icons/process_logo.png +0 -0
  228. PaIRS_UniNa/icons/process_loop.png +0 -0
  229. PaIRS_UniNa/icons/project.png +0 -0
  230. PaIRS_UniNa/icons/pylog.png +0 -0
  231. PaIRS_UniNa/icons/python_warning.png +0 -0
  232. PaIRS_UniNa/icons/queue.png +0 -0
  233. PaIRS_UniNa/icons/quit.png +0 -0
  234. PaIRS_UniNa/icons/read.png +0 -0
  235. PaIRS_UniNa/icons/read_list.png +0 -0
  236. PaIRS_UniNa/icons/redo.png +0 -0
  237. PaIRS_UniNa/icons/redx.png +0 -0
  238. PaIRS_UniNa/icons/reset.png +0 -0
  239. PaIRS_UniNa/icons/reset_levels.png +0 -0
  240. PaIRS_UniNa/icons/resize_icon.png +0 -0
  241. PaIRS_UniNa/icons/restore.png +0 -0
  242. PaIRS_UniNa/icons/restore_undo.png +0 -0
  243. PaIRS_UniNa/icons/rotate_clock.png +0 -0
  244. PaIRS_UniNa/icons/rotate_counter.png +0 -0
  245. PaIRS_UniNa/icons/rotate_v_clock.png +0 -0
  246. PaIRS_UniNa/icons/rotate_v_counter.png +0 -0
  247. PaIRS_UniNa/icons/running.gif +0 -0
  248. PaIRS_UniNa/icons/running.png +0 -0
  249. PaIRS_UniNa/icons/running_warn.png +0 -0
  250. PaIRS_UniNa/icons/sandglass.png +0 -0
  251. PaIRS_UniNa/icons/save.png +0 -0
  252. PaIRS_UniNa/icons/save_and_stop.png +0 -0
  253. PaIRS_UniNa/icons/save_cfg.png +0 -0
  254. PaIRS_UniNa/icons/saveas.png +0 -0
  255. PaIRS_UniNa/icons/saveas_workspace.png +0 -0
  256. PaIRS_UniNa/icons/scale_all.png +0 -0
  257. PaIRS_UniNa/icons/scale_down.png +0 -0
  258. PaIRS_UniNa/icons/scale_up.png +0 -0
  259. PaIRS_UniNa/icons/scan_list.png +0 -0
  260. PaIRS_UniNa/icons/scan_path.png +0 -0
  261. PaIRS_UniNa/icons/scan_path_loop.png +0 -0
  262. PaIRS_UniNa/icons/scan_path_loop_off.png +0 -0
  263. PaIRS_UniNa/icons/search.png +0 -0
  264. PaIRS_UniNa/icons/showIW_off.png +0 -0
  265. PaIRS_UniNa/icons/showIW_on.png +0 -0
  266. PaIRS_UniNa/icons/show_all.png +0 -0
  267. PaIRS_UniNa/icons/sort.png +0 -0
  268. PaIRS_UniNa/icons/sort_reversed.png +0 -0
  269. PaIRS_UniNa/icons/spiv_proc.png +0 -0
  270. PaIRS_UniNa/icons/spiv_proc_off.png +0 -0
  271. PaIRS_UniNa/icons/spiv_setup_no.png +0 -0
  272. PaIRS_UniNa/icons/spiv_setup_ok.png +0 -0
  273. PaIRS_UniNa/icons/star.png +0 -0
  274. PaIRS_UniNa/icons/step_inheritance.png +0 -0
  275. PaIRS_UniNa/icons/subMIN_off.png +0 -0
  276. PaIRS_UniNa/icons/subMIN_on.png +0 -0
  277. PaIRS_UniNa/icons/tom.png +0 -0
  278. PaIRS_UniNa/icons/trash.png +0 -0
  279. PaIRS_UniNa/icons/undo.png +0 -0
  280. PaIRS_UniNa/icons/unedited.png +0 -0
  281. PaIRS_UniNa/icons/unina_dii.png +0 -0
  282. PaIRS_UniNa/icons/uninitialized.png +0 -0
  283. PaIRS_UniNa/icons/unlink.png +0 -0
  284. PaIRS_UniNa/icons/unwrap_items.png +0 -0
  285. PaIRS_UniNa/icons/up.png +0 -0
  286. PaIRS_UniNa/icons/updating_import.gif +0 -0
  287. PaIRS_UniNa/icons/updating_pairs.gif +0 -0
  288. PaIRS_UniNa/icons/vectorColor.png +0 -0
  289. PaIRS_UniNa/icons/vettore.png +0 -0
  290. PaIRS_UniNa/icons/view.png +0 -0
  291. PaIRS_UniNa/icons/view_off.png +0 -0
  292. PaIRS_UniNa/icons/vis_logo.png +0 -0
  293. PaIRS_UniNa/icons/waiting_circle.png +0 -0
  294. PaIRS_UniNa/icons/warning.png +0 -0
  295. PaIRS_UniNa/icons/warning_circle.png +0 -0
  296. PaIRS_UniNa/icons/window.png +0 -0
  297. PaIRS_UniNa/icons/workspace.png +0 -0
  298. PaIRS_UniNa/icons/wrap_items.png +0 -0
  299. PaIRS_UniNa/icons/write_list.png +0 -0
  300. PaIRS_UniNa/listLib.py +303 -0
  301. PaIRS_UniNa/mtfPIV.py +256 -0
  302. PaIRS_UniNa/parForMulti.py +435 -0
  303. PaIRS_UniNa/parForWorkers.py +593 -0
  304. PaIRS_UniNa/pivParFor.py +235 -0
  305. PaIRS_UniNa/plt_util.py +141 -0
  306. PaIRS_UniNa/preProcParFor.py +155 -0
  307. PaIRS_UniNa/procTools.py +1439 -0
  308. PaIRS_UniNa/readcfg.py +52 -0
  309. PaIRS_UniNa/rqrdpckgs.txt +9 -0
  310. PaIRS_UniNa/stereoPivParFor.py +227 -0
  311. PaIRS_UniNa/tAVarie.py +215 -0
  312. PaIRS_UniNa/tabSplitter.py +612 -0
  313. PaIRS_UniNa/ui_Calibration_Tab.py +578 -0
  314. PaIRS_UniNa/ui_Custom_Top.py +296 -0
  315. PaIRS_UniNa/ui_Input_Tab.py +1101 -0
  316. PaIRS_UniNa/ui_Input_Tab_CalVi.py +1283 -0
  317. PaIRS_UniNa/ui_Log_Tab.py +263 -0
  318. PaIRS_UniNa/ui_Output_Tab.py +2362 -0
  319. PaIRS_UniNa/ui_Process_Tab.py +3810 -0
  320. PaIRS_UniNa/ui_Process_Tab_CalVi.py +1549 -0
  321. PaIRS_UniNa/ui_Process_Tab_Disp.py +1141 -0
  322. PaIRS_UniNa/ui_Process_Tab_Min.py +437 -0
  323. PaIRS_UniNa/ui_ResizePopup.py +204 -0
  324. PaIRS_UniNa/ui_Vis_Tab.py +1628 -0
  325. PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1251 -0
  326. PaIRS_UniNa/ui_Whatsnew.py +132 -0
  327. PaIRS_UniNa/ui_gPairs.py +877 -0
  328. PaIRS_UniNa/ui_infoPaIRS.py +551 -0
  329. PaIRS_UniNa/whatsnew.txt +4 -0
  330. pairs_unina-0.2.10.dist-info/METADATA +159 -0
  331. pairs_unina-0.2.10.dist-info/RECORD +333 -0
  332. pairs_unina-0.2.10.dist-info/WHEEL +5 -0
  333. pairs_unina-0.2.10.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1439 @@
1
+ ''' 2d PIV helper function for parfor '''
2
+ from datetime import timedelta
3
+ import os.path
4
+
5
+ # In hex is easy 0606 both read and processed 01234156789abcdef
6
+ FLAG_READ_ERR = [1, 1<<8] #2, 256= 0001 1 0001 0000 0000
7
+ FLAG_READ = [2 ,1<<9] #1<<9=2**9=512 0010 2
8
+ FLAG_PROC = [1<<2 ,1<<10] #8 ,1024 0100 4
9
+ FLAG_FINALIZED = [1<<3 ,1<<11] #completely processed 1000 8
10
+ # In hex is easy 0E0E both read, processed and finalized
11
+ FLAG_CALLBACK_INTERNAL = 1<<16 #on if the callback has been called in its internal parts
12
+ FLAG_GENERIC_ERROR = 1<<17 #on if the callback has been called in its internal parts
13
+ FLAG_PROC_AB =FLAG_PROC[0]|FLAG_PROC[1] #4+1024=1028=x404 se si somma anche FLAG_READ 6+1536=1542=x606
14
+ FLAG_FINALIZED_AB =FLAG_FINALIZED[0]|FLAG_FINALIZED[1]
15
+ FLAG_PROC_OR_ERR=[ p|e for (p,e) in zip(FLAG_PROC,FLAG_READ_ERR)]
16
+ FLAG_FINALIZED_OR_ERR = [ p|e for (p,e) in zip(FLAG_FINALIZED,FLAG_READ_ERR)]
17
+ # usare con
18
+ # supponendo che k sia 0 (img a) o 1 (img b)
19
+ # if pim(i)&FLAG_PROC[k]: allora img i, k processata
20
+ # per annullare un bit f=f& (~FLAG_CALLBACK)
21
+
22
+ from .PaIRS_pypacks import*
23
+ from .Input_Tab import INPpar as INPpar
24
+ from .Output_Tab import OUTpar as OUTpar
25
+ from .Output_Tab import outType_dict
26
+ from .Process_Tab import PROpar as PROpar
27
+ from .Process_Tab_Min import PROpar_Min as PROpar_Min
28
+ from .Process_Tab_Disp import PROpar_Disp as PROpar_Disp
29
+ from .Vis_Tab import VISpar as VISpar
30
+ from .Vis_Tab import NamesPIV
31
+ from .TabTools import TABpar
32
+ from .readcfg import readCalFile
33
+ from .__init__ import __version__,__subversion__,__year__
34
+
35
+ processData = {
36
+ ProcessTypes.min: {'name': 'Pre-process', 'caption': 'Pre-process analysis of a set of images aimed at computing historical minimum background',
37
+ 'class': 0, 'icon': 'min_proc.png',
38
+ 'children': {StepTypes.min:True}, 'mandatory': [StepTypes.min]},
39
+ ProcessTypes.piv: {'name': 'PIV process', 'caption': 'Particle Image Velocimetry analysis for computation of the two-dimensional two-component velocity field',
40
+ 'class': 0, 'icon': 'piv_proc.png',
41
+ 'children': {StepTypes.min:False,StepTypes.piv:True}, 'mandatory': [StepTypes.piv]},
42
+ ProcessTypes.cal: {'name': 'Calibration', 'caption': 'Accurate optical calibration of single and multiple camera bundles',
43
+ 'class': 0, 'icon': 'cal_proc.png',
44
+ 'children': {StepTypes.cal:True}, 'mandatory': [StepTypes.cal]},
45
+ ProcessTypes.spiv: {'name': 'Stereo-PIV process', 'caption': 'Stereoscopic Particle Image Velocimetry analysis for computation of the two-dimensional three-component velocity field',
46
+ 'class': 0, 'icon': 'spiv_proc.png',
47
+ 'children': {StepTypes.cal:True,StepTypes.min:False,StepTypes.disp:True,StepTypes.spiv:True},'mandatory': [StepTypes.cal]},
48
+ }
49
+ for p in processData:
50
+ processData[p]['type']=p
51
+
52
+ stepData= {
53
+ StepTypes.cal: {'name': 'Camera calibration', 'caption': 'Select an appropriate camera model and estimate the parameters of the mapping functions based on calibration target images',
54
+ 'class': 1, 'icon': 'cal_step.png', 'parents': [],
55
+ 'tabs': ['Calibration','Input_CalVi','Process_CalVi','Vis_CalVi'], },
56
+ StepTypes.min: {'name': 'Image pre-processing', 'caption': 'Select a set of particle images and compute the historical minimum background for subsets corresponding to the same laser light source',
57
+ 'class': 1, 'icon': 'min_step.png', 'parents': [],
58
+ 'tabs': ['Input','Output','Process_Min','Log','Vis'], },
59
+ StepTypes.piv: {'name': 'PIV analysis', 'caption': 'Select a set of particle images, craft a custom iterative multi-grid method and compute the two-dimensional two-component displacement field',
60
+ 'class': 1, 'icon': 'piv_step.png', 'parents': [],
61
+ 'tabs': ['Input','Output','Process','Log','Vis'], },
62
+ StepTypes.disp: {'name': 'Disparity correction', 'caption': 'Select a a set of particle images and compute the laser sheet position and orientation to adjust the camera disparities in the stereo-setup',
63
+ 'class': 1, 'icon': 'disp_step.png', 'parents': [StepTypes.cal],
64
+ 'tabs': ['Input','Output','Process_Disp','Log','Vis'], },
65
+ StepTypes.spiv: {'name': 'Stereoscopic PIV analysis', 'caption': 'Select a set of particle images, craft a custom iterative multi-grid method and compute the two-dimensional three-component displacement field',
66
+ 'class': 1, 'icon': 'piv_step.png', 'parents': [StepTypes.cal,StepTypes.disp],
67
+ 'tabs': ['Input','Output','Process','Log','Vis'], },
68
+ }
69
+ for p in stepData:
70
+ stepData[p]['type']=p
71
+
72
+ class dataTreePar(TABpar):
73
+ def __init__(self,Process=ProcessTypes.null,Step=StepTypes.null):
74
+ self.setup(Process,Step)
75
+ super().__init__('dataTreePar','ITEpar')
76
+
77
+ self.setCompleteLog()
78
+
79
+ self.surname='itemTreePar.gPaIRS'
80
+ self.unchecked_fields+=['name_fields']
81
+ self.uncopied_fields+=['ind']
82
+
83
+ def setup(self,Process,Step):
84
+ #typeProc, names, icon, log: item fields
85
+ self.Process=Process
86
+ self.Step=Step
87
+ self.namesPIV=NamesPIV(Step)
88
+
89
+ if Step:
90
+ self.itemname=stepData[Step]['name']
91
+ else:
92
+ self.itemname=''
93
+ self.filename_proc = ''
94
+ self.name_proc = ''
95
+
96
+ self.Log=''
97
+ self.procLog=['','',''] #LogProc, LogStat, LogErr
98
+ self.FlagErr=False
99
+ self.warnings=['',''] #warnings once completed the process, warnings related to current state
100
+
101
+ self.item_fields=[f for f,_ in self.__dict__.items()]+['ind']
102
+
103
+ #common data
104
+ self.inpPath=''
105
+ self.outPath=''
106
+ self.outPathRoot=''
107
+ self.ndig=-1
108
+ self.outExt=''
109
+ self.compMin:CompMin=CompMin()
110
+ self.mediaPIV:MediaPIV=MediaPIV(stepType=Step)
111
+ #if Step==StepTypes.min:
112
+ self.FlagTR = False
113
+ self.LaserType = False
114
+ self.SogliaNoise_Min = 0.0
115
+ self.SogliaStd_Min = 100.0
116
+
117
+ #elif Step in (StepTypes.piv, StepTypes.disp, StepTypes.spiv):
118
+ #common
119
+ self.FlagMIN=False
120
+ self.Imin=[]
121
+
122
+ self.dispFrames=0
123
+
124
+ self.numUsedProcs=1
125
+ self.numPivOmpCores=-1 # used by PIV_ParFor_Workerfor setting the correct number of threads
126
+
127
+ self.OUT_dict={}
128
+ self.PRO_dict={}
129
+ self.PRO_Disp_dict={}
130
+
131
+ self.Nit=0
132
+ self.nimg=0
133
+ self.ncam=0
134
+ self.nframe=2
135
+ self.nsteps=0
136
+ self.list_Image_Files=[]
137
+ self.list_eim=[]
138
+ self.list_pim=[]
139
+ self.list_print=[]
140
+
141
+ #if Step in (StepTypes.disp, StepTypes.spiv):
142
+ self.calList=[]
143
+ self.calEx=[]
144
+ self.res=0
145
+ self.laserConst=[0.0 for _ in range(3)]
146
+
147
+ #if Step==StepTypes.spiv:
148
+ self.FlagDISP=False
149
+ #self.dispFile=''
150
+
151
+ fields=[f for f,_ in self.__dict__.items()]
152
+ self.numCallBackTotOk=0 #numero di callback ricevute= quelle con problema + finalized
153
+ self.numFinalized=0 #numero di processi andati a buon fine
154
+ self.numProcOrErrTot=0
155
+ self.FlagFinished=False
156
+ self.flagParForCompleted=False # par for completed
157
+
158
+ # processing time
159
+ self.initProcTime=time() #initial time qhen starting the process
160
+ self.eta=0 # expexted time to finish the process
161
+ self.procTime=0 # processing time
162
+ self.timePerImage=0
163
+
164
+ #interface
165
+ self.freset_par=''
166
+ self.procfields=[f for f,_ in self.__dict__.items() if f not in fields]+ ['compMin','mediaPIV']
167
+
168
+ self.assignDataName()
169
+ return
170
+
171
+ def resF(self,i,string=''):
172
+ if self.ndig<-1: return ''
173
+ if string=='dispMap':
174
+ fold=os.path.dirname(self.outPathRoot)
175
+ rad=os.path.splitext(os.path.basename(self.outPathRoot))[0]
176
+ if rad[-1]!='_': rad+='_'
177
+ return myStandardRoot(os.path.join(fold, f'dispMap_rot_{rad}{i}.png'))
178
+ else:
179
+ if type(i)==str:
180
+ return f"{self.outPathRoot}_{i}{self.outExt}"
181
+ elif type(i)==int:
182
+ return f"{self.outPathRoot}_{i:0{self.ndig:d}d}{self.outExt}"
183
+ else:
184
+ return ''
185
+
186
+ def setProc(self,INP:INPpar=INPpar(),OUT:OUTpar=OUTpar(),PRO:PROpar=PROpar(),PRO_Min:PROpar_Min=PROpar_Min(),PRO_Disp:PROpar_Disp=PROpar_Disp()):
187
+ if INP is None: return
188
+ self.inpPath=INP.path
189
+ self.outPath=myStandardRoot(OUT.path+OUT.subfold)
190
+ self.outPathRoot=myStandardRoot(OUT.path+OUT.subfold+OUT.root)
191
+
192
+ if self.Step==StepTypes.disp:
193
+ self.list_Image_Files=INP.imList
194
+ self.list_eim=INP.imEx
195
+ else:
196
+ self.list_Image_Files=[]
197
+ self.list_eim=[]
198
+ for c in range(INP.ncam):
199
+ for k in range(INP.nimg):
200
+ for f in range(2):
201
+ self.list_Image_Files.append(INP.imList[c][f][k])
202
+ self.list_eim.append(INP.imEx[c][f][k])
203
+ self.ncam=len(INP.imList)
204
+ self.FlagTR=INP.FlagTR
205
+ self.LaserType=INP.LaserType
206
+ self.FlagMIN=INP.FlagMIN
207
+ self.Imin=INP.imListMin
208
+
209
+ if self.Step==StepTypes.min:
210
+ self.compMin.outName = self.outPathRoot+'_data'+outExt.min
211
+ self.compMin.name_proc = self.name_proc
212
+ self.compMin.flag_TR=self.FlagTR
213
+ self.compMin.LaserType=self.LaserType
214
+ self.compMin.setup(self.ncam,self.nframe)
215
+ self.nimg=(len(self.list_Image_Files)//(2*self.ncam)+1)//2 if self.FlagTR else len(self.list_Image_Files)//(2*self.ncam)
216
+ elif self.Step in (StepTypes.piv,StepTypes.disp,StepTypes.spiv):
217
+ if self.Step==StepTypes.piv:
218
+ self.mediaPIV.outName = self.outPathRoot+'_data'+outExt.piv
219
+ self.mediaPIV.name_proc = self.name_proc
220
+ elif self.Step==StepTypes.spiv:
221
+ self.mediaPIV.outName = self.outPathRoot+'_data'+outExt.spiv
222
+ self.mediaPIV.name_proc = self.name_proc
223
+ self.nimg=INP.nimg
224
+ self.ndig=len(str(self.nimg))
225
+ self.outExt=list(outType_dict)[OUT.outType]
226
+ self.numUsedProcs=self.numUsedProcs #TODEL
227
+ if self.Step in (StepTypes.disp,StepTypes.spiv):
228
+ self.calList=INP.calList
229
+ self.calEx =INP.calEx
230
+ if self.Step==StepTypes.disp:
231
+ self.Nit = PRO_Disp.Nit
232
+ self.dispFrames = PRO_Disp.frames
233
+ #if self.Step==StepTypes.spiv:
234
+ #self.FlagDISP=INP.FlagDISP
235
+ #self.dispFile=INP.dispFile
236
+
237
+ self.nsteps=self.Nit if self.Step==StepTypes.disp else self.nimg
238
+ self.list_pim=[0]*self.nsteps
239
+ self.list_print=['']*self.nsteps
240
+
241
+ if PRO_Min:
242
+ self.SogliaNoise_Min=PRO_Min.SogliaNoise
243
+ self.SogliaStd_Min=PRO_Min.SogliaStd
244
+
245
+ for f,v in OUT.duplicate().__dict__.items():
246
+ self.OUT_dict[f]=v
247
+ if self.Step in (StepTypes.piv,StepTypes.spiv):
248
+ for f,v in PRO.duplicate().__dict__.items():
249
+ self.PRO_dict[f]=v
250
+ if self.Step == StepTypes.disp:
251
+ for f,v in PRO_Disp.duplicate().__dict__.items():
252
+ self.PRO_Disp_dict[f]=v
253
+ #self.setPIV(OUT,PRO,flagSpiv)
254
+
255
+ def assignDataName(self):
256
+ self.name_proc,_,_=identifierName(typeObject='proc')
257
+
258
+ if self.Step!=StepTypes.null:
259
+ self.itemname=stepData[self.Step]['name']
260
+ for f,v in StepTypes.__dict__.items():
261
+ if v==self.Step:
262
+ break
263
+ ext=getattr(outExt,f)
264
+ self.filename_proc=f"{self.outPathRoot}{ext}"
265
+
266
+ def procOutName(self):
267
+ return procOutName(self)
268
+
269
+ def stepOutName(self):
270
+ return stepOutName(self)
271
+
272
+ def resetTimeStat(self):
273
+ ''' reset all the TimeStat parameters should be called before starting a new process maybe it is useless ask GP'''
274
+ self.procTime=0
275
+ self.eta=0
276
+ self.timePerImage=0
277
+
278
+ def onStartTimeStat(self):
279
+ ''' Should be called whenever play is pressed '''
280
+ pri.Time.blue(f'onStartTimeStat self.procTime={self.procTime}')
281
+ self.initProcTime=time()
282
+
283
+ def onPauseTimeStat(self):
284
+ ''' Should be called whenever pause is pressed '''
285
+ actualTime=time()
286
+ self.calcTimeStat(actualTime,self.numFinalized) #if paused should evaluate the correct eta when restarting
287
+ self.procTime+=actualTime-self.initProcTime
288
+ pri.Time.blue(f'onPauseTimeStat self.procTime={self.procTime} self.eta={self.eta} self.numFinalized={self.numFinalized}')
289
+
290
+ def deltaTime2String(self,dt,FlagMilliseconds=False):
291
+ if FlagMilliseconds:
292
+ s=str(timedelta(seconds=int(dt)))
293
+ s+="."+f"{dt:#.3f}".split('.')[-1] #
294
+ else:
295
+ s=str(timedelta(seconds=round(dt)))
296
+ return s
297
+
298
+ def calcTimeStat(self,actualTime,numDone):
299
+ ''' Should be called when when the eta should be updated '''
300
+ procTime=self.procTime+actualTime-self.initProcTime
301
+ numStilToProc=self.nsteps-numDone
302
+
303
+ if numDone==0:
304
+ self.eta=0
305
+ self.timePerImage=0
306
+ else:
307
+ self.timePerImage=(procTime)/numDone
308
+ self.eta=self.timePerImage*numStilToProc
309
+
310
+ #pr(f'dt={procTime} ETA={self.eta} {self.deltaTime2String(self.eta)} dt+ETA={round(procTime+ self.eta)} timePerImage={self.timePerImage} numStilToProc={numStilToProc} numDone={numDone} ')
311
+ return self.deltaTime2String(self.eta)
312
+
313
+ def setPIV(self,flagSpiv=False):
314
+ self.PIV=data2PIV(self,flagSpiv)
315
+
316
+ def createLogHeader(self):
317
+ header=PaIRS_Header
318
+ if self.Step==StepTypes.null: #minimum
319
+ name='Welcome to PaIRS!\nEnjoy it!\n\n'
320
+ header=header+name
321
+ else:
322
+ name=f'{self.itemname} ({self.filename_proc})\n'
323
+ name+=self.name_proc
324
+ date_time=QDate.currentDate().toString('yyyy/MM/dd')+' at '+\
325
+ QTime().currentTime().toString()
326
+ header+=f'{name}\n'+'Last modified date: '+date_time+'\n\n\n'
327
+ return header
328
+
329
+ def setCompleteLog(self):
330
+ warn1=self.headerSection('WARNINGS',self.warnings[1],'!')
331
+ if self.flagRun not in (0,-10):
332
+ warn0=''
333
+ self.createLogProc()
334
+ LogProc = self.headerSection('OUTPUT',self.procLog[0])
335
+ LogStat = self.headerSection('PROGRESS status',self.procLog[1])
336
+ LogErr = self.headerSection('ERROR report',self.procLog[2])
337
+ procLog=LogProc+LogStat+LogErr
338
+ if self.warnings[0]: warn0='*Further information:\n'+self.warnings[0]+'\n'
339
+ self.Log=self.createLogHeader()+procLog+warn0+warn1
340
+ else:
341
+ if self.flagRun:
342
+ self.Log=self.createLogHeader()
343
+ else:
344
+ self.Log=self.createLogHeader()+warn1
345
+
346
+ def createWarningLog(self,warning):
347
+ warn1=self.headerSection('WARNINGS',warning,'!')
348
+ return self.createLogHeader()+warn1
349
+
350
+ def headerSection(self,nameSection,Log,*args):
351
+ if len(Log):
352
+ c='-'
353
+ n=36
354
+ if len(args): c=args[0]
355
+ if len(args)>1: n=args[1]
356
+ ln=len(nameSection)
357
+ ns=int((n-ln)/2)
358
+ header=f'{f"{c}"*n}\n{" "*ns}{nameSection}{" "*ns}\n{f"{c}"*n}\n'
359
+ if Log!=' ': Log=header+Log+'\n'
360
+ else: Log=header
361
+ return Log
362
+
363
+ def eyeHeaderSection(self, text:str, width:int=54, height:int=11, border:str='o', pad:int=0)->str:
364
+ """
365
+ Draw an eye-shaped frame with the given text centered on the middle row.
366
+ Works in monospace consoles or QTextEdit. Uses a smooth parametric eye curve.
367
+ """
368
+ width=max(width, len(text)+2*pad+2)
369
+ height=max(5, height|(1)) # make it odd
370
+ mid=height//2
371
+ # eye boundary: y = a*(1 - |x|^p)^b, mirrored top/bottom
372
+ import math
373
+ p,b=1.6,1.0 # shape controls (p: pointiness, b: roundness)
374
+ ax=width/2-1
375
+ ay=mid-1 # vertical semi-size (controls thickness of eye)
376
+ eps=0.6 # border thickness in "cells"
377
+
378
+ rows=[]
379
+ for r in range(height):
380
+ y=(r-mid)/ay # -1..1
381
+ line=[]
382
+ for c in range(width):
383
+ x=(c- (width-1)/2)/ax # -1..1
384
+ # target boundary (top curve positive y, bottom negative)
385
+ yb = (1 - abs(x)**p)
386
+ yb = (yb if yb>0 else 0)**b # clamp
387
+ # distance to boundary (abs because top/bottom)
388
+ d=abs(abs(y)-yb)
389
+ ch=' '
390
+ if yb<=0 and abs(y)<eps/ay: # very ends -> leave blank
391
+ ch=' '
392
+ elif d*ay<=eps and yb>0: # on border
393
+ ch=border
394
+ line.append(ch)
395
+ rows.append(''.join(line))
396
+
397
+ # write text on middle row
398
+ body=list(rows[mid])
399
+ s=f' {text} '
400
+ start=(width-len(s))//2
401
+ body[start:start+len(s)]=list(s)
402
+ rows[mid]=''.join(body)
403
+
404
+ return '\n'.join(rows)
405
+
406
+ def createLogProc(self):
407
+ splitAs='\n '#used to join the strings together tab or spaces may be use to indent the error
408
+ numImgTot=len(self.list_pim) if self.Step!=StepTypes.min else (2*len(self.list_pim))
409
+ LogProc=''
410
+ LogErr=''
411
+ cont=0
412
+ contErr=0
413
+ for i,p in enumerate(self.list_pim):
414
+ if not p or self.list_print[i]=='':
415
+ continue
416
+ if self.Step==StepTypes.min: #minimum
417
+ cont+=2
418
+ #flag=(p&FLAG_FINALIZED[0]) and (p&FLAG_FINALIZED[1])
419
+ if (p&FLAG_FINALIZED[0]):
420
+ if (p&FLAG_FINALIZED[1]):
421
+ LogProc+=(self.list_print[i])
422
+ else:
423
+ sAppo=self.list_print[i].split('\n')
424
+ LogProc+=sAppo[0]+'\n'
425
+ if (not p&FLAG_READ[1]) and p&FLAG_READ_ERR[1]:
426
+ LogErr+=splitAs.join(sAppo[1:-1])+'\n'
427
+ contErr+=1
428
+ #pri.Process.magenta(f'LogProc {i} {p} {splitAs.join(sAppo[1:-1])} {hex(p)} ')
429
+ else:# la b nonè stata proprio letta
430
+ cont-=1
431
+ #pri.Process.magenta(f'LogProc wrong {i} {p} {splitAs.join(sAppo[1:-1])} {hex(p)} ')
432
+ LogProc+='\n'
433
+ else:
434
+ sAppo=self.list_print[i].split('\n')
435
+ if (p&FLAG_FINALIZED[1]):
436
+ LogProc+=(sAppo[-2])+'\n'
437
+ LogErr+=splitAs.join(sAppo[0:-2])+'\n'
438
+ contErr+=1
439
+ else:
440
+ iDum=len(sAppo)//2
441
+ LogErr+=splitAs.join(sAppo[0:iDum])+'\n'+splitAs.join(sAppo[iDum:-1])+'\n'
442
+ contErr+=2
443
+ elif self.Step in (StepTypes.piv,StepTypes.disp,StepTypes.spiv): #PIV process
444
+ cont+=1
445
+ if p&FLAG_FINALIZED[0]:
446
+ LogProc+=self.list_print[i]+"\n"
447
+ #pr(f'LogProc {i} {p} {self.list_print[i]} {hex(p)} = {hex(FLAG_FINALIZED_AB)}\n')
448
+ else:
449
+ contErr+=1
450
+ errString=splitAs.join(self.list_print[i].split('\n')[0:-1])
451
+ if errString: LogErr+=errString+'\n'
452
+
453
+ if not LogProc: LogProc=self.nullLogProc()
454
+
455
+ self.FlagErr=bool(LogErr) or 'CRITICAL ERROR' in self.warnings[0]
456
+ if self.Step in (StepTypes.piv,StepTypes.spiv):
457
+ errStr=f' ({contErr}/{numImgTot} images)'
458
+ else:
459
+ errStr=''
460
+ if 'CRITICAL ERROR' in self.warnings[0]:
461
+ errStr2='!!! Critical errors occured! Please, see further information reported below.\n\n'
462
+ else:
463
+ errStr2=''
464
+ if self.FlagErr:
465
+ LogErr=f'There were errors in the current process{errStr}:\n\n{errStr2}'+LogErr
466
+ else:
467
+ LogErr=f'There were no errors in the current process!\n\n'
468
+ if numImgTot:
469
+ pProc=cont*100/numImgTot
470
+ else:
471
+ pProc=100
472
+ pLeft=100-pProc
473
+ if cont:
474
+ pErr=contErr*100/cont
475
+ else:
476
+ pErr=0
477
+ pCorr=100-pErr
478
+ item='pair' if self.Step!=StepTypes.disp else 'iteration'
479
+ sp=' '*6 if self.Step!=StepTypes.disp else ' '
480
+ Log_PIVCores='' if self.Step==StepTypes.min else f' PIV cores: {self.numPivOmpCores}\n'
481
+ LogStat=\
482
+ f'Percentage of {item}s\n'+\
483
+ f' processed: {pProc:.2f}%\n'+\
484
+ f' remaining: {pLeft:.2f}%\n'+\
485
+ f' without errors: {pCorr:.2f}%\n'+\
486
+ f' with errors: {pErr:.2f}%\n\n'+\
487
+ f'Time\n'+\
488
+ f' of the process: {self.deltaTime2String(self.procTime,True)}\n'+\
489
+ f' {sp} per {item}: {self.deltaTime2String(self.timePerImage,True)}\n'+\
490
+ f' to the end: {self.deltaTime2String(self.eta,True)}\n\n'+\
491
+ f'Multi processing\n'+\
492
+ Log_PIVCores+\
493
+ f' processing units: {floor(self.numUsedProcs)}\n'
494
+ #5f' processing units: {floor(self.numUsedProcs/self.numPivOmpCores)}\n'
495
+ self.procLog=[LogProc,LogStat,LogErr]
496
+ return
497
+
498
+ def nullLogProc(self):
499
+ return 'No output produced!\n\n'
500
+
501
+ def resetLog(self):
502
+ if self.procLog[0]!=self.nullLogProc():
503
+ self.Log=self.createLogHeader()+self.procLog[0]
504
+ else:
505
+ self.Log=self.createLogHeader()
506
+ return
507
+
508
+ def writeCfgProcPiv(self,filename='',FlagWarningDialog=False):
509
+ flagSpiv=self.Step==StepTypes.spiv
510
+ if filename=='':
511
+ outPathRoot=self.outPathRoot
512
+ foldOut=os.path.dirname(outPathRoot)
513
+ if not os.path.exists(foldOut):
514
+ try:
515
+ os.mkdir(foldOut)
516
+ except Exception as inst:
517
+ pri.Error.red(f'It was not possible to make the directory {foldOut}:\n{traceback.format_exc()}\n\n{inst}')
518
+ filename=f"{outPathRoot}.cfg"
519
+ try:
520
+ writeCfgProcPiv(self,filename,flagSpiv)
521
+ except Exception as inst:
522
+ warningMessage=f'Error while writing PIV configuration file to location "{filename}":\n{inst}'
523
+ if FlagWarningDialog: warningDialog(None,warningMessage)
524
+ pri.Error.red(f'{warningMessage}\n{traceback.format_exc()}\n')
525
+
526
+ class MediaPIV():
527
+ ''' helper class to perform the avearages '''
528
+ def __init__(self,stepType=StepTypes.piv):
529
+ self.outName=''
530
+ self.name_proc=''
531
+
532
+ self.stepType=stepType
533
+ self.namesPIV=NamesPIV(Step=self.stepType)
534
+
535
+ #self.avgVel=[self.x,self.y,self.u,self.v,self.up,self.vp,self.uvp,self.FCl,self.Info,self.sn]
536
+ self.x=np.zeros(1)
537
+ self.y=np.zeros(1)
538
+ self.u=np.zeros(1)
539
+ self.v=np.zeros(1)
540
+ self.up=np.zeros(1)
541
+ self.vp=np.zeros(1)
542
+ self.uvp=np.zeros(1)
543
+ self.sn=np.zeros(1)
544
+ self.FCl=np.zeros(1)
545
+ self.Info=np.zeros(1)
546
+ if self.stepType==StepTypes.disp:
547
+ self.z=np.zeros(1)
548
+ self.dPar=np.zeros(1)
549
+ self.dOrt=np.zeros(1)
550
+ if self.stepType==StepTypes.spiv:
551
+ self.z=np.zeros(1)
552
+ self.w=np.zeros(1)
553
+ self.wp=np.zeros(1)
554
+ self.uwp=np.zeros(1)
555
+ self.vwp=np.zeros(1)
556
+ self.indu=3 if self.stepType==StepTypes.spiv else 2
557
+
558
+ # just for checking that the variables are the same
559
+ # I cannot do it automatically since variables are not recognized by vscode
560
+ for n in self.namesPIV.avgVelFields:
561
+ v=getattr(self,n)
562
+
563
+ self.cont=0
564
+ self.nimg=0
565
+
566
+ self.fields=[f for f,_ in self.__dict__.items()]
567
+
568
+ def sum(self,var):
569
+ # should start with x, y ,u ,v
570
+ infoSi=1
571
+ self.cont=self.cont+1
572
+ for v, n in zip(var[2:], self.namesPIV.instVelFields[2:]) :
573
+ f=getattr(self,n)
574
+ #piv.Info #verificare se sia il caso di sommare solo se =Infosi
575
+ setattr(self,n,f+1*(v==infoSi) if n=='Info' else f+v )
576
+
577
+ '''
578
+ self.u=self.u+var[2] #piv.u
579
+ self.v=self.v+var[3] #piv.v
580
+ self.FCl=self.FCl+var[4] #piv.FCl
581
+ self.Info=self.Info+1*(var[5]==infoSi) #piv.Info #verificare se sia il caso di sommare solo se =Infosi
582
+ self.sn=self.sn+var[6] #piv.sn
583
+ '''
584
+ self.up=self.up+var[self.indu]*var[self.indu] #piv.up
585
+ self.vp=self.vp+var[self.indu+1]*var[self.indu+1] #piv.vp
586
+ self.uvp=self.uvp+var[self.indu]*var[self.indu+1] #piv.uvp
587
+ if self.stepType==StepTypes.spiv:
588
+ self.wp=self.wp+var[self.indu+2]*var[self.indu+2] #piv.wp
589
+ self.uwp=self.uwp+var[self.indu]*var[self.indu+2] #piv.uwp
590
+ self.vwp=self.vwp+var[self.indu+1]*var[self.indu+2] #piv.vwp
591
+
592
+
593
+ if self.x.size<=1:
594
+ self.x=var[0] #piv.x dovrebbero essere tutti uguali
595
+ self.y=var[1] #piv.y dovrebbero essere tutti uguali
596
+ if self.stepType==StepTypes.spiv:
597
+ self.z=var[2] #piv.y dovrebbero essere tutti uguali
598
+
599
+ def sumMedia(self,medToSum):
600
+ self.cont=self.cont+medToSum.cont
601
+ self.u=self.u+medToSum.u
602
+ self.v=self.v+medToSum.v
603
+ self.sn=self.sn+medToSum.sn
604
+ self.FCl=self.FCl+medToSum.FCl
605
+ self.up=self.up+medToSum.up
606
+ self.vp=self.vp+medToSum.vp
607
+ self.uvp=self.uvp+medToSum.uvp
608
+ self.Info=self.Info+medToSum.Info
609
+ if self.stepType==StepTypes.spiv:
610
+ self.w=self.w+medToSum.w
611
+ self.wp=self.wp+medToSum.wp
612
+ self.uwp=self.uwp+medToSum.uwp
613
+ self.vwp=self.vwp+medToSum.vwp
614
+ if self.x.size<=1:
615
+ self.x=medToSum.x #piv.x dovrebbero essere tutti uguali
616
+ self.y=medToSum.y #piv.y dovrebbero essere tutti uguali
617
+ if self.stepType==StepTypes.spiv:
618
+ self.z=medToSum.z #piv.y dovrebbero essere tutti uguali
619
+
620
+ def calcMedia(self):
621
+ if self.cont>0:
622
+
623
+ self.u/=self.cont
624
+ self.v/=self.cont
625
+
626
+ self.sn/=self.cont
627
+ self.FCl/=self.cont
628
+ self.Info/=self.cont#percentuale di vettori buoni 1=100% 0 nememno un vettore buono
629
+ self.up=(self.up/self.cont-self.u*self.u)#nan or inf is no good vector
630
+ self.vp=(self.vp/self.cont-self.v*self.v)#nan or inf is no good vector
631
+ self.uvp=(self.uvp/self.cont-self.u*self.v)#nan or inf is no good vector
632
+ if self.stepType==StepTypes.spiv:
633
+ self.w/=self.cont
634
+ self.wp=(self.wp/self.cont-self.w*self.w)#nan or inf is no good vector
635
+ self.uwp=(self.uwp/self.cont-self.u*self.w)#nan or inf is no good vector
636
+ self.vwp=(self.vwp/self.cont-self.w*self.v)#nan or inf is no good vector
637
+ def restoreSum(self):
638
+
639
+ #OPTIMIZE TA GP gestione delle statistiche ora si usano tutti i vettori anche quelli corretti forse si dovrebbe dare la possibiltà all'utente di scegliere?
640
+ self.up=(self.up+self.u*self.u)*self.cont # inf is no good vector
641
+ self.vp=(self.vp+self.v*self.v)*self.cont # inf is no good vector
642
+ self.uvp=(self.uvp+self.u*self.v)*self.cont # inf is no good vector
643
+ if self.stepType==StepTypes.spiv:
644
+ self.wp=(self.wp+self.w*self.w)*self.cont # inf is no good vector
645
+ self.uwp=(self.uwp+self.u*self.w)*self.cont # inf is no good vector
646
+ self.vwp=(self.vwp+self.w*self.v)*self.cont # inf is no good vector
647
+ self.w=self.w*self.cont
648
+
649
+ self.u=self.u*self.cont
650
+ self.v=self.v*self.cont
651
+ self.sn=self.sn*self.cont
652
+ self.Info=self.Info*self.cont#percentuale di vettori buoni 1=100% 0 nememno un vettore buono
653
+
654
+ class CompMin():
655
+ ''' helper class to compute minimum '''
656
+ def __init__(self,ncam=1,nframe=2):
657
+ self.outName=''
658
+ self.name_proc=''
659
+
660
+ self.setup(ncam,nframe)
661
+ #self.cont=0
662
+ #self.cont0=0
663
+
664
+ self.flag_TR=None
665
+ self.LaserType=-1 #0 single, 1 double
666
+
667
+ self.fields=[f for f,_ in self.__dict__.items()]
668
+
669
+ def setup(self,ncam,nframe):
670
+ self.ncam=ncam
671
+ self.nframe=nframe
672
+ self.Imin=[np.zeros(0) for _ in range(self.ncam*self.nframe)]
673
+ self.med=[np.zeros(1) for _ in range(self.ncam*self.nframe)]
674
+ self.contab=[0 for _ in range(ncam*2)]
675
+
676
+ def minSum(self,I,k):
677
+ ''' min '''
678
+ #sleep(0.15)
679
+ # min or max
680
+ if len(I):# why
681
+ if self.contab[k]==0:
682
+ self.Imin[k]=I
683
+ else:
684
+ self.Imin[k]=np.minimum(I,self.Imin[k])
685
+ # verage std and the like
686
+ self.med[k]=self.med[k]+I#+= non funziona all'inizio
687
+ self.contab[k]+=1
688
+ #prLock(f"minSum contab={self.contab[k]}")
689
+ def checkImg(self,I,sogliaMedia,sogliaStd)->bool:
690
+ ''' checkImg '''
691
+ #dum=1/I.size
692
+ media=I.mean() #I.ravel().sum()*dum #faster than mean, but affected by overflow
693
+ dev=I.std() #np.square(I-media).ravel().sum()*dum
694
+ return media>sogliaMedia and dev >sogliaStd*sogliaStd
695
+
696
+ def calcMin(self,minMed):
697
+ ''' calcMin and sum media '''
698
+ #pri.Time.magenta(0,f"self.cont0={self.cont0}")
699
+ #self.cont+=self.cont0
700
+ #nImg=1 if self.flag_TR else 2
701
+ #nImg=2
702
+ for k in range(len(self.Imin)):
703
+ if minMed.contab[k]>0:
704
+ if self.contab[k]==0:
705
+ self.Imin[k]=minMed.Imin[k]
706
+ else:
707
+ self.Imin[k]=np.minimum(minMed.Imin[k],self.Imin[k])
708
+ self.med[k]=self.med[k]+minMed.med[k]
709
+ self.contab[k]+=minMed.contab[k]# uno viene comunque sommato in min
710
+
711
+ def calcMed(self):
712
+ ''' calcMed and sum media '''
713
+ pri.Time.magenta(f"calcMed contab={self.contab} ")
714
+ #nImg=1 if self.flag_TR else 2
715
+ if self.LaserType==0: # single laser
716
+ for cam in range(self.ncam):
717
+ k=self.nframe*cam
718
+ for j in range(1,self.nframe):
719
+ self.Imin[k]=np.minimum(self.Imin[k],self.Imin[k+j])
720
+ self.med[k]+=self.med[k+j]
721
+ self.contab[k]+=self.contab[k+j]
722
+ self.med[k]/=self.contab[k]
723
+ for j in range(1,self.nframe):
724
+ self.Imin[k+j]=self.Imin[k].copy()
725
+ self.med[k+j]=self.med[k].copy()
726
+ self.contab[k+j]=self.contab[k] #useless? I don't think so, important for restoreMin
727
+ else:
728
+ for k in range(len(self.Imin)):
729
+ if self.contab[k]>0:
730
+ self.med[k]/=self.contab[k]
731
+ pri.Time.magenta(f"calcMed fine contab={self.contab} ")
732
+
733
+
734
+
735
+ def restoreMin(self):
736
+ #pr(f"restoreMin contab={self.contab} self.cont={self.cont} self.cont0={self.cont0}")
737
+ #nImg=1 if self.flag_TR else 2
738
+ for k in range(len(self.Imin)):
739
+ self.med[k]*=self.contab[k]
740
+
741
+ def foList(li,formato):
742
+ ''' format a list call with
743
+ where:
744
+ li is a list
745
+ format is the format that would have been used fo a single element of the list
746
+ e.g. print(f'{a:<4d}') -> print(f'{foList([a a],"<4d")}')
747
+ '''
748
+ return f"{''.join(f' {x:{formato}}' for x in li)}"
749
+ # todo delete old function
750
+ def writeCfgProcPivOld(data,nomeFile,flagSpiv=False):
751
+ PIV=data2PIV(data,flagSpiv)
752
+ PIV.SetVect([v.astype(np.intc) for v in data.PRO.Vect])
753
+ inp=PIV.Inp
754
+ vect=data.PRO.Vect
755
+
756
+ with open(nomeFile,'w', encoding="utf8") as f:
757
+ f.write('%TA000N3 Do not modify the previous string - It indicates the file version\n')
758
+ f.write('% PIV process configuration file - A % symbol on the first column indicates a comment\n')
759
+ f.write('% Windows dimensions ***************************************\n')
760
+ # % Windows dimensions ***************************************
761
+ f.write(f'[{foList(vect[0],"<3d")}], Height of the windows (rows) - insert the sequence of numbers separated by a blank character (1)\n')
762
+ f.write(f'[{foList(vect[2],"<3d")}], Width of the windows (columns) (2)\n')
763
+ f.write(f'[{foList(vect[1],"<3d")}], Grid distance along the height direction (y) (3)\n')
764
+ f.write(f'[{foList(vect[3],"<3d")}], Grid distance along the width direction (x) (4)\n')
765
+ f.write(f'{inp.FlagBordo}, Flag boundary: if =1 the first vector is placed at a distance to the boundary equal to the grid distance (5)\n')
766
+ # % Process parameters - Interpolation ***********************************
767
+ f.write(f'% Process parameters - Interpolation ***********************************\n')
768
+ f.write(f'{inp.IntIniz}, Type of interpolation in the initial part of the process (6)\n')
769
+ f.write(f'{inp.IntFin}, Type of interpolation in the final part of the process (7)\n')
770
+ f.write(f'{inp.FlagInt}, Flag Interpolation: if >0 the final interpolation is used in the final #par iterations (8)\n')
771
+ f.write(f'{inp.IntCorr}, Type of interpolation of the correlation map (0=gauss classic; 1=gauss reviewed; 2=Simplex) (9)\n')
772
+ f.write(f'{inp.IntVel}, Type of interpolation of the velocity field (1=bilinear; 2= Simplex,...) (10)\n')
773
+ # % Process parameters **************************************\n')
774
+ f.write(f'% Process parameters **************************************\n')
775
+ f.write(f'{inp.FlagDirectCorr}, Flag direct correlation on the final iterations (0=no 1=yes ) (11)\n')
776
+ f.write(f'{inp.NIterazioni}, Number of final iterations (12)\n')
777
+ f.write(f'% Activation flags **************************************\n')
778
+ # % Activation flags - Validation **************************************
779
+ f.write(f'1, Flag Validation (0=default parameters (see manual); otherwise the validation parameters in the final part of the cfg file are activated) (13)\n')
780
+ f.write(f'1, Flag Windowing (0=default parameters (see manual); otherwise the windowing parameters in the final part of the cfg file are activated) (14)\n')
781
+ f.write(f'1, Flag Filter (0=default parameters (see manual); otherwise the additional filter parameters in the final part of the cfg file are activated) (29)\n')
782
+ f.write(f'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n')
783
+ f.write(f'%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n')
784
+ # % Process parameters - Validation **************************************
785
+
786
+ f.write(f'% Process parameters - Validation **************************************\n')
787
+ f.write(f'{inp.FlagValid}, Flag median test: 0=no; 1=classic; 2=universal (Scarano, Westerweel 2005) (15)\n')
788
+ f.write(f'{inp.SemiDimValid}, Half-dimension of the kernel (it uses 2*(#par)+1 vectors for each direction) (16)\n')
789
+ f.write(f'{inp.SogliaMed:.2f}, Threshold for the median test - Advised value 2 (1.0 - 3.0) (17)\n')
790
+ f.write(f'{inp.ErroreMed:.2f}, Allowed Error in pixel for the median test - Advised value 0.1 (0.0 -> no limits) (18)\n')
791
+ f.write(f'{inp.FlagAttivaValSN}, Flag test sn/CC: 0=no; 1=sn; 2=CC; 3=both +4 for limiting the maximum displacement (19)\n')
792
+ f.write(f'{inp.SogliaSN:.2f}, Threshold for the signal/noise test (Advised value 1.5) - it doesn\'t work on the direct correlation (20)\n')
793
+ f.write(f'{inp.SogliaFcl:.2f}, Threshold correlation coefficient (Advised value 0.25) (21)\n')
794
+ f.write(f'{inp.FlagSecMax}, Flag correction with the second maximum; 0=not active; otherwise it is active (22)\n')
795
+ f.write(f'{inp.FlagCorrezioneVel}, Flag correction vectors: 0=average on correct vectors; 1=weighted average with the distance; 2=iterative average (23)\n')
796
+ f.write(f'{inp.SogliaNoise:.2f}, Minimum allowed average value in the interrogation window (24)\n')
797
+ f.write(f'{inp.SogliaStd:.2f}, Minimum allowed std deviation value in the interrogation window(25)\n')
798
+ f.write(f'{inp.FlagValidNog}, Flag Nogueira Test (discontinued) : 0 --> no; !=0 -->yes (if activated disables the other validation criteria )\n')
799
+ f.write(f'0.2, First parameter Nogueira Test(0.20-0.35) \n')
800
+ f.write(f'0.1, Second parameter Nogueira Test(0.01-0.1) \n')
801
+ f.write(f'{0}, Hart Correction uses 4 interrogation windows W=W-W/Par e H=H-/Par 0 disables\n')
802
+ f.write(f'{0}, Value of info for a good vector \n')
803
+ f.write(f'{1}, Value of info for an outlier\n')
804
+ # % Windowing parameters (Astarita, Exp Flu, 2007) *************************
805
+ f.write(f'% Windowing parameters (Astarita EiF 2007) *************************\n')
806
+ f.write(f'{inp.FlagCalcVel}, Weighting window for absolute velocity (0=TopHat, 1=Nogueira, 2=Blackman,...) (26)\n')
807
+ f.write(f'{inp.FlagWindowing}, Weighting window for the correlation map (0=TopHat 1= Nogueira 2=Blackman 3=top hat at 50%) (27)\n')
808
+ f.write(f'{inp.SemiDimCalcVel}, Half-width of the filtering window (0=window dimension) (28)\n')
809
+ # % Adaptive PIV parameters (Astarita, Exp Flu, 2009) *************************
810
+ f.write(f'% Adaptive PIV parameters (Astarita EiF 2009) *************************\n')
811
+ f.write(f'{inp.MaxC:.3f}, Maximum value of zita (30)\n')
812
+ f.write(f'{inp.MinC:.3f}, Minimum value of zita (30) \n')
813
+ f.write(f'{inp.LarMin}, Minimum Half-width of the weighting window (31)\n')
814
+ f.write(f'{inp.LarMax}, Maximum Half-width of the weighting window (31)\n')
815
+ # % Further processing parameters *************************
816
+ f.write(f'% Further processing parameters *************************\n')
817
+ f.write(f'{inp.FlagSommaProd}, Flag product or sum of correlation 0 prod 1 sum (only used if par 27 or 11 are !=0) (32)\n')
818
+ f.write(f'{inp.ItAtt if not -1000 else 0 }, Flag for restarting from a previous process (0 no otherwise the previous iteration) (33)\n')
819
+ # % Filter parameters *************************
820
+ FlagFilt=0
821
+ CutOff=18
822
+ VelCut=-1
823
+ f.write(f'% Additional filter parameters 2009) *************************\n')
824
+ f.write(f'{FlagFilt:}, Flag for alternate direction filtering 0 disable 1 dense predictor 2 displacement (34)\n')
825
+ f.write(f'{CutOff:.2f}, Vertical Cutoff wavelength (35) \n')
826
+ f.write(f'{VelCut:.2f}, Vertical filter rate (36)\n')
827
+ f.write(f'{CutOff:.2f}, Horizontal Cutoff wavelength (35) \n')
828
+ f.write(f'{VelCut}, Horizontal filter rate (36)\n')
829
+ f.write(f'{inp.FlagRemNoise}, Flag to activate noise removal on the images (37)\n')
830
+ PercCap=-.001
831
+ PercFc=-3
832
+ f.write(f'{PercFc}, Parameter for noise removal (38)\n')
833
+ f.write(f'{PercCap}, Number of std to cap the particles (negative disables) (39)\n')
834
+
835
+
836
+ '''
837
+ try:
838
+ p=PaIRS_lib.PIV()
839
+ p.readCfgProc(nomeFile)
840
+ except Exception as inst:
841
+ pri.Error.white(inst.__cause__)
842
+
843
+ import inspect
844
+ notUsedKey=['FlagLog','HCellaVec','HOverlapVec','ImgH','ImgW','RisX','RisY','WCellaVec','WOverlapVec','dt','this' ]
845
+ diPro= dict(inspect.getmembers(PIV.Inp))
846
+ flagEqual=1
847
+ for k,v in inspect.getmembers(p.Inp):
848
+ if not k[0].startswith('_'):
849
+ if not k in notUsedKey:
850
+ if v!=diPro[k]:
851
+ flagEqual=0
852
+ print(f'{k}={v}->{diPro[k]}')
853
+ if flagEqual:
854
+ pr('The cfg is identical to the master')
855
+ #verifica uguaglianza PROpar, mancano i vettori
856
+ flagEqual=1
857
+ try:
858
+ pro=PIV2Pro(p)
859
+ pDum=data2PIV(data)
860
+ pDum.SetVect([v.astype(np.intc) for v in data.PRO.Vect])
861
+ pro=PIV2Pro(pDum)
862
+
863
+ notUsedKey=['change_top','copyfrom','copyfromdiz','duplicate','indexes','isDifferentFrom','isEqualTo','printDifferences','printPar','setup','tip','uncopied_fields','indTree','indItem']
864
+ listOfList=['Vect' ]
865
+ diPro= dict(inspect.getmembers(data.PRO))
866
+ #pro.printDifferences(data.PRO,[],[],True) #questo è automatico
867
+ for k,v in inspect.getmembers(pro):
868
+ if not k[0].startswith('_') and not k in notUsedKey:
869
+
870
+ if k in listOfList:
871
+
872
+ for i,(a,b) in enumerate(zip (v,diPro[k])):
873
+ if (a!=b).any():
874
+ flagEqual=0
875
+ print(f'{k}[{i}]={a}->{b}')
876
+ else:
877
+ if v!=diPro[k]:
878
+ flagEqual=0
879
+ print(f'{k}={v}->{diPro[k]}')
880
+ if flagEqual:
881
+ pr('The PROpar is identical to the master')
882
+ except Exception as inst:
883
+ pri.Error.red(f'{inst}')
884
+
885
+
886
+ #'''
887
+ def writeCfgProcPiv(data,nomeFile,flagSpiv=False):
888
+ PIV=data2PIV(data,flagSpiv)
889
+ inp=PIV.Inp
890
+ vect=PIV.GetVect()
891
+ vectWindowing=PIV.GetWindowingVect()
892
+
893
+ with open(nomeFile,'w', encoding="utf8") as f:
894
+ f.write('%TA000N5 Do not modify the previous string - It indicates the file version\n')
895
+ f.write('% PIV process configuration file - A % symbol on the first column indicates a comment\n')
896
+ f.write('% Windows dimensions position and iterations *******************************\n')
897
+ # % Windows dimensions position and iterations *******************************
898
+ f.write(f'[{foList(vect[0],"<3d")}], Height of the windows - sequence separated by a space (1)\n')
899
+ f.write(f'[{foList(vect[2],"<3d")}], Width of the IW if equal to -1 then square IW are used (1)\n')
900
+ f.write(f'[{foList(vect[1],"<3d")}], Grid distance along the height direction (y) (2)\n')
901
+ f.write(f'[{foList(vect[3],"<3d")}], Grid distance along x if equal to -1 then a square grid is used (2)\n')
902
+ f.write(f'{inp.FlagBordo}, Pos flag: 0 normal 1 1st vector is placed par#2 from the border (3)\n')
903
+ f.write(f'{inp.NIterazioni}, Number of final iterations (4)\n')
904
+
905
+ # % Process parameters - Interpolation ***********************************
906
+ f.write(f'% Process parameters - Interpolation ***********************************\n')
907
+ f.write(f'[{foList([inp.IntIniz,inp.FlagInt,inp.IntFin],"<3d")}], Image Interpolation: [intial; #iter; final] (5)\n')
908
+ f.write(f'{inp.IntCorr}, Correlation peak IS (3=gauss; 4=gauss reviewed; 5=Simplex) (6)\n')
909
+ f.write(f'{inp.IntVel}, Dense predictor IS (1=bilinear; 2=Simplex...) (7)\n')
910
+ # % Process parameters - Validation ******************************************\n')
911
+ f.write(f'% Process parameters - Validation ******************************************\n')
912
+ f.write(f'[{foList([inp.FlagValid,inp.SemiDimValid,inp.SogliaMed,inp.ErroreMed],".6g")}], Median test: [0=no; 1=med; 2=univ; kernel dim=1; thr=2; eps=0.1] (8)\n')
913
+ f.write(f'[{foList([inp.FlagAttivaValSN,inp.SogliaSN,inp.SogliaFcl],".6g")}], sn/CC test: [0=no; 1=sn; 2=CC; 3=both;sn thr=1.5; cc thr=0.3] (9)\n')
914
+ f.write(f'[{foList([inp.FlagValidNog,inp.SogliaMedia,inp.SogliaNumVet],".6g")}], Nog test:[0 no; 1 active; par1; par2] (10)\n')
915
+ f.write(f'[{foList([inp.SogliaNoise,inp.SogliaStd],".6g")}], Minimum threshold: [mean=2; std=3] (11)\n')
916
+ f.write(f'{inp.FlagCorrHart}, Hart correction 4 IW of W=W-W/Par are used o correct outliers (12)\n')
917
+ f.write(f'{inp.FlagSecMax}, Flag second maximum correction; 0 no 1 active (13)\n')
918
+ f.write(f'{inp.FlagCorrezioneVel}, Flag vectors correction: 0=average on correct vectors; 1=weighted average with the distance; 2=iterative average (14)\n')
919
+ f.write(f'[{foList([inp.InfoSi,inp.InfoNo],".6g")}], Output values (info): [value for good=1; value for corrected=0] (15)\n')
920
+ # % Windowing parameters (Astarita, Exp Flu, 2007) ***************************
921
+
922
+ f.write(f'% Windowing parameters (Astarita, Exp Flu, 2007) ***************************\n')
923
+ f.write(f'[{foList(vectWindowing[1],"<3d")}], WW for predictor (0=TopHat; 2=Blackman;...) (16)\n')
924
+ f.write(f'[{foList(vectWindowing[2],"<3d")}], WW for the correlation map (0=TopHat;2=Blackman 3=top hat at 50%)(17)\n')
925
+ f.write(f'[{foList(vectWindowing[3],"<3d")}], Half-width of the filtering window (0=window dimension) (18)\n')
926
+ f.write(f'[{foList(vectWindowing[4],"<3d")}], Flag direct correlation (0=no 1=yes ) (19)\n')
927
+ f.write(f'[{foList(vectWindowing[0],"<3d")}], Max displacement if <0 fraction of wa i.e. -4-> Wa/4 (20)\n')
928
+ f.write(f'{inp.FlagSommaProd}, Double CC operation (0 Product 1 sum) (21)\n')
929
+ f.write(f'[{foList([inp.flagAdaptive,inp.MaxC,inp.MinC,inp.LarMin,inp.LarMax],".6g")}], Adaptive process [0=no;#of it; par1; par2; par3; par4] (22)\n')
930
+ f.write(f'{inp.ItAtt if not -1000 else 0 }, Flag for restarting from a previous process (0 no; prev iter) (23)\n')
931
+ # % Filter parameters *******************************************************
932
+ f.write(f'% Filter parameters *******************************************************\n')
933
+ f.write(f'[{foList([inp.FlagFilt,inp.CutOffH,inp.VelCutH,inp.CutOffW,inp.VelCutW ],".6g")}], Additional AD filter [0 no; 1 Pred; 2 disp; cutoff H;Rate H;W;W] (24)\n')
934
+ f.write(f'[{foList([inp.FlagRemNoise,inp.PercFc,],".6g")}], Noise reduction removal of particles [0 no; it=2; perc=0.01] (25)\n')
935
+
936
+ f.write(f'[{0 if inp.PercCap<0 else 1:d} {abs(inp.PercCap):.6g}], Noise reduction capping [0 no; val=1.05] (26)\n')
937
+ f.write('\n')
938
+
939
+
940
+
941
+ '''
942
+ # Mettere alla fine di updateGuiFromTree
943
+ tree,_=self.w_Tree.pickTree(self.w_Tree.TREpar.indTree)
944
+ d=tree.currentItem().data(0,Qt.UserRole)
945
+ data:dataTreePar=self.w_Tree.TABpar_prev[d.indTree][d.indItem][d.ind]
946
+ data.writeCfgProcPiv()
947
+ #'''
948
+ '''
949
+ try:
950
+ p=PaIRS_lib.PIV()
951
+ p.readCfgProc(nomeFile)
952
+ except Exception as inst:
953
+ pri.Error.white(inst)
954
+
955
+ import inspect
956
+ notUsedKey=['FlagLog','HCellaVec','HOverlapVec','ImgH','ImgW','RisX','RisY','WCellaVec','WOverlapVec','dt','this' ,'FlagCalcVelVec', 'FlagDirectCorrVec','FlagWindowingVec','MaxDispInCCVec','SemiDimCalcVelVec' ]
957
+ diPro= dict(inspect.getmembers(PIV.Inp))
958
+ app=1e-6# to avoid false detections in case of float
959
+ flagEqual=1
960
+ for k,v in inspect.getmembers(p.Inp):
961
+ if not k[0].startswith('_'):
962
+ if not k in notUsedKey:
963
+ if v!=diPro[k]:
964
+ flagEqual=0
965
+ print(f'{k}={v}->{diPro[k]}')
966
+ if flagEqual:
967
+ pr('The cfg is identical to the master')
968
+ #verifica uguaglianza PROpar, mancano i vettori
969
+ flagEqual=1
970
+
971
+ try:
972
+ #pro=PIV2Pro(p)
973
+ pDum=data2PIV(data)
974
+ pDum.SetVect([v.astype(np.intc) for v in data.PRO.Vect])
975
+ pro=PIV2Pro(pDum)
976
+
977
+ notUsedKey=['change_top','copyfrom','copyfromdiz','duplicate','indexes','isDifferentFrom','isEqualTo','printDifferences','printPar','setup','tip','uncopied_fields','indTree','indItem']
978
+ listOfList=['Vect' ]## to add ,'windowingVect'
979
+ diPro= dict(inspect.getmembers(data.PRO))
980
+ #pro.printDifferences(data.PRO,[],[],True) #questo è automatico
981
+ for k,v in inspect.getmembers(pro):
982
+ if not k[0].startswith('_') and not k in notUsedKey:
983
+
984
+ if k in listOfList:
985
+
986
+ for i,(a,b) in enumerate(zip (v,diPro[k])):
987
+ if (a!=b).any():
988
+ flagEqual=0
989
+ print(f'{k}[{i}]={a}->{b}')
990
+ else:
991
+ if v!=diPro[k]:
992
+ if isinstance(v, float) and v !=0 :
993
+ if abs((v-diPro[k])/v) >app:
994
+ flagEqual=0
995
+ print(f'{k}={v}->{diPro[k]}')
996
+ if flagEqual:
997
+ pr('The PROpar is identical to the master')
998
+ except Exception as inst:
999
+ pri.Error.red(f'{inst}')
1000
+
1001
+
1002
+ #'''
1003
+ # TODO rivedere quando Gerardo aggiunge i vettori
1004
+ def PIV2Pro(piv:PaIRS_lib.PIV)-> PROpar:
1005
+ pro=PROpar()
1006
+
1007
+ #PIV.SetVect([v.astype(np.intc) for v in data.PRO.Vect])
1008
+ pro.Vect=[v.astype(np.intc) for v in piv.GetVect()]
1009
+ #pro.windowingVect=[v.astype(np.intc) for v in piv.GetVect()]
1010
+
1011
+ pro.SogliaNoise=piv.Inp.SogliaNoise
1012
+ pro.SogliaStd=piv.Inp.SogliaStd
1013
+ pro.SogliaMed=piv.Inp.SogliaMed
1014
+ pro.ErroreMed=piv.Inp.ErroreMed
1015
+ # Parameters not used in PaIrs but read by readcfg.
1016
+ # int FlagFilt;
1017
+ # Tom_Real CutOffH; // Lunghezza d'onda massima per il filtro
1018
+ # Tom_Real CutOffW; // Lunghezza d'onda massima per il filtro
1019
+ # Tom_Real VelCutH; // Rateo di filtraggio
1020
+ # Tom_Real VelCutW; //
1021
+ # Tom_Real PercCap; // PPercentuale massimo livello di grigio non trattato
1022
+ # Tom_Real PercFc; // Percentuale per considerare cattivo un punto
1023
+ # int FlagCorrHart; // Flag Per Correzione Hart
1024
+ # These parameters are not exposed in Inp if needed modify PIV_input.i
1025
+ #Valid Nog
1026
+ pro.SogliaMedia=0.25#piv.Inp.SogliaMedia
1027
+ pro.SogliaNumVet=0.10#piv.Inp.SogliaNumVet
1028
+ pro.FlagCorrHart=0#piv.Inp.SogliaNumVet
1029
+
1030
+ if piv.Inp.FlagValidNog==1:
1031
+ pro.FlagNogTest=1
1032
+ pro.FlagMedTest=0
1033
+ pro.FlagCPTest=0
1034
+ pro.FlagSNTest =0
1035
+ else:
1036
+ if piv.Inp.FlagValid>0 :
1037
+ pro.FlagMedTest=1
1038
+ pro.TypeMed=piv.Inp.FlagValid-1
1039
+ pro.KernMed=piv.Inp.SemiDimValid
1040
+ pro.FlagSecMax=piv.Inp.FlagSecMax
1041
+ pro.FlagSNTest =1 if piv.Inp.FlagAttivaValSN&1 else 0
1042
+ pro.FlagCPTest =1 if piv.Inp.FlagAttivaValSN&2 else 0
1043
+
1044
+ pro.SogliaSN=piv.Inp.SogliaSN
1045
+ pro.SogliaCP=piv.Inp.SogliaFcl
1046
+
1047
+ pro.IntIniz=piv.Inp.IntIniz
1048
+ pro.IntFin=piv.Inp.IntFin
1049
+ pro.FlagInt=piv.Inp.FlagInt
1050
+ pro.IntVel=piv.Inp.IntVel
1051
+ pro.FlagCorrezioneVel=piv.Inp.FlagCorrezioneVel
1052
+ #pro.FlagCorrHart=PIV.Inp.FlagCorrHart
1053
+ pro.IntCorr=piv.Inp.IntCorr
1054
+ pro.FlagWindowing=piv.Inp.FlagWindowing
1055
+
1056
+ pro.MaxC=piv.Inp.MaxC
1057
+ pro.MinC=piv.Inp.MinC
1058
+ pro.LarMin=piv.Inp.LarMin
1059
+ pro.LarMax=piv.Inp.LarMax
1060
+
1061
+ pro.FlagCalcVel=piv.Inp.FlagCalcVel
1062
+ pro.FlagSommaProd=piv.Inp.FlagSommaProd
1063
+ pro.FlagDirectCorr=piv.Inp.FlagDirectCorr
1064
+ pro.FlagBordo=piv.Inp.FlagBordo
1065
+
1066
+ if piv.Inp.SemiDimCalcVel<0:
1067
+ pro.NItAdaptative=-piv.Inp.SemiDimCalcVel
1068
+ pro.NIterazioni=piv.Inp.NIterazioni-pro.NItAdaptative
1069
+ pro.FlagAdaptative=1
1070
+ else:
1071
+ pro.SemiDimCalcVel=piv.Inp.SemiDimCalcVel
1072
+ pro.NIterazioni=piv.Inp.NIterazioni
1073
+ pro.FlagAdaptative=0
1074
+
1075
+ return pro
1076
+
1077
+ def data2PIV(data:dataTreePar,flagSpiv=False):
1078
+ OUT=OUTpar()
1079
+ OUT.copyfromdiz(data.OUT_dict)
1080
+ PRO=PROpar()
1081
+ PRO.copyfromdiz(data.PRO_dict)
1082
+
1083
+ if flagSpiv:
1084
+ PIV=PaIRS_lib.Stereo()
1085
+ else:
1086
+ PIV=PaIRS_lib.PIV()
1087
+
1088
+ PIV.DefaultValues()
1089
+ PIV.Inp.FlagNumThreads=data.numPivOmpCores
1090
+ #OUT=data.OUT
1091
+ #PRO=data.PRO
1092
+
1093
+ # % Windows dimensions position and iterations *******************************
1094
+ PIV.SetVect([np.array(v).astype(np.intc) for v in PRO.Vect])
1095
+ PIV.Inp.FlagBordo=PRO.FlagBordo
1096
+ PIV.Inp.NIterazioni=PRO.NIterazioni+PRO.NItAdaptative if PRO.FlagAdaptative else PRO.NIterazioni
1097
+ # % Process parameters - Interpolation ***********************************
1098
+ PIV.Inp.IntIniz=PRO.IntIniz
1099
+ PIV.Inp.FlagInt=PRO.FlagInt
1100
+ PIV.Inp.IntFin=PRO.IntFin
1101
+ PIV.Inp.IntCorr=PRO.IntCorr+3
1102
+ PIV.Inp.IntVel=PRO.IntVel
1103
+
1104
+ # % Process parameters - Validation ******************************************
1105
+ # Median test : [0 = no; 1 = med; 2 = univ, kernel dim = 1, thr = 2, eps = 0.1] (8)
1106
+ PIV.Inp.FlagValid=1 if PRO.TypeMed==0 else 2
1107
+ PIV.Inp.SemiDimValid=PRO.KernMed
1108
+ PIV.Inp.SogliaMed=PRO.SogliaMed
1109
+ PIV.Inp.ErroreMed=PRO.ErroreMed
1110
+ PIV.Inp.jumpDimValid=1
1111
+ # sn/CC test: [0=no; 1=sn; 2=CC; 3=both,sn thr=1.5, cc thr=0.3] (9)
1112
+ PIV.Inp.FlagAttivaValSN=1 if PRO.FlagSNTest else 0
1113
+ PIV.Inp.FlagAttivaValSN|=2 if PRO.FlagCPTest else 0
1114
+ PIV.Inp.SogliaSN=PRO.SogliaSN
1115
+ PIV.Inp.SogliaFcl=PRO.SogliaCP
1116
+
1117
+ # Nog test : [0 no; 1 active, par1, par2] (10)
1118
+ PIV.Inp.FlagValidNog=1 if PRO.FlagNogTest else 0
1119
+ PIV.Inp.SogliaMedia=PRO.SogliaMedia
1120
+ PIV.Inp.SogliaNumVet=PRO.SogliaNumVet
1121
+
1122
+ PIV.Inp.SogliaNoise=PRO.SogliaNoise
1123
+ PIV.Inp.SogliaStd=PRO.SogliaStd
1124
+
1125
+ PIV.Inp.FlagCorrHart=0 # to be seen
1126
+ PIV.Inp.FlagSecMax=1 if PRO.FlagSecMax else 0
1127
+ PIV.Inp.FlagCorrezioneVel=PRO.FlagCorrezioneVel
1128
+ # Output values(info) : [value for good = 1, value for corrected = 0] (16)
1129
+ PIV.Inp.InfoSi=1
1130
+ PIV.Inp.InfoNo=0
1131
+
1132
+ # % Windowing parameters (Astarita, Exp Flu, 2007) ***************************
1133
+ PIV.Inp.numInitIt=max(len(v) for v in PRO.Vect)
1134
+ PIV.Inp.FlagWindowing=PRO.FlagWindowing
1135
+ """
1136
+ if (PIV.Inp.FlagWindowing >= 0) :
1137
+ FlagWindowingVec=np.array([PIV.Inp.FlagWindowing],dtype=np.intc)
1138
+ else :
1139
+ numInitIt = PIV.Inp.numInitIt +1# if negative onlhy in the final iterations
1140
+ FlagWindowingVec=np.array([0 if ii<numInitIt -1 else -PIV.Inp.FlagWindowing for ii in range(numInitIt) ],dtype=np.intc)
1141
+ """
1142
+ FlagWindowingVec=np.array(PRO.vFlagWindowing,dtype=np.intc)
1143
+
1144
+ flagCalcVelVec=np.array(PRO.vFlagCalcVel,dtype=np.intc)
1145
+ semiDimCalcVelVec=np.array(PRO.vSemiDimCalcVel,dtype=np.intc)
1146
+
1147
+ PIV.Inp.FlagDirectCorr=PRO.FlagDirectCorr
1148
+ """
1149
+ if (PIV.Inp.FlagDirectCorr == 0) :
1150
+ FlagDirectCorrVec=np.array([PIV.Inp.FlagDirectCorr],dtype=np.intc)
1151
+ else :
1152
+ numInitIt = PIV.Inp.numInitIt +(PIV.Inp.FlagDirectCorr - 1)# if equal to 2 then should be one element longer
1153
+ FlagDirectCorrVec=np.array([0 if ii<numInitIt -1 else 1 for ii in range(numInitIt) ],dtype=np.intc)
1154
+ """
1155
+ FlagDirectCorrVec=np.array(PRO.vDC,dtype=np.intc)
1156
+
1157
+ maxDispInCCVec=np.array(PRO.vMaxDisp,dtype=np.intc)
1158
+ vect1=[maxDispInCCVec,flagCalcVelVec,FlagWindowingVec,semiDimCalcVelVec,FlagDirectCorrVec]
1159
+
1160
+ PIV.Inp.numInitIt=max(*[len(v) for v in vect1],PIV.Inp.numInitIt)
1161
+
1162
+ PIV.SetWindowingVect(vect1)
1163
+ PIV.Inp.FlagSommaProd=PRO.FlagSommaProd
1164
+
1165
+ # Adaptive process[0 = no; #of it, par1, par2, par3, par4](22)
1166
+ # questo è l'equivalente del c
1167
+ #PIV.Inp.flagAdaptive =-PIV.Inp.SemiDimCalcVel if PIV.Inp.SemiDimCalcVel <= -1 else 0
1168
+ #PIV.Inp.SemiDimCalcVel = abs(PIV.Inp.SemiDimCalcVel)
1169
+ #flagCalcVelVec=np.array(abs(PIV.Inp.SemiDimCalcVel),dtype=np.intc)
1170
+ PIV.Inp.flagAdaptive =PRO.NItAdaptative if PRO.FlagAdaptative else 0
1171
+ PIV.Inp.MaxC=PRO.MaxC
1172
+ PIV.Inp.MinC=PRO.MinC
1173
+ PIV.Inp.LarMin=PRO.LarMin
1174
+ PIV.Inp.LarMax=PRO.LarMax
1175
+
1176
+ PIV.Inp.ItAtt=-1000
1177
+
1178
+
1179
+ PIV.Inp.RisX=OUT.xres#*float(10.0)
1180
+ PIV.Inp.RisY=OUT.xres*OUT.pixAR#*float(10.0)
1181
+ PIV.Inp.dt=OUT.dt*float(10)
1182
+ PIV.Inp.ImgH=OUT.h
1183
+ PIV.Inp.ImgW=OUT.W
1184
+ ''' already done in DefaultValues
1185
+
1186
+ PIV.Inp.FlagFilt = 0; # Flag filtro: 0 nessuno, 1 AD,
1187
+ PIV.Inp.CutOffH=18; # Lunghezza d'onda massima per il filtro
1188
+ PIV.Inp.VelCutH=-1; # Rateo di filtraggio
1189
+ PIV.Inp.CutOffW=18; # Lunghezza d'onda massima per il filtro
1190
+ PIV.Inp.VelCutW=-1; #
1191
+ PIV.Inp.FlagRemNoise = 0; # Flag per eliminare rumore 0 no,1 si
1192
+ PIV.Inp.PercFc=0.01; # Percentuale per considerare cattivo un punto
1193
+ PIV.Inp.PercCap=-1.05; # PPercentuale massimo livello di grigio non trattato
1194
+ '''
1195
+
1196
+
1197
+ return PIV
1198
+
1199
+ def data2StereoPIV(data:dataTreePar):
1200
+ StereoPIV=data2PIV(data,flagSpiv=True)
1201
+
1202
+ OUT=OUTpar()
1203
+ OUT.copyfromdiz(data.OUT_dict)
1204
+ PRO=PROpar()
1205
+ PRO.copyfromdiz(data.PRO_dict)
1206
+
1207
+ spiv=StereoPIV.SPIVIn
1208
+ dP=StereoPIV.dataProc
1209
+ inPiv=StereoPIV.Inp
1210
+
1211
+ # STEREO CFG file
1212
+ # A €£ indicate that the feature is not enabled in the python wrapper
1213
+ spiv.nomecal='' # Root of calibration constants
1214
+ #spiv.NomeCostPiano=data.dispFile[:-4] # Root of disparity plane constants
1215
+
1216
+ spiv.percorsocal='' # Path of calibration constants
1217
+ spiv.FlagParallel=0 # Type of parallel process 0 horizontal 1 vertical (faster but with less information and mor RAM occupied)
1218
+ dP.FlagInt=StereoPIV.Inp.IntFin # IS for image reconstruction (only used when FlagRad==0)
1219
+ inPiv.FlagRad=1 # 1 internal (in piv) or 0 external de-warping of the images (the latter €£)
1220
+ dP.FlagCoordRad=0 # when equal to 0 the de-warping is carried on with the larger resolution (pix/mm)
1221
+ # when equal to 1 (2) the x (y) axis resolution is used
1222
+ spiv.salvarad=0 # if true and FlagRad is equal to 0 then the dewarped images are saved (€£)
1223
+
1224
+
1225
+ # % ********************* Input/Output
1226
+ spiv.FirstImg=0 # # of first img to be processed (€£)
1227
+ spiv.LastImg=0 # # of first last to be processed (€£)
1228
+ spiv.Digit=0 # number of figures i.e. zeros (MAX 10) (€£)
1229
+ spiv.ImgRoot='' # Root of the input Images (€£)
1230
+ spiv.InDir='' # Path of the images (€£)
1231
+ spiv.InExt='' # Extension of the images (€£)
1232
+ spiv.OutRoot ='' # Root of the output Files (€£)
1233
+ spiv.OutDir ='' # Output path (€£)
1234
+ spiv.OutExt ='' # Output extension (€£)
1235
+ spiv.OutFlag = 0 # type of output file : 0 binary Tecplot 1 ascii tecplot (€£)
1236
+ spiv.WrtFlag = 1 # 0 only mean values are saved 1 all the instantaneous images are written (€£)
1237
+
1238
+ spiv.RigaPart=OUT.x # Starting row (€£)
1239
+ spiv.ColPart=OUT.y # Starting Col (€£)
1240
+ dP.ImgH=OUT.H # Ending row
1241
+ dP.ImgW=OUT.W # Starting Col
1242
+ # % *********************** Process parameters
1243
+ dP.FlagZonaCom=0 # Flag for common zone should be equal to 0
1244
+ # Volume ********************************
1245
+ dP.xinfZC = OUT.x_min # minimum x world coordinates
1246
+ dP.yinfZC = OUT.y_min # minimum y world coordinates
1247
+ dP.xsupZC = OUT.x_max # maximum x world coordinates
1248
+ dP.ysupZC = OUT.y_max # maximum y world coordinates
1249
+ spiv.FlagRis=OUT.unit # 0 displacements in m/s 1 in pixels
1250
+ spiv.dt=OUT.dt # time separation. If the displacements in mm are needed use 1000 (and 0 for the previous parameter)
1251
+ spiv.Sfas=3 # in case of images in a single file the distance between images. Normally define the name (€£)
1252
+ # 1=a,b (after number); 2=_1,_2 (after number); 3=a,b (before number)
1253
+ # % Output
1254
+ spiv.FlagRotImg=0 # Rotation of the img 0=no rot 1=90°, 2=180° 3= 270° clockwise (£€)
1255
+ inPiv.FlagLog=9 # 0=no 1=video 2=log 3=video e log 4=Log short 5=video e log short (£€)
1256
+ spiv.StatFlag =0 # stat on: 1 all the vectors 0 only the good ones
1257
+ spiv.nomecfgPiv ='' # name of the cfg file for PIV
1258
+
1259
+ # ******************************
1260
+ flagReadCalConst=0# if true internal reading
1261
+ if flagReadCalConst:
1262
+ StereoPIV.readCalConst()
1263
+ else:
1264
+ c=0
1265
+ cost=[]
1266
+ for c in range(2):
1267
+ fileName=data.calList[c]
1268
+ flagCal,numCostCalib,costDum=readCalFile(fileName)
1269
+ if c==0:
1270
+ dP.FlagCal=flagCal
1271
+ dP.NumCostCalib=numCostCalib
1272
+ else:
1273
+ if (dP.FlagCal!=flagCal):
1274
+ raise('error the two calibration file are not compatible')
1275
+ cost.append(costDum)
1276
+ StereoPIV.setCalConst( flagCal, numCostCalib,cost)
1277
+
1278
+ StereoPIV.vect.PianoLaser[0]=np.float32(data.OUT_dict['zconst'])
1279
+ StereoPIV.vect.PianoLaser[1]=np.float32(data.OUT_dict['xterm'])
1280
+ StereoPIV.vect.PianoLaser[2]=np.float32(data.OUT_dict['yterm'])
1281
+ """
1282
+ flagReadPlaneConst=0# if true internal reading
1283
+ if flagReadPlaneConst:
1284
+ if StereoPIV.readPlaneConst()==0:
1285
+ pri.Callback.green('Laser plane constants correclty read!')
1286
+ else:
1287
+ pri.Error.red('Error while reading the file containing the laser plane constants!')
1288
+ data.laserConst=[const for const in StereoPIV.vect.PianoLaser]
1289
+ else:
1290
+ StereoPIV.vect.PianoLaser[0]=data.laserConst[0]
1291
+ StereoPIV.vect.PianoLaser[1]=data.laserConst[1]
1292
+ StereoPIV.vect.PianoLaser[2]=data.laserConst[2]
1293
+ #piv *******************************************************************************
1294
+ """
1295
+ #StereoPIV.readCfgProc(spiv.nomecfgPiv)
1296
+ return StereoPIV
1297
+
1298
+ def data2Disp(data:dataTreePar):
1299
+ OUT=OUTpar()
1300
+ OUT.copyfromdiz(data.OUT_dict)
1301
+ PRO_Disp=PROpar_Disp()
1302
+ PRO_Disp.copyfromdiz(data.PRO_Disp_dict)
1303
+
1304
+ Disp=PaIRS_lib.StereoDisp()
1305
+ spiv=Disp.SPIVIn
1306
+ dP=Disp.dataProc
1307
+ dAC=Disp.dispAvCo
1308
+
1309
+ spiv.nomecal='' #os.path.splitext(os.path.basename(INP.calList[0])) # Root of calibration constants
1310
+ spiv.percorsocal='' #os.path.dirname(INP.calList[0]) #Path of calibration constants
1311
+ spiv.ImgRoot='' # Root input Images
1312
+ spiv.InExt='' # Extension of the images
1313
+ spiv.InDir='' #Path of the images
1314
+ spiv.FirstImg=0 # # of first img to be processed
1315
+ spiv.LastImg=0 # # of first last to be processed
1316
+ spiv.Digit=0 # number of figures i.e. zeros (MAX 10)
1317
+
1318
+ spiv.RigaPart=OUT.y # Starting row
1319
+ spiv.ColPart=OUT.x # Starting column
1320
+ dP.ImgH=OUT.h # Ending row
1321
+ dP.ImgW=OUT.w # Starting row
1322
+ spiv.Sfas=1 # Sfasamento sub-immagini (righe a partire dall'origine): 0 per singola img: 1=a,b (finali); 2=_1,_2 (finali); 3=a,b (prima del numero sequenziale
1323
+ spiv.FlagImgTau=data.dispFrames # Img da processare: 0-entrambe; 1-solo la prima; 2-solo la seconda;PARAMETRO IGNORATO SE SFAS=0
1324
+
1325
+ #Output
1326
+ spiv.OutRoot = OUT.root # Root of output Files
1327
+ spiv.OutDir = OUT.path+OUT.subfold # Output path
1328
+ # Process parameters **********************
1329
+ dP.FlagInt=PRO_Disp.IntIniz # Metodo di raddrizzamento: 0=veloce (simp.), 1=quad…….
1330
+ dP.FlagZonaCom=0 # Flag per la zona comune: 0=coordinate nel piano oggetto; 1=coord. nel piano img
1331
+ spiv.Niter=PRO_Disp.Nit # Numero di iterazioni
1332
+ """
1333
+ if (spiv.Niter < 0) :
1334
+ spiv.WrtFlag = 1
1335
+ spiv.Niter = -spiv.Niter
1336
+ else:
1337
+ spiv.WrtFlag = 0
1338
+ """
1339
+
1340
+ dAC.HCella=PRO_Disp.Vect[0] # Correlation window Height
1341
+ dAC.WCella=PRO_Disp.Vect[2] # Correlation window Width
1342
+ dAC.HGrid=PRO_Disp.Vect[1] # Grid distance vertical
1343
+ dAC.WGrid=PRO_Disp.Vect[3] # Grid distance horizontal
1344
+ dAC.N_NormEpi=PRO_Disp.SemiWidth_Epipolar # Semiwidth in the direction normal to the epipolar line
1345
+ dAC.RaggioFiltro=PRO_Disp.Filter_SemiWidth # Semiwidth of the filter for the detection of the maximum in the displacement map
1346
+ dAC.SogliaCor = PRO_Disp.Threshold # Threshold for the determination of point used in the baricentric search of the maximum in the disp map
1347
+ dAC.nIterMaxValid = PRO_Disp.Nit_OutDet
1348
+ dAC.numStd = PRO_Disp.Std_Threshold
1349
+
1350
+ #%% Volume ********************************
1351
+ dP.xinfZC = OUT.x_min # Coordinata x inferiore
1352
+ dP.yinfZC = OUT.y_min # Coordinata y inferiore
1353
+ dP.xsupZC = OUT.x_max #28 # Coordinata x superiore
1354
+ dP.ysupZC = OUT.y_max #15 # Coordinata y superiore
1355
+ # ******************************
1356
+ flagReadCalConst=0# if true internal reading
1357
+ if flagReadCalConst:
1358
+ Disp.readCalConst()
1359
+ else:
1360
+ c=0
1361
+ cost=[]
1362
+ for c in range(2):
1363
+ fileName=data.calList[c]
1364
+ flagCal,numCostCalib,costDum=readCalFile(fileName)
1365
+ if c==0:
1366
+ dP.FlagCal=flagCal
1367
+ dP.NumCostCalib=numCostCalib
1368
+ else:
1369
+ if (dP.FlagCal!=flagCal):
1370
+ raise('error the two calibration file are not compatible')
1371
+ cost.append(costDum)
1372
+ Disp.setCalConst( flagCal, numCostCalib,cost)
1373
+
1374
+ flagReadPlaneConst=0# if true internal reading
1375
+ if flagReadPlaneConst:
1376
+ if Disp.readPlaneConst()==0:
1377
+ pri.Callback.green('readPlaneConst ok')
1378
+ else:
1379
+ Disp.vect.PianoLaser[0]=0
1380
+ Disp.vect.PianoLaser[1]=0
1381
+ Disp.vect.PianoLaser[2]=0
1382
+ return Disp
1383
+
1384
+ def printPIVLog(PD):
1385
+ stampa="It IW #IW #Vect/#Tot % CC CC(avg) DC%\n"# NR% Cap%\n"
1386
+ for j in range(len(PD.It)):
1387
+ riga="%3d %3dx%-3d %4dx%-4d %7d/%-7d %5.1f %8.7f %8.7f %4.1f\n" %\
1388
+ (PD.It[j], PD.WCella[j], PD.HCella[j], PD.W[j], PD.H[j], PD.NVect[j],\
1389
+ PD.W[j]*PD.H[j], 100.0*PD.NVect[j]/(PD.W[j]*PD.H[j]), PD.Fc[j],\
1390
+ PD.FcMedia[j], 100.0*PD.ContErorreDc[j]/(PD.W[j]*PD.H[j]))#,\
1391
+ #100.0*PIV.PD.ContRemNoise[j]/(PIV.Inp.ImgW*PIV.Inp.ImgH),\
1392
+ #100.0*PIV.PD.ContCap[j]/(PIV.Inp.ImgW*PIV.Inp.ImgH))
1393
+ stampa=stampa+riga
1394
+ return stampa
1395
+
1396
+
1397
+ def saveMin(data:dataTreePar,Imin=list):
1398
+ pri.Time.magenta('saveMin Init ')
1399
+ frames='ab'
1400
+ #nImg=1 if self.flag_TR else 2
1401
+ #nImg=2
1402
+ for j in range(len(Imin)):
1403
+ k=j%data.nframe
1404
+ cam=j//data.nframe%data.ncam
1405
+ name_min=f"{data.outPathRoot}_cam{cam+1}_{frames[k]}_min.png"
1406
+ im = Image.fromarray(Imin[j])
1407
+ im.save(name_min)
1408
+ pri.Time.magenta('saveMin End')
1409
+
1410
+ def saveResults(data:dataTreePar,i,Var,nameVar):
1411
+ #pri.Time.magenta('saveResults Init')
1412
+ if type(i)==int:
1413
+ if i<0:
1414
+ nameFileOut=data.resF('*').replace('_*','')
1415
+ else:
1416
+ nameFileOut=data.resF(i)
1417
+ elif type(i)==str:
1418
+ nameFileOut=data.resF(i)
1419
+ #infoPrint.white(f'---> Saving field #{i}: {nameFileOut}')
1420
+
1421
+ if '.plt' in data.outExt:
1422
+ writePlt(nameFileOut,Var,f'PaIRS - 2D PIV',nameVar,nameFileOut)
1423
+ elif '.mat' in data.outExt:
1424
+ dict_out={}
1425
+ for j in range(len(nameVar)):
1426
+ dict_out[nameVar[j]]=Var[j]
1427
+ scipy.io.savemat(nameFileOut,dict_out)
1428
+ #import timeit
1429
+ #timeit.timeit (lambda :'writePlt(nameFileOut,Var,"b16",nameVar,nameFileOut)')
1430
+ #timeit.timeit (lambda :'scipy.io.savemat(nameFileOut,dict_out)')
1431
+ #pri.Time.magenta('saveResults End')
1432
+ return
1433
+
1434
+ def memoryUsagePsutil():
1435
+ ''' return the memory usage in MB '''
1436
+ process = psutil.Process(os.getpid())
1437
+ mem = process.memory_info().rss
1438
+ #print(f"Memory={mem/ float(2 ** 20)}MByte")
1439
+ return mem