cf-xarray 0.9.5__tar.gz → 0.10.0__tar.gz

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 (93) hide show
  1. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/workflows/pypi.yaml +2 -2
  2. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.pre-commit-config.yaml +4 -4
  3. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/CITATION.cff +4 -0
  4. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/PKG-INFO +2 -2
  5. cf_xarray-0.10.0/cf_xarray/_version.py +1 -0
  6. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/accessor.py +20 -47
  7. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/coding.py +6 -3
  8. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/formatting.py +2 -2
  9. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/geometry.py +1 -1
  10. cf_xarray-0.10.0/cf_xarray/parametric.py +821 -0
  11. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/scripts/make_doc.py +3 -1
  12. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/sgrid.py +2 -1
  13. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_accessor.py +14 -44
  14. cf_xarray-0.10.0/cf_xarray/tests/test_parametric.py +615 -0
  15. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/utils.py +3 -1
  16. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray.egg-info/PKG-INFO +2 -2
  17. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray.egg-info/SOURCES.txt +2 -0
  18. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray.egg-info/requires.txt +1 -1
  19. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/parametricz.md +1 -1
  20. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/whats-new.rst +1 -3
  21. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/pyproject.toml +3 -3
  22. cf_xarray-0.9.5/cf_xarray/_version.py +0 -1
  23. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.binder/environment.yml +0 -0
  24. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.deepsource.toml +0 -0
  25. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/dependabot.yml +0 -0
  26. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/release.yml +0 -0
  27. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/workflows/ci.yaml +0 -0
  28. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/workflows/parse_logs.py +0 -0
  29. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/workflows/testpypi-release.yaml +0 -0
  30. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.github/workflows/upstream-dev-ci.yaml +0 -0
  31. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.gitignore +0 -0
  32. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.readthedocs.yml +0 -0
  33. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/.tributors +0 -0
  34. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/LICENSE +0 -0
  35. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/README.rst +0 -0
  36. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/__init__.py +0 -0
  37. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/criteria.py +0 -0
  38. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/datasets.py +0 -0
  39. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/helpers.py +0 -0
  40. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/options.py +0 -0
  41. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/py.typed +0 -0
  42. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/scripts/print_versions.py +0 -0
  43. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/__init__.py +0 -0
  44. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/conftest.py +0 -0
  45. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_coding.py +0 -0
  46. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_geometry.py +0 -0
  47. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_helpers.py +0 -0
  48. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_options.py +0 -0
  49. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_scripts.py +0 -0
  50. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/tests/test_units.py +0 -0
  51. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray/units.py +0 -0
  52. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray.egg-info/dependency_links.txt +0 -0
  53. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/cf_xarray.egg-info/top_level.txt +0 -0
  54. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/ci/doc.yml +0 -0
  55. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/ci/environment-no-optional-deps.yml +0 -0
  56. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/ci/environment.yml +0 -0
  57. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/ci/upstream-dev-env.yml +0 -0
  58. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/codecov.yml +0 -0
  59. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/2D_bounds_averaged.png +0 -0
  60. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/2D_bounds_error.png +0 -0
  61. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/2D_bounds_nonunique.png +0 -0
  62. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/Makefile +0 -0
  63. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/dataset-diagram-logo.tex +0 -0
  64. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/full-logo.png +0 -0
  65. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/logo.png +0 -0
  66. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/logo.svg +0 -0
  67. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/rich-repr-example.png +0 -0
  68. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/_static/style.css +0 -0
  69. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/api.rst +0 -0
  70. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/bounds.md +0 -0
  71. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/cartopy_rotated_pole.png +0 -0
  72. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/coding.md +0 -0
  73. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/conf.py +0 -0
  74. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/contributing.rst +0 -0
  75. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/coord_axes.md +0 -0
  76. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/custom-criteria.md +0 -0
  77. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/dsg.md +0 -0
  78. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/examples/introduction.ipynb +0 -0
  79. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/faq.md +0 -0
  80. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/flags.md +0 -0
  81. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/geometry.md +0 -0
  82. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/grid_mappings.md +0 -0
  83. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/howtouse.md +0 -0
  84. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/index.rst +0 -0
  85. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/make.bat +0 -0
  86. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/plotting.md +0 -0
  87. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/provenance.md +0 -0
  88. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/quickstart.md +0 -0
  89. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/roadmap.rst +0 -0
  90. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/selecting.md +0 -0
  91. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/sgrid_ugrid.md +0 -0
  92. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/doc/units.md +0 -0
  93. {cf_xarray-0.9.5 → cf_xarray-0.10.0}/setup.cfg +0 -0
