tecio-python 0.3.3__py3-none-any.whl → 0.4.0__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.
Files changed (34) hide show
  1. tecio/__init__.py +6 -2
  2. tecio/_dat_read.py +38 -28
  3. tecio/_dat_write.py +206 -146
  4. tecio/_io.py +87 -71
  5. tecio/_meta.py +6 -6
  6. tecio/_plt_legacy.py +400 -0
  7. tecio/_plt_read.py +180 -41
  8. tecio/_plt_write.py +195 -125
  9. tecio/_reader.py +82 -37
  10. tecio/_szl_read.py +68 -61
  11. tecio/_szl_write.py +249 -188
  12. tecio/_writer.py +380 -134
  13. tecio/cli/tec2mat.py +21 -11
  14. tecio/cli/tecaux.py +77 -93
  15. tecio/cli/tecdump.py +1 -1
  16. tecio/cli/tecextract.py +68 -86
  17. tecio/cli/tecfix.py +45 -64
  18. tecio/cli/tecmerge.py +75 -68
  19. tecio/cli/teconvert.py +22 -37
  20. tecio/cli/tecscale.py +185 -109
  21. tecio/cli/tecslice.py +75 -100
  22. tecio/cli/tecstats.py +41 -41
  23. tecio_python-0.3.3.data/data/share/plugins/matlab/fecplot.m → tecio_python-0.4.0.data/data/share/plugins/matlab/contourfe.m +3 -3
  24. tecio_python-0.4.0.data/data/share/plugins/matlab/tecmat2struct.m +137 -0
  25. tecio_python-0.4.0.data/data/share/plugins/paraview/TecplotTecioWriter.py +651 -0
  26. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/METADATA +1 -1
  27. tecio_python-0.4.0.dist-info/RECORD +38 -0
  28. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/WHEEL +1 -1
  29. tecio_python-0.3.3.dist-info/RECORD +0 -35
  30. {tecio_python-0.3.3.data → tecio_python-0.4.0.data}/data/share/plugins/paraview/TecplotTecioReader.py +0 -0
  31. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/entry_points.txt +0 -0
  32. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/licenses/LICENSE +0 -0
  33. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/licenses/NOTICE +0 -0
  34. {tecio_python-0.3.3.dist-info → tecio_python-0.4.0.dist-info}/top_level.txt +0 -0
tecio/__init__.py CHANGED
@@ -4,12 +4,14 @@ Wraps the TecIO C library for ``.szplt``, ``.plt``, and ``.dat`` formats.
4
4
  Requires Python 3.10+, NumPy, and a Tecplot 360 installation.
5
5
  """
6
6
 
7
+ # ruff: noqa: A004
8
+
7
9
  from importlib import metadata
8
10
 
9
11
  try:
10
12
  __version__ = metadata.version("tecio")
11
13
  except metadata.PackageNotFoundError:
12
- __version__ = "0.3.3"
14
+ __version__ = "0.4.0"
13
15
 
14
16
  from . import cli, libtecio
15
17
  from ._constants import (
@@ -54,7 +56,7 @@ from ._reader import (
54
56
  )
55
57
  from ._szl_read import TecplotSzlReader
56
58
  from ._szl_write import TecplotSzlWriter
57
- from ._writer import TecplotWriter
59
+ from ._writer import EmptyZoneWarning, TecplotWriter
58
60
 
59
61
  # Ensure these display as their canonical public name in docs and help(),
60
62
  # rather than the private module they're actually defined in.
@@ -77,6 +79,7 @@ for _cls in (
77
79
  TecplotSzlWriter,
78
80
  TecplotPltWriter,
79
81
  TecplotDatWriter,
82
+ EmptyZoneWarning,
80
83
  Boolean,
81
84
  DataPacking,
82
85
  DataType,
@@ -122,6 +125,7 @@ __all__ = [
122
125
  "TecplotSzlWriter",
123
126
  "TecplotPltWriter",
124
127
  "TecplotDatWriter",
128
+ "EmptyZoneWarning",
125
129
  "Boolean",
126
130
  "DataPacking",
127
131
  "DataType",
tecio/_dat_read.py CHANGED
@@ -37,6 +37,7 @@ from ._reader import (
37
37
  TecplotReader,
38
38
  TecplotVariableReader,
39
39
  TecplotZoneReader,
40
+ convert_face_connections_to_zero_based,
40
41
  )
41
42
 
42
43
  # --------------------------------------------------------------------------------------
@@ -696,9 +697,9 @@ def _parse_auxdata_line(line: str) -> tuple[str, str]:
696
697
  def _apply_varauxdata(line: str, var_auxdata_list: list[dict[str, str]]) -> None:
697
698
  """Parse ``VARAUXDATA 1-based-idx name="value"`` and store in list.
698
699
 
