pyvale 2025.5.3__cp311-cp311-win32.whl → 2025.7.0__cp311-cp311-win32.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.
- pyvale/__init__.py +12 -0
- pyvale/blendercalibrationdata.py +3 -1
- pyvale/blenderscene.py +7 -5
- pyvale/blendertools.py +27 -5
- pyvale/camera.py +1 -0
- pyvale/cameradata.py +3 -0
- pyvale/camerasensor.py +147 -0
- pyvale/camerastereo.py +4 -4
- pyvale/cameratools.py +23 -61
- pyvale/cython/rastercyth.c +1657 -1352
- pyvale/cython/rastercyth.cp311-win32.pyd +0 -0
- pyvale/cython/rastercyth.py +71 -26
- pyvale/data/plate_hole_def0000.tiff +0 -0
- pyvale/data/plate_hole_def0001.tiff +0 -0
- pyvale/data/plate_hole_ref0000.tiff +0 -0
- pyvale/data/plate_rigid_def0000.tiff +0 -0
- pyvale/data/plate_rigid_def0001.tiff +0 -0
- pyvale/data/plate_rigid_ref0000.tiff +0 -0
- pyvale/dataset.py +96 -6
- pyvale/dic/cpp/dicbruteforce.cpp +370 -0
- pyvale/dic/cpp/dicfourier.cpp +648 -0
- pyvale/dic/cpp/dicinterpolator.cpp +559 -0
- pyvale/dic/cpp/dicmain.cpp +215 -0
- pyvale/dic/cpp/dicoptimizer.cpp +675 -0
- pyvale/dic/cpp/dicrg.cpp +137 -0
- pyvale/dic/cpp/dicscanmethod.cpp +677 -0
- pyvale/dic/cpp/dicsmooth.cpp +138 -0
- pyvale/dic/cpp/dicstrain.cpp +383 -0
- pyvale/dic/cpp/dicutil.cpp +563 -0
- pyvale/dic2d.py +164 -0
- pyvale/dic2dcpp.cp311-win32.pyd +0 -0
- pyvale/dicchecks.py +476 -0
- pyvale/dicdataimport.py +247 -0
- pyvale/dicregionofinterest.py +887 -0
- pyvale/dicresults.py +55 -0
- pyvale/dicspecklegenerator.py +238 -0
- pyvale/dicspecklequality.py +305 -0
- pyvale/dicstrain.py +387 -0
- pyvale/dicstrainresults.py +37 -0
- pyvale/errorintegrator.py +10 -8
- pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +124 -113
- pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +124 -132
- pyvale/examples/basics/ex1_3_customsens_therm3d.py +199 -195
- pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +125 -121
- pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +145 -141
- pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +96 -101
- pyvale/examples/basics/ex1_7_spatavg_therm2d.py +109 -105
- pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +92 -91
- pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +96 -90
- pyvale/examples/basics/ex2_3_sensangle_disp2d.py +88 -89
- pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +172 -171
- pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +88 -86
- pyvale/examples/basics/ex3_1_basictensors_strain2d.py +90 -90
- pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +93 -91
- pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +172 -160
- pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +154 -148
- pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +249 -231
- pyvale/examples/dic/ex1_region_of_interest.py +98 -0
- pyvale/examples/dic/ex2_plate_with_hole.py +149 -0
- pyvale/examples/dic/ex3_plate_with_hole_strain.py +93 -0
- pyvale/examples/dic/ex4_dic_blender.py +95 -0
- pyvale/examples/dic/ex5_dic_challenge.py +102 -0
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +4 -2
- pyvale/examples/renderblender/ex1_1_blenderscene.py +152 -105
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +151 -100
- pyvale/examples/renderblender/ex2_1_stereoscene.py +183 -116
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +185 -112
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +164 -109
- pyvale/examples/renderrasterisation/ex_rastenp.py +74 -35
- pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +6 -13
- pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +2 -2
- pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +2 -4
- pyvale/imagedef2d.py +3 -2
- pyvale/imagetools.py +137 -0
- pyvale/rastercy.py +34 -4
- pyvale/rasternp.py +300 -276
- pyvale/rasteropts.py +58 -0
- pyvale/renderer.py +47 -0
- pyvale/rendermesh.py +52 -62
- pyvale/renderscene.py +51 -0
- pyvale/sensorarrayfactory.py +2 -2
- pyvale/sensortools.py +19 -35
- pyvale/simcases/case21.i +1 -1
- pyvale/simcases/run_1case.py +8 -0
- pyvale/simtools.py +2 -2
- pyvale/visualsimplotter.py +180 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/METADATA +11 -57
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/RECORD +91 -56
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/WHEEL +1 -1
- pyvale/examples/visualisation/ex1_1_plot_traces.py +0 -102
- pyvale/examples/visualisation/ex2_1_animate_sim.py +0 -89
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.5.3.dist-info → pyvale-2025.7.0.dist-info}/top_level.txt +0 -0
pyvale/dicdataimport.py
ADDED
|
@@ -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
|