@@ -72,7 +72,7 @@ jobs:
72
72
 
73
73
  - name: Publish package to TestPyPI
74
74
  if: github.event_name == 'push'
75
- uses: pypa/gh-action-pypi-publish@v1.9.0
75
+ uses: pypa/gh-action-pypi-publish@v1.10.2
76
76
  with:
77
77
  password: ${{ secrets.TESTPYPI_TOKEN }}
78
78
  repository_url: https://test.pypi.org/legacy/
@@ -96,6 +96,6 @@ jobs:
96
96
  name: releases
97
97
  path: dist
98
98
  - name: Publish package to PyPI
99
- uses: pypa/gh-action-pypi-publish@v1.9.0
99
+ uses: pypa/gh-action-pypi-publish@v1.10.2
100
100
  with:
101
101
  verbose: true
@@ -10,13 +10,13 @@ repos:
10
10
 
11
11
  - repo: https://github.com/astral-sh/ruff-pre-commit
12
12
  # Ruff version.
13
- rev: 'v0.6.1'
13
+ rev: 'v0.6.9'
14
14
  hooks:
15
15
  - id: ruff
16
16
  args: ["--show-fixes", "--fix"]
17
17
 
18
18
  - repo: https://github.com/psf/black-pre-commit-mirror
19
- rev: 24.8.0
19
+ rev: 24.10.0
20
20
  hooks:
21
21
  - id: black
22
22
 
@@ -47,7 +47,7 @@ repos:
47
47
  additional_dependencies: [mdformat==0.7.17]
48
48
 
49
49
  - repo: https://github.com/pre-commit/pre-commit-hooks
50
- rev: v4.6.0
50
+ rev: v5.0.0
51
51
  hooks:
52
52
  - id: trailing-whitespace
53
53
  - id: end-of-file-fixer
@@ -67,7 +67,7 @@ repos:
67
67
  - id: validate-cff
68
68
 
69
69
  - repo: https://github.com/abravalheri/validate-pyproject
70
- rev: v0.19
70
+ rev: v0.20.2
71
71
  hooks:
72
72
  - id: validate-pyproject
73
73
 
@@ -83,6 +83,10 @@ authors:
83
83
  - family-names: Haëck
84
84
  given-names: Clément
85
85
  affiliation: Laboratoire d'Océanographie et du Climat (LOCEAN), Paris
86
+ - family-names: Boutte
87
+ given-names: Jason
88
+ orcid: 'https://orcid.org/0009-0009-3996-3772'
89
+ affiliation: Lawrence Livermore National Laboratory
86
90
  identifiers:
87
91
  - type: doi
88
92
  value: 10.5281/zenodo.4749735
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cf_xarray
3
- Version: 0.9.5
3
+ Version: 0.10.0
4
4
  Summary: A convenience wrapper for using CF attributes on xarray objects
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -220,7 +220,7 @@ Classifier: Programming Language :: Python :: 3.12
220
220
  Requires-Python: >=3.10
221
221
  Description-Content-Type: text/x-rst
222
222
  License-File: LICENSE
223
- Requires-Dist: xarray
223
+ Requires-Dist: xarray>=2022.03.0
224
224
  Provides-Extra: all
225
225
  Requires-Dist: matplotlib; extra == "all"
226
226
  Requires-Dist: pint!=0.24.0,>=0.18; extra == "all"
@@ -0,0 +1 @@
1
+ __version__ = "0.10.0"
@@ -18,7 +18,6 @@ from typing import (
18
18
  Any,
19
19
  Literal,
20
20
  TypeVar,
21
- Union,
22
21
  cast,
23
22
  overload,
24
23
  )
@@ -31,7 +30,7 @@ from xarray.core.resample import Resample
31
30
  from xarray.core.rolling import Coarsen, Rolling
32
31
  from xarray.core.weighted import Weighted
33
32
 
34
- from . import sgrid
33
+ from . import parametric, sgrid
35
34
  from .criteria import (
36
35
  _DSG_ROLES,
37
36
  _GEOMETRY_TYPES,
@@ -89,7 +88,7 @@ ATTRS["time"] = ATTRS["T"]
89
88
  ATTRS["vertical"] = ATTRS["Z"]
90
89
 
91
90
  # Type for Mapper functions
92
- Mapper = Callable[[Union[DataArray, Dataset], Hashable], list[Hashable]]
91
+ Mapper = Callable[[DataArray | Dataset, Hashable], list[Hashable]]
93
92
 
94
93
  # Type for decorators
95
94
  F = TypeVar("F", bound=Callable[..., Any])
@@ -538,7 +537,7 @@ def _get_coords(obj: DataArray | Dataset, key: Hashable) -> list[Hashable]:
538
537
  def _variables(func: F) -> F:
539
538
  @functools.wraps(func)
540
539
  def wrapper(obj: DataArray | Dataset, key: Hashable) -> list[DataArray]:
541
- return [obj[k] for k in func(obj, key)] # type: ignore[misc]
540
+ return [obj[k] for k in func(obj, key)]
542
541
 
543
542
  return cast(F, wrapper)
544
543
 
@@ -1150,9 +1149,10 @@ def create_flag_dict(da) -> Mapping[Hashable, FlagParam]:
1150
1149
  )
