marEx 3.0.2__tar.gz → 3.1__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.
- {marex-3.0.2 → marex-3.1}/.github/workflows/release.yml +1 -1
- marex-3.1/CITATION.cff +52 -0
- {marex-3.0.2/marEx.egg-info → marex-3.1}/PKG-INFO +4 -4
- {marex-3.0.2 → marex-3.1}/README.md +3 -3
- {marex-3.0.2 → marex-3.1/marEx.egg-info}/PKG-INFO +4 -4
- {marex-3.0.2 → marex-3.1}/tests/test_unstructured_tracking.py +75 -90
- marex-3.0.2/CITATION.cff +0 -21
- {marex-3.0.2 → marex-3.1}/.github/workflows/README.md +0 -0
- {marex-3.0.2 → marex-3.1}/.github/workflows/ci.yml +0 -0
- {marex-3.0.2 → marex-3.1}/.github/workflows/tests.yml.bak +0 -0
- {marex-3.0.2 → marex-3.1}/.github/workflows/validate.py +0 -0
- {marex-3.0.2 → marex-3.1}/.readthedocs.yaml +0 -0
- {marex-3.0.2 → marex-3.1}/CONTRIBUTING.md +0 -0
- {marex-3.0.2 → marex-3.1}/MANIFEST.in +0 -0
- {marex-3.0.2 → marex-3.1}/examples/gridded data/01_preprocess_extremes.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/examples/gridded data/02_id_track_events.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/examples/gridded data/03_visualise_events.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/examples/unstructured data/01_preprocess_extremes.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/examples/unstructured data/02_id_track_events.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/examples/unstructured data/03_visualise_events.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/__init__.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/_coverage_init.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/_dependencies.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/detect.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/exceptions.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/helper.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/logging_config.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/plotX/__init__.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/plotX/base.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/plotX/gridded.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/plotX/unstructured.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx/track.py +0 -0
- {marex-3.0.2 → marex-3.1}/marEx.egg-info/SOURCES.txt +0 -0
- {marex-3.0.2 → marex-3.1}/marEx.egg-info/dependency_links.txt +0 -0
- {marex-3.0.2 → marex-3.1}/marEx.egg-info/requires.txt +0 -0
- {marex-3.0.2 → marex-3.1}/marEx.egg-info/top_level.txt +0 -0
- {marex-3.0.2 → marex-3.1}/pyproject.toml +0 -0
- {marex-3.0.2 → marex-3.1}/setup.cfg +0 -0
- {marex-3.0.2 → marex-3.1}/tests/__init__.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/conftest.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/coverage_config.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/make_test_data.ipynb +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_detect_helpers.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_error_handling.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_exceptions.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_gridded_preprocessing.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_gridded_tracking.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_integration.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_logging_system.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_plotx.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_track_helpers.py +0 -0
- {marex-3.0.2 → marex-3.1}/tests/test_unstructured_preprocessing.py +0 -0
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
- name: Validate and parse version
|
|
28
28
|
id: version
|
|
29
29
|
run: |
|
|
30
|
-
if [[ "${GITHUB_REF}" =~ ^refs/tags/v([0-9]+\.[0-9]
|
|
30
|
+
if [[ "${GITHUB_REF}" =~ ^refs/tags/v([0-9]+\.[0-9]+(\.[0-9]+)?.*)$ ]]; then
|
|
31
31
|
VERSION="${BASH_REMATCH[1]}"
|
|
32
32
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
|
33
33
|
|
marex-3.1/CITATION.cff
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
type: software
|
|
4
|
+
title: "MarEx: Marine Extremes Detection and Tracking"
|
|
5
|
+
abstract: "Efficient & scalable Marine Extremes detection, identification, & tracking for Exascale Climate Data. A high-performance Python framework for identifying and tracking extreme oceanographic events (such as Marine Heatwaves or Acidity Extremes) in massive climate datasets."
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: "Wienkers"
|
|
8
|
+
given-names: "Aaron"
|
|
9
|
+
email: "aaron@wienkers.com"
|
|
10
|
+
orcid: "https://orcid.org/0000-0002-8464-3139"
|
|
11
|
+
repository-code: "https://github.com/wienkers/marEx"
|
|
12
|
+
url: "https://github.com/wienkers/marEx"
|
|
13
|
+
doi: "10.5281/zenodo.16922881"
|
|
14
|
+
identifiers:
|
|
15
|
+
- type: doi
|
|
16
|
+
value: "10.5281/zenodo.16922881"
|
|
17
|
+
description: "DOI for this software"
|
|
18
|
+
keywords:
|
|
19
|
+
- "marine heatwaves"
|
|
20
|
+
- "extreme events"
|
|
21
|
+
- "oceanography"
|
|
22
|
+
- "extremes tracking"
|
|
23
|
+
- "ocean extremes"
|
|
24
|
+
- "marine extremes"
|
|
25
|
+
- "climate data"
|
|
26
|
+
- "distributed computing"
|
|
27
|
+
- "dask"
|
|
28
|
+
- "python"
|
|
29
|
+
version: "3.1"
|
|
30
|
+
date-released: "2025-08-22"
|
|
31
|
+
preferred-citation:
|
|
32
|
+
type: software
|
|
33
|
+
title: "MarEx: Marine Extremes Detection and Tracking"
|
|
34
|
+
authors:
|
|
35
|
+
- family-names: "Wienkers"
|
|
36
|
+
given-names: "Aaron"
|
|
37
|
+
email: "aaron@wienkers.com"
|
|
38
|
+
orcid: "https://orcid.org/0000-0002-8464-3139"
|
|
39
|
+
doi: "10.5281/zenodo.16922881"
|
|
40
|
+
url: "https://github.com/wienkers/marEx"
|
|
41
|
+
version: "3.1"
|
|
42
|
+
year: 2025
|
|
43
|
+
funding:
|
|
44
|
+
- agency: "European Commission"
|
|
45
|
+
program: "Horizon Europe"
|
|
46
|
+
grant-id: "101081383"
|
|
47
|
+
title: "EERIE (European Eddy-Rich ESMs) Project"
|
|
48
|
+
- agency: "Swiss State Secretariat for Education, Research and Innovation (SERI)"
|
|
49
|
+
grant-id: "22.00366"
|
|
50
|
+
contact:
|
|
51
|
+
- email: "aaron@wienkers.com"
|
|
52
|
+
name: "Aaron Wienkers"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marEx
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1
|
|
4
4
|
Summary: Marine Extremes Detection and Tracking
|
|
5
5
|
Author-email: Aaron Wienkers <aaron@wienkers.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/wienkers/marEx
|
|
@@ -86,15 +86,15 @@ Requires-Dist: pytest-xdist; extra == "test"
|
|
|
86
86
|
Requires-Dist: coverage[toml]>=6.0.0; extra == "test"
|
|
87
87
|
Requires-Dist: psutil; extra == "test"
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-

|
|
89
|
+

|
|
91
90
|
|
|
92
91
|
[](https://github.com/wienkers/marEx/actions/workflows/ci.yml)
|
|
93
92
|
[](https://github.com/wienkers/marEx/actions/workflows/tests.yml)
|
|
94
93
|
[](https://codecov.io/gh/wienkers/marEx)
|
|
95
94
|
[](https://badge.fury.io/py/marEx)
|
|
96
95
|
[](https://marex.readthedocs.io/en/latest/)
|
|
97
|
-
[](https://pepy.tech/projects/marex)
|
|
96
|
+
[](https://pepy.tech/projects/marex) \
|
|
97
|
+
[](https://doi.org/10.5281/zenodo.16922881)
|
|
98
98
|
|
|
99
99
|
Marine Extremes Python Package
|
|
100
100
|
==============================
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-

|
|
1
|
+

|
|
3
2
|
|
|
4
3
|
[](https://github.com/wienkers/marEx/actions/workflows/ci.yml)
|
|
5
4
|
[](https://github.com/wienkers/marEx/actions/workflows/tests.yml)
|
|
6
5
|
[](https://codecov.io/gh/wienkers/marEx)
|
|
7
6
|
[](https://badge.fury.io/py/marEx)
|
|
8
7
|
[](https://marex.readthedocs.io/en/latest/)
|
|
9
|
-
[](https://pepy.tech/projects/marex)
|
|
8
|
+
[](https://pepy.tech/projects/marex) \
|
|
9
|
+
[](https://doi.org/10.5281/zenodo.16922881)
|
|
10
10
|
|
|
11
11
|
Marine Extremes Python Package
|
|
12
12
|
==============================
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marEx
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1
|
|
4
4
|
Summary: Marine Extremes Detection and Tracking
|
|
5
5
|
Author-email: Aaron Wienkers <aaron@wienkers.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/wienkers/marEx
|
|
@@ -86,15 +86,15 @@ Requires-Dist: pytest-xdist; extra == "test"
|
|
|
86
86
|
Requires-Dist: coverage[toml]>=6.0.0; extra == "test"
|
|
87
87
|
Requires-Dist: psutil; extra == "test"
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-

|
|
89
|
+

|
|
91
90
|
|
|
92
91
|
[](https://github.com/wienkers/marEx/actions/workflows/ci.yml)
|
|
93
92
|
[](https://github.com/wienkers/marEx/actions/workflows/tests.yml)
|
|
94
93
|
[](https://codecov.io/gh/wienkers/marEx)
|
|
95
94
|
[](https://badge.fury.io/py/marEx)
|
|
96
95
|
[](https://marex.readthedocs.io/en/latest/)
|
|
97
|
-
[](https://pepy.tech/projects/marex)
|
|
96
|
+
[](https://pepy.tech/projects/marex) \
|
|
97
|
+
[](https://doi.org/10.5281/zenodo.16922881)
|
|
98
98
|
|
|
99
99
|
Marine Extremes Python Package
|
|
100
100
|
==============================
|
|
@@ -346,11 +346,11 @@ class TestUnstructuredTracking:
|
|
|
346
346
|
assert_reasonable_bounds(
|
|
347
347
|
tracked_ds.attrs["preprocessed_area_fraction"],
|
|
348
348
|
2.2,
|
|
349
|
-
tolerance_relative=0.
|
|
349
|
+
tolerance_relative=0.2,
|
|
350
350
|
)
|
|
351
|
-
assert_count_in_reasonable_range(tracked_ds.attrs["N_objects_prefiltered"], 15, tolerance=
|
|
352
|
-
assert_count_in_reasonable_range(tracked_ds.attrs["N_objects_filtered"], 8, tolerance=
|
|
353
|
-
assert_count_in_reasonable_range(tracked_ds.attrs["N_events_final"], 3, tolerance=
|
|
351
|
+
assert_count_in_reasonable_range(tracked_ds.attrs["N_objects_prefiltered"], 15, tolerance=5)
|
|
352
|
+
assert_count_in_reasonable_range(tracked_ds.attrs["N_objects_filtered"], 8, tolerance=2)
|
|
353
|
+
assert_count_in_reasonable_range(tracked_ds.attrs["N_events_final"], 3, tolerance=1)
|
|
354
354
|
|
|
355
355
|
@pytest.mark.slow
|
|
356
356
|
def test_unstructured_different_filtering_parameters(self, dask_client_unstructured):
|
|
@@ -439,13 +439,13 @@ class TestUnstructuredTracking:
|
|
|
439
439
|
# Assert tracking statistics are within reasonable bounds for low filter case
|
|
440
440
|
assert_reasonable_bounds(
|
|
441
441
|
tracked_low_filter.attrs["preprocessed_area_fraction"],
|
|
442
|
-
|
|
443
|
-
tolerance_relative=0.
|
|
442
|
+
1.4,
|
|
443
|
+
tolerance_relative=0.2,
|
|
444
444
|
)
|
|
445
445
|
# Expected ranges for full dataset (732 timesteps × 1000 cells)
|
|
446
|
-
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_objects_prefiltered"], 15, tolerance=
|
|
447
|
-
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_objects_filtered"], 15, tolerance=
|
|
448
|
-
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_events_final"], 3, tolerance=
|
|
446
|
+
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_objects_prefiltered"], 15, tolerance=5)
|
|
447
|
+
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_objects_filtered"], 15, tolerance=2)
|
|
448
|
+
assert_count_in_reasonable_range(tracked_low_filter.attrs["N_events_final"], 3, tolerance=1)
|
|
449
449
|
|
|
450
450
|
@pytest.mark.slow
|
|
451
451
|
def test_unstructured_temporal_gap_filling(self, dask_client_unstructured):
|
|
@@ -539,12 +539,12 @@ class TestUnstructuredTracking:
|
|
|
539
539
|
assert_reasonable_bounds(
|
|
540
540
|
tracked_no_gaps.attrs["preprocessed_area_fraction"],
|
|
541
541
|
2.2,
|
|
542
|
-
tolerance_relative=0.
|
|
542
|
+
tolerance_relative=0.2,
|
|
543
543
|
)
|
|
544
544
|
# Expected ranges for full dataset (732 timesteps × 1000 cells)
|
|
545
|
-
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_objects_prefiltered"], 15, tolerance=
|
|
546
|
-
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_objects_filtered"],
|
|
547
|
-
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_events_final"],
|
|
545
|
+
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_objects_prefiltered"], 15, tolerance=5)
|
|
546
|
+
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_objects_filtered"], 7, tolerance=2)
|
|
547
|
+
assert_count_in_reasonable_range(tracked_no_gaps.attrs["N_events_final"], 2, tolerance=1)
|
|
548
548
|
|
|
549
549
|
@pytest.mark.slow
|
|
550
550
|
def test_unstructured_grid_requirements(self, dask_client_unstructured):
|
|
@@ -715,28 +715,23 @@ class TestUnstructuredTracking:
|
|
|
715
715
|
cell_areas=renamed_data.cell_areas,
|
|
716
716
|
)
|
|
717
717
|
|
|
718
|
-
|
|
719
|
-
try:
|
|
720
|
-
tracked_ds_no_merge = tracker_no_merge.run()
|
|
718
|
+
tracked_ds_no_merge = tracker_no_merge.run()
|
|
721
719
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
720
|
+
# If successful, verify output structure for no merge case
|
|
721
|
+
assert isinstance(tracked_ds_no_merge, xr.Dataset)
|
|
722
|
+
assert "ID_field" in tracked_ds_no_merge.data_vars
|
|
725
723
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
724
|
+
# Verify custom dimensions are preserved
|
|
725
|
+
assert "t" in tracked_ds_no_merge.ID_field.dims
|
|
726
|
+
assert "cell" in tracked_ds_no_merge.ID_field.dims
|
|
729
727
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
728
|
+
# Verify attributes are set
|
|
729
|
+
assert "N_events_final" in tracked_ds_no_merge.attrs
|
|
730
|
+
assert "allow_merging" in tracked_ds_no_merge.attrs
|
|
731
|
+
assert tracked_ds_no_merge.attrs["allow_merging"] == 0
|
|
734
732
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
except (marEx.exceptions.TrackingError, KeyError):
|
|
738
|
-
# This is expected if custom dimension handling has issues or insufficient data
|
|
739
|
-
pass
|
|
733
|
+
# Verify ID_field is int
|
|
734
|
+
assert np.issubdtype(tracked_ds_no_merge.ID_field.dtype, np.integer), "ID_field should be integer type"
|
|
740
735
|
|
|
741
736
|
# Verify tracker was created successfully with custom dimension and coordinate names (no merging)
|
|
742
737
|
assert tracker_no_merge is not None
|
|
@@ -763,35 +758,30 @@ class TestUnstructuredTracking:
|
|
|
763
758
|
cell_areas=renamed_data.cell_areas,
|
|
764
759
|
)
|
|
765
760
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
# Verify ID_field is int
|
|
791
|
-
assert np.issubdtype(tracked_ds_with_merge.ID_field.dtype, np.integer), "ID_field should be integer type"
|
|
792
|
-
except (marEx.exceptions.TrackingError, KeyError):
|
|
793
|
-
# This is expected if custom dimension handling has issues or insufficient data
|
|
794
|
-
pass
|
|
761
|
+
tracked_ds_with_merge = tracker_with_merge.run()
|
|
762
|
+
|
|
763
|
+
# If successful, verify output structure for merge case
|
|
764
|
+
assert isinstance(tracked_ds_with_merge, xr.Dataset)
|
|
765
|
+
assert "ID_field" in tracked_ds_with_merge.data_vars
|
|
766
|
+
assert "global_ID" in tracked_ds_with_merge.data_vars
|
|
767
|
+
assert "area" in tracked_ds_with_merge.data_vars
|
|
768
|
+
assert "centroid" in tracked_ds_with_merge.data_vars
|
|
769
|
+
assert "presence" in tracked_ds_with_merge.data_vars
|
|
770
|
+
assert "time_start" in tracked_ds_with_merge.data_vars
|
|
771
|
+
assert "time_end" in tracked_ds_with_merge.data_vars
|
|
772
|
+
assert "merge_ledger" in tracked_ds_with_merge.data_vars
|
|
773
|
+
|
|
774
|
+
# Verify custom dimensions are preserved
|
|
775
|
+
assert "t" in tracked_ds_with_merge.ID_field.dims
|
|
776
|
+
assert "cell" in tracked_ds_with_merge.ID_field.dims
|
|
777
|
+
|
|
778
|
+
# Verify advanced tracking attributes
|
|
779
|
+
assert tracked_ds_with_merge.attrs["allow_merging"] == 1
|
|
780
|
+
assert tracked_ds_with_merge.attrs["T_fill"] == 2
|
|
781
|
+
assert "total_merges" in tracked_ds_with_merge.attrs
|
|
782
|
+
|
|
783
|
+
# Verify ID_field is int
|
|
784
|
+
assert np.issubdtype(tracked_ds_with_merge.ID_field.dtype, np.integer), "ID_field should be integer type"
|
|
795
785
|
|
|
796
786
|
# Verify tracker was created successfully with custom dimension and coordinate names (with merging)
|
|
797
787
|
assert tracker_with_merge is not None
|
|
@@ -851,36 +841,31 @@ class TestUnstructuredTracking:
|
|
|
851
841
|
cell_areas=renamed_data.cell_areas,
|
|
852
842
|
)
|
|
853
843
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
tracked_ds_original.attrs["N_events_final"] == tracked_ds_custom.attrs["N_events_final"]
|
|
880
|
-
), "Different event counts between original and custom dimensions"
|
|
881
|
-
except (marEx.exceptions.TrackingError, KeyError):
|
|
882
|
-
# This is expected if custom dimension handling has issues or insufficient data
|
|
883
|
-
pass
|
|
844
|
+
tracked_ds_original = tracker_original.run()
|
|
845
|
+
tracked_ds_custom = tracker_custom.run()
|
|
846
|
+
|
|
847
|
+
# If successful, verify output structure for both
|
|
848
|
+
assert isinstance(tracked_ds_original, xr.Dataset)
|
|
849
|
+
assert isinstance(tracked_ds_custom, xr.Dataset)
|
|
850
|
+
assert "ID_field" in tracked_ds_original.data_vars
|
|
851
|
+
assert "ID_field" in tracked_ds_custom.data_vars
|
|
852
|
+
|
|
853
|
+
# Verify original dimensions
|
|
854
|
+
assert "time" in tracked_ds_original.ID_field.dims
|
|
855
|
+
assert "ncells" in tracked_ds_original.ID_field.dims
|
|
856
|
+
|
|
857
|
+
# Verify custom dimensions
|
|
858
|
+
assert "t" in tracked_ds_custom.ID_field.dims
|
|
859
|
+
assert "cell" in tracked_ds_custom.ID_field.dims
|
|
860
|
+
|
|
861
|
+
# Verify both have integer ID fields
|
|
862
|
+
assert np.issubdtype(tracked_ds_original.ID_field.dtype, np.integer), "Original ID_field should be integer type"
|
|
863
|
+
assert np.issubdtype(tracked_ds_custom.ID_field.dtype, np.integer), "Custom ID_field should be integer type"
|
|
864
|
+
|
|
865
|
+
# Verify both have same number of events (should produce equivalent results)
|
|
866
|
+
assert (
|
|
867
|
+
tracked_ds_original.attrs["N_events_final"] == tracked_ds_custom.attrs["N_events_final"]
|
|
868
|
+
), "Different event counts between original and custom dimensions"
|
|
884
869
|
|
|
885
870
|
# Verify both trackers were created successfully
|
|
886
871
|
assert tracker_original is not None
|
marex-3.0.2/CITATION.cff
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
cff-version: 1.2.0
|
|
2
|
-
message: "If you use this software, please cite it as below."
|
|
3
|
-
type: software
|
|
4
|
-
title: "MarEx: Marine Extremes Detection and Tracking"
|
|
5
|
-
abstract: "Efficient & scalable Marine Extremes detection, identification, & tracking for Exascale Climate Data. A high-performance Python framework for identifying and tracking extreme oceanographic events (such as Marine Heatwaves or Acidity Extremes) in massive climate datasets."
|
|
6
|
-
authors:
|
|
7
|
-
- family-names: "Wienkers"
|
|
8
|
-
given-names: "Aaron"
|
|
9
|
-
email: "aaron@wienkers.com"
|
|
10
|
-
orcid: "https://orcid.org/0000-0002-8464-3139"
|
|
11
|
-
repository-code: "https://github.com/wienkers/marEx"
|
|
12
|
-
url: "https://github.com/wienkers/marEx"
|
|
13
|
-
keywords:
|
|
14
|
-
- "marine heatwaves"
|
|
15
|
-
- "extreme events"
|
|
16
|
-
- "oceanography"
|
|
17
|
-
- "extremes tracking"
|
|
18
|
-
- "ocean extremes"
|
|
19
|
-
- "marine extremes"
|
|
20
|
-
version: "3.0.0"
|
|
21
|
-
date-released: "2025-07-28"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|