699
- *var_auxdata_list* holds plain, mutable dicts, one per variable (index 0 is an
700
- unused placeholder), accumulated during parsing. Wrapped into an immutable
701
- TecplotDatAuxDataReader lazily, only once parsing is complete.
700
+ *var_auxdata_list* holds plain, mutable dicts, one per variable, 0-based,
701
+ accumulated during parsing. Wrapped into an immutable TecplotDatAuxDataReader
702
+ lazily, only once parsing is complete.
702
703
 
703
704
  Example:
704
705
  >>> _apply_varauxdata(line, var_auxdata_list)
@@ -706,14 +707,14 @@ def _apply_varauxdata(line: str, var_auxdata_list: list[dict[str, str]]) -> None
706
707
  m = re.match(r"(?i)VARAUXDATA\s+(\d+)\s+", line)
707
708
  if not m:
708
709
  return
709
- var_idx = int(m.group(1)) # 1-based
710
+ var_idx = int(m.group(1)) - 1 # 1-based in text, converted to 0-based
710
711
  rest = line[m.end() :]
711
712
  eq = rest.find("=")
712
713
  if eq < 0:
713
714
  return
714
715
  name = rest[:eq].strip()
715
716
  value = _unquote(rest[eq + 1 :].strip())
716
- if 1 <= var_idx < len(var_auxdata_list):
717
+ if 0 <= var_idx < len(var_auxdata_list):
717
718
  var_auxdata_list[var_idx][name] = value
718
719
 
719
720
 
@@ -927,7 +928,7 @@ class TecplotDatVariableReader(TecplotVariableReader):
927
928
 
928
929
  @property
929
930
  def shared_zone(self) -> int | None:
930
- """1-based source zone index if shared, else None."""
931
+ """0-based source zone index if shared, else None."""
931
932
  return self._shared_zone
932
933
 
933
934
  @property
@@ -985,9 +986,9 @@ class TecplotDatOrderedZoneReader(TecplotOrderedZoneReader):
985
986
  self,
986
987
  zone_index: int,
987
988
  title: str,
988
- I: int, # noqa: E741 - matches Tecplot's own IJK convention
989
- J: int,
990
- K: int,
989
+ I: int, # noqa: E741 N803
990
+ J: int, # noqa: N803
991
+ K: int, # noqa: N803
991
992
  solution_time: float,
992
993
  strand_id: int,
993
994
  variables: list[TecplotVariableReader],
@@ -1306,9 +1307,9 @@ class TecplotDatReader(TecplotReader):
1306
1307
  # TecplotDatAuxDataReader lazily, only once fully parsed.
1307
1308
  self._dataset_auxdata_raw: dict[str, str] = {}
1308
1309
  self._dataset_auxdata: TecplotAuxDataReader | None = None
1309
- # Index 0 is an unused placeholder so that 1-based indexing works directly;
1310
- # populated once num_vars is known, see _parse().
1311
- self._var_auxdata_raw: list[dict[str, str]] = [{}]
1310
+ # 0-based, one dict per variable; populated once num_vars is known, see
1311
+ # _parse().
1312
+ self._var_auxdata_raw: list[dict[str, str]] = []
1312
1313
  # Raw VARAUXDATA lines seen before the first zone, buffered by
1313
1314
  # _parse_file_header() and applied once _var_auxdata_raw is allocated with the
1314
1315
  # correct length (num_vars isn't known until the header finishes parsing).
@@ -1377,7 +1378,7 @@ class TecplotDatReader(TecplotReader):
1377
1378
  self._parse_file_header(tokens)
1378
1379
 
1379
1380
  # Build per-variable aux data slots now that num_vars is known.
1380
- self._var_auxdata_raw = [{}] + [{} for _ in range(self.num_vars)]
1381
+ self._var_auxdata_raw = [{} for _ in range(self.num_vars)]
1381
1382
 
1382
1383
  # Now that _var_auxdata exists, apply any VARAUXDATA lines that appeared before
1383
1384
  # the first zone
@@ -1581,11 +1582,11 @@ class TecplotDatReader(TecplotReader):
1581
1582
  active_count = self.num_vars - len(passive_set) - len(share_map)
1582
1583
  num_nodes = self._infer_ordered_point_count(tokens, active_count)
1583
1584
  I = num_nodes # noqa E741
1584
- J = K = 1
1585
+ J = K = 1 # noqa: N806
1585
1586
  else:
1586
- I = int(kv.get("I", "1") or "1") # noqa E741
1587
- J = int(kv.get("J", "1") or "1")
1588
- K = int(kv.get("K", "1") or "1")
1587
+ I = int(kv.get("I", "1") or "1") # noqa: E741 N806
1588
+ J = int(kv.get("J", "1") or "1") # noqa: N806
1589
+ K = int(kv.get("K", "1") or "1") # noqa: N806
1589
1590
  num_nodes = I * J * K