1151
1150
 
1152
1151
  flag_params = tuple(
1153
- FlagParam(mask, value) for mask, value in zip(flag_masks, flag_values)
1152
+ FlagParam(mask, value)
1153
+ for mask, value in zip(flag_masks, flag_values, strict=False)
1154
1154
  )
1155
- return dict(zip(flag_meanings, flag_params))
1155
+ return dict(zip(flag_meanings, flag_params, strict=False))
1156
1156
 
1157
1157
 
1158
1158
  class CFAccessor:
@@ -1368,7 +1368,7 @@ class CFAccessor:
1368
1368
  kwargs: dict[str, Any] | None = None,
1369
1369
  ):
1370
1370
  if coords is not None:
1371
- if isinstance(coords, (Hashable, DataArray)):
1371
+ if isinstance(coords, Hashable | DataArray):
1372
1372
  coords_iter: Iterable[Hashable | DataArray] = [coords]
1373
1373
  else:
1374
1374
  coords_iter = coords
@@ -2754,13 +2754,8 @@ class CFDatasetAccessor(CFAccessor):
2754
2754
  """
2755
2755
  ds = self._obj
2756
2756
 
2757
- requirements = {
2758
- "ocean_s_coordinate_g1": {"depth_c", "depth", "s", "C", "eta"},
2759
- "ocean_s_coordinate_g2": {"depth_c", "depth", "s", "C", "eta"},
2760
- "ocean_sigma_coordinate": {"sigma", "eta", "depth"},
2761
- }
2762
-
2763
2757
  allterms = self.formula_terms
2758
+
2764
2759
  for dim in allterms:
2765
2760
  if prefix is None:
2766
2761
  assert (
@@ -2782,6 +2777,7 @@ class CFDatasetAccessor(CFAccessor):
2782
2777
  suffix = dim.split("_")
2783
2778
  zname = f"{prefix}_" + "_".join(suffix[1:])
2784
2779
 
2780
+ # never touched, if standard name is missing it's not included in allterms
2785
2781
  if "standard_name" not in ds[dim].attrs:
2786
2782
  continue
2787
2783
  stdname = ds[dim].attrs["standard_name"]
@@ -2790,46 +2786,23 @@ class CFDatasetAccessor(CFAccessor):
2790
2786
  terms = {}
2791
2787
  for key, value in allterms[dim].items():
2792
2788
  if value not in ds:
2789
+ # is this ever hit, if variable is missing it's missing in decoded allterms
2793
2790
  raise KeyError(
2794
2791
  f"Variable {value!r} is required to decode coordinate for {dim!r}"
2795
2792
  " but it is absent in the Dataset."
2796
2793
  )
2797
- terms[key] = ds[value]
2798
-
2799
- absent_terms = requirements[stdname] - set(terms)
2800
- if absent_terms:
2801
- raise KeyError(f"Required terms {absent_terms} absent in dataset.")
2802
-
2803
- if stdname == "ocean_s_coordinate_g1":
2804
- # S(k,j,i) = depth_c * s(k) + (depth(j,i) - depth_c) * C(k)
2805
- S = (
2806
- terms["depth_c"] * terms["s"]
2807
- + (terms["depth"] - terms["depth_c"]) * terms["C"]
2808
- )
2809
-
2810
- # z(n,k,j,i) = S(k,j,i) + eta(n,j,i) * (1 + S(k,j,i) / depth(j,i))
2811
- ztemp = S + terms["eta"] * (1 + S / terms["depth"])
2794
+ # keys should be case insensitive
2795
+ terms[key.lower()] = ds[value]
2812
2796
 
2813
- elif stdname == "ocean_s_coordinate_g2":
2814
- # make sure all necessary terms are present in terms
2815
- # (depth_c * s(k) + depth(j,i) * C(k)) / (depth_c + depth(j,i))
2816
- S = (terms["depth_c"] * terms["s"] + terms["depth"] * terms["C"]) / (
2817
- terms["depth_c"] + terms["depth"]
2818
- )
2819
-
2820
- # z(n,k,j,i) = eta(n,j,i) + (eta(n,j,i) + depth(j,i)) * S(k,j,i)
2821
- ztemp = terms["eta"] + (terms["eta"] + terms["depth"]) * S
2822
-
2823
- elif stdname == "ocean_sigma_coordinate":
2824
- # z(n,k,j,i) = eta(n,j,i) + sigma(k)*(depth(j,i)+eta(n,j,i))
2825
- ztemp = terms["eta"] + terms["sigma"] * (terms["depth"] + terms["eta"])
2826
-
2827
- else:
2797
+ try:
2798
+ transform = parametric.TRANSFORM_FROM_STDNAME[stdname]
2799
+ except KeyError:
2800
+ # Should occur since stdname is check before
2828
2801
  raise NotImplementedError(
2829
- f"Coordinate function for {stdname!r} not implemented yet. Contributions welcome!"
2830
- )
2802
+ f"Coordinate function for {stdname!r} not implmented yet. Contributions welcome!"
2803
+ ) from None
2831
2804
 
2832
- ds.coords[zname] = ztemp
2805
+ ds.coords[zname] = transform.from_terms(terms)
2833
2806
 
2834
2807
 
2835
2808
  @xr.register_dataarray_accessor("cf")
@@ -3024,7 +2997,7 @@ class CFDataArrayAccessor(CFAccessor):
3024
2997
  x = self._obj.astype("i")
3025
2998
  bit_comp = x & bit_mask
3026
2999
 
3027
- for i, (flag, value) in enumerate(zip(flags_reduced, values)):
3000
+ for i, (flag, value) in enumerate(zip(flags_reduced, values, strict=False)):
3028
3001
  bit = bit_comp.isel(_mask=i)
3029
3002
  if value is not None:
3030
3003
  out[flag] = bit == value
@@ -46,7 +46,7 @@ def encode_multi_index_as_compress(ds, idxnames=None):
46
46
  encoded = ds.reset_index(idxnames)
47
47
  for idxname in idxnames:
48
48
  mindex = ds.indexes[idxname]
49
- coords = dict(zip(mindex.names, mindex.levels))
49
+ coords = dict(zip(mindex.names, mindex.levels, strict=False))
50
50
  encoded.update(coords)
51
51
  for c in coords:
52
52
  encoded[c].attrs = ds[c].attrs
@@ -112,13 +112,16 @@ def decode_compress_to_multi_index(encoded, idxnames=None):
112
112
 
113
113
  variables = {
114
114
  dim: encoded[dim].isel({dim: xr.Variable(data=index, dims=idxname)})
115
- for dim, index in zip(names, indices)
115
+ for dim, index in zip(names, indices, strict=False)
116
116
  }
117
117
  decoded = decoded.assign_coords(variables).set_xindex(
118
118
  names, PandasMultiIndex
119
119
  )
120
120
  except ImportError:
121
- arrays = [encoded[dim].data[index] for dim, index in zip(names, indices)]
121
+ arrays = [
122
+ encoded[dim].data[index]
123
+ for dim, index in zip(names, indices, strict=False)
124
+ ]
122
125
  mindex = pd.MultiIndex.from_arrays(arrays, names=names)
123
126
  decoded.coords[idxname] = mindex
124
127
 
@@ -268,14 +268,14 @@ def _format_flags(accessor, rich):
268
268
  table.add_column("Value", justify="right")
269
269
  table.add_column("Bits", justify="center")
270
270
 
271
- for val, bit, key in zip(value_text, bit_text, flag_dict):
271
+ for val, bit, key in zip(value_text, bit_text, flag_dict, strict=False):
272
272
  table.add_row(_format_cf_name(key, rich), val, bit)
273
273
 
274
274
  return table
275
275
 
276
276
  else:
277
277
  rows = []
278
- for val, bit, key in zip(value_text, bit_text, flag_dict):
278
+ for val, bit, key in zip(value_text, bit_text, flag_dict, strict=False):
279
279
  rows.append(
280
280
  f"{TAB}{_format_cf_name(key, rich):>{key_width}}: {TAB} {val} {bit}"
281
281
  )
@@ -324,7 +324,7 @@ def encode_geometries(ds: xr.Dataset):
324
324
  # TODO: this is incomplete. It works for vector data cubes where one of the geometry vars
325
325
  # is a dimension coordinate.
326
326
  if name in var.dims:
327
- var = var.copy()
327
+ var = var.copy(deep=False)
328
328
  var._attrs = copy.deepcopy(var._attrs)
329
329
  var.attrs["geometry"] = container_name
330
330
  # The grid_mapping and coordinates attributes can be carried by the geometry container