pivtools 0.1.3__cp311-cp311-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 (127) hide show
  1. pivtools-0.1.3.dist-info/METADATA +222 -0
  2. pivtools-0.1.3.dist-info/RECORD +127 -0
  3. pivtools-0.1.3.dist-info/WHEEL +5 -0
  4. pivtools-0.1.3.dist-info/entry_points.txt +3 -0
  5. pivtools-0.1.3.dist-info/top_level.txt +3 -0
  6. pivtools_cli/__init__.py +5 -0
  7. pivtools_cli/_build_marker.c +25 -0
  8. pivtools_cli/_build_marker.cp311-win_amd64.pyd +0 -0
  9. pivtools_cli/cli.py +225 -0
  10. pivtools_cli/example.py +139 -0
  11. pivtools_cli/lib/PIV_2d_cross_correlate.c +334 -0
  12. pivtools_cli/lib/PIV_2d_cross_correlate.h +22 -0
  13. pivtools_cli/lib/common.h +36 -0
  14. pivtools_cli/lib/interp2custom.c +146 -0
  15. pivtools_cli/lib/interp2custom.h +48 -0
  16. pivtools_cli/lib/peak_locate_gsl.c +711 -0
  17. pivtools_cli/lib/peak_locate_gsl.h +40 -0
  18. pivtools_cli/lib/peak_locate_gsl_print.c +736 -0
  19. pivtools_cli/lib/peak_locate_lm.c +751 -0
  20. pivtools_cli/lib/peak_locate_lm.h +27 -0
  21. pivtools_cli/lib/xcorr.c +342 -0
  22. pivtools_cli/lib/xcorr.h +31 -0
  23. pivtools_cli/lib/xcorr_cache.c +78 -0
  24. pivtools_cli/lib/xcorr_cache.h +26 -0
  25. pivtools_cli/piv/interp2custom/interp2custom.py +69 -0
  26. pivtools_cli/piv/piv.py +240 -0
  27. pivtools_cli/piv/piv_backend/base.py +825 -0
  28. pivtools_cli/piv/piv_backend/cpu_instantaneous.py +1005 -0
  29. pivtools_cli/piv/piv_backend/factory.py +28 -0
  30. pivtools_cli/piv/piv_backend/gpu_instantaneous.py +15 -0
  31. pivtools_cli/piv/piv_backend/infilling.py +445 -0
  32. pivtools_cli/piv/piv_backend/outlier_detection.py +306 -0
  33. pivtools_cli/piv/piv_backend/profile_cpu_instantaneous.py +230 -0
  34. pivtools_cli/piv/piv_result.py +40 -0
  35. pivtools_cli/piv/save_results.py +342 -0
  36. pivtools_cli/piv_cluster/cluster.py +108 -0
  37. pivtools_cli/preprocessing/filters.py +399 -0
  38. pivtools_cli/preprocessing/preprocess.py +79 -0
  39. pivtools_cli/tests/helpers.py +107 -0
  40. pivtools_cli/tests/instantaneous_piv/test_piv_integration.py +167 -0
  41. pivtools_cli/tests/instantaneous_piv/test_piv_integration_multi.py +553 -0
  42. pivtools_cli/tests/preprocessing/test_filters.py +41 -0
  43. pivtools_core/__init__.py +5 -0
  44. pivtools_core/config.py +703 -0
  45. pivtools_core/config.yaml +135 -0
  46. pivtools_core/image_handling/__init__.py +0 -0
  47. pivtools_core/image_handling/load_images.py +464 -0
  48. pivtools_core/image_handling/readers/__init__.py +53 -0
  49. pivtools_core/image_handling/readers/generic_readers.py +50 -0
  50. pivtools_core/image_handling/readers/lavision_reader.py +190 -0
  51. pivtools_core/image_handling/readers/registry.py +24 -0
  52. pivtools_core/paths.py +49 -0
  53. pivtools_core/vector_loading.py +248 -0
  54. pivtools_gui/__init__.py +3 -0
  55. pivtools_gui/app.py +687 -0
  56. pivtools_gui/calibration/__init__.py +0 -0
  57. pivtools_gui/calibration/app/__init__.py +0 -0
  58. pivtools_gui/calibration/app/views.py +1186 -0
  59. pivtools_gui/calibration/calibration_planar/planar_calibration_production.py +570 -0
  60. pivtools_gui/calibration/vector_calibration_production.py +544 -0
  61. pivtools_gui/config.py +703 -0
  62. pivtools_gui/image_handling/__init__.py +0 -0
  63. pivtools_gui/image_handling/load_images.py +464 -0
  64. pivtools_gui/image_handling/readers/__init__.py +53 -0
  65. pivtools_gui/image_handling/readers/generic_readers.py +50 -0
  66. pivtools_gui/image_handling/readers/lavision_reader.py +190 -0
  67. pivtools_gui/image_handling/readers/registry.py +24 -0
  68. pivtools_gui/masking/__init__.py +0 -0
  69. pivtools_gui/masking/app/__init__.py +0 -0
  70. pivtools_gui/masking/app/views.py +123 -0
  71. pivtools_gui/paths.py +49 -0
  72. pivtools_gui/piv_runner.py +261 -0
  73. pivtools_gui/pivtools.py +58 -0
  74. pivtools_gui/plotting/__init__.py +0 -0
  75. pivtools_gui/plotting/app/__init__.py +0 -0
  76. pivtools_gui/plotting/app/views.py +1671 -0
  77. pivtools_gui/plotting/plot_maker.py +220 -0
  78. pivtools_gui/post_processing/POD/__init__.py +0 -0
  79. pivtools_gui/post_processing/POD/app/__init__.py +0 -0
  80. pivtools_gui/post_processing/POD/app/views.py +647 -0
  81. pivtools_gui/post_processing/POD/pod_decompose.py +979 -0
  82. pivtools_gui/post_processing/POD/views.py +1096 -0
  83. pivtools_gui/post_processing/__init__.py +0 -0
  84. pivtools_gui/static/404.html +1 -0
  85. pivtools_gui/static/_next/static/chunks/117-d5793c8e79de5511.js +2 -0
  86. pivtools_gui/static/_next/static/chunks/484-cfa8b9348ce4f00e.js +1 -0
  87. pivtools_gui/static/_next/static/chunks/869-320a6b9bdafbb6d3.js +1 -0
  88. pivtools_gui/static/_next/static/chunks/app/_not-found/page-12f067ceb7415e55.js +1 -0
  89. pivtools_gui/static/_next/static/chunks/app/layout-b907d5f31ac82e9d.js +1 -0
  90. pivtools_gui/static/_next/static/chunks/app/page-334cc4e8444cde2f.js +1 -0
  91. pivtools_gui/static/_next/static/chunks/fd9d1056-ad15f396ddf9b7e5.js +1 -0
  92. pivtools_gui/static/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
  93. pivtools_gui/static/_next/static/chunks/main-a1b3ced4d5f6d998.js +1 -0
  94. pivtools_gui/static/_next/static/chunks/main-app-8a63c6f5e7baee11.js +1 -0
  95. pivtools_gui/static/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
  96. pivtools_gui/static/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
  97. pivtools_gui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  98. pivtools_gui/static/_next/static/chunks/webpack-4a8ca7c99e9bb3d8.js +1 -0
  99. pivtools_gui/static/_next/static/css/7d3f2337d7ea12a5.css +3 -0
  100. pivtools_gui/static/_next/static/vQeR20OUdSSKlK4vukC4q/_buildManifest.js +1 -0
  101. pivtools_gui/static/_next/static/vQeR20OUdSSKlK4vukC4q/_ssgManifest.js +1 -0
  102. pivtools_gui/static/file.svg +1 -0
  103. pivtools_gui/static/globe.svg +1 -0
  104. pivtools_gui/static/grid.svg +8 -0
  105. pivtools_gui/static/index.html +1 -0
  106. pivtools_gui/static/index.txt +8 -0
  107. pivtools_gui/static/next.svg +1 -0
  108. pivtools_gui/static/vercel.svg +1 -0
  109. pivtools_gui/static/window.svg +1 -0
  110. pivtools_gui/stereo_reconstruction/__init__.py +0 -0
  111. pivtools_gui/stereo_reconstruction/app/__init__.py +0 -0
  112. pivtools_gui/stereo_reconstruction/app/views.py +1985 -0
  113. pivtools_gui/stereo_reconstruction/stereo_calibration_production.py +606 -0
  114. pivtools_gui/stereo_reconstruction/stereo_reconstruction_production.py +544 -0
  115. pivtools_gui/utils.py +63 -0
  116. pivtools_gui/vector_loading.py +248 -0
  117. pivtools_gui/vector_merging/__init__.py +1 -0
  118. pivtools_gui/vector_merging/app/__init__.py +1 -0
  119. pivtools_gui/vector_merging/app/views.py +759 -0
  120. pivtools_gui/vector_statistics/app/__init__.py +1 -0
  121. pivtools_gui/vector_statistics/app/views.py +710 -0
  122. pivtools_gui/vector_statistics/ensemble_statistics.py +49 -0
  123. pivtools_gui/vector_statistics/instantaneous_statistics.py +311 -0
  124. pivtools_gui/video_maker/__init__.py +0 -0
  125. pivtools_gui/video_maker/app/__init__.py +0 -0
  126. pivtools_gui/video_maker/app/views.py +436 -0
  127. pivtools_gui/video_maker/video_maker.py +662 -0