1590
1591
  num_cells = max(I - 1, 1) * max(J - 1, 1) * max(K - 1, 1)
1591
1592
  else:
@@ -1696,12 +1697,15 @@ class TecplotDatReader(TecplotReader):
1696
1697
  else:
1697
1698
  nodes_per_cell = _NODES_PER_ELEM[zone_type]
1698
1699
  flat = self._read_int_block(tokens, num_cells * nodes_per_cell)
1699
- node_map = flat.reshape(num_cells, nodes_per_cell)
1700
+ # Node numbers are 1-based in ASCII; convert to 0-based indices
1701
+ # that point directly into the corresponding coordinate array.
1702
+ node_map = flat.reshape(num_cells, nodes_per_cell) - 1
1700
1703
 
1701
1704
  # -- Read face-neighbor connections (FE zones only, if declared) ---------------
1702
1705
  #
1703
- # Immediately follows connectivity in the file. Values are already
1704
- # 1-based in ASCII (unlike PLT's binary layout, no +1 needed here).
1706
+ # Immediately follows connectivity in the file. Values are 1-based in ASCII;
1707
+ # cell references, remote-zone references, and the face ordinal are all
1708
+ # converted to 0-based below.
1705
1709
 
1706
1710
  face_connections: npt.NDArray[np.int64] | None = None
1707
1711
  one_to_one = (
@@ -1715,6 +1719,9 @@ class TecplotDatReader(TecplotReader):
1715
1719
  face_connections = self._read_int_block(
1716
1720
  tokens, declared_face_connections * values_per
1717
1721
  )
1722
+ face_connections = convert_face_connections_to_zero_based(
1723
+ face_connections, face_neighbor_mode
1724
+ )
1718
1725
  elif face_neighbor_mode is not None:
1719
1726
  # "Many" modes: ragged, each record's own 4th value (nz) gives the
1720
1727
  # count of additional neighbor references that follow it.
@@ -1730,6 +1737,9 @@ class TecplotDatReader(TecplotReader):
1730
1737
  face_connections = (
1731
1738
  np.concatenate(pieces) if pieces else np.empty(0, dtype=np.int64)
1732
1739
  )
1740
+ face_connections = convert_face_connections_to_zero_based(
1741
+ face_connections, face_neighbor_mode
1742
+ )
1733
1743
 
1734
1744
  # -- Build ReadVariable and ReadZone objects -----------------------------------
1735
1745
 
@@ -1758,13 +1768,13 @@ class TecplotDatReader(TecplotReader):
1758
1768
  self._zones[src_zone_1based - 1].variables[var_idx].values
1759
1769
  )
1760
1770
 
1761
- # This zone's own 1-based index
1762
- zone_index = len(self._zones) + 1
1771
+ # This zone's own 0-based index
1772
+ zone_index = len(self._zones)
1763
1773
 
1764
1774
  read_vars: list[TecplotVariableReader] = [
1765
1775
  TecplotDatVariableReader(
1766
1776
  zone_index=zone_index,
1767
- var_index=idx + 1,
1777
+ var_index=idx,
1768
1778
  name=name,
1769
1779
  data=_shaped(
1770
1780
  var_arrays[idx],
@@ -1772,7 +1782,7 @@ class TecplotDatReader(TecplotReader):
1772
1782
  ),
1773
1783
  value_location=var_locs.get(idx, ValueLocation.NODAL),
1774
1784
  is_passive=(idx in passive_set),
1775
- shared_zone=share_map.get(idx, None),
1785
+ shared_zone=(share_map[idx] - 1 if idx in share_map else None),
1776
1786
  )
1777
1787
  for idx, name in enumerate(self._variable_names)
1778
1788
  ]
@@ -1791,7 +1801,7 @@ class TecplotDatReader(TecplotReader):
1791
1801
  auxdata=zone_aux,
1792
1802
  node_map=node_map,
1793
1803
  datapacking=packing,
1794
- shared_connectivity=con_share_zone if con_share_zone else None,
1804
+ shared_connectivity=(con_share_zone - 1) if con_share_zone else None,
1795
1805
  face_neighbor_mode=face_neighbor_mode,
1796
1806
  num_face_connections=declared_face_connections or None,
1797
1807
  face_connections=face_connections,
@@ -1804,9 +1814,9 @@ class TecplotDatReader(TecplotReader):
1804
1814
  zone_index: int,
1805
1815
  title: str,
1806
1816
  zone_type: ZoneType,
1807
- I: int, # noqa: E741 - matches Tecplot's own IJK convention
1808
- J: int,
1809
- K: int,
1817
+ I: int, # noqa: E741 N803
1818
+ J: int, # noqa: N803
1819
+ K: int, # noqa: N803
1810
1820
  solution_time: float,
1811
1821
  strand_id: int,
1812
1822
  variables: list[TecplotVariableReader],