micress-micpy 0.3.2b0__py3-none-any.whl → 0.4.0a1__py3-none-any.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.
@@ -0,0 +1,221 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Dict, List, Optional, Tuple
4
+
5
+ import vtk
6
+ from vtkmodules.vtkCommonExecutionModel import vtkStreamingDemandDrivenPipeline
7
+ from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
8
+
9
+ from micpy import bin as micpy_bin
10
+ from micpy import vtk as micpy_vtk
11
+
12
+
13
+ class MicressBinaryReader(VTKPythonAlgorithmBase):
14
+ """ParaView reader for MICRESS binary files via MicPy."""
15
+
16
+ def __init__(self):
17
+ super().__init__(nInputPorts=0, nOutputPorts=1, outputType="vtkImageData")
18
+
19
+ self._filename: Optional[str] = None
20
+ self._file: Optional[micpy_bin.File] = None
21
+
22
+ self._array_name: str = "values"
23
+
24
+ self._cached_meta: Optional[
25
+ Tuple[
26
+ Tuple[int, int, int, int, int, int],
27
+ Tuple[float, float, float],
28
+ Tuple[float, float, float],
29
+ ]
30
+ ] = None # (extent6, spacing3, origin3)
31
+
32
+ self._times: List[float] = []
33
+ self._time_to_index: Dict[float, int] = {}
34
+
35
+ def SetFileName(self, filename: str) -> None:
36
+ filename = str(filename)
37
+ if filename == self._filename:
38
+ return
39
+ self._filename = filename
40
+ self._reset()
41
+ self.Modified()
42
+
43
+ def SetArrayName(self, name: str) -> None:
44
+ name = str(name) if name else "values"
45
+ if name == self._array_name:
46
+ return
47
+ self._array_name = name
48
+ self.Modified()
49
+
50
+ def _reset(self) -> None:
51
+ if self._file is not None:
52
+ try:
53
+ self._file.close()
54
+ except Exception:
55
+ pass
56
+ self._file = None
57
+ self._cached_meta = None
58
+ self._times = []
59
+ self._time_to_index = {}
60
+
61
+ def _open(self) -> None:
62
+ if self._file is None:
63
+ if not self._filename:
64
+ raise RuntimeError("No filename set.")
65
+ self._file = micpy_bin.File(self._filename).open()
66
+
67
+ def _ensure_meta(self) -> None:
68
+ if self._cached_meta is not None:
69
+ return
70
+ self._open()
71
+
72
+ field0 = self._file._read_field(0)
73
+ image0 = micpy_vtk.to_image(field0, name=self._array_name)
74
+
75
+ extent = tuple(int(x) for x in image0.GetExtent())
76
+ spacing = tuple(float(x) for x in image0.GetSpacing())
77
+ origin = tuple(float(x) for x in image0.GetOrigin())
78
+
79
+ self._cached_meta = (extent, spacing, origin)
80
+
81
+ def _ensure_times(self) -> None:
82
+ if self._times:
83
+ return
84
+ self._open()
85
+
86
+ times: List[float] = []
87
+ time_to_index: Dict[float, int] = {}
88
+
89
+ i = 0
90
+ while True:
91
+ try:
92
+ fld = self._file._read_field(i)
93
+ except (IndexError, EOFError):
94
+ break
95
+
96
+ tt = float(fld.time)
97
+ times.append(tt)
98
+ if tt not in time_to_index:
99
+ time_to_index[tt] = i
100
+ i += 1
101
+
102
+ self._times = times
103
+ self._time_to_index = time_to_index
104
+
105
+ # Temporary debug (prints to ParaView output console)
106
+ print(
107
+ "MicressBinaryReader: discovered",
108
+ len(self._times),
109
+ "timesteps:",
110
+ self._times,
111
+ )
112
+
113
+ def _get_index_for_requested_time(
114
+ self, req_t: Optional[float]
115
+ ) -> Tuple[int, float]:
116
+ self._ensure_times()
117
+
118
+ if not self._times:
119
+ return 0, 0.0
120
+
121
+ if req_t is None:
122
+ chosen_t = self._times[0]
123
+ return 0, float(chosen_t)
124
+
125
+ req_t = float(req_t)
126
+ chosen_t = min(self._times, key=lambda x: abs(x - req_t))
127
+ idx = self._time_to_index.get(chosen_t)
128
+ if idx is None:
129
+ idx = self._times.index(chosen_t)
130
+ return int(idx), float(chosen_t)
131
+
132
+ def _read_image_at_index(self, idx: int) -> vtk.vtkImageData:
133
+ self._open()
134
+ field = self._file._read_field(idx)
135
+ image = micpy_vtk.to_image(field, name=self._array_name)
136
+ return image
137
+
138
+ def RequestInformation(self, request, inInfo, outInfo):
139
+ if not self._filename:
140
+ return 1
141
+
142
+ self._ensure_meta()
143
+ self._ensure_times()
144
+
145
+ info = outInfo.GetInformationObject(0)
146
+
147
+ extent, spacing, origin = self._cached_meta
148
+ info.Set(vtkStreamingDemandDrivenPipeline.WHOLE_EXTENT(), extent, 6)
149
+ info.Set(vtk.vtkDataObject.SPACING(), spacing, 3)
150
+ info.Set(vtk.vtkDataObject.ORIGIN(), origin, 3)
151
+
152
+ if self._times:
153
+ ts = [float(x) for x in self._times]
154
+ vtkStreamingDemandDrivenPipeline.TIME_STEPS().Set(info, ts, len(ts))
155
+
156
+ tr = [float(min(ts)), float(max(ts))]
157
+ vtkStreamingDemandDrivenPipeline.TIME_RANGE().Set(info, tr, 2)
158
+
159
+ return 1
160
+
161
+ def RequestData(self, request, inInfo, outInfo):
162
+ if not self._filename:
163
+ raise RuntimeError("No filename set.")
164
+
165
+ self._ensure_meta()
166
+
167
+ info = outInfo.GetInformationObject(0)
168
+ output = vtk.vtkImageData.GetData(outInfo, 0)
169
+
170
+ req_t = None
171
+ if info.Has(vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP()):
172
+ req_t = float(info.Get(vtkStreamingDemandDrivenPipeline.UPDATE_TIME_STEP()))
173
+
174
+ idx, chosen_t = self._get_index_for_requested_time(req_t)
175
+ image = self._read_image_at_index(idx)
176
+
177
+ extent, spacing, origin = self._cached_meta
178
+ output.SetExtent(extent)
179
+ output.SetSpacing(spacing)
180
+ output.SetOrigin(origin)
181
+ output.AllocateScalars(image.GetScalarType(), 0)
182
+
183
+ output.GetPointData().ShallowCopy(image.GetPointData())
184
+ output.GetCellData().ShallowCopy(image.GetCellData())
185
+ output.Modified()
186
+
187
+ output.GetInformation().Set(vtk.vtkDataObject.DATA_TIME_STEP(), float(chosen_t))
188
+
189
+ return 1
190
+
191
+
192
+ try:
193
+ from paraview.util.vtkAlgorithm import smproxy, smproperty, smdomain
194
+ except Exception:
195
+ smproxy = smproperty = smdomain = None
196
+
197
+ if smproxy is not None:
198
+
199
+ @smproxy.reader(
200
+ name="MicressBinaryReader",
201
+ label="Micress Binary Reader (MicPy)",
202
+ extensions="mcr conc1 conc2 conc3 conc4 conc5 conc6 conc7 conc8 conc9 frac0 frac1 frac2 frac3 frac4 frac5 frac6 frac7 frac8 frac9 korn intf orie phas",
203
+ file_description="MICRESS Binary Files",
204
+ )
205
+ class _MicressBinaryReader(MicressBinaryReader):
206
+
207
+ @smproperty.stringvector(
208
+ name="FileName",
209
+ command="SetFileName",
210
+ number_of_elements=1,
211
+ panel_visibility="default",
212
+ )
213
+ @smdomain.filelist()
214
+ def FileName(self):
215
+ return [self._filename or ""]
216
+
217
+ @smproperty.stringvector(
218
+ name="ArrayName", command="SetArrayName", number_of_elements=1
219
+ )
220
+ def ArrayName(self):
221
+ return [self._array_name]
@@ -0,0 +1 @@
1
+ import micpy.paraview_plugin.reader
micpy/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.2b0"
1
+ __version__ = "0.4.0a1"
micpy/vtk.py ADDED
@@ -0,0 +1,60 @@
1
+ from pathlib import Path
2
+
3
+ import numpy as np
4
+ import vtk
5
+ from vtkmodules.util.numpy_support import numpy_to_vtk
6
+
7
+ from micpy.bin import Field
8
+
9
+
10
+ def to_image(
11
+ field: Field,
12
+ name: str = "values",
13
+ ):
14
+ a = np.asarray(field)
15
+ if a.ndim != 3:
16
+ raise ValueError("field must be 3D (nz, ny, nx)")
17
+
18
+ nz, ny, nx = a.shape
19
+ dz, dy, dx = field.spacing
20
+
21
+ image = vtk.vtkImageData()
22
+ image.SetOrigin(0.0, 0.0, 0.0)
23
+ image.SetSpacing(float(dx), float(dy), float(dz))
24
+ image.SetDimensions(nx + 1, ny + 1, nz + 1)
25
+
26
+ if not a.flags["C_CONTIGUOUS"]:
27
+ a = np.ascontiguousarray(a)
28
+
29
+ a_vtk = np.ndarray(shape=(nx, ny, nz), dtype=a.dtype, buffer=a, order="F")
30
+
31
+ flat_view = a_vtk.ravel(order="F")
32
+
33
+ arr = numpy_to_vtk(flat_view, deep=True)
34
+ arr.SetName(name)
35
+ image.GetCellData().SetScalars(arr)
36
+
37
+ return image
38
+
39
+
40
+ def save_vti(
41
+ field: Field,
42
+ filename: str,
43
+ name: str = "values",
44
+ ) -> str:
45
+ image = to_image(field, name=name)
46
+
47
+ filename = str(Path(filename).with_suffix(".vti"))
48
+
49
+ writer = vtk.vtkXMLImageDataWriter()
50
+ writer.SetFileName(filename)
51
+
52
+ writer.SetInputData(image)
53
+ writer.SetDataModeToAppended()
54
+ writer.EncodeAppendedDataOff()
55
+
56
+ ok = writer.Write()
57
+ if ok != 1:
58
+ raise OSError(f"Failed to write {filename}")
59
+
60
+ return filename
@@ -1,10 +1,10 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: micress-micpy
3
- Version: 0.3.2b0
3
+ Version: 0.4.0a1
4
4
  Summary: MicPy is a Python package to facilitate MICRESS workflows.