@@ -0,0 +1,167 @@
1
+ import unittest
2
+ from pathlib import Path
3
+ from unittest import skip
4
+ from unittest.mock import MagicMock, patch
5
+
6
+ import dask.array as da
7
+ import h5py
8
+ import numpy as np
9
+ import pandas as pd
10
+ import pytest
11
+ import tifffile
12
+ from dask.distributed import get_worker
13
+ from scipy.io import loadmat
14
+
15
+ from pivtools_cli.config import Config
16
+ from pivtools_cli.piv.piv_backend.base import CrossCorrelator
17
+ from pivtools_cli.piv.piv_backend.cpu_instantaneous import InstantaneousCorrelatorCPU
18
+ from pivtools_cli.piv.piv_backend.factory import make_correlator_backend
19
+ from pivtools_cli.tests.helpers import assert_arrays_close, compare_matrices
20
+
21
+
22
+ def _fake_inpaint_biharm(self, x: np.ndarray) -> np.ndarray:
23
+ return np.nan_to_num(x, nan=1.0)
24
+
25
+
26
+ class InstantaneousPIVTestCase(unittest.TestCase):
27
+
28
+ def setUp(self):
29
+ test_dir = Path(__file__).parent
30
+ config_path = test_dir / "config.yaml"
31
+ self.config = Config(config_path)
32
+ self.config.data["paths"]["base_path"] = str(
33
+ test_dir.parent / "data" / "instantaneous_piv"
34
+ )
35
+ camera_path = self.config.base_path / self.config.cameras[0]
36
+ file_paths = [
37
+ camera_path / (self.config.image_format % 1),
38
+ camera_path / (self.config.image_format.replace("_A", "_B") % 1),
39
+ ]
40
+
41
+ self.img_pair = np.stack(
42
+ [
43
+ tifffile.imread(file_paths[0]).astype(self.config.image_dtype),
44
+ tifffile.imread(file_paths[1]).astype(self.config.image_dtype),
45
+ ],
46
+ axis=0,
47
+ )
48
+ C, H, W = self.img_pair.shape
49
+ self.img_pair = self.img_pair.reshape((1, C, H, W))
50
+ self.base_path = Path(self.config.data["paths"]["base_path"]) / "Matlab"
51
+
52
+ inpaint_patcher = patch(
53
+ "pivtools_cli.piv.piv_backend.cpu_instantaneous.InstantaneousCorrelatorCPU._inpaint_nans_biharm",
54
+ new=_fake_inpaint_biharm,
55
+ )
56
+ self._mock_inpaint = inpaint_patcher.start()
57
+ fake_worker = MagicMock()
58
+ fake_worker.name = "worker-123"
59
+ self._worker_patcher = patch(
60
+ "pivtools_cli.piv.piv_backend.cpu_instantaneous.get_worker",
61
+ return_value=fake_worker,
62
+ )
63
+ self._worker_patcher.start()
64
+
65
+ def test_peak_height(self):
66
+ """Test peak heights against MATLAB results"""
67
+ self.config.data["piv"]["secondary_peak"] = False
68
+ cpu_backend = make_correlator_backend(config=self.config)
69
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
70
+ for i in range(1, len(self.config.window_sizes) + 1):
71
+ peak_height_mat_file = self.base_path / f"MATLAB_peak_height_{i}.mat"
72
+ with h5py.File(peak_height_mat_file, "r") as f:
73
+ matlab_peaks = np.array(f["peak_height"], dtype=np.float32)
74
+
75
+ matlab_peaks = np.transpose(matlab_peaks, (2, 1, 0))
76
+ assert_arrays_close(
77
+ self, matlab_peaks, piv_result.passes[i - 1].peak_mag, tol=0.0001
78
+ )
79
+
80
+ def test_ux_mat(self):
81
+ """Test x displacement field against MATLAB results"""
82
+ self.config.data["piv"]["secondary_peak"] = False
83
+ cpu_backend = make_correlator_backend(config=self.config)
84
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
85
+ for i in range(2, len(self.config.window_sizes) + 1):
86
+ ux_mat_file = self.base_path / f"MATLAB_ux_mat_{i}.mat"
87
+
88
+ with h5py.File(ux_mat_file, "r") as f:
89
+ matlab_ux_mat = np.array(f["ux_mat"], dtype=np.float32)
90
+ matlab_ux_mat = np.transpose(matlab_ux_mat, (1, 0))
91
+ print("UX", matlab_ux_mat[0], piv_result.passes[i - 1].ux_mat[0])
92
+ assert_arrays_close(
93
+ self, matlab_ux_mat, piv_result.passes[i - 1].ux_mat, tol=0.0001
94
+ )
95
+
96
+ def test_uy_mat(self):
97
+ """Test y displacement field against MATLAB results"""
98
+ self.config.data["piv"]["secondary_peak"] = False
99
+ cpu_backend = make_correlator_backend(config=self.config)
100
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
101
+ for i in range(1, 3): # len(self.config.window_sizes)+1):
102
+ uy_mat_file = self.base_path / f"MATLAB_uy_mat_{i}.mat"
103
+ with h5py.File(uy_mat_file, "r") as f:
104
+ matlab_uy_mat = np.array(f["uy_mat"], dtype=np.float32)
105
+ matlab_uy_mat = np.transpose(matlab_uy_mat, (1, 0))
106
+ compare_matrices(matlab_uy_mat, piv_result.passes[i - 1].uy_mat)
107
+ assert_arrays_close(
108
+ self, matlab_uy_mat, piv_result.passes[i - 1].uy_mat, tol=1.001
109
+ )
110
+
111
+ def test_nan(self):
112
+ """Test nan mask against MATLAB results"""
113
+ self.config.data["piv"]["secondary_peak"] = False
114
+ cpu_backend = make_correlator_backend(config=self.config)
115
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
116
+
117
+ for i in range(1, 3): # self.MAX_PASS): # len(self.config.window_sizes)+1):
118
+ nan_file = self.base_path / f"MATLAB_nan_{i}.mat"
119
+ with h5py.File(nan_file, "r") as f:
120
+ matlab_nan = np.array(f["nan_mask"], dtype=bool)
121
+
122
+ matlab_nan = np.transpose(matlab_nan, (1, 0))
123
+ python_nan = piv_result.passes[i - 1].nan_mask
124
+ try:
125
+ np.testing.assert_array_equal(matlab_nan, python_nan)
126
+ except AssertionError:
127
+ diff = matlab_nan != python_nan
128
+ idx = np.argwhere(diff)
129
+
130
+ print(f"nan_mask mismatch: {len(idx)} elements differ")
131
+ for r, c in idx[:]:
132
+ print(
133
+ f"({r},{c}): MATLAB={matlab_nan[r,c]}, Python={python_nan[r,c]}"
134
+ )
135
+ raise
136
+
137
+ def test_q_mat(self):
138
+ """Test Q matrix against MATLAB results"""
139
+ self.config.data["piv"]["secondary_peak"] = True
140
+ cpu_backend = make_correlator_backend(config=self.config)
141
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
142
+ for i in range(1, len(self.config.window_sizes) + 1):
143
+ q_mat_file = self.base_path / f"MATLAB_Qmat_{i}.mat"
144
+ with h5py.File(q_mat_file, "r") as f:
145
+ matlab_q_mat = np.array(f["Q_mat"], dtype=np.float32)
146
+ matlab_q_mat = np.transpose(matlab_q_mat, (0, 2, 1))
147
+ assert_arrays_close(
148
+ self, matlab_q_mat, piv_result.passes[i - 1].Q_mat, tol=0.1
149
+ )
150
+
151
+ def test_delta_ab_old(self):
152
+ """Test delta_ab_old matrix against MATLAB results"""
153
+
154
+ self.config.data["piv"]["secondary_peak"] = False
155
+ cpu_backend = make_correlator_backend(config=self.config)
156
+ piv_result = cpu_backend.correlate_batch(self.img_pair, self.config)
157
+ for i in range(1, len(self.config.window_sizes) + 1):
158
+ q_mat_file = self.base_path / f"MATLAB_delta_ab_old_padded_{i}.mat"
159
+ with h5py.File(q_mat_file, "r") as f:
160
+ matlab_delta_ab_old = np.array(f["delta_ab_old"], dtype=np.float32)
161
+ matlab_delta_ab_old = np.transpose(matlab_delta_ab_old, (2, 1, 0))
162
+ assert_arrays_close(
163
+ self,
164
+ matlab_delta_ab_old,
165
+ piv_result.passes[i - 1].predictor_field,
166
+ tol=0.01,
167
+ )