pyvale 2025.5.3__cp311-cp311-musllinux_1_2_i686.whl → 2025.7.1__cp311-cp311-musllinux_1_2_i686.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.

Potentially problematic release.


This version of pyvale might be problematic. Click here for more details.

Files changed (98) hide show
  1. pyvale/__init__.py +12 -0
  2. pyvale/blendercalibrationdata.py +3 -1
  3. pyvale/blenderscene.py +7 -5
  4. pyvale/blendertools.py +27 -5
  5. pyvale/camera.py +1 -0
  6. pyvale/cameradata.py +3 -0
  7. pyvale/camerasensor.py +147 -0
  8. pyvale/camerastereo.py +4 -4
  9. pyvale/cameratools.py +23 -61
  10. pyvale/cython/rastercyth.c +1657 -1352
  11. pyvale/cython/rastercyth.cpython-311-i386-linux-musl.so +0 -0
  12. pyvale/cython/rastercyth.py +71 -26
  13. pyvale/data/DIC_Challenge_Star_Noise_Def.tiff +0 -0
  14. pyvale/data/DIC_Challenge_Star_Noise_Ref.tiff +0 -0
  15. pyvale/data/plate_hole_def0000.tiff +0 -0
  16. pyvale/data/plate_hole_def0001.tiff +0 -0
  17. pyvale/data/plate_hole_ref0000.tiff +0 -0
  18. pyvale/data/plate_rigid_def0000.tiff +0 -0
  19. pyvale/data/plate_rigid_def0001.tiff +0 -0
  20. pyvale/data/plate_rigid_ref0000.tiff +0 -0
  21. pyvale/dataset.py +96 -6
  22. pyvale/dic/cpp/dicbruteforce.cpp +370 -0
  23. pyvale/dic/cpp/dicfourier.cpp +648 -0
  24. pyvale/dic/cpp/dicinterpolator.cpp +559 -0
  25. pyvale/dic/cpp/dicmain.cpp +215 -0
  26. pyvale/dic/cpp/dicoptimizer.cpp +675 -0
  27. pyvale/dic/cpp/dicrg.cpp +137 -0
  28. pyvale/dic/cpp/dicscanmethod.cpp +677 -0
  29. pyvale/dic/cpp/dicsmooth.cpp +138 -0
  30. pyvale/dic/cpp/dicstrain.cpp +383 -0
  31. pyvale/dic/cpp/dicutil.cpp +563 -0
  32. pyvale/dic2d.py +164 -0
  33. pyvale/dic2dcpp.cpython-311-i386-linux-musl.so +0 -0
  34. pyvale/dicchecks.py +476 -0
  35. pyvale/dicdataimport.py +247 -0
  36. pyvale/dicregionofinterest.py +887 -0
  37. pyvale/dicresults.py +55 -0
  38. pyvale/dicspecklegenerator.py +238 -0
  39. pyvale/dicspecklequality.py +305 -0
  40. pyvale/dicstrain.py +387 -0
  41. pyvale/dicstrainresults.py +37 -0
  42. pyvale/errorintegrator.py +10 -8
  43. pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +124 -113
  44. pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +124 -132
  45. pyvale/examples/basics/ex1_3_customsens_therm3d.py +199 -195
  46. pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +125 -121
  47. pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +145 -141
  48. pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +96 -101
  49. pyvale/examples/basics/ex1_7_spatavg_therm2d.py +109 -105
  50. pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +92 -91
  51. pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +96 -90
  52. pyvale/examples/basics/ex2_3_sensangle_disp2d.py +88 -89
  53. pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +172 -171
  54. pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +88 -86
  55. pyvale/examples/basics/ex3_1_basictensors_strain2d.py +90 -90
  56. pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +93 -91
  57. pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +172 -160
  58. pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +154 -148
  59. pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +249 -231
  60. pyvale/examples/dic/ex1_region_of_interest.py +98 -0
  61. pyvale/examples/dic/ex2_plate_with_hole.py +149 -0
  62. pyvale/examples/dic/ex3_plate_with_hole_strain.py +93 -0
  63. pyvale/examples/dic/ex4_dic_blender.py +95 -0
  64. pyvale/examples/dic/ex5_dic_challenge.py +102 -0
  65. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +4 -2
  66. pyvale/examples/renderblender/ex1_1_blenderscene.py +152 -105
  67. pyvale/examples/renderblender/ex1_2_blenderdeformed.py +151 -100
  68. pyvale/examples/renderblender/ex2_1_stereoscene.py +183 -116
  69. pyvale/examples/renderblender/ex2_2_stereodeformed.py +185 -112
  70. pyvale/examples/renderblender/ex3_1_blendercalibration.py +164 -109
  71. pyvale/examples/renderrasterisation/ex_rastenp.py +74 -35
  72. pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +6 -13
  73. pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +2 -2
  74. pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +2 -4
  75. pyvale/imagedef2d.py +3 -2
  76. pyvale/imagetools.py +137 -0
  77. pyvale/rastercy.py +34 -4
  78. pyvale/rasternp.py +300 -276
  79. pyvale/rasteropts.py +58 -0
  80. pyvale/renderer.py +47 -0
  81. pyvale/rendermesh.py +52 -62
  82. pyvale/renderscene.py +51 -0
  83. pyvale/sensorarrayfactory.py +2 -2
  84. pyvale/sensortools.py +19 -35
  85. pyvale/simcases/case21.i +1 -1
  86. pyvale/simcases/run_1case.py +8 -0
  87. pyvale/simtools.py +2 -2
  88. pyvale/visualsimplotter.py +180 -0
  89. {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/METADATA +11 -57
  90. {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/RECORD +96 -56
  91. {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/WHEEL +1 -1
  92. pyvale.libs/libgcc_s-887de51c.so.1 +0 -0
  93. pyvale.libs/libgomp-24921df4.so.1.0.0 +0 -0
  94. pyvale.libs/libstdc++-d6415257.so.6.0.33 +0 -0
  95. pyvale/examples/visualisation/ex1_1_plot_traces.py +0 -102
  96. pyvale/examples/visualisation/ex2_1_animate_sim.py +0 -89
  97. {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/licenses/LICENSE +0 -0
  98. {pyvale-2025.5.3.dist-info → pyvale-2025.7.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,247 @@
1
+ # ================================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ================================================================================
6
+
7
+
8
+
9
+ import numpy as np
10
+ import glob
11
+ import os
12
+ from pathlib import Path
13
+
14
+ # import cython module
15
+ from pyvale.dicresults import DICResults
16
+
17
+ """
18
+ Module responsible for handling importing of DIC results from completed
19
+ calculations.
20
+ """
21
+
22
+
23
+ def dic_data_import(data: str | Path,
24
+ binary: bool = False,
25
+ layout: str = "matrix",
26
+ delimiter: str = " ") -> DICResults:
27
+ """
28
+ Import DIC result data from human readable text or binary files.
29
+
30
+ Parameters
31
+ ----------
32
+
33
+ data : str or pathlib.Path
34
+ Path pattern to the data files (can include wildcards). Default is "./".
35
+
36
+ layout : str, optional
37
+ Format of the output data layout: "column" (flat array per frame) or "matrix"
38
+ (reshaped grid per frame). Default is "column".
39
+
40
+ binary : bool, optional
41
+ If True, expects files in a specific binary format. If False, expects text data.
42
+ Default is False.
43
+
44
+ delimiter : str, optional
45
+ Delimiter used in text data files. Ignored if binary=True. Default is a single space.
46
+
47
+ Returns
48
+ -------
49
+ DICResults
50
+ A named container with the following fields:
51
+ - ss_x, ss_y (grid arrays if layout=="matrix"; otherwise, 1D integer arrays)
52
+ - u, v, m, converged, cost, ftol, xtol, niter (arrays with shape depending on layout)
53
+ - filenames (python list)
54
+
55
+ Raises
56
+ ------
57
+ ValueError:
58
+ If `layout` is not "column" or "matrix", or text data has insufficient columns,
59
+ or binary rows are malformed.
60
+
61
+ FileNotFoundError:
62
+ If no matching data files are found.
63
+ """
64
+
65
+
66
+ print("")
67
+ print("Attempting DIC Data import...")
68
+ print("")
69
+
70
+ # convert to str
71
+ if isinstance(data, Path):
72
+ data = str(data)
73
+
74
+ files = sorted(glob.glob(data))
75
+ filenames = files
76
+ if not files:
77
+ raise FileNotFoundError(f"No results found in: {data}")
78
+
79
+ print(f"Found {len(files)} files containing DIC results:")
80
+ for file in files:
81
+ print(f" - {file}")
82
+ print("")
83
+
84
+
85
+ # Read first file to define reference coordinates
86
+ read_data = read_binary if binary else read_text
87
+ ss_x_ref, ss_y_ref, *fields = read_data(files[0], delimiter=delimiter)
88
+ frames = [list(fields)]
89
+
90
+ for file in files[1:]:
91
+ ss_x, ss_y, *f = read_data(file, delimiter)
92
+ if not (np.array_equal(ss_x_ref, ss_x) and np.array_equal(ss_y_ref, ss_y)):
93
+ raise ValueError("Mismatch in coordinates across frames.")
94
+ frames.append(f)
95
+
96
+ # Stack fields into arrays
97
+ arrays = [np.stack([frame[i] for frame in frames]) for i in range(8)]
98
+
99
+ if layout == "matrix":
100
+ x_unique = np.unique(ss_x_ref)
101
+ y_unique = np.unique(ss_y_ref)
102
+ X, Y = np.meshgrid(x_unique, y_unique)
103
+ shape = (len(files), len(y_unique), len(x_unique))
104
+ arrays = [to_grid(a,shape,ss_x_ref, ss_y_ref, x_unique,y_unique) for a in arrays]
105
+ return DICResults(X, Y, *arrays, filenames)
106
+ else:
107
+ return DICResults(ss_x_ref, ss_y_ref, *arrays, filenames)
108
+
109
+
110
+
111
+
112
+
113
+ def read_binary(file: str, delimiter: str):
114
+ """
115
+ Read a binary DIC result file and extract DIC fields.
116
+
117
+ Assumes a fixed binary structure with each row containing:
118
+ - 2 × int32 (subset coordinates)
119
+ - 6 × float64 (u, v, match quality, cost, ftol, xtol)
120
+ - 1 × int32 (number of iterations)
121
+
122
+ Parameters
123
+ ----------
124
+ file : str
125
+ Path to the binary result file.
126
+
127
+ delimiter : str
128
+ Ignored for binary data (included for API consistency).
129
+
130
+ Returns
131
+ -------
132
+ tuple of np.ndarray
133
+ Arrays corresponding to:
134
+ (ss_x, ss_y, u, v, m, cost, ftol, xtol, niter)
135
+
136
+ Raises
137
+ ------
138
+ ValueError
139
+ If the binary file size does not align with expected row size.
140
+ """
141
+
142
+ row_size = (3 * 4 + 6 * 8)
143
+ with open(file, "rb") as f:
144
+ raw = f.read()
145
+ if len(raw) % row_size != 0:
146
+ raise ValueError("Binary file has incomplete rows.")
147
+ rows = len(raw) // row_size
148
+ arr = np.frombuffer(raw, dtype=np.uint8).reshape(rows, row_size)
149
+ def extract(col, dtype, start): return np.frombuffer(arr[:, start:start+col], dtype=dtype)
150
+ ss_x = extract(4, np.int32, 0)
151
+ ss_y = extract(4, np.int32, 4)
152
+ u = extract(8, np.float64, 8)
153
+ v = extract(8, np.float64, 16)
154
+ m = extract(8, np.float64, 24)
155
+ conv = extract(1, np.bool_, 25)
156
+ cost = extract(8, np.float64, 33)
157
+ ftol = extract(8, np.float64, 41)
158
+ xtol = extract(8, np.float64, 49)
159
+ niter = extract(4, np.int32, 57)
160
+ return ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter
161
+
162
+
163
+
164
+
165
+ def read_text(file: str, delimiter: str):
166
+ """
167
+ Read a human-readable text DIC result file and extract DIC fields.
168
+
169
+ Expects at least 9 columns:
170
+ [ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter]
171
+
172
+ Parameters
173
+ ----------
174
+ file : str
175
+ Path to the text result file.
176
+
177
+ delimiter : str
178
+ Delimiter used in the text file (e.g., space, tab, comma).
179
+
180
+ Returns
181
+ -------
182
+ tuple of np.ndarray
183
+ Arrays corresponding to:
184
+ (ss_x, ss_y, u, v, m, conv, cost, ftol, xtol, niter)
185
+
186
+ Raises
187
+ ------
188
+ ValueError
189
+ If the text file has fewer than 9 columns.
190
+ """
191
+
192
+ data = np.loadtxt(file, delimiter=delimiter, skiprows=1)
193
+ if data.shape[1] < 9:
194
+ raise ValueError("Text data must have at least 9 columns.")
195
+ return (
196
+ data[:, 0].astype(np.int32), # ss_x
197
+ data[:, 1].astype(np.int32), # ss_y
198
+ data[:, 2], data[:, 3], data[:, 4], # u, v, mag
199
+ data[:, 5].astype(np.bool_), # convergence
200
+ data[:, 6], data[:, 7], data[:,8], # cost, ftol, xtol
201
+ data[:, 9].astype(np.int32) #niter
202
+ )
203
+
204
+
205
+
206
+
207
+
208
+ def to_grid(data, shape, ss_x_ref, ss_y_ref, x_unique, y_unique):
209
+ """
210
+ Reshape a 2D DIC field from flat (column) format into grid (matrix) format.
211
+
212
+ This is used when output layout is specified as "matrix".
213
+ Maps values using reference subset coordinates (ss_x_ref, ss_y_ref).
214
+
215
+ Parameters
216
+ ol
217
+ ----------
218
+ data : np.ndarray
219
+ Array of shape (n_frames, n_points) to be reshaped into (n_frames, height, width).
220
+
221
+ shape : tuple
222
+ Target shape of output array: (n_frames, height, width).
223
+
224
+ ss_x_ref : np.ndarray
225
+ X coordinates of subset centers.
226
+
227
+ ss_y_ref : np.ndarray
228
+ Y coordinates of subset centers.
229
+
230
+ x_unique : np.ndarray
231
+ Sorted unique X coordinates in the grid.
232
+
233
+ y_unique : np.ndarray
234
+ Sorted unique Y coordinates in the grid.
235
+
236
+ Returns
237
+ -------
238
+ np.ndarray
239
+ Reshaped array with shape `shape`, filled with NaNs where no data exists.
240
+ """
241
+
242
+ grid = np.full(shape, np.nan)
243
+ for i, (x, y) in enumerate(zip(ss_x_ref, ss_y_ref)):
244
+ x_idx = np.where(x_unique == x)[0][0]
245
+ y_idx = np.where(y_unique == y)[0][0]
246
+ grid[:, y_idx, x_idx] = data[:, i]
247
+ return grid