5
5
  Author: Lukas Koschmieder
6
6
  Author-email: l.koschmieder@access-technology.de
7
- License: BSD-3-Clause (Copyright (c) 2024 Access e.V.)
7
+ License: BSD-3-Clause (Copyright (c) 2024-2026 Access e.V.)
8
8
  Keywords: MICRESS
9
9
  Classifier: Development Status :: 4 - Beta
10
10
  Classifier: Intended Audience :: Science/Research
@@ -16,6 +16,18 @@ Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: matplotlib
18
18
  Requires-Dist: pandas
19
+ Requires-Dist: rapidgzip
20
+ Dynamic: author
21
+ Dynamic: author-email
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: keywords
26
+ Dynamic: license
27
+ Dynamic: license-file
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
19
31
 
20
32
  <center>
21
33
 
@@ -40,6 +52,7 @@ MicPy requires the following dependencies:
40
52
  - Python (>= 3.9)
41
53
  - Pandas (>= 1.1)
42
54
  - Matplotlib (>= 3) as an optional dependency for plotting
55
+ - VTK (>= 9) as an optional dependency for 3D visualization
43
56
 
44
57
  ## Documentation
45
58
 
@@ -0,0 +1,18 @@
1
+ micpy/MicressBinaryReader copy.py,sha256=2LEgaL1hn5Azgu-itGtgKj7fK6naAAGKkzmN2sjItv4,4382
2
+ micpy/MicressBinaryReader.py,sha256=1c-RGmKNmCR7LH1BVXJTx2IdeJ0vE_KS1bkpfQ0VJ_E,8540
3
+ micpy/__init__.py,sha256=tM_wXPVfBznC9YIhVK1iukTkqW-Vg2OegKPGki12xb4,63
4
+ micpy/bin copy.py,sha256=-cT-Xkih_jJmGbjKx4ahdWC8Y30lfudbCVGekXgccaE,26912
5
+ micpy/bin.py,sha256=W7ksqCKRwTPvaMSUyPAWyUuN1WAUMg3sr7QmIkmINOw,26085
6
+ micpy/geo.py,sha256=z7dP3hC2Fhed4N5eRrlWlC4jtIXiYPIx2BYNhn10dfw,7447
7
+ micpy/matplotlib.py,sha256=GF2ghyBORC5RRjW00DdsHu5aSkpMFdI9wqg6d_psPsI,1198
8
+ micpy/paraview_plugin.py,sha256=bN9KnoNp5eToiKDyBxi4qtDQFF1Yy_tKmFOAJEGdGDk,7010
9
+ micpy/paraview_plugin_stub.py,sha256=GovBBOLZnJ-_csPvrJDu2cTj7qnHNnhbQPX1yxm7aY0,37
10
+ micpy/tab.py,sha256=QCnfggxRWkKgS9-zGj8kyCjhfUw7QeTgGZWedHh4MTw,3548
11
+ micpy/utils.py,sha256=Kt1AvhMvWer9uftbb88X7N27aXtQdJl26grHmmm2vOQ,859
12
+ micpy/version.py,sha256=LP80qjLpeagualL_zMvkW8O_mhv-NwTuvnzc_4bOmK4,25
13
+ micpy/vtk.py,sha256=48VB0pORhVkXqVHY4F8XdyfBlChyNl_OJWqQ5XK7mdY,1388
14
+ micress_micpy-0.4.0a1.dist-info/licenses/LICENSE,sha256=seHdCiArizUoWZ6bEFg6N3K2ZtfPK35wvOwg0kH-f6o,1488
15
+ micress_micpy-0.4.0a1.dist-info/METADATA,sha256=2P0y6lKMyU-NhgBimydwpd_GU33kjqho7qycm3YmNiw,1567
16
+ micress_micpy-0.4.0a1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
17
+ micress_micpy-0.4.0a1.dist-info/top_level.txt,sha256=RiopkpW0AGNYdtOW2eQUWgm3yHGC13q9pWlHb2alhiE,6
18
+ micress_micpy-0.4.0a1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.2)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,12 +0,0 @@
1
- micpy/__init__.py,sha256=7wQUaseppjQYZW1iAVNm2WSDjvBLlqtY8tiHsfDaW5Q,148
2
- micpy/bin.py,sha256=5_VjciuoY7MGgbsYGD4YEBsGIRtN1UHEu1bF4c84KoU,26150
3
- micpy/geo.py,sha256=z7dP3hC2Fhed4N5eRrlWlC4jtIXiYPIx2BYNhn10dfw,7447
4
- micpy/matplotlib.py,sha256=GF2ghyBORC5RRjW00DdsHu5aSkpMFdI9wqg6d_psPsI,1198
5
- micpy/tab.py,sha256=QCnfggxRWkKgS9-zGj8kyCjhfUw7QeTgGZWedHh4MTw,3548
6
- micpy/utils.py,sha256=Kt1AvhMvWer9uftbb88X7N27aXtQdJl26grHmmm2vOQ,859
7
- micpy/version.py,sha256=cmRz06nS65Gsdx46NbGK09hWYOtmDwCXP9-XRCvNvUc,25
8
- micress_micpy-0.3.2b0.dist-info/LICENSE,sha256=seHdCiArizUoWZ6bEFg6N3K2ZtfPK35wvOwg0kH-f6o,1488
9
- micress_micpy-0.3.2b0.dist-info/METADATA,sha256=iJ3JJYKKdZzkdnCkfYstoSu4NDaYJMX0aIAuMKIFoQs,1229
10
- micress_micpy-0.3.2b0.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
11
- micress_micpy-0.3.2b0.dist-info/top_level.txt,sha256=RiopkpW0AGNYdtOW2eQUWgm3yHGC13q9pWlHb2alhiE,6
12
- micress_micpy-0.3.2b0.dist-info/RECORD,,