From 91b5e01ef8c854714e730b35bb3fb65803cc3cb1 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Tue, 6 Feb 2024 10:54:23 +0100 Subject: [PATCH 01/19] CI: stable notebook dependency versions (#1838) --- .github/workflows/tutorials.yaml | 4 ++-- docs/tutorials/transforms.ipynb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tutorials.yaml b/.github/workflows/tutorials.yaml index 5833bccd4f6..a55b4693b70 100644 --- a/.github/workflows/tutorials.yaml +++ b/.github/workflows/tutorials.yaml @@ -26,11 +26,11 @@ jobs: id: cache with: path: ${{ env.pythonLocation }} - key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-tutorials + key: ${{ env.pythonLocation }}-${{ hashFiles('requirements/required.txt') }}-${{ hashFiles('requirements/docs.txt') }}-${{ hashFiles('requirements/tests.txt') }}-tutorials - name: Install pip dependencies if: steps.cache.outputs.cache-hit != 'true' run: | - pip install .[docs,tests] planetary_computer pystac + pip install -r requirements/required.txt -r requirements/docs.txt -r requirements/tests.txt planetary_computer pystac pip cache purge - name: List pip dependencies run: pip list diff --git a/docs/tutorials/transforms.ipynb b/docs/tutorials/transforms.ipynb index 80a53f52643..ca76d9dc5a9 100644 --- a/docs/tutorials/transforms.ipynb +++ b/docs/tutorials/transforms.ipynb @@ -501,7 +501,7 @@ "id": "w4ZbjxPyHoiB" }, "source": [ - "It's even possible to chain indices along with augmentations from kornia for a single callable during training." + "It's even possible to chain indices along with augmentations from Kornia for a single callable during training." ] }, { From 55b3c508914e01a11c17297cb22515ed80e8de83 Mon Sep 17 00:00:00 2001 From: Konstantin Klemmer Date: Tue, 6 Feb 2024 04:55:15 -0500 Subject: [PATCH 02/19] load_state_dict does not return the model (#1503) * Update pretrained_weights.ipynb Fixed an error in the state dict loading of the turorial and added a comment on the num_classes parameter when creating timm models. * Update docs/tutorials/pretrained_weights.ipynb * Update utils.py * Import Tuple from typing * Change return of `load_state_dict` from `model` to `Tuple[List[str], List[str]]`, matching the return of the standard PyTorch builtin function. * Update pretrained_weights.ipynb Remove example of loading pretrained model without prediction head (`num_classes=0`). * Update README.md Adapt new `load_state_dict` function. * Mimic return type of builtin load_state_dict * Modern type hints * Blacken * Try being explicit --------- Co-authored-by: Caleb Robinson Co-authored-by: Adam J. Stewart --- README.md | 2 +- docs/tutorials/pretrained_weights.ipynb | 2 +- tests/trainers/test_utils.py | 6 +++--- torchgeo/trainers/byol.py | 2 +- torchgeo/trainers/classification.py | 2 +- torchgeo/trainers/moco.py | 2 +- torchgeo/trainers/regression.py | 2 +- torchgeo/trainers/simclr.py | 2 +- torchgeo/trainers/utils.py | 12 ++++++++---- 9 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 36ae3aa37eb..ec31fcb7753 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ from torchgeo.models import ResNet18_Weights weights = ResNet18_Weights.SENTINEL2_ALL_MOCO model = timm.create_model("resnet18", in_chans=weights.meta["in_chans"], num_classes=10) -model = model.load_state_dict(weights.get_state_dict(progress=True), strict=False) +model.load_state_dict(weights.get_state_dict(progress=True), strict=False) ``` These weights can also directly be used in TorchGeo Lightning modules that are shown in the following section via the `weights` argument. For a notebook example, see this [tutorial](https://torchgeo.readthedocs.io/en/stable/tutorials/pretrained_weights.html). diff --git a/docs/tutorials/pretrained_weights.ipynb b/docs/tutorials/pretrained_weights.ipynb index 26d97fcbc6c..e15dd1ebc16 100644 --- a/docs/tutorials/pretrained_weights.ipynb +++ b/docs/tutorials/pretrained_weights.ipynb @@ -228,7 +228,7 @@ "source": [ "in_chans = weights.meta[\"in_chans\"]\n", "model = timm.create_model(\"resnet18\", in_chans=in_chans, num_classes=10)\n", - "model = model.load_state_dict(weights.get_state_dict(progress=True), strict=False)" + "model.load_state_dict(weights.get_state_dict(progress=True), strict=False)" ] }, { diff --git a/tests/trainers/test_utils.py b/tests/trainers/test_utils.py index 52d7a9be25d..06da0a359eb 100644 --- a/tests/trainers/test_utils.py +++ b/tests/trainers/test_utils.py @@ -41,7 +41,7 @@ def test_get_input_layer_name_and_module() -> None: def test_load_state_dict(checkpoint: str, model: Module) -> None: _, state_dict = extract_backbone(checkpoint) - model = load_state_dict(model, state_dict) + load_state_dict(model, state_dict) def test_load_state_dict_unequal_input_channels(checkpoint: str, model: Module) -> None: @@ -58,7 +58,7 @@ def test_load_state_dict_unequal_input_channels(checkpoint: str, model: Module) f" model {expected_in_channels}. Overriding with new input channels" ) with pytest.warns(UserWarning, match=warning): - model = load_state_dict(model, state_dict) + load_state_dict(model, state_dict) def test_load_state_dict_unequal_classes(checkpoint: str, model: Module) -> None: @@ -74,7 +74,7 @@ def test_load_state_dict_unequal_classes(checkpoint: str, model: Module) -> None f" {expected_num_classes}. Overriding with new num classes" ) with pytest.warns(UserWarning, match=warning): - model = load_state_dict(model, state_dict) + load_state_dict(model, state_dict) def test_reinit_initial_conv_layer() -> None: diff --git a/torchgeo/trainers/byol.py b/torchgeo/trainers/byol.py index 68bdb6c9c43..d6c0b62765e 100644 --- a/torchgeo/trainers/byol.py +++ b/torchgeo/trainers/byol.py @@ -343,7 +343,7 @@ def configure_models(self) -> None: _, state_dict = utils.extract_backbone(weights) else: state_dict = get_weight(weights).get_state_dict(progress=True) - backbone = utils.load_state_dict(backbone, state_dict) + utils.load_state_dict(backbone, state_dict) self.model = BYOL(backbone, in_channels=in_channels, image_size=(224, 224)) diff --git a/torchgeo/trainers/classification.py b/torchgeo/trainers/classification.py index 9ac312051c7..5d8d10c9dce 100644 --- a/torchgeo/trainers/classification.py +++ b/torchgeo/trainers/classification.py @@ -137,7 +137,7 @@ def configure_models(self) -> None: _, state_dict = utils.extract_backbone(weights) else: state_dict = get_weight(weights).get_state_dict(progress=True) - self.model = utils.load_state_dict(self.model, state_dict) + utils.load_state_dict(self.model, state_dict) # Freeze backbone and unfreeze classifier head if self.hparams["freeze_backbone"]: diff --git a/torchgeo/trainers/moco.py b/torchgeo/trainers/moco.py index d2621a8da74..4dbc1e453c9 100644 --- a/torchgeo/trainers/moco.py +++ b/torchgeo/trainers/moco.py @@ -261,7 +261,7 @@ def configure_models(self) -> None: _, state_dict = utils.extract_backbone(weights) else: state_dict = get_weight(weights).get_state_dict(progress=True) - self.backbone = utils.load_state_dict(self.backbone, state_dict) + utils.load_state_dict(self.backbone, state_dict) # Create projection (and prediction) head batch_norm = version == 3 diff --git a/torchgeo/trainers/regression.py b/torchgeo/trainers/regression.py index c58f033b5bc..9cc2ea56441 100644 --- a/torchgeo/trainers/regression.py +++ b/torchgeo/trainers/regression.py @@ -128,7 +128,7 @@ def configure_models(self) -> None: _, state_dict = utils.extract_backbone(weights) else: state_dict = get_weight(weights).get_state_dict(progress=True) - self.model = utils.load_state_dict(self.model, state_dict) + utils.load_state_dict(self.model, state_dict) # Freeze backbone and unfreeze classifier head if self.hparams["freeze_backbone"]: diff --git a/torchgeo/trainers/simclr.py b/torchgeo/trainers/simclr.py index a889be1c96f..27719eda224 100644 --- a/torchgeo/trainers/simclr.py +++ b/torchgeo/trainers/simclr.py @@ -172,7 +172,7 @@ def configure_models(self) -> None: _, state_dict = utils.extract_backbone(weights) else: state_dict = get_weight(weights).get_state_dict(progress=True) - self.backbone = utils.load_state_dict(self.backbone, state_dict) + utils.load_state_dict(self.backbone, state_dict) # Create projection head input_dim = self.backbone.num_features diff --git a/torchgeo/trainers/utils.py b/torchgeo/trainers/utils.py index e1b6678ed73..b5cd8f1e923 100644 --- a/torchgeo/trainers/utils.py +++ b/torchgeo/trainers/utils.py @@ -71,7 +71,9 @@ def _get_input_layer_name_and_module(model: Module) -> tuple[str, Module]: return key, module -def load_state_dict(model: Module, state_dict: "OrderedDict[str, Tensor]") -> Module: +def load_state_dict( + model: Module, state_dict: "OrderedDict[str, Tensor]" +) -> tuple[list[str], list[str]]: """Load pretrained resnet weights to a model. Args: @@ -79,7 +81,7 @@ def load_state_dict(model: Module, state_dict: "OrderedDict[str, Tensor]") -> Mo state_dict: dict containing tensor parameters Returns: - the model with pretrained weights + The missing and unexpected keys Warns: If input channels in model != pretrained model input channels @@ -115,8 +117,10 @@ def load_state_dict(model: Module, state_dict: "OrderedDict[str, Tensor]") -> Mo state_dict[output_module_key + ".bias"], ) - model.load_state_dict(state_dict, strict=False) - return model + missing_keys: list[str] + unexpected_keys: list[str] + missing_keys, unexpected_keys = model.load_state_dict(state_dict, strict=False) + return missing_keys, unexpected_keys def reinit_initial_conv_layer( From f5624ac2cc305ff54ccc43a49bddd27d0cb4aa88 Mon Sep 17 00:00:00 2001 From: Jingtong <115182031+cookie-kyu@users.noreply.github.com> Date: Tue, 6 Feb 2024 06:11:17 -0600 Subject: [PATCH 03/19] Adding South America Soybean Dataset (#1668) * Created file for South America Soybean dataset and added it to __init__.py * Updated south_america_soybean.py * Added tests * Updated data.py * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Update tests/datasets/test_south_america_soybean.py Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Updated tests * fixed an error in init * fixed some path inconsistencies * fixed all errors * Fix comments * added dataset to datasets.rst * edit datasets.rst * pushed again * Delete tests/data/south_america_soybean/.DS_Store * Update docs/api/datasets.rst Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> * Edited datasets.rst * Edited datasets.rst * Fixed styling * Fix docstring formatting * Fix whitespace * Add blank line * Fixed download urls * Update geo_datasets.csv * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Adam J. Stewart * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Adam J. Stewart * Update torchgeo/datasets/south_america_soybean.py Co-authored-by: Adam J. Stewart * Updated geo_datasets.csv and added years parameter to class * Delete tests/data/.DS_Store * Delete tests/.DS_Store * Update south_america_soybean.py * Fix docstring formatting --------- Co-authored-by: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> Co-authored-by: Adam J. Stewart --- docs/api/datasets.rst | 7 + docs/api/geo_datasets.csv | 1 + .../SouthAmericaSoybean.zip | Bin 0 -> 1578 bytes .../South_America_Soybean_2002.tif | Bin 0 -> 644 bytes .../South_America_Soybean_2021.tif | Bin 0 -> 643 bytes tests/data/south_america_soybean/data.py | 66 +++++++ tests/datasets/test_south_america_soybean.py | 104 +++++++++++ torchgeo/datasets/__init__.py | 2 + torchgeo/datasets/south_america_soybean.py | 175 ++++++++++++++++++ 9 files changed, 355 insertions(+) create mode 100644 tests/data/south_america_soybean/SouthAmericaSoybean.zip create mode 100644 tests/data/south_america_soybean/SouthAmericaSoybean/South_America_Soybean_2002.tif create mode 100644 tests/data/south_america_soybean/SouthAmericaSoybean/South_America_Soybean_2021.tif create mode 100644 tests/data/south_america_soybean/data.py create mode 100644 tests/datasets/test_south_america_soybean.py create mode 100644 torchgeo/datasets/south_america_soybean.py diff --git a/docs/api/datasets.rst b/docs/api/datasets.rst index 34835176851..645acbacc47 100644 --- a/docs/api/datasets.rst +++ b/docs/api/datasets.rst @@ -166,6 +166,13 @@ Sentinel .. autoclass:: Sentinel1 .. autoclass:: Sentinel2 + +South America Soybean +^^^^^^^^^^^^^^^^^^^^^ + +.. autoclass:: SouthAmericaSoybean + + .. _Non-geospatial Datasets: Non-geospatial Datasets diff --git a/docs/api/geo_datasets.csv b/docs/api/geo_datasets.csv index d8596a16068..ed7655e843d 100644 --- a/docs/api/geo_datasets.csv +++ b/docs/api/geo_datasets.csv @@ -24,3 +24,4 @@ Dataset,Type,Source,License,Size (px),Resolution (m) `Open Buildings`_,Geometries,"Maxar, CNES/Airbus","CC-BY-4.0 OR ODbL-1.0",-,- `PRISMA`_,Imagery,PRISMA,-,512x512,5--30 `Sentinel`_,Imagery,Sentinel,"CC-BY-SA-3.0-IGO","10,000x10,000",10 +`South America Soybean`_,Masks,"Landsat, MODIS",-,-,30 diff --git a/tests/data/south_america_soybean/SouthAmericaSoybean.zip b/tests/data/south_america_soybean/SouthAmericaSoybean.zip new file mode 100644 index 0000000000000000000000000000000000000000..5453b89fc25128d3e30c0281ee069bf1e8773aa7 GIT binary patch literal 1578 zcmWIWW@Zs#0D)zjR3g9(C=mdpLyJ?3iuJR~^+WQDk~7>>^Yu$WjC2qqwYa2MKP9mw zQNK99v?L=wF*mg+GdVH7IKMI}H8D>=7$oWl5e$Zk1wd`%0NWO~$II^tBLhPV69a=0 z&^By3z+&-GW8$Ia#2XnH80nQ{rhWc$CFwyzLV`d_LPAPf0?Q_mh8cpLXIWC4Lkyj7 zu5mcSmfE~QL798TIwqk-9*>edo^?21Enwu7R59HaU?wcUuDtQ*tV)R)jbC&X^0FQ# zCNN)`-%wF&ZG6KAk|JsrLsD^uGb-R;1}aPY}gdHtVik~a=#urV$8v~-rD zyYq=g`-HE21z&p-#5WonY-qUQ!_%V^V8|!%*Qa4(ac;MLCOD~pexaf4u zZ_4_cnvnsEkN8er{xhSi@%U^T$Ekehr*w*HCSKbUJCEOf@0ZM?(ANc31rMK3&2IZ7 ztha*m&7;bt`IZ;mzcxOR(=UHm*&fujt7seRFI_$_-k6dZrjC%`}sdW{eEUPcuw|GR-tLI{s(oWe4N{mbCY{u=<*a$;VEaA2ojHbabLp^hZs18J@CbE=y?cc@MJu|C4 zGbdl2vaj`__xV*mdn?ngC7rC?H>+uT^!mFZZ#X@*p6n{h+J9kL_b;)i?CWpWzTmIQ zUUzhNY((A3zhA|I76v{4?0>KR``YgC`0&q8JqM>x4c7NIm)-N@*Q=AozUQBot1Wx~ zq~`fH>$h$jcBQ1p#+1F7_a*;XRC=>+`MllB;(ot#c{g4xTfhKJGmK0k%(%-nND(K%@YWH;qJAj{vmJXm2eF-jVM${i rkV$%}hwvT5eDpklFniev$BEAU-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!rhQKs7Q*YHXowCZL*NBsO0&4+Aq$>=qC=weT>o0qIXbyuO_o>_#P^IUCw} z7(n`xfb5O!OkkfB0ofohdF97TzDWl5Fd8C?o2-1PX2{VHa^MeGpMyP2B_r5p>RyeS6voty>Y_yQE6Xk1mN*2^8ans~!KAK|S z@g`4DrNc92Vns@rHE);a!%r`Lnq1X7oE}{GdF7g+{Dcc?0=sx#>03_pQGFn}$ID%K z-l3GDuAFUwev5-r16OV>QZ`zD@_E6HEAy86Pr9)B+seCny3&i!YhM1%8>g=}?SxiI zW$dHNnVW;wU5{Ssx6^)Y$Oh3F+l)>cu1NkA+{3f%c>N0R7p6PEp8FYg;`CLfg-P}6YolX6=OUtLa)@@P#XX)3nd?$-{T{6BcXToK?;(XMP jQ17Wx=ldUCO#Apd&%FNZ(l%PtwtX%7Fc0m9D8>Xl~ literal 0 HcmV?d00001 diff --git a/tests/data/south_america_soybean/SouthAmericaSoybean/South_America_Soybean_2021.tif b/tests/data/south_america_soybean/SouthAmericaSoybean/South_America_Soybean_2021.tif new file mode 100644 index 0000000000000000000000000000000000000000..a220b500677c0b2b954c9a735358450535cfec60 GIT binary patch literal 643 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!ri5Ks7Q*YHXowCZL*NBsO0&4+Aq$>=qC=weT>o0qIXbyuO_o>_#P^IUCw} z7(n`xfb5O!OkkfB0ofohdF97TzDWl5Fd8C?o2-1PX2{VHa^MeGpMyP2B_r5p>MYiHojyM?XOo>W2ne6#QU?odYzUk}$wSt?We1SUcUXM2YJhCoP zWU>3BASsz!=H`=5s+P?Bqt_WT_ma{kt0{d8!+}h^QE)^ literal 0 HcmV?d00001 diff --git a/tests/data/south_america_soybean/data.py b/tests/data/south_america_soybean/data.py new file mode 100644 index 00000000000..fbe7d7b23d1 --- /dev/null +++ b/tests/data/south_america_soybean/data.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +import hashlib +import os +import shutil + +import numpy as np +import rasterio +from rasterio.crs import CRS +from rasterio.transform import Affine + +SIZE = 32 + + +np.random.seed(0) +files = ["South_America_Soybean_2002.tif", "South_America_Soybean_2021.tif"] + + +def create_file(path: str, dtype: str): + """Create the testing file.""" + profile = { + "driver": "GTiff", + "dtype": dtype, + "count": 1, + "crs": CRS.from_epsg(4326), + "transform": Affine( + 0.0002499999999999943131, + 0.0, + -82.0005000000000024, + 0.0, + -0.0002499999999999943131, + 0.0005000000000000, + ), + "height": SIZE, + "width": SIZE, + "compress": "lzw", + "predictor": 2, + } + + allowed_values = [0, 1] + + Z = np.random.choice(allowed_values, size=(SIZE, SIZE)) + + with rasterio.open(path, "w", **profile) as src: + src.write(Z, 1) + + +if __name__ == "__main__": + dir = os.path.join(os.getcwd(), "SouthAmericaSoybean") + if os.path.exists(dir) and os.path.isdir(dir): + shutil.rmtree(dir) + + os.makedirs(dir, exist_ok=True) + + for file in files: + create_file(os.path.join(dir, file), dtype="int8") + + # Compress data + shutil.make_archive("SouthAmericaSoybean", "zip", ".", dir) + + # Compute checksums + with open("SouthAmericaSoybean.zip", "rb") as f: + md5 = hashlib.md5(f.read()).hexdigest() + print(f"SouthAmericaSoybean.zip: {md5}") diff --git a/tests/datasets/test_south_america_soybean.py b/tests/datasets/test_south_america_soybean.py new file mode 100644 index 00000000000..11dcc2b5ff9 --- /dev/null +++ b/tests/datasets/test_south_america_soybean.py @@ -0,0 +1,104 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. +import os +import shutil +from pathlib import Path + +import matplotlib.pyplot as plt +import pytest +import torch +import torch.nn as nn +from pytest import MonkeyPatch +from rasterio.crs import CRS + +import torchgeo.datasets.utils +from torchgeo.datasets import ( + BoundingBox, + DatasetNotFoundError, + IntersectionDataset, + SouthAmericaSoybean, + UnionDataset, +) + + +def download_url(url: str, root: str, *args: str, **kwargs: str) -> None: + shutil.copy(url, root) + + +class TestSouthAmericaSoybean: + @pytest.fixture + def dataset(self, monkeypatch: MonkeyPatch, tmp_path: Path) -> SouthAmericaSoybean: + monkeypatch.setattr( + torchgeo.datasets.south_america_soybean, "download_url", download_url + ) + transforms = nn.Identity() + url = os.path.join( + "tests", + "data", + "south_america_soybean", + "SouthAmericaSoybean", + "South_America_Soybean_{}.tif", + ) + + monkeypatch.setattr(SouthAmericaSoybean, "url", url) + root = str(tmp_path) + return SouthAmericaSoybean( + paths=root, + years=[2002, 2021], + transforms=transforms, + download=True, + checksum=True, + ) + + def test_getitem(self, dataset: SouthAmericaSoybean) -> None: + x = dataset[dataset.bounds] + assert isinstance(x, dict) + assert isinstance(x["crs"], CRS) + assert isinstance(x["mask"], torch.Tensor) + + def test_and(self, dataset: SouthAmericaSoybean) -> None: + ds = dataset & dataset + assert isinstance(ds, IntersectionDataset) + + def test_or(self, dataset: SouthAmericaSoybean) -> None: + ds = dataset | dataset + assert isinstance(ds, UnionDataset) + + def test_already_extracted(self, dataset: SouthAmericaSoybean) -> None: + SouthAmericaSoybean(dataset.paths, download=True) + + def test_already_downloaded(self, tmp_path: Path) -> None: + pathname = os.path.join( + "tests", + "data", + "south_america_soybean", + "SouthAmericaSoybean", + "South_America_Soybean_2002.tif", + ) + root = str(tmp_path) + shutil.copy(pathname, root) + SouthAmericaSoybean(root) + + def test_plot(self, dataset: SouthAmericaSoybean) -> None: + query = dataset.bounds + x = dataset[query] + dataset.plot(x, suptitle="Test") + plt.close() + + def test_plot_prediction(self, dataset: SouthAmericaSoybean) -> None: + query = dataset.bounds + x = dataset[query] + x["prediction"] = x["mask"].clone() + dataset.plot(x, suptitle="Prediction") + plt.close() + + def test_not_downloaded(self, tmp_path: Path) -> None: + with pytest.raises(DatasetNotFoundError, match="Dataset not found"): + SouthAmericaSoybean(str(tmp_path)) + + def test_invalid_query(self, dataset: SouthAmericaSoybean) -> None: + query = BoundingBox(0, 0, 0, 0, 0, 0) + with pytest.raises( + IndexError, match="query: .* not found in index with bounds:" + ): + dataset[query] diff --git a/torchgeo/datasets/__init__.py b/torchgeo/datasets/__init__.py index fd20414e995..235ab83c8eb 100644 --- a/torchgeo/datasets/__init__.py +++ b/torchgeo/datasets/__init__.py @@ -98,6 +98,7 @@ from .sentinel import Sentinel, Sentinel1, Sentinel2 from .skippd import SKIPPD from .so2sat import So2Sat +from .south_america_soybean import SouthAmericaSoybean from .spacenet import ( SpaceNet, SpaceNet1, @@ -185,6 +186,7 @@ "Sentinel", "Sentinel1", "Sentinel2", + "SouthAmericaSoybean", # NonGeoDataset "ADVANCE", "BeninSmallHolderCashews", diff --git a/torchgeo/datasets/south_america_soybean.py b/torchgeo/datasets/south_america_soybean.py new file mode 100644 index 00000000000..e1d1e952cf0 --- /dev/null +++ b/torchgeo/datasets/south_america_soybean.py @@ -0,0 +1,175 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +"""South America Soybean Dataset.""" + +from collections.abc import Iterable +from typing import Any, Callable, Optional, Union + +import matplotlib.pyplot as plt +from matplotlib.figure import Figure +from rasterio.crs import CRS + +from .geo import RasterDataset +from .utils import DatasetNotFoundError, download_url + + +class SouthAmericaSoybean(RasterDataset): + """South America Soybean Dataset. + + This dataset produced annual 30-m soybean maps of South America from 2001 to 2021. + + Link: https://www.nature.com/articles/s41893-021-00729-z + + Dataset contains 2 classes: + + 0. other + 1. soybean + + Dataset Format: + + * 21 .tif files + + + If you use this dataset in your research, please cite the following paper: + + * https://doi.org/10.1038/s41893-021-00729-z + + .. versionadded:: 0.6 + """ + + filename_glob = "South_America_Soybean_*.*" + filename_regex = r"South_America_Soybean_(?P\d{4})" + + date_format = "%Y" + is_image = False + url = "https://glad.umd.edu/projects/AnnualClassMapsV1/SouthAmerica_Soybean_{}.tif" + + md5s = { + 2021: "edff3ada13a1a9910d1fe844d28ae4f", + 2020: "0709dec807f576c9707c8c7e183db31", + 2019: "441836493bbcd5e123cff579a58f5a4f", + 2018: "503c2d0a803c2a2629ebbbd9558a3013", + 2017: "4d0487ac1105d171e5f506f1766ea777", + 2016: "770c558f6ac40550d0e264da5e44b3e", + 2015: "6beb96a61fe0e9ce8c06263e500dde8f", + 2014: "824ff91c62a4ba9f4ccfd281729830e5", + 2013: "0263e19b3cae6fdaba4e3b450cef985e", + 2012: "9f3a71097c9836fcff18a13b9ba608b2", + 2011: "b73352ebea3d5658959e9044ec526143", + 2010: "9264532d36ffa93493735a6e44caef0d", + 2009: "341387c1bb42a15140c80702e4cca02d", + 2008: "96fc3f737ab3ce9bcd16cbf7761427e2", + 2007: "bb8549b6674163fe20ffd47ec4ce8903", + 2006: "eabaa525414ecbff89301d3d5c706f0b", + 2005: "89faae27f9b5afbd06935a465e5fe414", + 2004: "f9882ca9c70e054e50172835cb75a8c3", + 2003: "cad5ed461ff4ab45c90177841aaecad2", + 2002: "8a4a9dcea54b3ec7de07657b9f2c0893", + 2001: "2914b0af7590a0ca4dfa9ccefc99020f", + } + + def __init__( + self, + paths: Union[str, Iterable[str]] = "data", + crs: Optional[CRS] = None, + res: Optional[float] = None, + years: list[int] = [2021], + transforms: Optional[Callable[[dict[str, Any]], dict[str, Any]]] = None, + cache: bool = True, + download: bool = False, + checksum: bool = False, + ) -> None: + """Initialize a new Dataset instance. + + Args: + paths: one or more root directories to search or files to load + crs: :term:`coordinate reference system (CRS)` to warp to + (defaults to the CRS of the first file found) + res: resolution of the dataset in units of CRS + (defaults to the resolution of the first file found) + years: list of years for which to use the South America Soybean layer + transforms: a function/transform that takes an input sample + and returns a transformed version + cache: if True, cache file handle to speed up repeated sampling + download: if True, download dataset and store it in the root directory + checksum: if True, check the MD5 after downloading files (may be slow) + + Raises: + DatasetNotFoundError: If dataset is not found and *download* is False. + """ + self.paths = paths + self.download = download + self.checksum = checksum + self.years = years + self._verify() + + super().__init__(paths, crs, res, transforms=transforms, cache=cache) + + def _verify(self) -> None: + """Verify the integrity of the dataset.""" + # Check if the extracted files already exist + if self.files: + return + assert isinstance(self.paths, str) + + # Check if the user requested to download the dataset + if not self.download: + raise DatasetNotFoundError(self) + + # Download the dataset + self._download() + + def _download(self) -> None: + """Download the dataset.""" + for year in self.years: + download_url( + self.url.format(year), + self.paths, + md5=self.md5s[year] if self.checksum else None, + ) + + def plot( + self, + sample: dict[str, Any], + show_titles: bool = True, + suptitle: Optional[str] = None, + ) -> Figure: + """Plot a sample from the dataset. + + Args: + sample: a sample returned by :meth:`RasterDataset.__getitem__` + show_titles: flag indicating whether to show titles above each panel + suptitle: optional string to use as a suptitle + + Returns: + a matplotlib Figure with the rendered sample + """ + mask = sample["mask"].squeeze() + ncols = 1 + + showing_predictions = "prediction" in sample + if showing_predictions: + pred = sample["prediction"].squeeze() + ncols = 2 + + fig, axs = plt.subplots( + nrows=1, ncols=ncols, figsize=(ncols * 4, 4), squeeze=False + ) + + axs[0, 0].imshow(mask, interpolation="none") + axs[0, 0].axis("off") + + if show_titles: + axs[0, 0].set_title("Mask") + + if showing_predictions: + axs[0, 1].imshow(pred, interpolation="none") + axs[0, 1].axis("off") + if show_titles: + axs[0, 1].set_title("Prediction") + + if suptitle is not None: + plt.suptitle(suptitle) + + return fig From 78d1854b737e3130762fa1e43b2f311f84a9dede Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Tue, 6 Feb 2024 16:04:22 +0100 Subject: [PATCH 04/19] Revert mypy changes (#1836) * Revert mypy changes * Remove unused import --- torchgeo/datamodules/chesapeake.py | 3 +-- torchgeo/datamodules/spacenet.py | 3 +-- torchgeo/datasets/benin_cashews.py | 3 +-- torchgeo/datasets/bigearthnet.py | 3 +-- torchgeo/datasets/biomassters.py | 3 +-- torchgeo/datasets/cloud_cover.py | 2 +- torchgeo/datasets/cowc.py | 6 ++---- torchgeo/datasets/cyclone.py | 3 +-- torchgeo/datasets/etci2021.py | 3 +-- torchgeo/datasets/idtrees.py | 4 +--- torchgeo/datasets/inria.py | 6 ++---- torchgeo/datasets/landcoverai.py | 6 ++---- torchgeo/datasets/levircd.py | 3 +-- torchgeo/datasets/loveda.py | 3 +-- torchgeo/datasets/mapinwild.py | 3 +-- torchgeo/datasets/nasa_marine_debris.py | 3 +-- torchgeo/datasets/oscd.py | 3 +-- torchgeo/datasets/pastis.py | 3 +-- torchgeo/datasets/potsdam.py | 3 +-- torchgeo/datasets/seasonet.py | 4 +--- torchgeo/datasets/skippd.py | 3 +-- torchgeo/datasets/spacenet.py | 6 ++---- torchgeo/datasets/ssl4eo_benchmark.py | 6 ++---- torchgeo/datasets/usavars.py | 3 +-- torchgeo/losses/qr.py | 16 +++++----------- torchgeo/models/rcf.py | 2 +- torchgeo/samplers/batch.py | 2 +- torchgeo/samplers/single.py | 2 +- torchgeo/transforms/color.py | 9 +++------ 29 files changed, 40 insertions(+), 79 deletions(-) diff --git a/torchgeo/datamodules/chesapeake.py b/torchgeo/datamodules/chesapeake.py index 912ccb58db5..604c0d7e3ec 100644 --- a/torchgeo/datamodules/chesapeake.py +++ b/torchgeo/datamodules/chesapeake.py @@ -6,7 +6,6 @@ from typing import Any, Optional import kornia.augmentation as K -import torch import torch.nn as nn import torch.nn.functional as F from einops import rearrange @@ -113,7 +112,7 @@ def __init__( self.test_splits = test_splits self.class_set = class_set self.use_prior_labels = use_prior_labels - self.prior_smoothing_constant = torch.tensor(prior_smoothing_constant) + self.prior_smoothing_constant = prior_smoothing_constant if self.use_prior_labels: self.layers = [ diff --git a/torchgeo/datamodules/spacenet.py b/torchgeo/datamodules/spacenet.py index ed4fbe15795..3a3b7531cba 100644 --- a/torchgeo/datamodules/spacenet.py +++ b/torchgeo/datamodules/spacenet.py @@ -6,7 +6,6 @@ from typing import Any import kornia.augmentation as K -import torch from torch import Tensor from ..datasets import SpaceNet1 @@ -88,6 +87,6 @@ def on_after_batch_transfer( # We add 1 to the mask to map the current {background, building} labels to # the values {1, 2}. This is necessary because we add 0 padding to the # mask that we want to ignore in the loss function. - batch["mask"] += torch.tensor(1) + batch["mask"] += 1 return super().on_after_batch_transfer(batch, dataloader_idx) diff --git a/torchgeo/datasets/benin_cashews.py b/torchgeo/datasets/benin_cashews.py index 9edda8d26cb..6b9f95d34bb 100644 --- a/torchgeo/datasets/benin_cashews.py +++ b/torchgeo/datasets/benin_cashews.py @@ -387,8 +387,7 @@ def _load_mask(self, transform: rasterio.Affine) -> Tensor: dtype=np.uint8, ) - mask = torch.from_numpy(mask_data) - mask = mask.long() + mask = torch.from_numpy(mask_data).long() return mask def _check_integrity(self) -> bool: diff --git a/torchgeo/datasets/bigearthnet.py b/torchgeo/datasets/bigearthnet.py index 3a821811f54..9a127248a8b 100644 --- a/torchgeo/datasets/bigearthnet.py +++ b/torchgeo/datasets/bigearthnet.py @@ -408,8 +408,7 @@ def _load_image(self, index: int) -> Tensor: ) images.append(array) arrays: "np.typing.NDArray[np.int_]" = np.stack(images, axis=0) - tensor = torch.from_numpy(arrays) - tensor = tensor.float() + tensor = torch.from_numpy(arrays).float() return tensor def _load_target(self, index: int) -> Tensor: diff --git a/torchgeo/datasets/biomassters.py b/torchgeo/datasets/biomassters.py index eff773308ae..970c5594950 100644 --- a/torchgeo/datasets/biomassters.py +++ b/torchgeo/datasets/biomassters.py @@ -198,8 +198,7 @@ def _load_target(self, filename: str) -> Tensor: with rasterio.open(os.path.join(self.root, "train_agbm", filename), "r") as src: arr: "np.typing.NDArray[np.float_]" = src.read() - target = torch.from_numpy(arr) - target = target.float() + target = torch.from_numpy(arr).float() return target def _verify(self) -> None: diff --git a/torchgeo/datasets/cloud_cover.py b/torchgeo/datasets/cloud_cover.py index 5f19a935beb..60bbe78e21d 100644 --- a/torchgeo/datasets/cloud_cover.py +++ b/torchgeo/datasets/cloud_cover.py @@ -384,7 +384,7 @@ def plot( else: n_cols = 2 - image, mask = sample["image"] / torch.tensor(3000), sample["mask"] + image, mask = sample["image"] / 3000, sample["mask"] fig, axs = plt.subplots(nrows=1, ncols=n_cols, figsize=(10, n_cols * 5)) diff --git a/torchgeo/datasets/cowc.py b/torchgeo/datasets/cowc.py index 47cd3766af6..0e0518502ad 100644 --- a/torchgeo/datasets/cowc.py +++ b/torchgeo/datasets/cowc.py @@ -144,8 +144,7 @@ def _load_image(self, index: int) -> Tensor: filename = os.path.join(self.root, self.images[index]) with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() # Convert from HxWxC to CxHxW tensor = tensor.permute((2, 0, 1)) return tensor @@ -160,8 +159,7 @@ def _load_target(self, index: int) -> Tensor: the target """ target = int(self.targets[index]) - tensor = torch.tensor(target) - tensor = tensor.float() + tensor = torch.tensor(target).float() return tensor def _check_integrity(self) -> bool: diff --git a/torchgeo/datasets/cyclone.py b/torchgeo/datasets/cyclone.py index 49cf247e409..c9a1243e970 100644 --- a/torchgeo/datasets/cyclone.py +++ b/torchgeo/datasets/cyclone.py @@ -164,8 +164,7 @@ def _load_image(self, directory: str) -> Tensor: img = img.resize(size=(self.size, self.size), resample=resample) array: "np.typing.NDArray[np.int_]" = np.array(img.convert("RGB")) tensor = torch.from_numpy(array) - tensor = tensor.permute((2, 0, 1)) - tensor = tensor.float() + tensor = tensor.permute((2, 0, 1)).float() return tensor def _load_features(self, directory: str) -> dict[str, Any]: diff --git a/torchgeo/datasets/etci2021.py b/torchgeo/datasets/etci2021.py index e93a35fa9af..7dfa50fb2ab 100644 --- a/torchgeo/datasets/etci2021.py +++ b/torchgeo/datasets/etci2021.py @@ -204,8 +204,7 @@ def _load_image(self, path: str) -> Tensor: filename = os.path.join(path) with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img.convert("RGB")) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() # Convert from HxWxC to CxHxW tensor = tensor.permute((2, 0, 1)) return tensor diff --git a/torchgeo/datasets/idtrees.py b/torchgeo/datasets/idtrees.py index 9253cadbafd..715c3bfedab 100644 --- a/torchgeo/datasets/idtrees.py +++ b/torchgeo/datasets/idtrees.py @@ -494,9 +494,7 @@ def plot( assert len(hsi_indices) == 3 def normalize(x: Tensor) -> Tensor: - # https://github.com/pytorch/pytorch/issues/116327 - out: Tensor = (x - x.min()) / (x.max() - x.min()) - return out + return (x - x.min()) / (x.max() - x.min()) ncols = 3 diff --git a/torchgeo/datasets/inria.py b/torchgeo/datasets/inria.py index b3b8c79d57a..b3ab0a6fd9c 100644 --- a/torchgeo/datasets/inria.py +++ b/torchgeo/datasets/inria.py @@ -135,8 +135,7 @@ def _load_image(self, path: str) -> Tensor: """ with rio.open(path) as img: array = img.read().astype(np.int32) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _load_target(self, path: str) -> Tensor: @@ -151,8 +150,7 @@ def _load_target(self, path: str) -> Tensor: with rio.open(path) as img: array = img.read().astype(np.int32) array = np.clip(array, 0, 1) - mask = torch.from_numpy(array[0]) - mask = mask.long() + mask = torch.from_numpy(array[0]).long() return mask def __len__(self) -> int: diff --git a/torchgeo/datasets/landcoverai.py b/torchgeo/datasets/landcoverai.py index 1962bdcbca5..8dec50b562e 100644 --- a/torchgeo/datasets/landcoverai.py +++ b/torchgeo/datasets/landcoverai.py @@ -364,8 +364,7 @@ def _load_image(self, id_: str) -> Tensor: filename = os.path.join(self.root, "output", id_ + ".jpg") with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() # Convert from HxWxC to CxHxW tensor = tensor.permute((2, 0, 1)) return tensor @@ -383,8 +382,7 @@ def _load_target(self, id_: str) -> Tensor: filename = os.path.join(self.root, "output", id_ + "_m.png") with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img.convert("L")) - tensor = torch.from_numpy(array) - tensor = tensor.long() + tensor = torch.from_numpy(array).long() return tensor def _verify_data(self) -> bool: diff --git a/torchgeo/datasets/levircd.py b/torchgeo/datasets/levircd.py index 0642557d187..76481fed1dd 100644 --- a/torchgeo/datasets/levircd.py +++ b/torchgeo/datasets/levircd.py @@ -109,8 +109,7 @@ def _load_image(self, path: str) -> Tensor: filename = os.path.join(path) with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img.convert("RGB")) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() # Convert from HxWxC to CxHxW tensor = tensor.permute((2, 0, 1)) return tensor diff --git a/torchgeo/datasets/loveda.py b/torchgeo/datasets/loveda.py index fc5b15af20a..9c7e2aaff4e 100644 --- a/torchgeo/datasets/loveda.py +++ b/torchgeo/datasets/loveda.py @@ -210,8 +210,7 @@ def _load_image(self, path: str) -> Tensor: filename = os.path.join(path) with Image.open(filename) as img: array: "np.typing.NDArray[np.int_]" = np.array(img.convert("RGB")) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() # Convert from HxWxC to CxHxW tensor = tensor.permute((2, 0, 1)) return tensor diff --git a/torchgeo/datasets/mapinwild.py b/torchgeo/datasets/mapinwild.py index f26c2564842..5eaa426d230 100644 --- a/torchgeo/datasets/mapinwild.py +++ b/torchgeo/datasets/mapinwild.py @@ -220,8 +220,7 @@ def _load_raster(self, filename: int, source: str) -> Tensor: array: "np.typing.NDArray[np.int_]" = np.stack(raw_array, axis=0) if array.dtype == np.uint16: array = array.astype(np.int32) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _verify(self, url: str, md5: Optional[str] = None) -> None: diff --git a/torchgeo/datasets/nasa_marine_debris.py b/torchgeo/datasets/nasa_marine_debris.py index b43b1881f1e..a1637f46e7d 100644 --- a/torchgeo/datasets/nasa_marine_debris.py +++ b/torchgeo/datasets/nasa_marine_debris.py @@ -138,8 +138,7 @@ def _load_image(self, path: str) -> Tensor: """ with rasterio.open(path) as f: array = f.read() - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _load_target(self, path: str) -> Tensor: diff --git a/torchgeo/datasets/oscd.py b/torchgeo/datasets/oscd.py index db98e6ff2b4..eebe7348d0a 100644 --- a/torchgeo/datasets/oscd.py +++ b/torchgeo/datasets/oscd.py @@ -222,8 +222,7 @@ def _load_image(self, paths: Sequence[str]) -> Tensor: with Image.open(path) as img: images.append(np.array(img)) array: "np.typing.NDArray[np.int_]" = np.stack(images, axis=0).astype(np.int_) - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _load_target(self, path: str) -> Tensor: diff --git a/torchgeo/datasets/pastis.py b/torchgeo/datasets/pastis.py index 4e38eb4af30..84925a85022 100644 --- a/torchgeo/datasets/pastis.py +++ b/torchgeo/datasets/pastis.py @@ -235,8 +235,7 @@ def _load_semantic_targets(self, index: int) -> Tensor: # See https://github.com/VSainteuf/pastis-benchmark/blob/main/code/dataloader.py#L201 # noqa: E501 # even though the mask file is 3 bands, we just select the first band array = np.load(self.files[index]["semantic"])[0].astype(np.uint8) - tensor = torch.from_numpy(array) - tensor = tensor.long() + tensor = torch.from_numpy(array).long() return tensor def _load_instance_targets(self, index: int) -> tuple[Tensor, Tensor, Tensor]: diff --git a/torchgeo/datasets/potsdam.py b/torchgeo/datasets/potsdam.py index a510a3f49fb..782fd7ce87d 100644 --- a/torchgeo/datasets/potsdam.py +++ b/torchgeo/datasets/potsdam.py @@ -192,8 +192,7 @@ def _load_image(self, index: int) -> Tensor: path = self.files[index]["image"] with rasterio.open(path) as f: array = f.read() - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _load_target(self, index: int) -> Tensor: diff --git a/torchgeo/datasets/seasonet.py b/torchgeo/datasets/seasonet.py index 82e0438f2d0..b01ad3cae68 100644 --- a/torchgeo/datasets/seasonet.py +++ b/torchgeo/datasets/seasonet.py @@ -359,9 +359,7 @@ def _load_target(self, index: int) -> Tensor: path = self.files.iloc[index][0] with rasterio.open(f"{path}_labels.tif") as f: array = f.read() - 1 - tensor = torch.from_numpy(array) - tensor = tensor.squeeze() - tensor = tensor.long() + tensor = torch.from_numpy(array).squeeze().long() return tensor def _verify(self) -> None: diff --git a/torchgeo/datasets/skippd.py b/torchgeo/datasets/skippd.py index baa21c4495c..156b3f1568d 100644 --- a/torchgeo/datasets/skippd.py +++ b/torchgeo/datasets/skippd.py @@ -173,8 +173,7 @@ def _load_image(self, index: int) -> Tensor: else: arr = rearrange(arr, "h w c -> c h w") - tensor = torch.from_numpy(arr) - tensor = tensor.to(torch.float32) + tensor = torch.from_numpy(arr).to(torch.float32) return tensor def _load_features(self, index: int) -> dict[str, Union[str, Tensor]]: diff --git a/torchgeo/datasets/spacenet.py b/torchgeo/datasets/spacenet.py index 5cb5d1e2356..c6780e1971c 100644 --- a/torchgeo/datasets/spacenet.py +++ b/torchgeo/datasets/spacenet.py @@ -200,8 +200,7 @@ def _load_mask( dtype=np.uint8, ) - mask = torch.from_numpy(mask_data) - mask = mask.long() + mask = torch.from_numpy(mask_data).long() return mask @@ -727,8 +726,7 @@ def _load_mask( dtype=np.uint8, ) - mask = torch.from_numpy(mask_data) - mask = mask.long() + mask = torch.from_numpy(mask_data).long() return mask def plot( diff --git a/torchgeo/datasets/ssl4eo_benchmark.py b/torchgeo/datasets/ssl4eo_benchmark.py index a3f769aa789..003cccf2fcf 100644 --- a/torchgeo/datasets/ssl4eo_benchmark.py +++ b/torchgeo/datasets/ssl4eo_benchmark.py @@ -306,8 +306,7 @@ def _load_image(self, path: str) -> Tensor: image """ with rasterio.open(path) as src: - image = torch.from_numpy(src.read()) - image = image.float() + image = torch.from_numpy(src.read()).float() return image def _load_mask(self, path: str) -> Tensor: @@ -320,8 +319,7 @@ def _load_mask(self, path: str) -> Tensor: mask """ with rasterio.open(path) as src: - mask = torch.from_numpy(src.read()) - mask = mask.long() + mask = torch.from_numpy(src.read()).long() mask = self.ordinal_map[mask] return mask diff --git a/torchgeo/datasets/usavars.py b/torchgeo/datasets/usavars.py index 81823cd848d..f33d268d4ce 100644 --- a/torchgeo/datasets/usavars.py +++ b/torchgeo/datasets/usavars.py @@ -181,8 +181,7 @@ def _load_image(self, path: str) -> Tensor: """ with rasterio.open(path) as f: array: "np.typing.NDArray[np.int_]" = f.read() - tensor = torch.from_numpy(array) - tensor = tensor.float() + tensor = torch.from_numpy(array).float() return tensor def _verify(self) -> None: diff --git a/torchgeo/losses/qr.py b/torchgeo/losses/qr.py index 9bffc4a915f..ecffa33e9fa 100644 --- a/torchgeo/losses/qr.py +++ b/torchgeo/losses/qr.py @@ -5,7 +5,6 @@ import torch import torch.nn.functional as F -from torch import Tensor from torch.nn.modules import Module @@ -29,16 +28,12 @@ def forward(self, probs: torch.Tensor, target: torch.Tensor) -> torch.Tensor: qr loss """ q = probs - # https://github.com/pytorch/pytorch/issues/116327 - q_bar: Tensor = q.mean(dim=(0, 2, 3)) - log_q_bar = torch.log(q_bar) - qbar_log_S: Tensor = q_bar * log_q_bar - qbar_log_S = qbar_log_S.sum() + q_bar = q.mean(dim=(0, 2, 3)) + qbar_log_S = (q_bar * torch.log(q_bar)).sum() - q_log_p = torch.einsum("bcxy,bcxy->bxy", q, torch.log(target)) - q_log_p = q_log_p.mean() + q_log_p = torch.einsum("bcxy,bcxy->bxy", q, torch.log(target)).mean() - loss: Tensor = qbar_log_S - q_log_p + loss = qbar_log_S - q_log_p return loss @@ -67,7 +62,6 @@ def forward(self, probs: torch.Tensor, target: torch.Tensor) -> torch.Tensor: z = q / q.norm(p=1, dim=(0, 2, 3), keepdim=True).clamp_min(1e-12).expand_as(q) r = F.normalize(z * target, p=1, dim=1) - loss = torch.einsum("bcxy,bcxy->bxy", r, torch.log(r) - torch.log(q)) - loss = loss.mean() + loss = torch.einsum("bcxy,bcxy->bxy", r, torch.log(r) - torch.log(q)).mean() return loss diff --git a/torchgeo/models/rcf.py b/torchgeo/models/rcf.py index ebf46bcc610..59f42223cf1 100644 --- a/torchgeo/models/rcf.py +++ b/torchgeo/models/rcf.py @@ -94,7 +94,7 @@ def __init__( ), ) self.register_buffer( - "biases", torch.zeros(num_patches, requires_grad=False) + torch.tensor(bias) + "biases", torch.zeros(num_patches, requires_grad=False) + bias ) if mode == "empirical": diff --git a/torchgeo/samplers/batch.py b/torchgeo/samplers/batch.py index a60a787444a..ef9bb05f10f 100644 --- a/torchgeo/samplers/batch.py +++ b/torchgeo/samplers/batch.py @@ -128,7 +128,7 @@ def __init__( # torch.multinomial requires float probabilities > 0 self.areas = torch.tensor(areas, dtype=torch.float) if torch.sum(self.areas) == 0: - self.areas += torch.tensor(1) + self.areas += 1 def __iter__(self) -> Iterator[list[BoundingBox]]: """Return the indices of a dataset. diff --git a/torchgeo/samplers/single.py b/torchgeo/samplers/single.py index 1180044c6e4..7251f4b274f 100644 --- a/torchgeo/samplers/single.py +++ b/torchgeo/samplers/single.py @@ -128,7 +128,7 @@ def __init__( # torch.multinomial requires float probabilities > 0 self.areas = torch.tensor(areas, dtype=torch.float) if torch.sum(self.areas) == 0: - self.areas += torch.tensor(1) + self.areas += 1 def __iter__(self) -> Iterator[BoundingBox]: """Return the index of a dataset. diff --git a/torchgeo/transforms/color.py b/torchgeo/transforms/color.py index e89ed471a4a..5459fc2f854 100644 --- a/torchgeo/transforms/color.py +++ b/torchgeo/transforms/color.py @@ -70,11 +70,8 @@ def apply_transform( Returns: The augmented input. """ - weights = flags["weights"] - weights = weights[..., :, None, None] - weights = weights.to(input.device) - out: Tensor = input * weights + weights = flags["weights"][..., :, None, None].to(input.device) + out = input * weights out = out.sum(dim=-3) - out = out.unsqueeze(-3) - out = out.expand(input.shape) + out = out.unsqueeze(-3).expand(input.shape) return out From 82e2559a1f292d9e43070ea0e1c8178f9cf94b62 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Tue, 6 Feb 2024 16:04:40 +0100 Subject: [PATCH 05/19] Test Python 3.12 (#1837) * Test Python 3.12 * Flake8 fix * Caching bug --- .github/workflows/release.yaml | 6 +++--- .github/workflows/style.yaml | 12 ++++++------ .github/workflows/tests.yaml | 4 ++-- .github/workflows/tutorials.yaml | 2 +- .readthedocs.yaml | 2 +- experiments/torchgeo/run_resisc45_experiments.py | 2 +- experiments/torchgeo/run_so2sat_experiments.py | 2 +- experiments/torchgeo/run_so2sat_seed_experiments.py | 2 +- pyproject.toml | 1 + 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6c6c680ae63..dce17ec3f94 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -16,7 +16,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -44,7 +44,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -72,7 +72,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache diff --git a/.github/workflows/style.yaml b/.github/workflows/style.yaml index 7d6236c9408..8bd60000d5f 100644 --- a/.github/workflows/style.yaml +++ b/.github/workflows/style.yaml @@ -18,7 +18,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -43,7 +43,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -68,7 +68,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -93,7 +93,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -118,7 +118,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache @@ -143,7 +143,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ec5a68feb25..613e442a012 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -17,7 +17,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - name: Clone repo uses: actions/checkout@v4.1.1 @@ -31,7 +31,7 @@ jobs: with: path: ${{ env.pythonLocation }} key: ${{ env.pythonLocation }}-${{ hashFiles('requirements/required.txt') }}-${{ hashFiles('requirements/datasets.txt') }}-${{ hashFiles('requirements/tests.txt') }} - if: ${{ ! (runner.os == 'macOS' && matrix.python-version == '3.11') }} + if: ${{ ! (runner.os == 'macOS' && (matrix.python-version == '3.11' || matrix.python-version == '3.12')) }} - name: Setup headless display for pyvista uses: pyvista/setup-headless-display-action@v2 - name: Install apt dependencies (Linux) diff --git a/.github/workflows/tutorials.yaml b/.github/workflows/tutorials.yaml index a55b4693b70..800a3ca46a7 100644 --- a/.github/workflows/tutorials.yaml +++ b/.github/workflows/tutorials.yaml @@ -20,7 +20,7 @@ jobs: - name: Set up python uses: actions/setup-python@v5.0.0 with: - python-version: '3.11' + python-version: '3.12' - name: Cache dependencies uses: actions/cache@v4.0.0 id: cache diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 534c7e24017..9cfd9895a23 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,7 +8,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.11" + python: "3.12" # Configuration of the Python environment to be used python: diff --git a/experiments/torchgeo/run_resisc45_experiments.py b/experiments/torchgeo/run_resisc45_experiments.py index e4915bc0c64..1049edf749b 100755 --- a/experiments/torchgeo/run_resisc45_experiments.py +++ b/experiments/torchgeo/run_resisc45_experiments.py @@ -37,7 +37,7 @@ def do_work(work: "Queue[str]", gpu_idx: int) -> bool: for model, lr, loss, weights in itertools.product( model_options, lr_options, loss_options, weight_options ): - experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_','-')}" + experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_', '-')}" output_dir = os.path.join("output", "resisc45_experiments") log_dir = os.path.join(output_dir, "logs") diff --git a/experiments/torchgeo/run_so2sat_experiments.py b/experiments/torchgeo/run_so2sat_experiments.py index d574d0987c0..fd8562ca345 100755 --- a/experiments/torchgeo/run_so2sat_experiments.py +++ b/experiments/torchgeo/run_so2sat_experiments.py @@ -37,7 +37,7 @@ def do_work(work: "Queue[str]", gpu_idx: int) -> bool: for model, lr, loss, weights in itertools.product( model_options, lr_options, loss_options, weight_options ): - experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_','-')}" + experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_', '-')}" output_dir = os.path.join("output", "so2sat_experiments") log_dir = os.path.join(output_dir, "logs") diff --git a/experiments/torchgeo/run_so2sat_seed_experiments.py b/experiments/torchgeo/run_so2sat_seed_experiments.py index 90e6d274910..2f88eba3c75 100755 --- a/experiments/torchgeo/run_so2sat_seed_experiments.py +++ b/experiments/torchgeo/run_so2sat_seed_experiments.py @@ -38,7 +38,7 @@ def do_work(work: "Queue[str]", gpu_idx: int) -> bool: for model, lr, loss, weights, seed in itertools.product( model_options, lr_options, loss_options, weight_options, seeds ): - experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_','-')}_{seed}" + experiment_name = f"{model}_{lr}_{loss}_{weights.replace('_', '-')}_{seed}" output_dir = os.path.join("output", "so2sat_seed_experiments") log_dir = os.path.join(output_dir, "logs") diff --git a/pyproject.toml b/pyproject.toml index d4a8c7ae955..5b0a12c4830 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,7 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Scientific/Engineering :: GIS", ] From 1cf860107192ac5daa385709b76df48ab2d8843f Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Tue, 6 Feb 2024 17:34:34 +0100 Subject: [PATCH 06/19] Debug coverage (#1857) --- .github/workflows/tests.yaml | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 613e442a012..3fbc4995661 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -101,20 +101,6 @@ jobs: with: name: coverage_minimum path: coverage.xml - codecov: - name: codecov - runs-on: ubuntu-latest - needs: [latest, minimum] - steps: - - name: Clone repo - uses: actions/checkout@v4.1.1 - - name: Download coverage artifacts - uses: actions/download-artifact@v4.1.1 - - name: Report coverage - uses: codecov/codecov-action@v3.1.6 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }} cancel-in-progress: true From 9515d87f6c23c1e9bd4c680b47f9a547fcd22690 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 03:38:49 -0600 Subject: [PATCH 07/19] Bump numpy from 1.26.3 to 1.26.4 in /requirements (#1859) Bumps [numpy](https://github.com/numpy/numpy) from 1.26.3 to 1.26.4. - [Release notes](https://github.com/numpy/numpy/releases) - [Changelog](https://github.com/numpy/numpy/blob/main/doc/RELEASE_WALKTHROUGH.rst) - [Commits](https://github.com/numpy/numpy/compare/v1.26.3...v1.26.4) --- updated-dependencies: - dependency-name: numpy dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/required.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/required.txt b/requirements/required.txt index 7631a543e30..ca884526ff6 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -8,7 +8,7 @@ kornia==0.7.1 lightly==1.4.25 lightning[pytorch-extra]==2.1.4 matplotlib==3.8.2 -numpy==1.26.3 +numpy==1.26.4 pandas==2.2.0 pillow==10.2.0 pyproj==3.6.1 From f0885eeb086a7dacc632d8a4aed1aaf8a7de8f6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 03:39:02 -0600 Subject: [PATCH 08/19] Bump pyvista from 0.43.2 to 0.43.3 in /requirements (#1860) Bumps [pyvista](https://github.com/pyvista/pyvista) from 0.43.2 to 0.43.3. - [Release notes](https://github.com/pyvista/pyvista/releases) - [Commits](https://github.com/pyvista/pyvista/compare/v0.43.2...v0.43.3) --- updated-dependencies: - dependency-name: pyvista dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- requirements/datasets.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/datasets.txt b/requirements/datasets.txt index a52aa575d9e..d2caa09ad30 100644 --- a/requirements/datasets.txt +++ b/requirements/datasets.txt @@ -3,7 +3,7 @@ h5py==3.10.0 laspy==2.5.3 opencv-python==4.9.0.80 pycocotools==2.0.7 -pyvista==0.43.2 +pyvista==0.43.3 radiant-mlhub==0.4.1 rarfile==4.1 scikit-image==0.22.0 From b6cbb17f0dde68a1f5411064af7c3e4ccc9928c0 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 7 Feb 2024 10:50:35 +0100 Subject: [PATCH 09/19] Debug coverage (#1858) * Debug coverage * Add necessary info --- .github/workflows/coverage.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 179e13377ad..59c31772e30 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -20,3 +20,5 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true + override_commit: ${{ github.event.workflow_run.pull_requests.head.sha || '' }} + override_pr: ${{ github.event.workflow_run.pull_requests.number || '' }} From 216773a72c9fc51885bb2181f40db598af7e88f2 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 7 Feb 2024 14:58:33 +0100 Subject: [PATCH 10/19] Debug coverage (#1862) * Debug coverage * Checkout PR commit --- .github/workflows/coverage.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 59c31772e30..0f74b6ac1b6 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -10,6 +10,8 @@ jobs: steps: - name: Clone repo uses: actions/checkout@v4.1.1 + with: + ref: ${{ github.event.workflow_run.pull_requests.head.sha || '' }} - name: Download coverage artifacts uses: actions/download-artifact@v4.1.1 with: From 78c97f97adc892f4ba140e6b70c9b2ab847b6541 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 7 Feb 2024 18:50:59 +0100 Subject: [PATCH 11/19] Debug coverage (#1863) * Debug coverage * Manually store PR information * Remove empty line --- .github/workflows/coverage.yaml | 19 ++++++++++++------- .github/workflows/tests.yaml | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 0f74b6ac1b6..5b4966003de 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -8,19 +8,24 @@ jobs: name: codecov runs-on: ubuntu-latest steps: - - name: Clone repo - uses: actions/checkout@v4.1.1 - with: - ref: ${{ github.event.workflow_run.pull_requests.head.sha || '' }} - - name: Download coverage artifacts + - name: Download artifacts uses: actions/download-artifact@v4.1.1 with: github-token: ${{ github.token }} run-id: ${{ github.event.workflow_run.id }} + - name: Parse artifacts + id: parse_artifacts + run: | + echo "pr_number=$(> "$GITHUB_OUTPUT" + echo "commit_sha=$(> "$GITHUB_OUTPUT" + - name: Clone repo + uses: actions/checkout@v4.1.1 + with: + ref: ${{ steps.parse_artifacts.outputs.commit_sha || '' }} - name: Report coverage uses: codecov/codecov-action@v4.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} fail_ci_if_error: true - override_commit: ${{ github.event.workflow_run.pull_requests.head.sha || '' }} - override_pr: ${{ github.event.workflow_run.pull_requests.number || '' }} + override_commit: ${{ steps.parse_artifacts.outputs.commit_sha || '' }} + override_pr: ${{ steps.parse_artifacts.outputs.pr_number || '' }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 3fbc4995661..dde41f34412 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -96,11 +96,25 @@ jobs: run: | pytest --cov=torchgeo --cov-report=xml --durations=10 python3 -m torchgeo --help + - name: Save PR information + run: | + echo "${{ github.event.number }}" > pr_number.txt + echo "${{ github.event.pull_request.head.sha }}" > commit_sha.txt - name: Upload coverage artifact uses: actions/upload-artifact@v4.3.0 with: name: coverage_minimum path: coverage.xml + - name: Upload PR number + uses: actions/upload-artifact@v4.3.0 + with: + name: pr_number + path: pr_number.txt + - name: Upload commit SHA + uses: actions/upload-artifact@v4.3.0 + with: + name: commit_sha + path: commit_sha.txt concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }} cancel-in-progress: true From cf6a459cce017cca658f762933567032fe21f68a Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 7 Feb 2024 19:56:20 +0100 Subject: [PATCH 12/19] Debug coverage (#1864) * Debug coverage * Extract all artifacts --- .github/workflows/coverage.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 5b4966003de..5d8b26b1fa4 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -16,6 +16,7 @@ jobs: - name: Parse artifacts id: parse_artifacts run: | + unzip *.zip echo "pr_number=$(> "$GITHUB_OUTPUT" echo "commit_sha=$(> "$GITHUB_OUTPUT" - name: Clone repo From ef31e932f1ac20357671250da6528cc1664fc93b Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Wed, 7 Feb 2024 20:25:35 +0100 Subject: [PATCH 13/19] Debug coverage (#1865) * Debug coverage * Unzip files first --- .github/workflows/coverage.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 5d8b26b1fa4..4883d7de856 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -16,7 +16,8 @@ jobs: - name: Parse artifacts id: parse_artifacts run: | - unzip *.zip + unzip pr_number.zip + unzip commit_sha.zip echo "pr_number=$(> "$GITHUB_OUTPUT" echo "commit_sha=$(> "$GITHUB_OUTPUT" - name: Clone repo From 67ef19e12b964d9524a3018558bb4e93c8b8e5c0 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Thu, 8 Feb 2024 11:59:15 +0100 Subject: [PATCH 14/19] Debug coverage (#1866) * Debug coverage * Restore to MetRonnie's solution --- .github/workflows/coverage.yaml | 33 --------------------------------- .github/workflows/tests.yaml | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 46 deletions(-) delete mode 100644 .github/workflows/coverage.yaml diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml deleted file mode 100644 index 4883d7de856..00000000000 --- a/.github/workflows/coverage.yaml +++ /dev/null @@ -1,33 +0,0 @@ -name: coverage -on: - workflow_run: - workflows: [tests] - types: [completed] -jobs: - codecov: - name: codecov - runs-on: ubuntu-latest - steps: - - name: Download artifacts - uses: actions/download-artifact@v4.1.1 - with: - github-token: ${{ github.token }} - run-id: ${{ github.event.workflow_run.id }} - - name: Parse artifacts - id: parse_artifacts - run: | - unzip pr_number.zip - unzip commit_sha.zip - echo "pr_number=$(> "$GITHUB_OUTPUT" - echo "commit_sha=$(> "$GITHUB_OUTPUT" - - name: Clone repo - uses: actions/checkout@v4.1.1 - with: - ref: ${{ steps.parse_artifacts.outputs.commit_sha || '' }} - - name: Report coverage - uses: codecov/codecov-action@v4.0.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - override_commit: ${{ steps.parse_artifacts.outputs.commit_sha || '' }} - override_pr: ${{ steps.parse_artifacts.outputs.pr_number || '' }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index dde41f34412..613e442a012 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -96,25 +96,25 @@ jobs: run: | pytest --cov=torchgeo --cov-report=xml --durations=10 python3 -m torchgeo --help - - name: Save PR information - run: | - echo "${{ github.event.number }}" > pr_number.txt - echo "${{ github.event.pull_request.head.sha }}" > commit_sha.txt - name: Upload coverage artifact uses: actions/upload-artifact@v4.3.0 with: name: coverage_minimum path: coverage.xml - - name: Upload PR number - uses: actions/upload-artifact@v4.3.0 - with: - name: pr_number - path: pr_number.txt - - name: Upload commit SHA - uses: actions/upload-artifact@v4.3.0 + codecov: + name: codecov + runs-on: ubuntu-latest + needs: [latest, minimum] + steps: + - name: Clone repo + uses: actions/checkout@v4.1.1 + - name: Download coverage artifacts + uses: actions/download-artifact@v4.1.1 + - name: Report coverage + uses: codecov/codecov-action@v3.1.6 with: - name: commit_sha - path: commit_sha.txt + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }} cancel-in-progress: true From fa35b10e828e9f1d32cd2ef4c079c8d450e0ee57 Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Thu, 8 Feb 2024 14:43:12 +0100 Subject: [PATCH 15/19] Debug coverage (#1867) * Debug coverage * Don't use artifacts --- .github/workflows/tests.yaml | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 613e442a012..d72a114f092 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -56,11 +56,10 @@ jobs: run: | pytest --cov=torchgeo --cov-report=xml --durations=10 python3 -m torchgeo --help - - name: Upload coverage artifact - uses: actions/upload-artifact@v4.3.0 + - name: Report coverage + uses: codecov/codecov-action@v3.1.6 with: - name: coverage_${{ matrix.os }}_py-${{ matrix.python-version }} - path: coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} minimum: name: minimum runs-on: ubuntu-latest @@ -96,25 +95,10 @@ jobs: run: | pytest --cov=torchgeo --cov-report=xml --durations=10 python3 -m torchgeo --help - - name: Upload coverage artifact - uses: actions/upload-artifact@v4.3.0 - with: - name: coverage_minimum - path: coverage.xml - codecov: - name: codecov - runs-on: ubuntu-latest - needs: [latest, minimum] - steps: - - name: Clone repo - uses: actions/checkout@v4.1.1 - - name: Download coverage artifacts - uses: actions/download-artifact@v4.1.1 - name: Report coverage uses: codecov/codecov-action@v3.1.6 with: token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.head.label || github.head_ref || github.ref }} cancel-in-progress: true From 684c780d91c46d93488a4e334a06af813ee68564 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:55:47 +0100 Subject: [PATCH 16/19] Bump lightning[pytorch-extra] from 2.1.4 to 2.2.0 in /requirements (#1872) --- requirements/required.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/required.txt b/requirements/required.txt index ca884526ff6..e7cb2af6ac1 100644 --- a/requirements/required.txt +++ b/requirements/required.txt @@ -6,7 +6,7 @@ einops==0.7.0 fiona==1.9.5 kornia==0.7.1 lightly==1.4.25 -lightning[pytorch-extra]==2.1.4 +lightning[pytorch-extra]==2.2.0 matplotlib==3.8.2 numpy==1.26.4 pandas==2.2.0 From ff9555a37a5461adbf29a0248463989132a99ce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:56:13 +0100 Subject: [PATCH 17/19] Bump ipywidgets from 8.1.1 to 8.1.2 in /requirements (#1871) --- requirements/docs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/docs.txt b/requirements/docs.txt index 898ddd75ed4..9cfb14b7a3d 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,4 +1,4 @@ # docs -ipywidgets==8.1.1 +ipywidgets==8.1.2 nbsphinx==0.9.3 sphinx==5.3.0 From 8af188c72ef0d0d6176172a0513cf34f6bff1d83 Mon Sep 17 00:00:00 2001 From: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:41:51 -0500 Subject: [PATCH 18/19] Add AgriFieldNet India Challenge dataset (#1459) * add agrifieldnet dataset * modified len check * improve _download * remove augmentation and wrong datamodule names * update data.py and dataset * update splits * remove patch_size change * fix style issues * add yaml and modify/test for training * fix data path and add trainer * export prediction * fix integrity check and len * extract predction * adding create submission file function * adding create submission file function * hyperparam tuning exp * backup experiments * remove redundant files * reverse segmentation.py * resolve minor issues * modify yaml and add exp files * update data.py * remove outdated train.py * update dataset, test, and new data * fix style * fix doc api * remove datamodule * fix geo_datasets.csv * fix codecov * fix read tif issue * Update torchgeo/datasets/agrifieldnet.py Co-authored-by: Adam J. Stewart * fix init * add ordinal_cmap to pred and remove comments * remove suffix * remove download entirely * style * Update agrifieldnet.py Co-authored-by: Adam J. Stewart * Update agrifieldnet.py Co-authored-by: Adam J. Stewart * remove url and if statement --------- Co-authored-by: Adam J. Stewart --- docs/api/datasets.rst | 5 + docs/api/geo_datasets.csv | 1 + tests/data/agrifieldnet/data.py | 108 +++++++ ...et_competition_v1_source_32407_B01_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B02_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B03_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B04_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B05_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B06_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B07_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B08_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B09_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B11_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B12_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_32407_B8A_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B01_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B02_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B03_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B04_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B05_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B06_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B07_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B08_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B09_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B11_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B12_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_8641e_B8A_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B01_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B02_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B03_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B04_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B05_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B06_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B07_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B08_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B09_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B11_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B12_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_a419f_B8A_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B01_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B02_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B03_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B04_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B05_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B06_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B07_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B08_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B09_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B11_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B12_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_eac11_B8A_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B01_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B02_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B03_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B04_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B05_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B06_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B07_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B08_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B09_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B11_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B12_10m.tif | Bin 0 -> 1384 bytes ...et_competition_v1_source_ff450_B8A_10m.tif | Bin 0 -> 1384 bytes ...etition_v1_labels_test_eac11_field_ids.tif | Bin 0 -> 1384 bytes ...etition_v1_labels_test_ff450_field_ids.tif | Bin 0 -> 1384 bytes ...dnet_competition_v1_labels_train_32407.tif | Bin 0 -> 1384 bytes ...tition_v1_labels_train_32407_field_ids.tif | Bin 0 -> 1384 bytes ...dnet_competition_v1_labels_train_8641e.tif | Bin 0 -> 1384 bytes ...tition_v1_labels_train_8641e_field_ids.tif | Bin 0 -> 1384 bytes ...dnet_competition_v1_labels_train_a419f.tif | Bin 0 -> 1384 bytes ...tition_v1_labels_train_a419f_field_ids.tif | Bin 0 -> 1384 bytes ...dnet_competition_v1_labels_train_eac11.tif | Bin 0 -> 1384 bytes ...tition_v1_labels_train_eac11_field_ids.tif | Bin 0 -> 1384 bytes ...dnet_competition_v1_labels_train_ff450.tif | Bin 0 -> 1384 bytes ...tition_v1_labels_train_ff450_field_ids.tif | Bin 0 -> 1384 bytes tests/datasets/test_agrifieldnet.py | 77 +++++ torchgeo/datasets/__init__.py | 2 + torchgeo/datasets/agrifieldnet.py | 272 ++++++++++++++++++ 78 files changed, 465 insertions(+) create mode 100644 tests/data/agrifieldnet/data.py create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B01_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B02_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B03_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B04_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B05_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B06_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B07_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B08_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B09_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B11_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B12_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B8A_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B01_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B02_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B03_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B04_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B05_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B06_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B07_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B08_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B09_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B11_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B12_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B8A_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B01_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B02_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B03_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B04_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B05_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B06_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B07_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B08_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B09_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B11_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B12_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B8A_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B01_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B02_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B03_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B04_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B05_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B06_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B07_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B08_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B09_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B11_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B12_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B8A_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B01_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B02_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B03_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B04_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B05_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B06_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B07_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B08_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B09_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B11_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B12_10m.tif create mode 100644 tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B8A_10m.tif create mode 100644 tests/data/agrifieldnet/test_labels/ref_agrifieldnet_competition_v1_labels_test_eac11_field_ids.tif create mode 100644 tests/data/agrifieldnet/test_labels/ref_agrifieldnet_competition_v1_labels_test_ff450_field_ids.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407_field_ids.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_8641e.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_8641e_field_ids.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_a419f.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_a419f_field_ids.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11_field_ids.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_ff450.tif create mode 100644 tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_ff450_field_ids.tif create mode 100644 tests/datasets/test_agrifieldnet.py create mode 100644 torchgeo/datasets/agrifieldnet.py diff --git a/docs/api/datasets.rst b/docs/api/datasets.rst index 645acbacc47..3f9539db034 100644 --- a/docs/api/datasets.rst +++ b/docs/api/datasets.rst @@ -23,6 +23,11 @@ Aboveground Woody Biomass .. autoclass:: AbovegroundLiveWoodyBiomassDensity +AgriFieldNet +^^^^^^^^^^^^ + +.. autoclass:: AgriFieldNet + Airphen ^^^^^^^ diff --git a/docs/api/geo_datasets.csv b/docs/api/geo_datasets.csv index ed7655e843d..ac611c00e45 100644 --- a/docs/api/geo_datasets.csv +++ b/docs/api/geo_datasets.csv @@ -1,5 +1,6 @@ Dataset,Type,Source,License,Size (px),Resolution (m) `Aboveground Woody Biomass`_,Masks,"Landsat, LiDAR","CC-BY-4.0","40,000x40,000",30 +`AgriFieldNet`_,"Imagery, Masks",Sentinel-2,"CC-BY-4.0","256x256",10 `Airphen`_,Imagery,Airphen,-,"1,280x960",0.047--0.09 `Aster Global DEM`_,Masks,Aster,"public domain","3,601x3,601",30 `Canadian Building Footprints`_,Geometries,Bing Imagery,"ODbL-1.0",-,- diff --git a/tests/data/agrifieldnet/data.py b/tests/data/agrifieldnet/data.py new file mode 100644 index 00000000000..e0b4d0e256c --- /dev/null +++ b/tests/data/agrifieldnet/data.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os + +import numpy as np +import rasterio +from rasterio.crs import CRS +from rasterio.transform import Affine + + +def generate_test_data(paths: str) -> str: + """Create test data archive for AgriFieldNet dataset. + + Args: + paths: path to store test data + n_samples: number of samples. + + Returns: + md5 hash of created archive + """ + dtype = np.uint8 + dtype_max = np.iinfo(dtype).max + + SIZE = 32 + + np.random.seed(0) + + bands = ( + "B01", + "B02", + "B03", + "B04", + "B05", + "B06", + "B07", + "B08", + "B8A", + "B09", + "B11", + "B12", + ) + + profile = { + "dtype": dtype, + "width": SIZE, + "height": SIZE, + "count": 1, + "crs": CRS.from_epsg(32644), + "transform": Affine(10.0, 0.0, 535840.0, 0.0, -10.0, 3079680.0), + } + + source_dir = os.path.join(paths, "source") + train_mask_dir = os.path.join(paths, "train_labels") + test_field_dir = os.path.join(paths, "test_labels") + + os.makedirs(source_dir, exist_ok=True) + os.makedirs(train_mask_dir, exist_ok=True) + os.makedirs(test_field_dir, exist_ok=True) + + source_unique_folder_ids = ["32407", "8641e", "a419f", "eac11", "ff450"] + train_folder_ids = source_unique_folder_ids[0:5] + test_folder_ids = source_unique_folder_ids[3:5] + + for id in source_unique_folder_ids: + directory = os.path.join( + source_dir, "ref_agrifieldnet_competition_v1_source_" + id + ) + os.makedirs(directory, exist_ok=True) + + for band in bands: + train_arr = np.random.randint(dtype_max, size=(SIZE, SIZE), dtype=dtype) + path = os.path.join( + directory, f"ref_agrifieldnet_competition_v1_source_{id}_{band}_10m.tif" + ) + with rasterio.open(path, "w", **profile) as src: + src.write(train_arr, 1) + + for id in train_folder_ids: + train_mask_arr = np.random.randint(size=(SIZE, SIZE), low=0, high=6) + path = os.path.join( + train_mask_dir, f"ref_agrifieldnet_competition_v1_labels_train_{id}.tif" + ) + with rasterio.open(path, "w", **profile) as src: + src.write(train_mask_arr, 1) + + train_field_arr = np.random.randint(20, size=(SIZE, SIZE), dtype=np.uint16) + path = os.path.join( + train_mask_dir, + f"ref_agrifieldnet_competition_v1_labels_train_{id}_field_ids.tif", + ) + with rasterio.open(path, "w", **profile) as src: + src.write(train_field_arr, 1) + + for id in test_folder_ids: + test_field_arr = np.random.randint(10, 30, size=(SIZE, SIZE), dtype=np.uint16) + path = os.path.join( + test_field_dir, + f"ref_agrifieldnet_competition_v1_labels_test_{id}_field_ids.tif", + ) + with rasterio.open(path, "w", **profile) as src: + src.write(test_field_arr, 1) + + +if __name__ == "__main__": + generate_test_data(os.getcwd()) diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B01_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B01_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..0742b602456fd948dc2cb9bb12c75f081dad8d97 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4Yq;ur^j963Ub;+d z`++lxH=H;7&H5d*==R~V+V1q)r#Cp4l;m8#w{X5_VC2$I*V2+ywzC$5TWR~a*?2#> zvA2aUV%DZ_J!j9jT3Ko)9dz=jdRDvcl)Bfe^WiH}+t;1AUlkFTJu$GmH)ZLw&u=81 zIIsC;>kE0zh!5kG_7j^j{oT@H4qes@!me?jC#hXMD#!8lpS$UCfA)9E>t%P|JHWZ` zUeNBgU&#q}l{c18J+rZf?W0+UK2a(FJ1kpu*l?){H^J&rw++TfALVyn*PAHa`CI3&i^Vm>z~#&IaaiK*`Dn# z$4X>wmcV6%SNX^V>A%1@9}1FG=s`3V!^MGaO{$|~3?%fBp*Dbtl8gyrUbaVitV#9Zx1AQ;|2PB`GHQQ88Cbq}hEVwf3$HZ0k z*EmBAJPJ;qh+pI)$o7|QbM4n7v*o4qU1XQnf2uJ3Vm^6M^AvB*GoMfYOOZBOzD4EB zlo#8tJNWU7Wc8~glutRtD*UGMI62 zb$u5uEaFV_&^9{uYnSm+x%ys~81WnDy?0-eu5S8}B3CKtvmq%WJ<#r6+QY@lyjl0E z1YcMG$QC%fywN=9mg~lK<{KtFKE*R}N=*6PixWOL8=dlQnmzS%D_``wSDH0E5>|gM zygq1EI9cV6n!w^!)!L>yt$1r|?~Ws?ta~~wwO(YJUh&sqGfOB0#x;`y-yE*2{vP~Uf6YKNrt*u>Vm_KIZte| g=KY>(GyC_e36+&MUb47NjjFiHXyPlsGGIF|04x;_)c^nh literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B02_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B02_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..bf0ae9b6617cceb7d8775d7f91be873b542af2eb GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B06_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B06_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..9a9b2daf1c6b6a057a7441e569f39446417fa957 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B08_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B08_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..034c797567bccf59392f715be1f457a0e88d4831 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4JGRX&JM>J^OhkI0 zbMqc!{y>AU$!olwAEEr(*u>)`L-OK{rAm9-*@p28yLfUu0LP(E^hT=wboG6f0cXPVTyF|SRi<{O4jZ~=E^O9#ME~eG3uo*oNf23%yhE<fboa^En%^A%`dW5&71QFQs^=bhy-+f+4B5Gn*>zh0 zvs(X-0;lQr2c_TKkTu)9E0w#h)i^E2xP0^dUsvQ7+Fq)^nsp{1|MJVdW`cL$W$JR| zAAK;{KFe;IEVI}d6OM;pmIS56&E@ZWcf^YIcg{_pqX!#pzwvHbm9c2gcc(vA69O3} zt$S_d1V3JEKJq7<%jT%{hnZsMs`{pMSmiRePP3JdT)Va4!P7v7BYqu_p zw_(Yy-FHCb=Dh0uzt?7Y>|1;#b(&Rc=jBgTm0n5_(zeG1IiuelQP;g`!MT0)0*#*9 fk0v1x0vU_-J<4jWJrBJ7_r&Rw!u(QM#kiLMl=B!Q literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B09_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B09_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..a89dee1c6842ff96ea0e3807edd912b3554a0217 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4lY?Uz?dJO|l2tC^ z=Unc5p!@Cnr?uMe)RQBMWtG4m~kHZ7Y{kIs3QR=hLW`x)n~Quj9J9k=6Vtp0oH;|zh- zdjfqoD~WzPv-4hf@{UPo%H8cZJbM#)RpN|noBAr%*v{u0y?t|5gtQ<3DEQGROSACi z{X0T&=@(pYa`%4SV(~E9{_B1BW&7vuyxe!A|E+>5|Biz*Ufrz}IT2Lq`2K<;^Nuwt zH$q7?&gfphbn=GE{=;QXYq}x@R+3 z%`?V^={R5AZ&h zYo`j&XaA?Q{MW}qpY@^25qTQ_N|z@!_Qd(EpFC~Tg;yA9dL|b_FlDI&r1>mNGpKD5^|-dhorlorHIT zg2_7eoCn5deopvub2jJ7^%M1f@fRG8{&QZcxzE8};N&$~d)s-+4%U6qyz?h+R^vBh zWD&eSpV{hg&g93^oPn1(R!!iEPp;#M{bZ=&2w?W3n9@CexW?O1qwiIIEL zrR=f};RtPyE2T?smI-`Uo5?lDgl)Up!@5G_h?7R=?Dy7$P1WX}#`0^S@BEW{CVp1> z^Xv2u@#dvf1$OM^M}JK7`)XD5P9;_=bsOLA8(U7^*E;*j?4Wwz$?)5i#r7Vln@tV> z24&6sBA)+df3S`AOv&&g9G2mQa!2p1I30QOahC4EMKALAik^rli`=t0edb1MRuPvq z?o(gQa2wom6vq?ElAu|DwodK&?k0dlDn^L!iU-~d);QOU~Jm- z>sznEyY-e6@6^a{Uy^(BZFJchdHdBd4v%knE)C#+QoYz^zUK2&E+ToM5qxi!=c#dK zHFz$5EvtSsZX3VkwZEMW41%Yf0+%_T+;yf$mnWxg|LrTg=V@E3pWY_ire0h5-DiE` z?E*1n#^SN eQR$4=2Mtq&eA}hJk1eP+VM{!wyn*-X`%VBe_zNrm literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B11_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B11_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..f7cdc4b45e8a61a078d31a19d2e052eb2c26a24c GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4GWVL}eJ=>|?)bJT zvXk>%$koQc3a94`L7cmur{sM}{Pbh?%&;XaF*jruUX1;6^-rRM&4s(CoWt2_Hs9RX zTe9!U>zW=Gre_i>mvVZ3Js!=d9zN&lrF(7v{$1=p^_uzF3dwwjdA5(tf8Py|w%_oX zEz~r@{~8q6CGPiB{pd+8=NonU_#=bo}v@`5WZWVsil2}o30A5LF!M5=O8+h2c)cDASU>t6<( zvw6Cg+pP*Kgz# zOlskC{Bt}Yqhaaey>{CB85dTRPCOL7eLrF6$2*fdgX`TwH6n?P7ny zDwntX&cyqQ^V0GX<4+bkrvGU_d1FpPctlNw%T$LhiJj{=v86aIO}xLQtEkl@;?lJ) z8@)%8H)_tUvh`>T{1Uypb$1N6_V=^T`78Iu^_^O|?!0VpR^WSAv+iXM2|ZDDd+p9F8x>K@vQD+%WlrUefYpfuduvI z_kiY?%6X>WC&#Kv=iOwtXfv*8-Od`YcWce*x#6d~Pj&o#lRocF)6S-sW^-pYva0#W z3BG=z^6Op^TkZV(R6jZ1XRYSSYJR_)I|EH}0KLF~54)g#3 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B12_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B12_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..6dbc5efeed4aa6a68e9f8c5708923ea62e50530f GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4#aTN|_hx_lcjBHR zLr<@W;QMmJxhEH>L?5eKzsNZM<0s}dJfClin>|qxmfGFYz%6PLsbs&w;m*Bl9DzUf zUKL7xR^>C%%KDqy9dF0;%N8DL)K)&wZ_$zdGP~~DtknW!KQ+&Fv^Qh2< zMX5|*!j7&8-g4LGy7^DXcOFlV@cE~FnFPFOc&-7f|)#sd_=U&*>xz+oMv-1Y74;ITlOP;==;8%V(&C@^R&~M$$ zaHA-pPtW{2+?gKU$t&d!(RuQHuFJ*N7k^I9bAE7SS5Bv|OIz1k>qOzD3X2{Ds-DmJ zv3ib|QLU2HNgLajt93W+*)J=3_WCb}-r2KNG+CbKZHbdU+_yyb%c`k$3JHZCGn_TN zMP5Ele6fo29FI?sT3&Yww{A-1Dc(}`Z^w=|N6Jg7E8O_3yh-g^m4-~iwqr}Yb>$>y zU76;lZCtH#na|tLX0meW46iGKOr=M>_j1}VySAN0_`#QrMO|ejlTWXjyJWTB{%cpi z*;=1i6wM^ikzdzaeK{uNY{o;UUr{q|#!IcswfB59Icn4N3v2FcTuX@aKk`R#dFG1a z&v@Tj$g{?LwqD_&TwV9ds}~9=}8MU4*nEFqvARa&ecDv z>VCgHn35>#H1*snyDJqO0x$f|>~Unrpa@9;<2qi z!(xk~ADf(F6W%C)@|$^J#S5`JjwKs^d9xUA4}a{x>eW?i|=_C*r#$O zzM*IH&Ap3*m&w^BI2}FOs_tg@z3Ig+#+9#qf@;---kmzyu<~^uW6RQ`SIk!Bo^?8P zAWALdO~ICF>De{UrKWCi67&1k`J4Bv@4FY1Wgj@7IlM8`{h83jn^wnJf3B~Ua#((9 z|F4bPXO|wk^t%50p0{cb6Ib%T;JxJgUibImGaKHTRahv^^tV#*G#AX7S%0l$Uvs?m iip@8F-&t~JMuGC#nxld3i7O4IR)$Lp&Qz^FA_V|*(;CkJ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B8A_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_32407/ref_agrifieldnet_competition_v1_source_32407_B8A_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..e496e2fbdf5b8ef84cd259cf7243cc78355e8685 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4p1B({Q+8?hn++NLsg#@f4G{z;8RgeaIBBRu2l1z zJ{5b+*rr+exLgvE$zzWbF*aZPaoI)<**d9^yjwp$MMbncT34BCvnV9;f$R^dFP{YV z)G@exUeUvx?^ntk9G3Lb&+2;hB%wE%m1`zACY%ad8?AZ&l1lc4;234F-cyr~rOBUNAiUi;!@AnA=uV$}UA6eb%JMCfu5Gm9IjNnUA635ob~NMj zABWnKv|li}$6x4)%e&vCJDd0Fg}xwBM~!~|2oGUift`z<>q_c;ufMr%+3gw6Z!c{S zTC&OUwc3oGyV*CiYcrf_`SpTDMeyT?%bM()gB{%0wN&bB{F$cTmml@?;~KV&U6zFk zvt=Jj`}ICbO%p!g+&gvBA(nIVe_jicoxp!}^J3XK47<-Md$+ENi8Gw}?{4a8mzvD` z8(ojxj+s_3c1lzwPbSVzyLj>UE3M_*`-<-TwK})D>4@CCnQ``yYM=e)s;HQm(%_c8 zIo|isn;i^iU*^rpayYimtL>6-wnkXhx~P3C@=w;ClGB?f{`0qy=LP=bD>56_>a@{acXs%6I$X+iuQZ)ARVAJY3p3-6P}IXL|@OhxrpUB~ z%T2pt(oYtxWJw9}T5gh__F%)Q7_~)$@q0E%=bR|~*v*`uvgmT@$>;+MEewy#*1K=w zSik(~`rx$JmQv-`rFvF1i&I&@Ow{shx#Sjce1dJyhWU*zx=Jh_KA9A0{eIonb3xa) zyxq=rlz*KU8;c5W?6mJbi?*r3f0sw4S4uk*z literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B01_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B01_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..6e0286c1b22d1fd5c5890d9738f359b59607c6ee GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4+Sej|)@MGbxwr1Z zo!T2!M`K*Yrv3Eo67rCDirnS5aJ96&?@hK9k5t>6dCqO^id|Q(KjnvMPq>uE%Nx~w z;WtiSlFU-wf2Ab$$YO`boTy=Zc{+}nqLhh*okz45Cfw-=f%y7Q^{_4Egs zN;^+|`Pz9c(4>Lu&*HQ?!^Fvs-W!hZl&?4PxyPmUOP%%b?=8)Lz6Dgz>+M$Mn^d{u zxL1X**9Yuaer(5WjocoABzVDMt71H?;o@_K>tLNtnND$&&p-y)3Rg zQV)w8x$ihhn{M02b?H9$VfBbtd)4P&5@>Eym9AB1uQ}!Snyo)5h9N2;lRbh@Z{{ym zKj$084c6^BAAg+V{#_C|`|rl1*-K`=GFr3q_0+3dRwnwa_{a8;@S-E;~iihKx)V8Sa)8bSQ zCiSGOdziGSTCmyu`r8*7fu{uIw(zoYIx}jVtJB-Q^t9&O-MeJAx+QNCORO_Y{b*q& z?zKDOx5Bj>Rs3rjmngH$dL5^-aQB9*2b9+2?mjmAoMl_&y~h!aQ3rgUnfw);!hS9O z+lG|}%MNy_p3l6&u!oubRIl#wLaEA-oa|kGEHa_fi}f2#%Nmv+JY%SDDYNwSldu0i z{QiF0u;YwQ^z35SuOQucxB$5@*NE{WPuvzO)K*J)ff1FnH+EiZL gJW?9>SvNTK=#}04vwlVLddyqaalvQPl!R(^0A!34mH+?% literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B02_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B02_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..225081bf2be931e9d5e2d29dcaae563ad59a8d29 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4TZIJPF3g>FGO8)} z;v~`2wQXly=T;~!o7OaCv&Af*1C!oKgm6n5uH@l;m6o@^d{NSEFT*u4@GlESK&sxpOeF*4WFM2lbj-E$8#{iz+|6ppWEsFv+IAi zz4^PS;)o{$XP35ri^r_o{9A$xe^0pbYE?YzLzTGseWL#+`9FKgvuci7=LOjfF12xc z+>U9o9eQ#2L$>v%W1Exh%MbC$Fec5F&$qliVZTbc^ue4d*|pDB)QP&*?$T?1+|RIl z(z9!NOcqOg#E#C=W9*&c)_OC<@aXpEGWi@zVxR3l{>bpp)1Jj-oAbGO-thxhX1}V= zdgAr_x@ViQwa41^2`1Mr_=W5<_%Qu2`zO1PD=r%p_NawB-89wtdEf8m9ufEIlgv)q$p#`aGmU4Z)*p)s znstVy#MsF+*I&^%So)*~TgwZB+_bZq$ye{K^-s@`kod?^+O}0Qx=y^`j_b|j(`&}_+QP`p5wNZtz`MtUS@WtvqxUrOe|pFS}~XRaIF-t z>pexzCr3gj9u`uMJNIGHJn<%x3TbJF+Lav#1DRg)ne?8&B4TJf?Lhu@20PdF-&1w% zwfD`P=aay}yDL5^X0=xHx@w^deHGf+R{Eq@-t>gW)J^3AH&0r5&TKrX_sjL&uHA9HywZ<(=J^`UHA>X- z^IFE95m~d!m*Kf(=e<7Bb?^1&?-2_8>C+_Y^mI$i=DF|ot3Q7jPextIfe9`do2m?d&~D*}yXxnh z_jY9}x170U!LGQ3Z)aYwdCt2s;lc^$HTz#Q)Z7!AzqEhi8*k=SU(~PZ_)hrr$Vbop d^fCj-@YgIoZpPsY&sAu7>#ciSVrF;eI{>ES080P> literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B03_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B03_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..e8a7ec10ea1a59b86fe0b1e35a284f4a08ea5580 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4o8sop(PnsI>9}a` zlylkaEUAXYN7*d1gDX9Zde@gMX;{M((a(9>iJiHrZhGfat^Vo{FU`OFyKw)v=FfFX zA(>n5on85x@mAG*HBqs*=U(jma$&lfP2B0gubbAo{pwX)`oy}bk^uXlrwSH|EHlh5BUTK-8tM3|yGoCtCbh7u2 z+O3@$4jTk^obaFRa%aX`_Pp#7Z{M^3pNt%u1;=^wx zIW?P_UT!*8&8u+b*49A30Jpnc`8SMpo4Fppa;^-p@zrL%`Y<(b!JXEx=U%V4pnBsA zOHCtx@Sy;{Csix1YSztUNZ7}(9IB9)7?u{^=ez3#+wpzL5s$v%&!19TxFmV@ z#7vPnS&rXTRzww+Xwh>Py$tnepprNaDdX6DF3Xna8KkJ^gQu%$f;-p8^FQHj65? zCWRji{`T|Lai+hrANGs5OgD~>zb9B7`&L{uiy@)pQ_~5x=(ZK63rY%jU(0@uSlRr< z@{*2A$=rz^CB5}^cR%&dI+Y_@|D`i)<9f4z8!a8LGp0%2*>`VY#>78@N*iZ?+_1N47Y7FwBykWb2mPm8Fybd_uu*Jtrwymjdp{ks&v)`>- zzjS7gQ16k5Ei)}^OKY!|vPNHf~)uQ z_q9S&Yka1d$*pWkvyL8XbpVHCh3@XH%n^csp?h5bwU1)??o7uU^LG&8}h#D|yy$a}BsF1z$^hKCXMgk=H!2 zb+f}qhV!a*b%Nh7UI<+7X4b$Ha_o4BcDU#1UfE+lmW-Yi)AqkF5|oR+UBAz9eek3J z%ZW#)PCX$%CFlM7w>(V@>)&6Ovzd74jLY)K7Nz;}7K-_5sflyN`1rTa6nJ^CGi9>s z(ueyQtd{AEE6?EU6^>)-X!vsUie=+lQ;XHbmpGa_1Ab0k#k+o$c!%Yqt!-;hUZ0&f hp?9gy=HH7OBR6T(T`!vTZt2>`Ba8WjKl literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B04_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B04_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..ac3212f37945c88831009a0d1ca0d386f4d622eb GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4x}Gzo0{FKiTID`J zIDO8>NB_Lm*M7S5RP_~8h`|ZwkC(pBKj{Ch`YQ7U&)f69=7^Wpu0Hfl$n5))Q^INn z{p_Xu&mI~+trbt48zDS->67v!AKzb#s&_cerr9ieH15{<eyRHYJ-6f2V%MX?~=_b+bt-uLH^-NQf-z2=P07XmOagWYzc1 zb!R_!DNHi=Q8Lz?p><8xDyI2Nx9SWog(n9bV}pvXeKU74zL_Qd;<&Pwi~n=`DO$+~ zCmeRXQ_~x}^L){iZErH4iWrx7pCzMaebf);xrcj~cg=Nt zqp2aAa_8r-*)y;0=-sCwrE_rmCWe_?E_``Ey;^9qCSv>gc&+XPFF zyZdn4Ke#I!F=1=#UCC_M6Y;xu1|57Or#dHGC_86K)+DtAfdqq=^7MDnfoshsp5Ah6 zE~iFlXQzAPvs+Qj%04M!ItQM;Uj1Bz_raX>1G?YbMA&^-Pr4TVnS14~)lveLt0b~E z%nklBJ9px#Y;`5InFR}WToFI3o*(g|$|vljpoH6%C9M8YYDy+04L%MZC+%Ld|GYL| zT=eTGHzHNOn_jv3_StW;mGsWNLNIsdx5s2P>!TBsMfUH! zUc*+PJ-_OiX43ad8sabKI|-K^$_ka@h}Y+K$^FINH5KSwIZ)~%D5OA${0?pEbMxA=-mDM z=c&>D~EQ7 zUhMi=$?xu4{B-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4(XWrBFdVs}v6w+6 zLF&#=gMA{!6Z6Fv^=#>8SpCYrk9FEIhwJli=^t(E^Qw%%VX8U!8x9*wmrHp@^q7d7W3JC zSAz4uu}%NNrDO2MJuuGtt&|!Mq(j<^oMw6_{GM}H{7>JO16%J;J^pP@?7aHPbA=XLrYdY+HI2!E!+KfV3JV@y z!3YO7Z~eN-hd=!}WL)L(=BXF6yJd8*?N7V9;^nrt+C8Q=3!IzsYzd#!v6p(c+s^4% zPPsXu&uVhdRi+n$FRnKKwp#z7e*04E+%0^~&#d@7=i~(}HVz6~*Zprp^t6Do_MeuT zXQEc`(^;ojn!N9oZ0=sy0PW(tIbGlVx3pwN&XLG^>o`m0tM;!b3DF}_DHE-@_h@}x zRmrTO@9^5LX>aKc8{aEWTX@ud=^ZnAx3sXu@}QyDT({;0`kf0dH(3<(yjr!9ZU6Vj z=QuC*zVuM`W)QI!^w}fgav(qWdalwIeaY~xUW}`jF1y*CQX=&u?yFB7dz$kK;SH9N z`6_Px?suoQypa6-mS1_%){Nu4=6?@3^MyK?vu)yN3H*DwdqN&t_Kzj0ImNI4aBqrj z=RG)K^JiJ9v$A5_f*LlQtXR3bQ83MAD>MI;%XMp*-f+xq{H>ob-(1_QF>~*_Y*}Xa zt*SZ~V|IFb+)w+uU(m$xrr8-I6;a(T8y<$$PwoYt4@&rQyIA^STFmOoELjat`9YwnLnrbQs?gAq{R;s)_Ah1c|LE00Pf@RmgX-kevJ>6AM!_tFW=?^mYuK5Tc3_@SYF zm(fB|NG&w6mqT^OwU_Ir%1pl;QuFJU>Tdt-%Qic<@%Gy@?AyGzzw4hn*Elm8<}C}AU8g61Y7v(Y03t>YsQ>@~ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B06_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B06_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..ef11a4387812775fedb0673a843fd89c5ee26095 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B11_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B11_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..6b2dab469caf9aa151c810222d4fb60c2c43715a GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4u9m?orfp}d{J4L) zQ9y}je|)8}{D(8=xeq++c=t)L)c^4EKZ%X+pUUTpyB-VW@;BMy;Oj6?ri5d=jh008 zwTW(5v`W2GzaBpFe)(Oy{#N_1Po{28WtlDHuD|le_ow1_B#+fvZGL%Wo0j&jR;$XR zOZ!z`w_M(({pS&vhuEizeXGxH&|1E;U%T2_{@``E|CgKH zA@bULNscVeInwI22Ko$BtCD9N)Vp55J-cYORJK_8;|T}mY3=@bV~XzQJJBIqW-QgZ zIPDcvop#W>IFk*VD!b-ZZrRT0pQot0V}VqB!@m2n{%z1^q%N19q{#cN0xbG;-BD)1g*QJ~@b9pAcOH4ZR){9-2L(-DO z&K}BTooMsyLb%|1-;T30+1H&2Xg#R#p~vh;(VF{mrOqEu?h!mObCt)Q18e!B_^&UP z|2nthWWbTi$*H6 zaM}E8scG^BM^bOid$cAyKJ0wQ>plGw-v8n$%reyd86sD-{mJjX*<26H0!wd~&P{Va zt90V*zTi_gpB<=N%F48C{_&bkPc8*~`;~GqZzH#X^m_GaiKdd#FVmA=FY9=g6DQQJ zbmEG2M5Uz7Es^Dn8*}fb&vs_IcwY8J?#5}GrsdmTG_mo{Xky)$-nVy3;-$x|%p(5( zq$=E$whB&rl&@35cEkPA!V@a?C3fTz=_ZVS{$D(Y(()9nT$cEZL@zW!LaM zNV#mDd!+sQ)zdz!x^}&KZB<<_v*IRWYTAd`$*6pIV_J(yQojdz*g;c#RO1&0(~JMP~p zXHX}%=5%bx-6E4I3)4z>WyYL$U6gJ5rM{fr{`=_o+@3Z{-=ZYoZC+Oi3cC0 ze%+$$|C`rnUWEVt@Adifl)bg(>*iiHe=p*kY`WmCgv=^Vl|>uOn(Dqr1lO(Eo^?U# zNu|((KiS4LRo8ChnJcSF?zoWm$uM^}hlr%r@uhoZR&DJ!cC+2DaPOVJkk@6_>@W>| h&a^sJqX*7Koj+6!zsok8{bRlI_m#~u?LLuvn*cpO6)yk) literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B12_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B12_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..e62de633c32bae44f23aebe7f31c6a7ba501ce30 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4ioe72Be&=_t+Y8X z<4xVB+248Beh{0moAc?__|s0B_Y^D-9p#+u=fU?*@SenHg>}!L#2vm>cBL% zC#OvhFZpMEtcP`B&zfZ={ZFn%NBeuri7u6V+gG+=dF70Y6CSN)>+#(3;K-ej^F|M= z9#=8#`Sro0T`^}(Ub@gn@g>IUBGKo&T{8}!WskfOq;fduMt+UUh0beycaL7_*d!U6 z;-y&hGxJKQ+cJk$dJ7l6*ent36L|cjY{^fijW-3ZozJMtVYnEs)7EXv-lAot|F@wi zOz?{2nRAP(0+{$$X)}pjNU}4YIGI&kL!n~6P3&{wz}gtuUvK5~|NbeN_3@&3`qOLI z{8lzjN?q3aG53tmHveNs)&}G&u0A61^qZjKTm2j7b{aMuEqEl(S+ee%YQk5Aw5xOH zbce5Fnfdsfk3jlmrC^(5Uu@?~$5!z!O`e{vF=tcjgiVz~$EpgZFnjF7Pc&OfNdFYB& zok3&T=~o`^0{%{x8K0(3d6t?|Q2G1(4cF7Vow7?W{Ik9G-e$*}CtQ!Dj~O#f|B*ER zdisrhMSB=nFHU#6@pu|g?(MVq$f*9ILlV2bxmpLM6Y+!_vvB)svSI=#au%B=2+F90i!6~q7l literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B8A_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_8641e/ref_agrifieldnet_competition_v1_source_8641e_B8A_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..6a89eb0a1887c6e8736584b48ccc3f6836d804c3 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4-|lYF$js>wS#QMg z_fzVZMyq)jQ%`=?EDhY0+%CO3_TTlm!g<}^`$G3_GM7tPle6+>^*4@~Dd!x2tj@{x zW7%=_EZ;Pax3M38>RbeJf)R8ZaZ2r0H#@2@(a*rjBtZZGX9&lP*x~6sI3A@vik9ePF-JV{)&e8pPjB466 z%d2nyEWDw=W{c|6C#STn*WKSO`Sa)!y^`4r7R?v;yq)#orAgJz%~^StSgW?os$E%s{R z;#i@!$8HxSG}><|U0GKD{kIZJhFR3~og0fw(iqKlpPV>1YDUuf8+VVXEMr~vgzv+b zTRj`PBahAGo*Z>#YJbtYu)IHN5?U)8DqrSW|J`@^9EWI)=NXxi-X zU%Ouig=g*ikeR(!NUrJh%XTfT^yw!ToUq*1sJx=+jZii3dY7p0i~8ytwB9nG*1D?t zIp^bq%cti2j$EZ^^5qZTrQI*Kbtmh+^LYPUxnaur*uAp3R{a}q`F)(7c`SX6Mw`}z zoK>Gc7ZgU<1(;v-T%CKRDQ5LFuLB>&((J>SUh5p$qg3lX|4dWWDN`{$ev_KmJiZyz z-%VU&fA~sp{HuNU>Ygy4ot_ZYepSQj@*3m(#}%uun;QB~{@U2^$}V?G`P|a;L06KF zAK>6Sx$cy4E2F0K3ARPTF8S+@_-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4oo!+_es%q@QT8xC zy*YPVNL!M|s(%YLq~y(Ve@Tm)&*U3)<-V z`A+_&A8u&}^2HY~Ss|?OCHRM`%LB8ZzF02b6XItszk6Nlw0n;I`y0zH{G3<3!a^$Y zrOC>T4G|3)%N(?;96p|q=~U*JWY=%dzEM4C4l^4EZ|f1BAA#MGzJKneYYIKRyGnQW zZr9UH-}gHlTE4YZZla4?Xu53QTP2{2U~9K&^(s5kzY-% zAf!fk#w3l)3r^Xccb@2Ge(%JE)#r>CwYC2W*t{h4L0LiekHdkbb3$bwKe_D3vml%G zz2W|FwGZD9#c&w@(Gb#y{c5+69gKE~~1uNhDzVE5%%XGiV=9OUH zyxAvOpIvZ^whLeIbdr;QrS9>^TT-6NZO_zQ@a4!9wsl($q%mA?eRzFk|nZWh^(fHbm>}b&lHd zdvhgU)D+tfy(e3GuUO5niqbvY*1Y>|He>buKNcQ4Jj$M|e0Heth;fTnG2iao&v~0% zZpfStUNm=snB{$)XOrU=e2C;=6`7SSbiwmb=F+9rBTT{E>7LILw)w?JFDMl zCHenarkdRTXjR$|-!vbS{#4OM<{KVjIjn(uP5atsD()yV+WaU)Zf^I~v?&vo`v=ay z=I!>WMPRp2kzW2Tn^!+~b33j)Ah|_<@AeLbr1m_{pZ8bhIV3$Wu6VRO%kn|*gbB}{ hchyhtQfyJ0)0%SjPaJcYa$M`*JBIg~oDToa0RS-26`ueA literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B02_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B02_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..05eebfe80d708efbb9a398a076e8cae2878135bf GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4MsG|7>r1aNtm2X6 zyyE4~wLx}Twl1^(ZvKP4PoH*t{r>U`zpOPK&)T;;Pn2U;t)+s&EB*7dt2Gk zTrSkbDLenN(dT-Qv*!Mtqg~7v@;*jeHmv>L_AcDS&s6rx{I9E@w`GRxR}_j`UC($& zeb<`%bAN4Ps;WEwc8gxcr}y=nl+C4*7~UI;$V^+n634X1u4=dxt!MmGRW35H_Az5RI=bW;gkBsiR)ZB7ddQ^YNiY1^`|FDI!-etRjxX%s zVcVp7vcykhou*Tv?81eUcy89zZU5%jZjfSq=bOT6MrHl|3zS~`JYe<5^Vps|lO>IQ z`ZW{1G)q<&{9F1V&GGg2lg@iMU)(L;e)8#_pSQTm{yr{bm{7J%(|Ph_$(2^-tFGOY zh}B=LtbJwCD*lKJ7ypNIxRZVx{@Y}=d{^?7^O1g6bEdpjX%3q8W}fy$p1qvEqzW!? zVLHRf{i|61@vn2QQpA$=3-#DSp9N2EVE8$Mak|h6Zcim0iI4GHaxNTR6Zn}y;Qq7O zVV5o&bo_~YXDb+ajmg>ji{W*)=J+*l{>;<)^5FaZNbUu8CIwwTm)*D~X*Vb0kh{jt zid82~1SOfQ4{bij8rWcM)%5kt>xeg8$;mTXY~$yhEZbR-yRy`@zT~=m)RxWbvhC_` z{|(rDgyUlfw`#0x(2Mojw;n}k^uJjx5%#TW%DS{UB`>0%^Jsp^I&^ba;Q4R6cE8!Q z(Z03#>w+>?Vb9aQlm#{}dD(7IbLeuv*VG%;hNArrlaflcSoW@+e8Y4$)A`NSHw}}Y z+T3$~Ys%|sp1#@ebJ&Ebae3Q2XNzSpe0ub@+4=bCeY+Rg_T)(>O*GFJG_81fEbHwb ziM-=YvFB{(-o5kL)ro6X&}oOag1`3v+@QB7>f#E6XLT3Za#NO@OnIo;@`&?r-ux#C2WyG3^vf9*f=d*#urU7RjXPp4lpamikwzI&-;a52}v{i#z|m$a%}Z8w`_ zA7x8CkxlJ?d~y7b i=4IE;o+G05XvNzv+E=U@&bUwh^Inf9mgCzw?-c;5BO0Cn literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B03_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B03_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..029b6f759c2e589d3311b26675935075fafc6d66 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!46}NsyzLnjVrErk7 z`GD%vRqy*Hm@Zy&az7(>NJk*d%Byt3!uLP)dKtY1JK6oKtd`uFa#PYcZPJYct?RS% zp7*`F6XdXa$z%U%HYQhHg!BXqFCGf^n|XyRQ=`h*Z>I6YXqM|q_q&#_;!Es!Xc_iq z7W2aiKl}4m*85+o`Mr4Al&v4O)$9s6ws={quymMJ;)}z{a$gUx&*gt`_M-8Z7n)B$ zrRyw+pSLscOt+=OR*p4ET$L}%XH{Hw8)be0O)ML|(-=8KN z@1EFxXy=>6*XJdJIu*8^?mS=hwqb=&-i>Vx%O9*x@ZZyQEIsY=<7-iCR?hwAopI7u zESP1QYPH>pie!&NH)3Or?!59$kG<|xGg~saq~MB*(8p@)?O)d@$~k+ijW1QRSuSyH z=@XIXdomXoDO#@l`r1vr|5Dv{R;v>&^XHeJzPHm+>gAqm=sJB9C_5xF6?kyLNv^lv0kb-7%@w z*0}h6L9;hp*Rg+=pVuqC{LT*3Z0BugRo>6)*48>}|l{##``jwU{4Y=1Hu1feJ9}NC>dUd}JaPVqGV!ct zZn|clw?{DeMF&4;<8L{x^y2zn@rd<-x&7-E-angQwP$~{Y?s8&`TQT>oezvjJiTne ziPyh(+?l_24U+!61P7gu~TV=KdIh7AoLm(?6xFnN={_fgC1H&owNM+wf9*q+s6G$og<4t?@ zgOADfGbR4f|74r?Ri?p$QLQKY%8w;dzUyoS!?n4WzD~R!v#(^ml`}8L?)AEVA2%pQ z_3h^}cgQGSezZFLb+C8sewWw2-05$NpC-h=oA~>r9DC+BhXXu^vm?XhkAGR$<{Y{G zU7eEF<-Dt^ha09um&WUNeCb#zR_^?ES1qoUMJVsN~JNh~?~m gs%@QIF2-$MHD#Ak@-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4^JeVfSIgLc#Jeyz z%H)1nZqnzyh2KrvnGdtczAZd@^5-kYe_jWA-YT-CSZ+|f_U-1s5{n*xc?Tua~EaVrf*O@EZjGH zf&RaynrTlPXE{gwZU1p#hsC)I(_#f0Z(Z4t_Qqqq!z3#O=4oGlm`r=ouYQ%4bHARL z*?RSzd-W~4=4LIj*#E`m7~{31xOyY!Gr1SG9&79U+_p`oh;hY_JMSl0Yi-o#W!NOQ zQ1xt5)w0vuXLS`G_dRiC%g*1|d}_DMm-UL1jrf&&vp?L+(d4Se+t6q?gF|n1%S+9h z{A~Zcw9E-T5$bxs?vm6q&sDXT3`;bkjU)~Kidl-?+IYfB+|nJ!ysa9HH*b-zwcPcl(&(Jr z(WPrmDx8}_lqO8&sn!u%{y{sya&AF#QrhYB84f(#ja59(pEz41+oW{szODA2toGB% z6P5>eX1B)4ca$2wS;HP+s8YjW&l~QZ9aA?|Ki)97!F$8;wfhaiYZixHG*frobfw>Z z!<|cwwrbq&hgD{H1kbDOEmS5&~S;{ZnvR-_00n5I|TS8_Mxhy%hD_>lcSC|-nHfTL( ziTtA6T|LJhEtOVy(D?9aroH>@c0=vdGn;yg|7>%Wb#&R3VP|dFg|W4b5Yt?--Qd-FEY)! f=${;?yqY_G=R?C;f8~5E%U0UU-I}vrI-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4-1*JNXZq}1@*$12 z^^Z%gi{(q{m7bqUuKZ#BG{NraotX(I0=G>qw{m{sEG}{Sfy4F1$5tooFfoy=j6SBd zhBe6X(6n#12^@)GF&3G|DP^bSf9$&1;FWc!EP3Z07TKR{NA^xR_U$#VZHDHBTP@e8 zKi;@BxRiIl(i+3LBD2>e+U~gg_r_HhWuB$lujE3dFL1PO4mr_xMbSpgqgiN`QT$Au zi*I!v7Q_hBe=+-CP6Xo`VZIlvJd(s ze{#F~K3L@%e&bls*Rz+-v}-ClUuQG+DUR6kGn>nG|A{Ms2mB1S$)D-v`uYCO8JR7| zG#SntUOX#ve7^X%*UT4PR}^?g;i}?ObQP6zdo`YD4)_2^y#U+ zQuEU{m%MWh$X=NDxxZH8@m9V3FwqI=_og!}c>dL(bM9~PJz|sFo`-i>+8UbHdP}XA zb1mB;=xn=T*ZhfV9o028$7CKCVg%x-QZtaDRDfe zQmgIw%Ql}B<(kCf4SE40wyx)X`qtcibn$0mYF{Gjq|C^a#ry4VaM_hJ2!EYd@}{ix z%4{!Pea^zpr3FSc^Owz)JX)n6+st#gs^a}R<|WV0Onm)Ob#ZJOLkYWUK;D@!!Dd;z z1q*U{);J|NiIpTI#_N}h7ZpWREFE1TuC=T{enrT0wnn^!Q?Tc7ef1Q>81^dtS%T??}Jg5INP-D-! z`t)9WxZ1JahacaSI{o|@Vld4_^;THy8O>9rtA-$JLN$}j|Rheotx92T3KsssF}a_u*lrE3+)5L@2+#! zT$A|GPSbnS<5_yn*=OT+DlEx6@}la;tIPAaRf`0V?e6P{-`+2-wEg!%P1{qGrV31t zJ9VomIoe`nWnh7#(6iK|X_m*g=C@t!Gwt?1b!u-wdQbr)xB1<2QNFWlf9%LR9vVEk zPbv4O!{21~7S#|-))(Rvm_B8>?a#MZ(Q#_g`R@-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!45Boj)f2CP2$=^H0 z`J`?rWB2w0J2ps&o__yZlPzY^`%r;mzmFeoFs?f^`S#8eF0mX74>sJd_B)@lVb`j# zK0{X472l@4b7cKWe9V(0!}De$9amoRiO-d+WAB;_2NVam$oSOL-1l zReyKKe9p1?9lGjsOx8lPIfAE6BrJH-mF1nX>*{46f?F`;L+XVwv| zRPCKB;=e1FK6kO3(D+IBMCe5+U%}Wv62Z?rT~egNUi`axPWX`{>bO7>zs}2e=X>$zVLBr@6Bg>w?_1wTJb!h&tYkv%biK@ z?&bv_Z}9a#nHXubXM&OXQQIlHbCuc`CLF&RSMp-@zhr}^D}+CNu=5ILtpQKSLdHgc`R~svBtn5qJ1tJmcUzS7Y_9vtMXWD+!x-6i{H=LxHz&-`X@eAlxqPg=ZddC$kA)L<&eNNf zzrd+}wf9$Y>6 zG2n2Em{xi19O3WJ|C|($iqchhF^Xq`Q~mgX#eZD}FAV9S&w zGsSxo&z)NEM#4FaSyOb&p1v7HCu)25J60&B^tXMOmw7pmmm~6udd0`MEhaOsc1`nk z>f+*17uIPJU)!_7ZaTA$mAhE#u3tS(+8HzbvRt;-1sX=J@lVkRD#%{B;FxQJnfLPT z`$YP!Rjz-0HqVrMOUR9tvwsx*)3{gA_JsGx>8o7RvqVjJ<{k58mG*JrxX|9ESk>&Z z&fdfzt6(4tfwB58QqSN=&Mh3wN>w5lqpX}=?elv4+>YM8= zOH@8w)#ET?TG6@nz=Ow(nthEszg=1;C3ASn(d1*gKC7Z4`&aR;xv=Vdq*iO+QRT&p z9Byjb{L8P1NZ+tn&T8#5-D9W4Pqn6&6>}qay;hYf<-eY*R!T%HCHDj{9Nht jqU_hfGraYs771qWWn%M|ehRwu<>>+M-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4d$&2xW>xd>pLk)D zkFOxw5OPxXX|+*pib^_Ry@Rtf?&-Ng5fKJ1rv3{HGQV!TKJl&IK5bIod8eJGFiB?uCmqQhJ`wOTB%5qu&v|{qvi&(pS9Y6ss?+zr!NQ%y-PKl<`NGM$Zjl zr}U7u$CdB;w?E1XdC@ax>sptd^Zu9SYztVsU725|c>VP(&Ewky*)vvKB-jW~_faWZ z99UTACot!I5Z{`OLIryF3`#ohmfuX7*&-Isa$?3}j;jx2w!B{>^khc6pO>P+^K;P` zr^N6(t7w$X@L)fzS+KP4eR}b(>%2m5M7~cyjjzP!QlWkH+w8S6(y*u?o=I~oTw%C1b=IiPMQR2Iw1jHQ8ys+c` z=_5{m1&@drn~8_DPH9TeQVniDUHfu}ZNO^L&VN23hazW9?q0(fIeCWM`jFoTmxeYL zMC>?mI9OTJfBQ;hqg76a7V@^8zpzHvUNO4s+3hgXRjZ>*%~v$<+FQ2MwPm3}yqj$H z;{~C$5&NC)urF4-BV{n-Ysk%u0zcJ!Pi?h28T*d;<-G&1B=zdxI z-i7+ztJl5AWPW(%%N~<}?I-3WxYxf52{~rK-aYk3*|7kL+!)8pO1Zlai85V$e|)({ zQIO@gijH3r#(!o{4|)zO ze~wkHUpj$5BP%e1=C{iVDXR&Vv^n%RXE@{-mnL)vW92z1Q;h?T_o+O({ITo4sbo1*TUK zI|ZAhN@6E!hBbE`eY~i%!|0hnX|k|cdw|k6#ZreePP13GaVGrwv0tCn@86+=+oHJ{ zY~6ysJZir&;n-&hxi#Gl5fu%&M%O>?nR~S1gvp^_;SmAijFXx-{4PoS9P4Pxpf50g zcbeS0GtVMUx4dzQdHhNHq}-;)vfme#f9hP0U}UYWSd@438{eI}e|ut%e!hM8x8kF| zcT8c1q3+$nN=*x|J(LaMQhWWK`_r=PP4&_H1#jQ=X3uQAIsNHrJAT8%;@|(g3{Pk= fFR8eE-~zw#=`9J0%IlIsjU($@VjkOW*8K$l1HlkR literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B08_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B08_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..3731fdf6438244d90bfd67fb0a179442a9d01e20 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4H@68I)M|fT`B`FS zy8D7PJv&%8$<<9ebxP%XW27-xeC7QI!TGi~bQ|^xRbRCC&G(JEClUEcfk zeCJdAGVPVu-uga{%5e6HwTa7?v`*JmUOY=m`re+l$S+f(A8(m9pSRQMX@lV$uEfv& z%okZLWp`{zbDjI+Qvc}=uc>=$?3XO!O$vFc9BsB?qAuv_I&kS z_IvDGSaT0}wAk}pTDOw8`_o{Y4-7_B@$uxZ8hMhke95=ayZ|tQWU@@0v8* zZSJfPCxyA;HSZQ)F!Vg?dzRN;=EsYdW}D^W->erG3HW}+Tzyr%dJ2#&qZ3 zI`i4&ZD#JDEi1G{hVOFtmMJltudz64XBX@g@pIF6Tl-&+-EPb>`?5~pF=N6aA*~e|oQ_ue zt~$5`+D)2kt8~x!j82D{iCM121HSKH@+Y_i*$Ztmv5VQ5y5xe!b6;6rCywiXi#Pv! ztk{$jadUFP_1WHR({oRM6TQ~^OkT^q=uDycnXPOt{NJ`lYrczh`%$a#g26YvzG&j~ zz1HWKYOt^CVw?K2)7-1UMA&p*r{_xzFC zGR@lw&SwnYT%W>N#>z;rZb9(({t-Ysc7$j+J>G_jgq1C*+DA zZ2j`GU8--U$jxI%S6C%ld6=BiDKXuY)v%|yI%8*$gAPh zspOh8PwF1~1K*BjGjq{5t18O%WE(7ZZJDe4i~W@IPTzM&JL;IEJ+t22;y5v<=c~_r zhul@N%oaOh_x@fqYxP%Vrvx_3YZ|i>W{cdZwc=CXxKx7gR-JS9EEk1Pjbol?8Tj3n ze$sI+Xo#}1=To0^Hs%Yn*v9AQe^y&Qh`F+HnP`@Oj?jcXG2g#?eGTTj@o87j=A-At eyBH5>?wP2QPzQXkn(|{Rv-Am8fzU=^|6bG09 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B09_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B09_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..a105d1539c6f56aa37000cae03069348201025bd GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4-cgDZr*o3>Ex7Y z?r4y<`FbW$R^>~&^wt+=7rdPm|F8Xdvj173n(7b1h4*FdFq>We@hf!qgtg9x`DWT3 zur!`{X6~HlE4YI=kJshA;Qn*Jiotq1^O3r|vJS4Zk(Rybj|6=Aizf4$9q7G0z0}ar ze%~$T91rK7BVsBXF-P8fcJ~VAs=x1B>pgKH+hy-|6Yby8^Id;=l`po<(tf)m>;Cp7 zVN;U~r}H{asCK{0e^~cuXS@uPAX8B3Ta~%?2h40!pBl}&IOD8Qqo)Xe+Ck@a@jJ>L zt&hp%rsUk%Toxi3ttT#Yjd$Hw>qRTnSAAZ#Vc+CzUHj;p(=H3$m;QA1!)aNjSREVh zHOsh;Z~QpN{0@VKPFiP~y|b9o-Y(aC&%)YkNyny}CkDDzAN?Md|KZ5>-|b3{{SEuK zKQC(E{$o$ttmr$6^MmHCnk;^veedCLX333}`(LDszHnc?{WrIqT~2jm&WxQ$m|mEF z>Jk$4UctRB{VadRm1I!{-L?Sk@E`Rm^BNN$Yu&LpoAQ_8&#O1PI0ScHw?BAs-Lvao z%DZxl7v9|T?BB~U@9Uf;;g8CycHRhiVAR0!(a&}F!?p$LJzW+Ts@eiB-OOA2Zr=*u zbE|$!UzZ70e3y01*d%g(ck<5*kE=6Yh!`9yULu#8TEyJqYsA$N6QnTHbN$qmgi|Ze zpVF_&UY3|Q$9ZvL>WOEQs=Cb|3bYz*&e^!_jE}{;{Ut@eO%^?ze(3F`+DP>ia<4e^ zR^EHr)390Wa*XFRmz6cg(gbfG*x#qT zTKaKB?1b6#BGWUv7O#kFo)oulzRu&4kBix4749%f_u9X^yRpQBT|I7oL&MT_2j7WJ z`6QvH-x>0-w^Q3l=UL{@*GFz0nmp%r$(NMEw(!qf+&jtepBF z_I-6q*!(w-xHR(07v2xpoyXC7FKlDrjLao^=`R9Jw_J)VX0U9$TV$~7L#mzZPuYE6 zKUD6$aAYoL$Q0(|9oJqwDz7`ytm64^RqSt%^}F3vb6zW)3(X1m;mn_EYR&t?M1N*q z*^+-zbxXKwPh=Tg(=NXOpPn#y~lrR`G4FJ{}AcOz_ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B11_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B11_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..c95848df4940b9aae0a8d08dd3b085fe4a3748c9 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!47G+nP?*v?b|EW&q zn9GLbhX>=g6}ToG*|x^z%!kmeHz)tfa%C-ao9!^;^V??~U&NSxuw9mXlej>xYDOzt z!P$R-Rad>P%{v%lr0`IoIrQl3iHGx*7L@+0C>aueGC5GxL8-3h!b_>z9*Rmm7=CkhZRS;BmI@SGxIOSK;yPKjIyki1trQMax3}7 zmF7)hd+7Y~`g-Y0i#F_cZ0GXu;P~k>&#KMOT88ydv7#2|QjKE@fzvbZtW{ZdEcXEG zsjr7@u8Jkk<9Z`*9dzwDM*^?fevx@=F3!m>Dp%aY6V`S|x!J;c2fwlT{Iv%6rlq$&q<(u7d?nhHDX%=Z zc;<;u?rRS;h*^7B(p9WHnHd)t<1tBDq`U6$m2mdVmcUW?hGz*y%6yUUBGZfe0c z`;Y#5{n`3moXq~^@n^R#Tyfs+i}k*8JDBwH^7PV_$tMv6}ClJDqP7HmQj1TiYGz*LTm_w z(P!&iaj!Y~yI;-rer5ir^RTD%k?o(WkF*+kF17xhdh51uh>P~Mo({|DFISbyX|3$s zBOJ7B%g5(Wc=hE>KDjz?kvC`kx+|dn+@Bs9wFzRkErh(a?lkUSIEjD7N2dj4UxNG^ zR&jgoU$=to@U&T<_nmCbmoCpg%%QNrjpw6p*?jqV=WG51-sNlG6S{rZ+RZ)9XT0jS zRqV33&VSaJy*~Q#iBGe3hww@rj#C%M_Bs$1K7{^RDkkJ;XAkXw2>X65D+w!B>3 zd;I2P_v<@4 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B12_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_a419f/ref_agrifieldnet_competition_v1_source_a419f_B12_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..1480fdac909d3857dd60b830915a8813257f590f GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B01_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B01_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..9854d4236702996a30c668113507668ce278b228 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B03_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B03_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..69526d1da36d61401d6dc7ff34243c9f00e53b01 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B05_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B05_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..abc820cd23bdd5f626c8c2e06735089e0e838d03 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4p>qVy%BI}IJ-Sc|=e)nDeU9+F>Hn^7P z{z124sb*HbgRJ?-#W&||^|`$ImU==tZ?unykACA9wg+ z7|0*B+VxOoLwoH0dwbGvv%X&|zmIL#3&Dv>yCdJ$Z4Yzw)d-c`bkT8r^%C*wd!P6h z9e$juli2w}#B6nJTuF=O(Z?mxORP)9#B2B}RVHh`T)@J@>~)&w=!Q*C?yX(weP_C# zkjahpKl9;|6r&A#k?zKz}IYt6Ny%ja0v zFnnO!b@1sOrkWim%d0I`&Of-;>v-YJ?9lDHvj0@flZkH`&6s$8o!rji!np98pY@4{>$0s= zF1+qvVwUC-n;`jo*)d*yuhb?>t-j7l%F6RIlGJ00tTwIUJCoIGD4G=a+pX{5yZZ~3 z&-U!HwbfcWU;a>D^zqHlYeJ{11hLKdeWIhj_lKU>{I}j8O%`4}eNRu$%ptflV~^|1 zt-k3?j~F{xKJqw|8#sw=k;}B!{8=@3HfU5yDX>q@ywId`O#7>Qa8Xi<^Xo*NBb!zy zsFz;Z$sv33Q^lKItqYx&Pg!;DtX=-cOLLivz2(oJS`ycBCgjFvMcwY>aF zR)O=cC#IGeD3_xmMh(4;&z#Ar{`Z8wmF@e%qje#YSpGwPuwI8e~PmFEZulA z@2u|8ue$7SCvsioy_n-^?3C(!EpaXoFbbE}^*u}tJ@ zC^T79cSrn%@Z~w#E+=2How)5Jp*3YyCCj1p*{gUT-!R`B`0Q%gb%U7?bmF@Ev!pYt z>gE`3I(4_y)F$MBt9{GrGkj&OtNsYYEIs_^Z0o$)wkEEyYoYqrGe1rnUzrz_r|mhhuXAzz-SDyleI@7fa=Iq( z-8HYxEX?Ffi&3`lh378zulVCvSxnLWc2mh#>)|A|wmFJwSE?qK@5<8^)_C-V^~A)} iH@~!BQPx^L=jPS}cRGF=y5>5c;C%e^3a^YQV-Nt$I~K11 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B06_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B06_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..2136c9f3968472687f0e771421e258eed5db8a8b GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4PxG!m_#^r3`s^wW z>(v5n!B%_oGx^ySZ*9rGUdmaP`B-A|HTe_5)-E~L?t3B?HfVo}njrl+`sBfNv$oy3 zUHWWt(o)3^-8XZj9fj`C-R7Ehg2mv<`A>gCW}FiVtL0E$S-MI1JI9*&*%P_vF- zzf3*xoP5ZpC1==TR(n3#!n9TID_8xc(_-^xRe7)f;KKL9|Jng#_62$Njjg`9GM4Wf z1)ffjp4&0uppU$TUSeRBW#bRwL!WvL&E{&&Ue}_tKF;V^@x|}gj~C9o%-DMN#iOZL z-wL#@KT`Bvx$)L4&QWJRe#<6 z=&LiAf6<37&czEnx%W6 z)wVh#$Vhbh#(CVL7Y{thSlF`r->riW%C1ko^et;m_Gu%>-Q_=Zoo@(S5Wf=oE_;P; zs!7$F!0&uhUx>e5U-|ut)fvwP32I{iT4UgO3EE(Xn;Rtxhy=8NQ-&iYWK?m_p>@CJzs zQtM{$?Pa+rC~G_U6{qO@%~`+0^lx1;DbzQ5bs1@msn@3fs7!pyX4f$VRkRf@Z(KQ>_hG^+SY`&6dmH`p)Cjnxdw4za&MnPD|e6)11_E zbKhYl5oX^W9{IiS#4XRY2Y7O{t#pgs zH+A0&Tw;B4>Dep%EC0N|s3vOBq`aa3qM>QWx{C#`gZY~z6U-#mh-tl2QH;DOq~@{q zBlB9J)9P!x8I$`v&aB=it+MZZ$eX^ZGgJPWNQLWVzwIu2@-CxTd1JkIl9WbMj>i57 ii*)tlji)=rzga6!eLT;qc>DUkgqViz1=6>;KLY>}_!KDs literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B07_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B07_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..97e5bab86723c8217a80e7023ed2f5323225f9c3 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4e~&DhUoX9~VdWJU z=1*(-?l3voEb7Y;ER@L2T6JUc73NoKTN;v8X9>@F{IT_T_Ss|$ey3`ORUXQk;I%tb35X%&-VSMLfX~CT)xMxVlH2N`(l;#l;BAg zJJYv0@43Ra_02h(9PvQ$W~s!C@a3wiiPcrshr?a>be1hYH7`^6P5(=qlMRz@EIaRd zd&~0kz2Q=lu8g+(_}ARZ=ZPQy@)2y(lsG|2ps}k6mE*!ag@`>)^%9rJRi~KI{ zQP`Y3>5Sx&)uC<+zB-8sr|db@w^BBt^bSXgE^CO2OZ3m@uiPGZo$j=B`H?)w=Ev*B zwexBiBExrW)!ys-PR~Z-^OPrMr}{n}Yc_qkHP7PeGsmrd+B28>T<*CVC~o7$TjjOm zN5;-aHkUultUEs~H%2&Dec_?I|3nl%j*7dI$jMISqT(D=@rPShiYkA76!bE+qm=bh*Wr5&MY~rguslf=2spZX(>s|= zp%>|AN~`cGQ6${)mYbzX?a1*G=fU%JT0a?TpYgSx^MlX_N_{u46N z*sk;E*Wv8zwyn26DPLUm=G`)dFQ&5-n6|&#ChX4sS7_$PxBuBCw(*;WM9Bjkj_rxYrxRc1#oW53)HP$nyk}GAJv;0j@nLyi zdZN`8ooT02cOClieCtKdi-FlG&o1i8-O~9K@4Rrv>|%>*_L|mPY6Gd8Z&(Oj4ObfraY>=gU;5A3Ed zXgQU2Lzlg*;@kH15jSnU?`wEC)HM})i`=@}ttGwf?>Uz3seApW^*QtKuf4tgrpmsm zRiZndC~j+;^!VH!>18*P3`(tq=Eyyb)6cm*bFJo7`yIZWo87Kie)U^ywE3WC*yXJ` zJBy`m_gA(2E{nFExB7i7kFElP-Hz?teR-Q39zFc}qqD&IQMpIr8LL0SnZ2r~3W^#Z zCRQ4Td2hXK^uy-r)7|&1C*FQuCS-P~&h^?f4v&=GUuSIf*xL5$cl~m6{Wo(CMIP9B zD|_b>r!8B&9Xf(j{9j7&SXHfGFh#xW_Q#tC?rJYq{&AD9=UV^#`;TUbO>@}uPF0jy zY8h9@`hO>KYa?w%c4pN$OP{`|zva?Gy<_WE{EC}7$Ikw~{N(fBJ0ASw)hc*#an0I& k51e<~9-q5sKfoz=Y3XMO`^}0sNjRGynhq literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B08_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B08_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..e75985b716077a4e96c47f2b706e04f849c62a50 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4_8CVki-eyZIIh~Z zCj8lhZ&Ok)ey?4<{?sAo01-=Bg{krDH#JDroqn~>nD_ayL$%9au{XG!U6JB%AbvV* z_o=r!yBvb+j9zV?6{mS$IqgO1p4V57oVD=!bLsEeGKbWK9G<$5`1lQ~Up}i9(p~lN z&DY7(m(J*RSs=61)tQN zlxHkUH?kC4Ex0O`JUjl)Dcv;h2G^^s)r-qZO0U>2`!j9(>qt4~d3@{mB@XC^pPtSU zr+eoX$Ha!yCQsL9y*hg6e9QK2{>A zc?*ZypV?22F1~*%-|DM*)Lxy|G>wjLHBIwF0*{9?e)nR$7aq;JbwjVx;ldu%iEPR2 zId8o6lC2Lc+x1|{%Q&Zbms}3Fy{Y>8S8Umd`^8L0Yt-9v3ij+;`|70e)cS>21i#Ik z^YqKfV`rbIZV72rZql2mw>MR@N=z*&?~Zfhr<{Asq#L;dWW5-B9;>rB$QTQ3sov*$ z%^>deg8d&pTzH@AAnnW;T*_g6Y*BgT;~5P$D;{~+$~8IdmXTB5zNWO{wA@135ZB4# zruGjjpZu<5-&AmX-liL~>J!^ePYpktSlT_2@qCTyG^iHvPBAHD@9XJvCvTRlStaCr_slBa!!HxX7C$-heU5{s@GAZ@ z_48TY?#x-%XrTG(?&amvcfRiblc#ch=HK5ZwS1n4pLW=jztSdB{KLZiuO*|l_wLvJ zrp~u~#(QlG-s>^=BUwc3@L#6Jn*!nV=Gv?cToOnv>Zoc)F-}P^4dreyCxd}&3 zr6d}D`g!HN!>Y~y7Afp5p8lt}X8$rjujcEmt6P}v$1OOlFCfM_fq8OP!)C^l`b>o( zzeG=6$a~;0N$fyghEt6 z@#80=4yQX+@5?b>vtZAj9@f^P_e+-WXD;L1v8rg+S^t^|>rKKrTYfW7YdAV@{r9Vv zYF5h}=B!iO`JShpQ}np-qtl*krmfaKt76SNc~m2%Qa*@GIq~FVnyj{|%DLS8W$(4_ z%nz}Z)|^=M^oqjg4HK4Cb}U%>_t)(}#+oxHQ$Nkum{g{J!zK3fkLIswM)f`_bvHkJ zT$Qgh{Xn+)B;}KTq!I%qj0G_DX|S>1V!wv`eiB leOF=kco*9of%6kzI6acMsP4vScUSk`{27Z^Y>YHD0|3jvC-MLQ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B09_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B09_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..1d9b2c0eb3751c863f244884b6da02db47b28307 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!45jq*yC(7*R5^$ID zta#9WP=@=laZzSb$@a6)qD2{2C|&Ae4dqTVlelr?sYc|CtPN2gf4+ZK!MyBUvh`#B zDGw#8u7AD%y^_0IwSHwuA`{a)Q5)q`z8yPH$E7*MghZ5myJsA5XZ9+dvyYDPyof!v zWjPbuxz29Y%$K)!Kd)4BRajH@J+7nLUZCOk2s@XY{i;G>`4xjP7ApdW*=I!(&r&^;pypmH{ zWVlM!MWxJ7@y%2FqHN7K!FbLC_0lB^6>eOKAwZ=;R{TvNSNi&jq zFQlYKXk_2m`b>D!_eID0^8<4itzIy#^779PPfMKzGd5`Mf80GY*ZNUi?DU9~%GRlu zMBNMd=R{sx=p(s<`;qj+z+Xo{FPnc#T_m(<$804xi^KaOS9zo-d@=IY=ok6^cwZ#LZMT(7kBw>kJ{iccg>ZZ z8P?u=Z#0HI|GILQ@`m69mwVw$K82KSS2&xHGk?d!=%z<2zZlLG+vKCOhk04+YW6=5 z{$*{*lr!dPx%;$6x&EF(xW(m|SC%giRM|h+%CzKVQqa^EZLaI@`Zvs46=P6*@Pf3T zgO^Ot_Ei-VL{zQ?HqH99(_(e%zwUJpd3slshZPBQ`aRBz=advtXG(k>+%bFhQEjmg z+}d%E6OB_?6`udQJwdNz+g7nlr_SA0e7ZsR?b79iuNPi7();jmDT{dUyZN8j8bv4n zRAM(=u{Aoy(`b*K%En(OIL~vHzI|ZLT{U6Nj~QR5d^;O!=6mzR>+fC>(|ONWxxaH; z<~FtZXxn{*J**Q}UOr+HUBAB0b(4W}@a-bqR*hc~dg(h~yPg+RU75jG#`UHyG;??R zRX?wJ-04qvwdDMa{%BlQ(a(Oebc5gd6TC+rTP|?vvN~=gYnu0I!**B1SF%l4+voUpLDKb8`Z+m8aWXd@53GE;t?YjI0@KTl zHD}JrJ)6oM+1>58u|wu%)FrRn7x%>19@)x!`D_6)%t$G z=lY?giE`%xZ!9)`dLzb5G3t%1o~hZ%qd_wLo(XfZ!{apquS|Sj7cKbRB6ffb2DgsUnp#RuUMlk$Q=M!U=Mr% literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B11_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B11_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..532abf9c548ab664d1080b7c0688afc1bc2d2825 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4vo~+x)fP+nlk|D= z-nHfB?&p52Su#t^dPh;+JD&;1Go7W>{s}dIvN)!olxcok<<1giH!kk&ujWj8cxBh~ zQl+ZWQc=0A>p!*ZHYDwxk(|Rk=dh(o$THij_YauGw{2X=%(30lt0&EF!fp*8-yK!6 zoE{#(WL7gP`pw))(yzRGnlzl)RIUU+bomw8ame?r%9@S)Z|-L}&MNdG_IAEah=iyh zQ_xd`)t2_m(!cM0JR&d1xIeO~AqS7#2CP#m^fw&t!h`a+bWS`pSA2!YDkX z;w@{+tjgTT7cxK8KPz(wZQXQi&Wrrhw(T1?ecZfh_R7W0PhLIq^p)71HOqQg(1hAu z^?DI|ww0>axE}GGJL^23$KF35-Ds#j}yxsU-I!9&b9lO;}v!> zY@4vQ!txE4n*%m2lAkw|FaK!`SJv}9=f@(p9*payZW~t=ILho$PPcaA*c9Zy=?&wf z%1K?9tG7>DzUbfSH(?$NRhBVSe2V|PgT>4zc3*C-?%}xlGk4alv^`UOdfWAxT^-N9 z=;&|@Whs4(W2*?zxW=)(XG|`f<;_L$`fr6dQJ& zx?dkZ;l!EG-A9idiP^c+`n7S^On07jz9uPRX;ob!=WTZ$D0fU-+`eSD#j7x*+9h{i zH0&uj9bm1ZwdVbGtNl~wel&fTx{>dW>ATD;E4K0!uW_8x=K1$__{zB&+ag@JA8K1) z2wkqN_x|DA-qMrO(aYH09sUqe^z7mEYj>kGrZWb!p7PM?>-#zRkNWM3>zgh2Ot2GJ hzCz|ol9X+-0$VxLpZ~Pa_k~-63jiAc7tsI! literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B12_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B12_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..b4df1ecf49f0e56073cfedd9f4ca8cb04c78d75b GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4{2QZR?6EVQd~MU3 zsvDYmL2EBq?AxMZW3O2^tNNtBvws!q%GO;ka@}7(Yjt0A>fp4;X@?BD{5ylaL)rMe zFWzM0e{1mb@(YG+<&^K|53l(!<#Bd>m*8^k(8_7TSwBV6H19s~Gu&lyZKrw(!^VD- zr5|cTrp*2OP&WJAU6;zYFP9t=n0~73&ji8tS`Go*`L2#ye-c% z;f9{sf`!L*7d()9yw_6K(|KR&)uq4PvR>Ut5G}qU6Tji!x_Vg_+fD0DC0OHoJ_~Q0 zx8TTZz0^Dg5rxdQho*`btfrmxGERH(s&#&pjg8B9mf)A1e(k34f_R*Q&PoHmRvi{*@p1q@R zlm5HyYrj^0*rPT(}D$tnmaR6*G_r4mrc@i>c55-##^6d-Oe#DO^Gzo>RB)Q zNF>|hz0CSKX&0{aiblV7pC;E4X%@YU)h<)NaN^d@kBdC(Ihn82yb?-Qv^ko8ZnCBe z+c70Mo3hSH-=7uj_^Mp2d(=8c-0+=(@voz@X3-lT@MN;b-@Kggo2QuD>uQN(r^B3- zsh&UMZ5!{ZT1Bb9-Okscm7I`gUMW6z!9RtGmNCmW-0qxgoV_76>$q0$goKzbzR}3cJxo~=>~$bukD$mJVf4}jS@b#t6m#a^INeD5oc_wl7knJ7z z3iEXzBl+G>;B3u$CZE>#ycN(&18BE5o~af3*Mr?z0jt literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B8A_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_eac11/ref_agrifieldnet_competition_v1_source_eac11_B8A_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..e1c736a62aa79fe9857f40558552e01b04346afe GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!49gThRXYc&D)6W^V z@4VjQ7oYfq&%cQXc>j0h+&{PNe1A=5SExSlFzdJ%v$F%&&ds~G*6$T~H&ZqILF%#0 zmiRMo564`Zyh2G&xwBrX-h5$ocSG?SO=ag@#dBuK#>ZK{e7y73?^l5zN|(5LOeuZn zH!Z15Sh4xF37dqj@%ai?+vlDVn`@HZZxU#_>e$N9YowEUb+y&>e_uW=x?LaJ_;SYS zZ2)0)@8WpEUuelbbyO@ zZk%P7w%{odkx$os51OYm>d5?cjNBljQ|OuBH>Zik-axsHk;{4Z-8scYd74TBznfa4 z**rLk=jGg3YInuxSztd7s z`)teNW+A)NtJnQGJbl7VIDc3eDfr@;6VmaL)HGJ^pPCJa$bTqWt?7{;)P*z5h~6U)aBU`_CPdS(j(a zd$Ph_(!r=X*4xm&@Wj=*L2oL=^ca7%yzl?GY3rPi<&stls_oq~Kd)4{ntNrDOhWCi zyXtvs4JW!~D>>=SW4d!%XNrZW9m8z36@UEhygL?RS|hO_CMvqzsi$y;55qF=+_Q)M zP8d$$dlT~at?0uy+m^~LN%xrC5!#uq%Wfp|mG#hpn?IBu7S0!)u`!f=XL!c@2P@q7 z_;GrwNg3xS9L$h<)V0=ndCE=2FSG3ga_?|0DZcO}^M0NGj;b3kgk~>)m{hs!`aPi< z&aJapzNcPY#Kg3a?OyFElavjW@~O(EZeN%e9XQJ4GkF4$d{>0Jt z%c8`!*S?zX*Hj8PI!DORJ}D=)y_)q_`R%XCrr)Fw&TgJ8a{NoFMfZh(HLlIci=H)V zZnsfi_H^UAJN%6u-N)8Etg79Z@IHfs@0a!b-Ig!wA0AMZ%$gK?L09!_H>;Xj^g%xV fstc$6ZcSLKA8?8*-756DR>b1=CkbD#i);e`0h|#5 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B01_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B01_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..21c86e54836e0f32f4007c67cf93b52d73b728e4 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4>gk%(SNh~_zw+|? z!Gkg*wKO8oA&4teh)aX1^3&``o!U>yxxuP{1?)zBl@b8&yse z$a1W2cs!wp+y1-5ofi+g6=y4H{qj%M2U+3nuq1wMJxXJ{}vwzlCrtI=R6J(`qw*UT7-gOfS=09p; zof`BpokQeEPJvX9Qt6zPQU`d_lLQ1;i?TIw9^CvTo+Vl3xohXC+e%eRbwP8NGc&4l zslXlyN@LSWQ%|*t&V@j%K?#{T${H&=z zLtpEKdZ*m?vi_Mh=fpcB4j$&ZkR`bv)ogk1E3?H#MS8AIc|4J+blb`5nTyRAu77o= zdhe;9vuo=TShvkTVH}pnc6RDMg{7P4REW!OPU?5yc;>Y%ul5e#kzI>luGgFKe7Zht>3)=_-uj3XL~A-byLW6~0gr$2!p?`ALf1sip6J=N+!SJyW?q zz4hhg!*3T()oxwXup&j|tK7Uzvh2+6`=3>mF38~4$T`3B#!6-Bnyz^-k`2ll>NLA< z@3(*6-Shd_k}r>SodSvir_Mf*d9wNJ;<#I{L#&=J-1Be6Lw4!yv6CmgpQTyKVx*lX zC0el2G38IyXNfbG&8yDe5WeE5v1?|naSiLdX|dbp6*+xMkqw`6Xsaa80Xc7MREdq}?(7gclo|Y^;9Qe9gPQ&2jf!vjZ^kgad%vgh9&7sB){xUG z<-JTf`&GH8>xazv-I5*G^j0oivTKi{+EUAjQ$PQH`DS6$H?tHtow{D?r#5&yK|PC`)F@-v~mbM@p5GY iU*+_9rIkkv8BThCY44h3=a{R(IA_(lKa9U4P6GgYUKv3E literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B02_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B02_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..cfa585af189a38ec089358535cd4f9c35c8cc73a GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4^W{!>3qli( zrFUvh+H}Y``buqE?Nz(JMa#P5n3vVhXEpa!{l>rT#?n1o@21u4U^%gOUSaW!*MFBv z?|P!*wc@s^%l69EvvZd9EWV$T^E@IvH<4rewpka%pC7)s;RefHVXMx&KHe?-nklz; zP7U^~G|rJ}mn!X)xN>dxDGi-nrb|DSZJP2(&g0y-mVa#5IaZi%_wZtpSswJz{1>CT~4m|Jgz9ajD|XIco13?Gg^K?0o9-G*SP{ z*OgyR?l9Chl{|cMTU_u4lM>ZAwx2C8)x9pC^lYhwV z=KA%vpq=e(Whg_`9;Op}f0oO9af=k#)3Q^0PxPt#9qoD+>gOT~%o7eC;DC*k&jekwPr^;!ZRX6y%eOl{0I zUS~1kbH`eN>mF92io5%dzTLAR>(tqe^hJ$gD`)8}?3(oV zxxey6LH}2>uZtW{9(}ta^V@axmdRU`k89m4wOwm%;~XQbHO*OZmviRd$}GL#dK<3Y zY2CE;E7LmZx~Fw(L%COaGMRBoDyBtEbYNR*l`q(;S}42C<%6EDuJKc`YXkpNJ eWv901XyH}2(9A=3H%*w4U=_G}M_$9hg-rm&s0b7Q literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B03_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B03_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..b9e4ad19d045c13042b4f1fc4914350c9a87e3f9 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!48)k;I$#3jE_tkvw zQO)BQ*Uz_~W9_niPfjY^a*H{ypK48#(5Q(&?V(-2tG;dm^Z9%?e{DD|CY1pPSb^IkN0sdDdIK{2pL&MHLa0*kLEp6|`%e+40o{2)& zOQUkLNdY}60hZA3wI=-5-ZBafLz%R9`MjQoIlFf*Q99VVta?3Dwor=xW(986 zuge^#>de2s;(NF2!9TUp=OxN~wEVBzEPs0`!lj&wcaskCM zx2$!(NaXrCubb}PUGEj(EnxOd&ANT&7XKrU<|wpPINWksbJ0(usz@rq;xo$(7fH8% zbJ~Tl#=+1RH zxvkF*Nj5ZU-F6Ms&8w}>m2oj+bXvg?zI07Vzbns_V|J_>O>&%ZKZ|7QGm;teH%_YN z(bKtiGyk>t-Dm4AJh|$@Z&%!+_QO8;P-AFm{8kC$+qd`KPnz~UeA~BteLE9Vg$F8| zCK>wo_-s$ppM6%dU;p3p1y>WN&X3&0z_lv=ht=&bXE_Y-tjnvP@-K6R#B8n)@=pJ( zo&C7jt{qg>{A%IPw)ygbrxg~p&0Ahfy1XxKW7zix?u|JXhfJ!M9to4Xo%ZP5TyNW) z{Da#(jI{SUy6jq1wbAg><(CT&J6RYo-E>rWEn#>l`%;JJ!i^s74XSH8%Gm;zU%VcB z;fdX+C*qUs(|;uiYCA5U_}wv3K8JB*_^R)PQtL#rR04b|x+71i?COtak6)>Fg(cx= zs(8$f8RaiUg%9XPRVVQ5J+iGM)pVAXhw=yJj;T8&Y9>udnj>y|PNZag>XcUoefsO2 z?X>p=etWue)5#*m1dE?ube{AKsd0+W!)O*ed@E>SYdl}E+TT=68IiW#u2ad8fj}b1%nT{`D+7?yG4|{dDT^kvGBz7VMe3X14C{BVVPq<=FIZ f*6cm9-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4>vNon))~KRD&@XZ zssD2^yDOiwiJp{}kCgJHxv_maY`$vh{8^j(z>D4M{4{3crd2b=8I~XXCEX&Ed&|?` zxhK6KE7<*lZY4wkjA@hP#*KSdoBv-!F=c9D$ z^GoxS!=~PNaY#x?@bdkG*%JaE?cbQaWZKqO2}`~w7Ydd9H1RxCbfGoIxS?GmIZzS?H zv2&kYsG75&tLnN*RR0gxjfeJ4?s)1c6&jq&UhL>ucIworo_{MuP2)~X3xB+`rt3G$ zZPU{aSzhfkF#9h2;Q0-gOpBP=s~u|9R)rU3)>I{jF)I0d)cu$EP0uW#D_iWyT*>oWKDthQ`OEh0a%aIN z+bKc*tJ5x<7;A`#&;1x4*ZMSlZA)v*pRSi$w)%@Ee`~lh<)hiQ*Fux`BuH;uD|yN0 zz~auT4?m9bZaVfTQm?2=V!f#Ng%)@DSBdj>Uih0{>HjOc@Sjd+%yfoJs@8i%46926 z{@q#kxrD1CcTJLIcGmq%*S5!epXl%7b*DC#^UlYW$8@Y^S57pXz@YhT!F|rt3v0zQ zYSYgC*%x@cu%giY@wr=juL#WQRZpM%C(YTp_p#s(t>Wz*HzT&{{VD(bdrA`XiO}GP zrl2{Y)wf@(vi41?@B4XNeBqTxdtJ8Z=zaU567WzdS0+PonUrHi!4+d>m&@AE)sueg zX=ci^zMtCM+Im0p?a%8bInL5I48QGV`Jk&HwdrZwyq~>VO9JZGo%^X;Z5*=c~^u!=2Xr(pYy`OfX^{WduNuBLfx0MGV>LmrfZ1zO*$x5Q+M^B{N|~N+@fhVviH}iEsmFdgL46fX-cbZ?Eb`ito7J?yH|z)9-g&f3P5xOQrik zo`2fzT)8(FEKm7;xoyLLc$-A~sY49Mt#3{C5_Fik@9o}>kn-mi3+E)|eQzzz6O!pM z^<_H0DxoO%#rlG**&mc{NG!g4*foKF_u)N0+vdifE|_;~@}2l6o4+eHx28%x;W&9% gSY_Xbl_A{X7c?iFa4|UWYGPRH4DnCfUl~6J0Ht;mH~;_u literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B05_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B05_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..3d57b1dba9711f70d05549dffb1b27bfe64c10ef GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4Z98Z3csR<;it@va3tYZS$7dRsDRkujn~Tsn7dGMOQz5aCmN_rs!}hP4|oLAI4Wt zEWbWDe{zz*q}LO_aHsoOb%xTpP7V6?Ma$acSQ?;OkJsqe3z61u6h z^0&tJ+j}Q#_A_uFSk$VoZJAukec)S9$CSelr@vmf$-*hh@9KQT^*`BHyt6pAdCrGD zO?S;(KP2XrpLCC95tXm~SdriH#!X06vg%F6>h3vTcJ#}isX7<)*7gSf>QikDop1dO zetS5moenr;sTi?tlWxHq-IwAbhm1YsI6kBqPrXsMW4n9j<5^eNm1@e~7jb(PH>KqH z3&Gm7qZj3_zn1^tG-Fcis+`6o)q(@5#lh-xJ{IkK>DJpEJ7sbI7DFA);wSHZJXd>` zapG#0Y3)j-n3UR|k=lW-`87N5W-OS{;He+*dwP&l{UvGc{w{Cz>AqLpN}hTs%I~%l zS~fkLzwGUbzD{Pn^rI{&e_AcJ<=;>xZVilf4yt?AY6+JQ?bP5Hx1@nRzO&Lx6@LJz&nzJ0c8 zKXd2yHiPUX$L~1I>p1+xC}d3(uVGzFC%3`3{WorwYSpCNFW;1Fwr1ADMrK~|_5zKD zoGvWed` zZhiLVInRcU4@;yAIxfErTQIRBud0RTAlpozlMBT~4l~FFzo>du?A|O;T4yhj$NAf| g_~=U07q_+s+*Hx;=MuAeG}qy1vR$Fhh4hWp04a1Dng9R* literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B06_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B06_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..b0e74ae62fe533786b70f269148f44162e23ac11 GIT binary patch literal 1384 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 literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B11_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B11_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..7fb135a42042e19c143cac2351f2c8ace83e3b31 GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4daaueNm$9=2~t}4 zE)kDOWwJC{SWoM3QhI4_Y*(OoT6Bf zFV_1k?rQY5sVhvsyg2+JP^{>M-FjQSq_sB9E2gdsXt2C9P5AW6b7{BiAJ3lk&pzhd zB(2sh`dTv&AJaJ8chrE5HC;%=EA$T+o6&p5_H&u)NB$;P%EqON-rMbc_TA}&OU>3e za&P4q*tYKSUCFCy+TWYme}Cim+VRyaeU;0qD}gU3F`sQPSh)FKmeiszI=5I;*Q)2; zIj1V-aa?+T9Wjn-XM#M^ag`Js5Fqirl7 z8eV5=SN>Vw{JFScE`KKD#!j}^Xa7E3cFrQ(lx0%t!__M5JsV4J&TAH)^jd(GU-v=b z$4#qq@2ChZet+ea9;@>c?{+TU9X)R&-F8o4W_rS0bz%csX@{^X%kT6*2HXq!%Nk83 zx4C>f^X0GT&(E8ZIs~-%#JO!H5B8hxOqM!+e)97z&;B+y{W58KwW#U0I9EfeRcK~U zO6HUtgK2XW_C8C<-1hrW!o-&?hqZg&iaI=2p8YLAH|nVWE?e{9m&}`uS-ytFE+|XL zGS_mnIro%t-luboE4}ZO8kbz1%hq6OTs$c;vd(nc@|pW|!j9jX!fmPA?j3I;Gu8Cp zDV6x1Q_nxR2V znlBG@oqJaCtFW|0EU{N?uktL(%roVCL@FlDU-jv8xBY@QFAZF|8AO(9-dQ_w(Z0A7 z%+fA(C9^MWEn0Rs_=%XHCHpS++M6L-99HggdcDeBOm#Q>;MjF|eo`Zg?%G=|KaXDJ zcrtO~yi1+wvnRdIH+DQCI)iQPv8}fx43|~p=J#<6^8fo4bh~zCz)Z0}Ke}I>nRH+C z(dzzb9W!sviPce1{(GnJd{l_Fmfg!$T*Ad{Z`k)nKmHlqA+je%{bHD(vVWLSzgwx% z^2Cp>N0fB)EHx(GU&&})ec4aI{_u>n`mE#$yxvE9>#A@2Yu~ZYd#50~?zQ9FU8d{~ zE9Y->_lrHWi!)SO|L+GOrw1S2X_Y-(95R8`BW~sFPUg_V3eQgOZt-8Cp%ARG!^iht f$f-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4*RDtKHLlw9V}s?! z@OLG9cP^@3Is4!-=j%c2=@yTY4;<51V%+yt_Ly*L$yI3~t3?YJt-DlF`t^IJadB#= z>J7_U*PFVR3^!UFy=W+RXY~TORy9+C4LeP4b=Fu9;I>B|5HO zd~ccDQg-HwI!k2b+4}oCR=j3wRIC58WYVJ~g&yza+h>`aUQ;w-_TNVtYf_|Z3s#oP zo4ZW6FJ9!nf9965h02pzj<4r#IQ%K2^`YdMO#b)(mTX5l>GpTbD=l$W-D7-58H=vk9y0Iy5m-gn6ov$RDR8-af z?#Ky0FQCfWts+>J$E0DwU|Z^TT2Ni_zIo=VrWEBzRx5k{7<>Hrc>VO^v@a@AGO;53 zT_RG3D>KCAW(1iLQ|!z zS8H^>dgWAYITtMTvy|VkNJGCl$J29RDEH<#maD=GXKxI?)h=JP>7n_rWuHz=+EsFA z*URr0_WR~uNUF_>d?TLq)$s3B z-Eq$?seNYUjp$bOGaJ>|^zU>Sm0Z?N(fO^tp5JGC z?ag;T5(eUupv-N;|y=xL+6KI8S`SFP!9BLC)0iK?8OB4S?{;QTq#hC{{d z`9nR1h~gWXPom3}mXuCzs?o9Myqgr<5&Ql-$4d5{nKK#Ly*P{?AJjgfKKGN-;l{$h z0oRgueYcR@zp?^bJwq?-D}iQc#Ws0L-c40v1>FL`4PZ}&!-gNKWLMm!G@ zQ+;&)<$QNe&rG?tSKp5{na`PfefO4$wyze?+bp{3qdPOJ$Kj`?DaB`3OuPI=?^|x~ h>pbW&i`wk?OBO(-rZ|o006t)7GVGY literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B8A_10m.tif b/tests/data/agrifieldnet/source/ref_agrifieldnet_competition_v1_source_ff450/ref_agrifieldnet_competition_v1_source_ff450_B8A_10m.tif new file mode 100644 index 0000000000000000000000000000000000000000..c0a55795956b047b0a5fd66cc55cb0bb6a988eeb GIT binary patch literal 1384 zcmebD)MDUZU|`^9U|?isU<9%hfS3`9%>-qGR53%@Aa!g=Y(YjAu-*)ygea1@7?ce% zQyi*>frWuV21!jY5}U7?hk+TW_7D&^weT>o0qI*nyuO_o>@F^#`5W7r803IrULZ%n zfrSQ!pc3XWijdUps7GLz|H`2ABYWfE|_Lw+1M@ylIPgi&dwmlzy=Hm zMut9R1|AUIQqKaWHI>8NgB2`H6!aBBLwpsg^7B#^OicW0Afh!4`8)Pr*y7t~*LTOL z@5sbyA>n(nZ@vp!?8*E}DP!l<4cwdBKSW*M>^QZp?(S?arXANyCg+BqGc`WSbNrz3 zBpU_${kkW8B2px#dFb23%G~X#t&%&KH*GEF#T_DxgE>~#MqO$!)%lSX$JsmU$^1r@ z$Dcf0XU?vlzIscyxZWnWKD~1bqxsoanshR6-10W(L+Yj%-IwC0e5vgAbWOS2(--2o zU$3d-7gNjnixW~C=aoN^RJ3`2R?2mu*?zgl4rMdrDkX1!NpQX6>Gj_G!E>oin|LHF ztUdotH$JiQ=gkhQmdnoe%k64w#2(L(bpAQx)bs=4EKdTzq!v})EmDqs)Dt;{`^So% zhvfB23@!J)b2=%@az4wlm%sU$N?3Br-R)P*MI3q`Fa2n8*X`QuDIRJc%r;CvSn-m1 z%B5+io>wa;2s;!mC}lkBA22QI;g6R#6MwJYq_|M1oOy218c(L*T_xEZ8)6r%KalmR z;G1ors9J5zy7N2dU;5~>|1W=P#hC?#s{K3fKDoJ4cpfAH3cuXmmquKkohK4Qz8=gJSSz31G@ z#m8~(_{yVJBArv$r9An=wnidFsjAqSW25u?(<{DSUhc(eU{G$qytB>g+LDt(&yZR*T_Cw>$s{5z6ed&)MpHgvBC-#oD&?=FS=eXyJm#CK0R z#4qO8`^MM*47ucY{he|zuu*71k=IJis`J_vGhXeJ5sp~o^6rG{t5B0T$H$&;bgsNg zdiXW-(NE#i)7W)uKg1{nz5P(K@|bARpUm`&?UAeIugcjfmvi}U8Oy(BlQo^6d&(Y7 zUa>mt57*1I`xYztj(A&hGUo1(b$`3{#s`);1s!vz2TPZ-L^@5ab>(>yeq&i|`V9Le zf}ehTu@hPHq~nfF-pRTb?hLU#NwK8*OT{iw=U@yottv;VuYXT#NgQW zP4Rbg8#G@ZO8Yi_b_8Enl6GP8v7U(~GbS|zeM+wiO(~R;%`Np<%5%$N&er)~PVjz< zI1wwU^5X4wwVb(Ml>{#C&v@m<>2-94l(K^K$>76s0nciZjQFO`U@2R2Xym2`3K8X6<=d=yPq-=u z_21$WoF3VCF)8#@OkGAq-)W`J&Cf9`gVI literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/test_labels/ref_agrifieldnet_competition_v1_labels_test_eac11_field_ids.tif b/tests/data/agrifieldnet/test_labels/ref_agrifieldnet_competition_v1_labels_test_eac11_field_ids.tif new file mode 100644 index 0000000000000000000000000000000000000000..e6ff77ac5919f73b4bad697ec2fc857e705fb1f6 GIT binary patch literal 1384 zcmZuw&5CA4481+w^bGZrR8s#*m3%O6bmOKMF2~g{f^J3;+zYOBF9QQQ&^up6`W1W( zpT>OM?a&J^6gjt&I+f(4-n{wzcySyD9>>Myabf6W>*5K1_K43>myh@ycl`v@#nt`U zpUqL9?6*gJ=IoC#$JKGHCoylIVE7{(mlpfCt=~U{h89k{V(orpC9eG zwnkhWf4)4z*?xF`b#Fg=`NQkCr!Q|#U!1=G?wiwZzy9*m>E`C!cMrSoj)b7ybKN*+ zn3ARW0@V-510nh#DdFg`2OT~Q=xzm>rBcnwLB{PkNh-+==efD)DWo)LWhUKqV2QAc zpAx0#m}V1M+Tz|l7La283)&}II_=+1J>>)_1QHE^n%TmR%5}mRmE>< zldTsEh8-iJ24gT3^hCjAh@_=WzpLni<`pP#9ZO0cd(X_QMCjZ^+$uylaX}Zk)RqIN z6W_x|@UluuK35DgPW2_O6sjwx2PdTk)kTvpPb`CykDX)iFt_V_XYy2nUl5nZnO$)e z9hABgN6{!NK*MOFw@kAFj!}JsvQcDWY-`(HqEm+z1DYZhDT~zV@~znT?6|w5l;gn6 z0XB#UGPl%~bKGJgOl{7xbfR+E(&gsW?_j>uu`-lh7OcS~cf ztXPugiPFHkVFeAPtlTJu-qVB-)mLk4=eg__ws}|zlUEKVTr>7Ma+B6wSLb`#Yef(m z&Gk0aQr0*sG4Ev0rgZB+jsQM6f$2=!qHch*6E^c4apxX-p56pRSg@>b0m!vLMKcn3 z9-5L&o0HhEm9qBgv?&F@_itOje}LoK;yxFzJ2$w`|bc=M&}42 z)a5zVox|)y^AaCiwZ@L;$;|;xTUQHQ0zW59Y$yeHBkzl;Q?oXUsAxx&lpc?SiCGN`y(J_C}=J z?`Q-7Oi5naXILUJ3>rSxP+&oZ=B>VjL~JHZHQp`e9c^grx?^0kZYgFHMr>qyYCS91 zYDU78;Y&3OS8rtm?7YWt4$L7>#j}zN1DyBDP)FR|dRN?YO6Y#ISqiOy)kHv#5=dvw zO)^`r*<~fSmQMCSX_@)fSp5vtCNFX*b?yx%3oc=BqZ5~@o6XFqtIj$?11en2A*g+t zL9sV!HDa<+m_f2K#>LB#qM6eIW<}1qYX~YZk{cN3s6k_3Eo1Q%Rl7VJLJ!6+uvmHW zW$hLR*N(u&wNg`ZzZcIdPw(r8m9@XdGX0IF?6TfXm^S-dws zCD;V_@{~gfYq-RK?8bDuV}_K^gWRKP_0*k8P1Cz57&xZ9v!6XNLMsXohBT4p=V($r z7Dey-lD^ue){|EDMP}NggF2p`?f!toW)MR!Cfq#dop?vG`Cu@mm3oP7L0#E2rNlMa WUkbRK>s99L+X<)QAc)D$tp5VJ*=Fki literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407.tif new file mode 100644 index 0000000000000000000000000000000000000000..02ec404531dd8607c4a4b6d14d66c0227da649cc GIT binary patch literal 1384 zcmZvcv1*k;5QS%FXK#W8#lmYN@;8i#rlWu*S1ey_rSl|W<2HWToQM`XD7GjzxD3o zzsAYO<@LO{I=x-lv{}JH$WI%(bIrQhuDw6J*&f6?RtVAJ=W!glUSHK*pC5lXy;xpt zmY2)>cW;(&U%z}>Hk-GXx2KnpEptSS-ZNSTe=VvbM;Up_tG{1(L~y&ur?f<^z8Y#~(&HD&{BV57y&LE;Q5>OiaD3cxTcB6eg}b~bQQ zUpb;Ese#kN1OMqfb8*iPCX=kX+8$w`PkCfjc#kNX-k<@vzHdfLG-ql?*%q3tJl0p1 z?Fr}v&L&ze7R64viGwU*ju8b(7O53fxxk?bG?J#0Mio`Tqz`O%XmH4)uEgZQ5i<6cAsjF);8$E1BTHDA*b00i4tXFeE65oDiT$hm?gO zrGQxwh_sfep|1e=KajGJ&oVg&+a~yIZLDL(9f!^$2V&DY+~AJCV?-1W&VO)!0UK2! A+5i9m literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407_field_ids.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_32407_field_ids.tif new file mode 100644 index 0000000000000000000000000000000000000000..438abb97986e68214c925eccb7924c1a96ee0bab GIT binary patch literal 1384 zcmZuxzp7_75T4AxB$NLMu8qhK)?`;fK8VIAOk%nIzvgGdV9_ds20$PPj&44}Ba9FDilPU6#pxrw0^hIw*&QD|nt$?u zuRT9}hye!p=uyneN4Wn{fjstaAHTn;pl<*1@z)*Q^D^K6?H$6$KKJ!S;{Ef_7$9IDd(0$ww7&eU&M?-Y<6QAI%?g_ zDbTQ1+Rii4XtAcOiI*IV#*}KeSX=F(L{ zB&jyUvYZHvh$J%|)x|T|h`FY{$DmbKkkDbx(Q?DuVpwg#s#L5`8?6}UrkW;`^?a22 zEHo(~L6&#`ckMBbkc>PwcRVtO9MkHJGRoRGCd^Y(%gLq0F;)8BJMIn1U)-k%v>5l5C|0R(QitXhsnjSH*D0QVa&~^Eq`o^r z-;?l?cv8%mSj(!tpe{%<%IUKr*>&EUZLI>k_pSli6?&&GnK>QEUQV8If@tVda*s2a z6&?g_dcktryzDw7v|Wh6n`(@+CT`17)`@MhJ(hQV=^Z43XOCSSr}rg>#Fl9=2vjF*ll0!NEBAJV#W2) zP9e3?v=v{?smk%&vT=LX6r5vAlM65+Djmyf$4k|nOE>Jd>X&C z=NfL|W$v7P&e=a}ueI;R#Y;Ojvqxs0=2#Q2FYK6YdF5=&Z?&)=dv)w*E}ksTH?ysr zPiG%1vy+9-)xv)GV{M7=Z{F{BYg@7Y;r+GC#`S>w`(4;G&MpPw{&{|OF#oOh7ymWR zK2C4?;`aQovhnWV$b?TeaC?o~?>4$W-tUfVV=IVo`*~_>t#`N8>xb)vQx@8Q2d2%$c zG7H)w11k#7xY4y6NllkdoCTg3R44%8ta@dG`T(F1zmX))-g>BNhK($)XpdF7h$W&T zv<;4pl}-e77|!4!dK#aoRU=-~t7e1rJ2n#ok8>n<^r8a>TR1+Vq ziSqy-R1J`dV92J&@hhT4%)p)WpjS~7x4K%G^Q6hu3LL0Pp4dj)cwshD)31_2IB+>lrkAnk<|ZV`;GkbsJWL4kPZ zN5rCWN^x9%DRjZFZXmpiGdI!uR#Mgs)N ze?2#90$3UWoK&!587$-joI2%-VdOyuX$m%Q!*&x69`@+VIq=BQ`I!+WK`w*zh^b+c xM7Z<^*3GL8@lSCL17)%Gm9XcV(uc}mfQi!54v1iYE%<=^o*UJdmWLS``4@^>B9{OF literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_8641e_field_ids.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_8641e_field_ids.tif new file mode 100644 index 0000000000000000000000000000000000000000..2433430a853749921499dcbe90f4111d71802cc1 GIT binary patch literal 1384 zcmZuxy^f_d47C%-&aaa=VrUS$($YXfGsTumwOS--7KB8PLAOpYzzzFE*;tQYP@QANj@eyD1_zB)f_s{<92OmAz zzj?&hnjb&r00DgRBn`5&s$T#7U4T!0@9Qgx55Lb| zJi!0rhlBqGFMhmyb${^ooDpc7d6O~SD4VCPImJ~- zN>p?O=21DVB?F~{(@(ui9uynyjM+&yc5x!Tbges0&ss=ZijxjdLmi1FjameI3M(D`q{NX;2BRA+ZJvp;#DY5&C$|HIO?u00+uk zyacQ`s|aTCaoTW3N!CnppHR<~y_?oDmpS`Ft748lrdEV-_+*V@2g?J8aIMSfRv&{{ z9WgpZiPJi6wzMnvqE=^~l4ADWe9CTq36l@?=BlRhE-Z`T%r+q^4Riu=?oNJB>aBJ? zomPxPj!lrZLTAC|w}pAqb#jvElr&5|J*IGmk~T%zDVyfGL);sVDHK$a-R0!$@<{_O z6o%46RWzxta}>!~f)kbDCgc*TfO`hR;^OyChbmC>vV6F!mOWNV2kL|kHgb)YQ#>1} zIK3VF(iF9iMR5@2nww?wsnor#2saBfyQ!i3Ojbm9K0q}KGn$GNaZ3^zChU_n%I2H^ zxw@km^V(<8ZYh$v1tJ2auCt$32N&>7oPo7^H4`=eW*yfWr$5G^HK5E%yW}QRqWXkX zbJotWPc@ng_t;?%KC8}}0&1!a(p3@Hqu$nHr(XRtGy@&0_?u`^ F{{<;XKDqz^ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_a419f.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_a419f.tif new file mode 100644 index 0000000000000000000000000000000000000000..4e0e2631d07013b3692dc5b8e5826435290d5369 GIT binary patch literal 1384 zcmZwGziO006b1148-oPJ!q|u`#6}yN6qd0P1#MIWd%;S32?R8d&R3DVf{)?T_&c+! zY~ivWGvC}h=bm%!{a(CyTnZ*@w-u6}Wi5UA@$$;6@3*?9p9o8`oFIi635H-6+T9fDyI)I4MV2FE7SgADz5^ z{$}&^bn|5M?(M71*Ds$xZca~MpKnjkOK)wG*5}|<9i#W!>Zqenfzd{C^MniKt@Y-Wu(+#Y<&JVg zfh}$+&<5cM#TL7=Op0=2Iw;O8GJ$8naD@Pz!SRU&IN_+uM6CDJi57kGz8-|^@cRK zh{hz4o*7CaYk1RhS6yIwM%t8m^WcJqw#0X?0LNE)^kA7YtGVzAtmqm>2kBT*d)EOi xO(RLef8`1obeYl;BgdV{%FyO33b00uxv5FA~6g(o;Z;%ioV#MeB2f>*%%y+3>4qbL5G zM||b{_%R0%;FBjgub<%lM}_3MfBX9VT?KagkFUS((!DNq{`YqgK6T&MR}mkc&t5#h z|Lljr|AH4kUcR~yynXp#{Uh9;K;WwHie2u#jrjiV<{HoM?*wjuy$}KZd74=VyRV54JoW_9F7r& z+!|<%wdM^|Vw!33$$Mh$p|;${S(y$sU^K&E8$+$cRtAwVltP53^?qdRaxz)SoVYJ* zr%9n_laN!1 zY4biA$du)&~T8JjMjN|SiP&BLKAKDWFe4==$r}W_B6}Knbyn^LWR{%Qgm-2E*-%-Xz5y)rs2o6 z9Y%JaX&Kr_IIgT<@4ze^>C8Y!`iXfaRgLuw(cQ^Q0O72ZWkD#ew^)_9rI)y~@+?!3 zHslpoNzzbDRZzb&Ckm%(t4aq`flLwiDY}hF(;B#X9(&nbP%7l!DS736B%6;$SHgBu zC~215lS@upfhxleCX4YDJJ?65Cr&LmP1&_nm`wi9F0Gz2#O23{8xM~;cJ^($oj6Fi z)}H(jOx8^Of|mx%?VM;{!r0UHI=0BtO5a0<$`}y6yVM1#1RFCQX>rcV!MI>qtdqow z>^vlS!hxML1qN^TG@T!daw`KXnI8ja#3pqeZ zx|h2gzyDJQRAb3?ONgkWVe?K4Z8ZqADaupn;8!BY zLr1$JXZAOxj4Iwc>y&kMf-t7G=PA`T`2eTb!rH-iTa!2vRg@$GK1S|HKDi-DwtoRT C=sxxU literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11.tif new file mode 100644 index 0000000000000000000000000000000000000000..e40ca4f2d9433ca7acad80030ce9942bcccd9639 GIT binary patch literal 1384 zcmZwGziO006b114^Gy;YC>F*>WFa=%*rc$GRY*XaD1yCUrM(0K8raTPk-UPB;nVm# zvuoJG-E3yQxpVJ5=iKw1pT8&vrIZJy)LyFH%CGM1+jgH@eY?-Sy`BBTy3E|q0*`ji zkGA{Ne7wC=mQtSV+_~J@-~Vw~y1T#qzTX^{J?kI8U+X?`-BbT|-O5vE7Xfkid3L(l z{#)+?|J|H^T)m!w>$A=3p-u+-CHS%jcdl)@T^}WWaJ$|wM`e!?wfsCThgol~m$^Pa z{&04=dUdjTxqAQZ&Fb6NFP~N?CvUGdr&nbVsEyHUE6XTLtBu-Y*o;Qk=6GqA*2dD8 zQEM&3D#7)(i1rLZPHpbh)afqtp;Q}n$;WQ#YO3a_FU6lSqc^cGp_XQZeT>#SNF$jQ zv{6cP(f=9Iv~~b>gcsJl^9+TofD3-5p&w0W{e^<6rwUvJOoq~Uz%wu)f<&1y z%?4^3`nrt-Y+^bpqp60j5d^&kv;Lu^u>cKCN-snp4172uahgSfkVU&y{2MXAu;|g; z#B%b85++YeLT}WJz><*8GdF-3n!XXH;}pG=h#jl!0GlE DlZYbb literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11_field_ids.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_eac11_field_ids.tif new file mode 100644 index 0000000000000000000000000000000000000000..a33060fef4a4cd2398854a7550854b1e09c32f08 GIT binary patch literal 1384 zcmZuxyRKa|5S{VZ9((K=zeH#dI#Ot$p-DjrRTLy>0z#rkqJkbpiUg5v$FHFL0-wRx zF#F~b-GU?e%xv3xdCjcl{o=)EPyk>6AOU)I^MQ}@@Q`1-=pn!MnItzVN}L z`6mzgh56yb9*6)RJ=*i~QEq>9Am979kKf;P$R7Xk@z)*Q^Ag8@dl%qipZoeE@&5P8 zm+#X5;`@dFO}_l`_SOBu>*w#HKj3`@3>UvEce?j6#J6`(uJ!Wvj^PPpZv?`hPoZD& z&Fgp{KYjYc^Ov_Tp4~pbegEAzx8HvK<)_=TXWzbhH~R__t=!MrG;^GF3U2F5LAS;( z!44y@2@^6;D;88WjzEJ8Z-uA~Stl?>Tckx-tx}4PcxJ^kvs#eO>tJqBNj5haQ4SH+ zys;XvAC8vU(j0ZSx^r0;3spOF(LNiblVK7Gu?PcOugl1^5OU_@Y;^`})OxWUY+@~& zVA(+1OZx80GNDhg=zek(G+qX6)&sNc9uUgOfe2N!Y(`^W-0E6B#k7=%N}6tvbD+>uV%V6C(ki7AZGiMRL}bCxsITU6KF zrzL6mh(x$i=lf2xlbT0}J`P&9KD2ywU(-tJPAs z8Ld!ds#|1Nf}J9EgjHY)5FuI{?GPF1%s35Mb3bp<)P8htfo$G2qW z3Q`&na3$@U)cYmg0WS|r_8RbvRb!`;{Hf$QbI_HzP1+p#NbU4=(Enrc+aty!r;K~& zb6WMa#(oKKFf6qJEapzSOoHWVTi9AI)Z%&yFHO<>vo&g(Zky&3_q0lNb-geY$wG|( E0)HDnMgRZ+ literal 0 HcmV?d00001 diff --git a/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_ff450.tif b/tests/data/agrifieldnet/train_labels/ref_agrifieldnet_competition_v1_labels_train_ff450.tif new file mode 100644 index 0000000000000000000000000000000000000000..a55c23fa29a2460be923ca5d8bbcb243e91350f6 GIT binary patch literal 1384 zcmZvby=oLu6vxj!ADbYHV&U2Z8HkNGHd|Q6DkPvy41&F2rM(0K8raTPk$nXp!>950 zKeL7@oSm6_=iYPA`G1_fxOi#DX7(b9=_xr9j+Y&(G%Rzwv(K zzmv0%)0^J7J)cKDMl(1v;nN(rJ$mkU8|@$OcSp9d6+#UAd1`BocemN&i_;J1SJUh5 z^lG|(|91NJ^~vuil_&d5)}fkHITP=?b@q;qEnfmq+FxiXf{9LW^-=N14Mn z-5eJ@FeQyRV!4BjNa8AoQe^0G4Wb9x14%QS)a(}mkBBJf8KGbhgn_rN^n4azI(c!x zDM(_Ljm+Q`cIpyeWdv9W5kcU9jqe9xZzz3j$&?xeW$jl@8QI z5&*Q894jzW2R0xCl|*08Hjn)7mih8kab;I5R*40O{@n*hc;txm?FGZefSJ z+?3itkguwaiv5GMydoG5pr_x+t48C^Hz(B7(wN>OM2fWKNJL6CAT-G-E2x#U3CxuX zU`V2pB$HL*CQ4*OZe;?YY?JQtkrWyby8i~Sqjyb6<*A5sra=@m04S5x2NHdbk_tRz w!Eo6oRp{vX98iTuOPxmwbDvA~$nG68^=WChc(f}WP%OXXjws%RRnXvNOM_O(1po-71>wtF?<^9 zpBa}4Y-s8`UDefJ-Oj65UqA+c0T2j+ql@qG1mh#VTG1oE+Qlb$1-`%gvnxJ&a(?rO zuRcG1v;hYA#8?=T+SQ`#XeB{p{;2i4W_u7Z311 z`9bl&;Kh%ZukICZUp`3x2=@^rxbnMVr+Y7v-{0L__4)l>f*XjQhyZ^+gL;+k-txWt z{MipLUtgZzUcS71|J^s2-+uk&r_1f_w{IR!-#~6sf=MyL)L9SCp)hI1lj2SiB+Z~a z+pgTJ%`_|YeL~M7ny5Ayt5fQw!(0UZ6CwB(kO1P!8D$}_mGGQM#U;bOsfPE4ymUNYT3p*7Gh#Mvom*= zy30WiVdMglwnc>0&Kd49b5gu^MNP{x{QxC7Iv zIAJ4#1XNAQW~8aza%`MCcsm@3j5GO_Fh_06?9fnc)vLQ~OG2H|I5_dPcu&)UIo7IC zJ*u-dAMogl%$fJj4brMC#Jy}RMQIM{+19X1xu2oP`!F&)9q&?2Cj`%ap^fR}6e>v4 z0rkv{gHOQWSrrVeqxa1isRwMUd*(?+S`1#v(u#Kyd3)DlEp~3X5*H33?bX(%u%>!K zLhO6SUITj2JrpllD`c~1rN(tyRIRo4%I*5!kUfvLWz8VNmbb@R*HIn~TDKC{@Tn?e z7DMjPj5$u3nr4YJlpWLyo391amdVF+r{2a=e~FQ(uA-KZg5S5Q(00Qq$P^CrmJ0q0 DDR4d% literal 0 HcmV?d00001 diff --git a/tests/datasets/test_agrifieldnet.py b/tests/datasets/test_agrifieldnet.py new file mode 100644 index 00000000000..cdb539671f9 --- /dev/null +++ b/tests/datasets/test_agrifieldnet.py @@ -0,0 +1,77 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import os +from pathlib import Path + +import matplotlib.pyplot as plt +import pytest +import torch +import torch.nn as nn +from rasterio.crs import CRS + +from torchgeo.datasets import ( + AgriFieldNet, + BoundingBox, + DatasetNotFoundError, + IntersectionDataset, + RGBBandsMissingError, + UnionDataset, +) + + +class TestAgriFieldNet: + @pytest.fixture + def dataset(self) -> AgriFieldNet: + path = os.path.join("tests", "data", "agrifieldnet") + transforms = nn.Identity() + return AgriFieldNet(paths=path, transforms=transforms) + + def test_getitem(self, dataset: AgriFieldNet) -> None: + x = dataset[dataset.bounds] + assert isinstance(x, dict) + assert isinstance(x["crs"], CRS) + assert isinstance(x["image"], torch.Tensor) + assert isinstance(x["mask"], torch.Tensor) + + def test_and(self, dataset: AgriFieldNet) -> None: + ds = dataset & dataset + assert isinstance(ds, IntersectionDataset) + + def test_or(self, dataset: AgriFieldNet) -> None: + ds = dataset | dataset + assert isinstance(ds, UnionDataset) + + def test_already_downloaded(self, dataset: AgriFieldNet) -> None: + AgriFieldNet(paths=dataset.paths) + + def test_not_downloaded(self, tmp_path: Path) -> None: + with pytest.raises(DatasetNotFoundError, match="Dataset not found"): + AgriFieldNet(str(tmp_path)) + + def test_plot(self, dataset: AgriFieldNet) -> None: + x = dataset[dataset.bounds] + dataset.plot(x, suptitle="Test") + plt.close() + + def test_plot_prediction(self, dataset: AgriFieldNet) -> None: + x = dataset[dataset.bounds] + x["prediction"] = x["mask"].clone() + dataset.plot(x, suptitle="Prediction") + plt.close() + + def test_invalid_query(self, dataset: AgriFieldNet) -> None: + query = BoundingBox(0, 0, 0, 0, 0, 0) + with pytest.raises( + IndexError, match="query: .* not found in index with bounds:" + ): + dataset[query] + + def test_rgb_bands_absent_plot(self, dataset: AgriFieldNet) -> None: + with pytest.raises( + RGBBandsMissingError, match="Dataset does not contain some of the RGB bands" + ): + ds = AgriFieldNet(dataset.paths, bands=["B01", "B02", "B05"]) + x = ds[ds.bounds] + ds.plot(x, suptitle="Test") + plt.close() diff --git a/torchgeo/datasets/__init__.py b/torchgeo/datasets/__init__.py index 235ab83c8eb..71eb3f168dc 100644 --- a/torchgeo/datasets/__init__.py +++ b/torchgeo/datasets/__init__.py @@ -5,6 +5,7 @@ from .advance import ADVANCE from .agb_live_woody_density import AbovegroundLiveWoodyBiomassDensity +from .agrifieldnet import AgriFieldNet from .airphen import Airphen from .astergdem import AsterGDEM from .benin_cashews import BeninSmallHolderCashews @@ -139,6 +140,7 @@ __all__ = ( # GeoDataset "AbovegroundLiveWoodyBiomassDensity", + "AgriFieldNet", "Airphen", "AsterGDEM", "CanadianBuildingFootprints", diff --git a/torchgeo/datasets/agrifieldnet.py b/torchgeo/datasets/agrifieldnet.py new file mode 100644 index 00000000000..67a0c994f44 --- /dev/null +++ b/torchgeo/datasets/agrifieldnet.py @@ -0,0 +1,272 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +"""AgriFieldNet India Challenge dataset.""" + +import os +import re +from collections.abc import Iterable, Sequence +from typing import Any, Callable, Optional, Union, cast + +import matplotlib.pyplot as plt +import torch +from matplotlib.figure import Figure +from rasterio.crs import CRS +from torch import Tensor + +from .geo import RasterDataset +from .utils import BoundingBox, RGBBandsMissingError + + +class AgriFieldNet(RasterDataset): + """AgriFieldNet India Challenge dataset. + + The `AgriFieldNet India Challenge + `__ dataset + includes satellite imagery from Sentinel-2 cloud free composites + (single snapshot) and labels for crop type that were collected by ground survey. + The Sentinel-2 data are then matched with corresponding labels. + The dataset contains 7081 fields, which have been split into training and + test sets (5551 fields in the train and 1530 fields in the test). + Satellite imagery and labels are tiled into 256x256 chips adding up to 1217 tiles. + The fields are distributed across all chips, some chips may only have train or + test fields and some may have both. Since the labels are derived from data + collected on the ground, not all the pixels are labeled in each chip. + If the field ID for a pixel is set to 0 it means that pixel is not included in + either of the train or test set (and correspondingly the crop label + will be 0 as well). For this challenge train and test sets have slightly + different crop type distributions. The train set follows the distribution + of ground reference data which is a skewed distribution with a few dominant + crops being over represented. The test set was drawn randomly from an area + weighted field list that ensured that fields with less common crop types + were better represented in the test set. The original dataset can be + downloaded from `Source Cooperative `__. + + Dataset format: + + * images are 12-band Sentinel-2 data + * masks are tiff images with unique values representing the class and field id + + Dataset classes: + + 0 - No-Data + 1 - Wheat + 2 - Mustard + 3 - Lentil + 4 - No Crop/Fallow + 5 - Green pea + 6 - Sugarcane + 8 - Garlic + 9 - Maize + 13 - Gram + 14 - Coriander + 15 - Potato + 16 - Berseem + 36 - Rice + + If you use this dataset in your research, please cite the following dataset: + + * https://doi.org/10.34911/rdnt.wu92p1 + + .. versionadded:: 0.6 + """ + + filename_regex = r""" + ^ref_agrifieldnet_competition_v1_source_ + (?P[a-z0-9]{5}) + _(?PB[0-9A-Z]{2})_10m + """ + + rgb_bands = ["B04", "B03", "B02"] + all_bands = [ + "B01", + "B02", + "B03", + "B04", + "B05", + "B06", + "B07", + "B08", + "B8A", + "B09", + "B11", + "B12", + ] + + cmap = { + 0: (0, 0, 0, 255), + 1: (255, 211, 0, 255), + 2: (255, 37, 37, 255), + 3: (0, 168, 226, 255), + 4: (255, 158, 9, 255), + 5: (37, 111, 0, 255), + 6: (255, 255, 0, 255), + 8: (111, 166, 0, 255), + 9: (0, 175, 73, 255), + 13: (222, 166, 9, 255), + 14: (222, 166, 9, 255), + 15: (124, 211, 255, 255), + 16: (226, 0, 124, 255), + 36: (137, 96, 83, 255), + } + + def __init__( + self, + paths: Union[str, Iterable[str]] = "data", + crs: Optional[CRS] = None, + classes: list[int] = list(cmap.keys()), + bands: Sequence[str] = all_bands, + transforms: Optional[Callable[[dict[str, Tensor]], dict[str, Tensor]]] = None, + cache: bool = True, + ) -> None: + """Initialize a new AgriFieldNet dataset instance. + + Args: + paths: one or more root directories to search for files to load + crs: :term:`coordinate reference system (CRS)` to warp to + (defaults to the CRS of the first file found) + classes: list of classes to include, the rest will be mapped to 0 + (defaults to all classes) + bands: the subset of bands to load + transforms: a function/transform that takes input sample and its target as + entry and returns a transformed version + cache: if True, cache the dataset in memory + + Raises: + DatasetNotFoundError: If dataset is not found. + """ + assert ( + set(classes) <= self.cmap.keys() + ), f"Only the following classes are valid: {list(self.cmap.keys())}." + assert 0 in classes, "Classes must include the background class: 0" + + self.paths = paths + self.classes = classes + self.ordinal_map = torch.zeros(max(self.cmap.keys()) + 1, dtype=self.dtype) + self.ordinal_cmap = torch.zeros((len(self.classes), 4), dtype=torch.uint8) + + super().__init__( + paths=paths, crs=crs, bands=bands, transforms=transforms, cache=cache + ) + + # Map chosen classes to ordinal numbers, all others mapped to background class + for v, k in enumerate(self.classes): + self.ordinal_map[k] = v + self.ordinal_cmap[v] = torch.tensor(self.cmap[k]) + + def __getitem__(self, query: BoundingBox) -> dict[str, Any]: + """Return an index within the dataset. + + Args: + index: index to return + + Returns: + data, label, and field ids at that index + """ + assert isinstance(self.paths, str) + + hits = self.index.intersection(tuple(query), objects=True) + filepaths = cast(list[str], [hit.object for hit in hits]) + + if not filepaths: + raise IndexError( + f"query: {query} not found in index with bounds: {self.bounds}" + ) + + data_list: list[Tensor] = [] + filename_regex = re.compile(self.filename_regex, re.VERBOSE) + for band in self.bands: + band_filepaths = [] + for filepath in filepaths: + filename = os.path.basename(filepath) + directory = os.path.dirname(filepath) + match = re.match(filename_regex, filename) + if match: + if "band" in match.groupdict(): + start = match.start("band") + end = match.end("band") + filename = filename[:start] + band + filename[end:] + filepath = os.path.join(directory, filename) + band_filepaths.append(filepath) + data_list.append(self._merge_files(band_filepaths, query)) + image = torch.cat(data_list) + + mask_filepaths = [] + for root, dirs, files in os.walk(os.path.join(self.paths, "train_labels")): + for file in files: + if not file.endswith("_field_ids.tif") and file.endswith(".tif"): + file_path = os.path.join(root, file) + mask_filepaths.append(file_path) + + mask = self._merge_files(mask_filepaths, query) + mask = self.ordinal_map[mask.squeeze().long()] + + sample = { + "crs": self.crs, + "bbox": query, + "image": image.float(), + "mask": mask.long(), + } + + if self.transforms is not None: + sample = self.transforms(sample) + + return sample + + def plot( + self, + sample: dict[str, Tensor], + show_titles: bool = True, + suptitle: Optional[str] = None, + ) -> Figure: + """Plot a sample from the dataset. + + Args: + sample: a sample returned by :meth:`__getitem__` + show_titles: flag indicating whether to show titles above each panel + suptitle: optional string to use as a suptitle + + Returns: + a matplotlib Figure with the rendered sample + + Raises: + RGBBandsMissingError: If *bands* does not include all RGB bands. + """ + rgb_indices = [] + for band in self.rgb_bands: + if band in self.bands: + rgb_indices.append(self.bands.index(band)) + else: + raise RGBBandsMissingError() + + image = sample["image"][rgb_indices].permute(1, 2, 0) + image = (image - image.min()) / (image.max() - image.min()) + + mask = sample["mask"].squeeze() + ncols = 2 + + showing_prediction = "prediction" in sample + if showing_prediction: + pred = sample["prediction"].squeeze() + ncols += 1 + + fig, axs = plt.subplots(nrows=1, ncols=ncols, figsize=(ncols * 4, 4)) + axs[0].imshow(image) + axs[0].axis("off") + axs[1].imshow(self.ordinal_cmap[mask], interpolation="none") + axs[1].axis("off") + if show_titles: + axs[0].set_title("Image") + axs[1].set_title("Mask") + + if showing_prediction: + axs[2].imshow(self.ordinal_cmap[pred], interpolation="none") + axs[2].axis("off") + if show_titles: + axs[2].set_title("Prediction") + + if suptitle is not None: + plt.suptitle(suptitle) + + return fig From f3270ca6ae5d30e4b5766713bf0f3578e13c1353 Mon Sep 17 00:00:00 2001 From: Yi-Chia Chang <61452667+yichiac@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:25:04 -0500 Subject: [PATCH 19/19] Resolve NCCM checksum error and add years args (#1870) * add new download links, years Args, and new test data * remove download test file * include all years by default * sort year and verify --- tests/data/nccm/13090442.zip | Bin 3043 -> 0 bytes tests/data/nccm/13090442/CDL2017_clip.tif | Bin 853 -> 0 bytes tests/data/nccm/13090442/CDL2018_clip1.tif | Bin 854 -> 0 bytes tests/data/nccm/13090442/CDL2019_clip.tif | Bin 857 -> 0 bytes tests/data/nccm/CDL2017_clip.tif | Bin 0 -> 977 bytes tests/data/nccm/CDL2018_clip1.tif | Bin 0 -> 973 bytes tests/data/nccm/CDL2019_clip.tif | Bin 0 -> 967 bytes tests/data/nccm/data.py | 17 ++----- tests/datasets/test_nccm.py | 21 +++++--- torchgeo/datasets/nccm.py | 56 ++++++++++++--------- 10 files changed, 50 insertions(+), 44 deletions(-) delete mode 100644 tests/data/nccm/13090442.zip delete mode 100644 tests/data/nccm/13090442/CDL2017_clip.tif delete mode 100644 tests/data/nccm/13090442/CDL2018_clip1.tif delete mode 100644 tests/data/nccm/13090442/CDL2019_clip.tif create mode 100644 tests/data/nccm/CDL2017_clip.tif create mode 100644 tests/data/nccm/CDL2018_clip1.tif create mode 100644 tests/data/nccm/CDL2019_clip.tif diff --git a/tests/data/nccm/13090442.zip b/tests/data/nccm/13090442.zip deleted file mode 100644 index 19d0792078a0042fb635f5a7c30c29df453f5458..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3043 zcmd6pX;jkb9>;OLQ#ejzTAJCSSFK#YeJLU}&D=EuMG;VtL_q@VgyvAg)v3vv#w~Zt zEVE20H4P~%7s4e=(bB}Nj1&|V!(Fe{+|#|CJ8!05%>Oy(|2)r|@Ao_}KELnR$6Y~D z9q{3!V36>Shd+Lh)%`FPN1=kKM<_TtCK5v;VMw6;IBFymDi>LggmskA<`7Zu=6nd*}}dDJR9} z#yrqA8&0VJ~co43tp0`$0z$By|NKRFlQl(Sj8$6=}$optK6UKKV=oUD6+uG;LVySYxl)G+oS zXl~NfoXTGrz+lVp8H|043X)nz>-W;F-;u$*v({VbtmQ-xKpn~@aaKu9E|~2GQ8{b4 z2hV=Xr1Bp3;uY>N<5i{Myna^Rn>6>~k+pE(1WQAzk@1s1>J3-Ds-`i!0EG;w zOkn;VN1b5$9L%Hh9CZe>61r~_8>Tw)_hwfc9`FoUoUX%XOJ2H~40GPG$HVG%N>dVq zf>a~?OAl+6-86hcC$D&6uJbL@HPlrWJ(~JRM`(^=lyg04EH!i)#1My&p+BVb)NdckS|?hmL&qZ4X_4{eT!YGCw3B!q4DI$D68x0UiN))vF1fzCEgop9hc$75X zhkA8sT{lOG-YZ!ahYTg{l^0!*jYRnLdyqB~kzPcMslz%-^F-D;7sIS~&OPnQh_wu( z6hCofTI?h?(;2lQB-iXfR4wIFdzpT7<(*!3m1lJ)3)9imjp_ouNsXO8D&_8gHJaoK zl!->nJEJ{!-{&^Xm*m=XXFB0JZd_+HE!U8u{9ew^!ScQOZsl}G!cQc3m(ER92^9K) zfo&T^lL$KE$UI?ZnL}Y z5tf+*4ejC}LuNqZ*N-kWHw;X^M9%?Luhp8Uc+YNq;%~LqL+U+e{QG0!^`3WAV#fx* z?X8#eFM}M-#}&J4yvZH&$1Pk+eIIlPulm%#j;2x#j_cc!$9J~V#-OQ`m=_^7xXX6~ z;;F#23bgE}i}(Z!x581X*81f7*!^Wnlr7Z-_?GR5rlHX{;*w|E7&xGkp}>8Xelt9u zcyM7%!?CC=I2(1_ij0gXNxBoeGA(NUbq`@Yep<3Lv7_Y*jF(1#JBd%HQ^tAmH?L?w z+thBy#>TEo|(}FhjhSWJAOIrf3tJ6*~8FUc6j$%<2ak0!Yj>ZOooPJhU|__F?+GO{NA{b zBZ5H%9S2liF(+nM&F#?6qKyzyR~x(hgogJ_@h2G zXiz|`T#jjT=p!1&g~|w8V`#RxddTal*m>XrE`b~XFtO&t?cX(0M@;|# diff --git a/tests/data/nccm/13090442/CDL2017_clip.tif b/tests/data/nccm/13090442/CDL2017_clip.tif deleted file mode 100644 index 8dce2bb82e94194da84eb4a0343cc364a4385521..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 853 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!riWfof!s)YwAVOh7fkNNm1l9tLKh*exJ#YT;pE1Ja*>czruF*o{g+b2hZ| zFo5(W0ofbdnZQ0N0KJ+XbCVt7#W@kFmh~c2g)+Af%$#PoE#h4LGs*Snt`Dsw`7{^k|L0K z4$DF!9K+p%6)a3@7#bKD@}K|UVPvmon14Y01Mk0o%?OWj0K;EK zhWG^%0bIIDJq(K{{4mL2SLk3++Hi8pDq9T(r{#tgTTVIhbRJgyu)?J9H~X9u3ol0Y zeDaiOJ@jzGO67mLtQ}rU4oE(Y+itVkOR4|I<$v3?C;BCtp5&EF<>?An3-GWN^A(tW zRA1!B6t}y^o1$M`Sha#2v1ah3DOrD`(hDHViv-XNA?tsr&iW=3PjgHGAqA_DLshJriDGQZFvF z)ZO5lg{V|&T1(Ut5Tdgd#ME!-1#0yh@=YoX`S4|Olz1DM8(pIgE?7FFkPyF)u zweICBnLVZ-wDT?<^pN^BPh~BW&+kL0lhnC&JxUCYxV-YVXIRH=r1ox4kcigGHS2ai zTe;RiM{I&MUzF5pZEd4j`?g%{sk^l*;MKGB3;C?|dQE-1Wx6(TNVEOcTAggS$Loc& y)bHh|FO@B{yi}afsqE8yZ1K9+Imc$1PA++C;>CT%YOa4*EW=X6i6I5e3lsoz2?TQh diff --git a/tests/data/nccm/13090442/CDL2018_clip1.tif b/tests/data/nccm/13090442/CDL2018_clip1.tif deleted file mode 100644 index 531cd5f4f1f5aa0046c0c81104b3da537f2d14cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!rhrfNErr)YwAVOh7fkNNm1l9tLKh*exJ#YT;pE1Ja*>czruF*o{g+b2hZ| zFo5(W0ofbdnZQ0N0KJ+XbCVt7#W@kFmh~c2g)+Af%$#PoE#h4LGs*Snt`Dsw`7{^k|L0K z4$DF!9K+p%6)a3@7#bKD^1pvzU}me|{~-T^@E0b=`h$-YI9&V$*%+LY7zBiWurM?+ zJiKuHj}$jM!@*>Oj6Y)5yj@=RFYc&u{maGR@z`Mb3l65gEeuciAIMZS3QY4)`7Dvb z=cwA~^6WyzQX$QtC7~}uGVTP~yH9Y_`gk)&u2H_z=cQ1@<8O0wCU_+{aPBG6bnQQs za&^~UH)Wx=SbcK~m9${?ewSy3GfJfDa~Tto#Ck-p1#%v^qG!w@Q}jP?s(X_7&wphL z1t;B0_<5^lpKVF|?G-|&uUwm7u{CgAX{?O0djIt6%ZfZ|?tS#{{qQKvqgKh4dFJtF zmU(jS$$hJ%6+h1sv3h!YS9!h^XP#elQs4c@mu93?Ust{UN^w?XNzh%EzPz+umPf1- zIy6=~?>VqS~NPm z|2RXYkSdp9ZPqsxgc;^Ouv zy3-nUK4hKL+xZ+Nw>_z>oLoXCxZ~y?E`V0U7 diff --git a/tests/data/nccm/13090442/CDL2019_clip.tif b/tests/data/nccm/13090442/CDL2019_clip.tif deleted file mode 100644 index 67be3087ed77aad718997c0c2d597c301dcf481b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 857 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!rjBfof!s)YwAVOh7fkNNm1l9tLKh*exJ#YT;pE1Ja*>czruF*o{g+b2hZ| zFo5(W0ofbdnZQ0N0KJ+XbCVt7#W@kFmh~c2g)+Af%$#PoE#h4LGs*Snt`Dsw`7{^k|L0K z4$DF!9K+p%6)a3@7#bKD^gpn0F#K<9xc^}T1Me@U`iA)%0;GR1G1NOOQVW=hSJItdqhPPCMZu=kKuK+_R0{bD5S-ow`3|o90_KJ%+O`Iz}^E zvy3%bT;4WF`=sT@?LYgVkmniOeDU_+Vmb*9|B_)$pW$De1PPjtT0u)I>|$~sQ(6~|Tu-+LOwulUSEKQMOA zs;mPW-redsr)t1`rpa=ZQNSa^mDa23ZBPH2GgBw;(zTaHUB+!!^z|ZFR$B zLi3*MHk_AZHYxee)|h%UV{)m;LW46YZOeIozw2GcF-L5_a-h<$CCjz4+`6|-xYe*> z)5_Uj)-U9gdh~Jg$0%0DEuGy4Z7YMa>e{yToyz*Goj2K;LuJ#dsDH}-yKZb!*!cNY zpHAMboY`wve3IF&`SQ2j1K$f-&lc-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!ri=ObiS%NNQ}MY@jehFcO=unTLTHD0T~on_74n*nspWAYR|j40fXu(5?;b zJPaUxNkI0-b|$b-ihyhoQ0$R=QQISK52GQXxXH*P^86p}#W;NJIDeVth?fIQB_r5p z>1JpFPQXY>zSVyKVS`NXYDw3!2ea~DqgR} z_6{t>H6qrcu%n?|DtPh2^Uzi z1(ll}Gqx}P5)>G=&}rQj4>c~qDUIjif@IbD>Qfod#U(IgpR(?_aOKNJ?kh>|0c-NU zMoHhW>g8G(m9SocW&7rg329F!Sk#48-)st1nh=m;rL4H^)1zn!6?;vcOQ-Y;wYO=D zbQ|($>1{URTr}yL>8YZqoeTN2qNXj};J2{uJvQ`$T=ix+dapXKgaxYom}Sd;N& z)US=}dV^dI?N4aQ9NF_y@Fin|Lh-pX*6XFNEYSbBCt$api1Cum7Cwh>ecEwi^II?L zo-CE`YtDx3XtOAK-Shv#s!P!Zww)yle(v74UG!D+3vC$-KSr5GM?D=sqJWYP8dV*mS1aH^jBmH W>K$Dr5-`!?BvZjl&5J!w4GjQ!s5wCZ literal 0 HcmV?d00001 diff --git a/tests/data/nccm/CDL2018_clip1.tif b/tests/data/nccm/CDL2018_clip1.tif new file mode 100644 index 0000000000000000000000000000000000000000..3313fef10d1de79f2e218ceb3e9fbd9855201f43 GIT binary patch literal 973 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!rigObiS%NNQ}MY@jehFcO=unTLTHD0T~on_74n*nspWAYR|j40fXu(5?;b zJPaUxNkI0-b|$b-ihyhoQ0$R=QQISK52GQXxXH*P^86p}#W;NJIDeVth?fIQB_r5p z>ZzhIF2%wT`;yZ{4_1Vcshy$L4@n79}! z?GL`!n8Cr!%W&v`{`Vg&G7MGBYWfB|Cm6+B8RQRW?mkwjJ9q!W%bvIYFq$^+X;6@q z*&-`Y?|gva`UK8Dd`le{=Kql3{VmnR>`+?K@=8~_?c^Fmhnl2YpI6*bEW5sBTO{+8 ziw8Gx%(2_?cjNID4xF_s*achMS5G+gbz7}^)3Jk-B>#N!Pp^+%Sd?YJZmhX{|C*xj z(}e68Hr-2}QdMTR?jz&=2j^dw1O@v|%2C|#eA#6oru|oUNWPSFQ`YHrdbjiS)$5sV zH!f_vQ5CB!ZeDrXxbi{C(U%QV5={kSmflnKntL{Hql_5W?(nXoPpr=5rX@N|J+V+h zWACA$DLed=Gajg}Htt(De^pe^w3V4bV#^nKeiAsm&EqiNCe@7Ywu6gL2BoZD((i1s za?^xMc}p3zK3B}O;+*(zq3TI4lQ+gEf6th@;X%@ajholKPU%p26(My}XNA#`lgC$h zf7-T~r~AxBjT15LY##Z^>kg>?PNma+1VfXUPT}d|-3yU)jnVsb-=2_(X zs&Cd3uFXd#nF^f_VL$2NWU6<*w`bWC#f_&o^E93gnel#s&l|g|ny+kjbz5szJ?l{N zQkr&V(HiD?|I~z~c1*PXvMAW!q3f}$$-+#fi_-3#m(&g2Ol7jBuFp7?$+GHX_K%*O zfq(YPUcNjh;;2FA;@v8`o~9{1TbBP$nzcVeHPq#l$1Slo#kadkmMzWB**4dLqiEH% W4GhWO^Fp^u#ob#HdP|IPfdT+A20}Fe literal 0 HcmV?d00001 diff --git a/tests/data/nccm/CDL2019_clip.tif b/tests/data/nccm/CDL2019_clip.tif new file mode 100644 index 0000000000000000000000000000000000000000..9c4d1dcae44475397ef013ec226a6772ace5d515 GIT binary patch literal 967 zcmebD)MDUZU|-qGR53%@tUxv!lnv4&$jAcLTLt8ZB8iJZ z*$O~4;!ridObiS%NNQ}MY@jehFcO=unTLTHD0T~on_74n*nspWAYR|j40fXu(5?;b zJPaUxNkI0-b|$b-ihyhoQ0$R=QQISK52GQXxXH*P^86p}#W;NJIDeVth?fIQB_r5p z>()Zg4;Ue&c#lpO~|XInnrqo*Ta+!v(#`uX!HbcAS=>=<6zq+Iy9 zG$`lq##KpbKN$Egv9+)1zI|t!O-Gc~q-|cWjR50L$7%I@w-*2ePHv zn$$I_H{5jVy(Mx`sq@iNZc|R>*~XfyxmxyY%&|GMy0QQ8w)V3Vuee-M+<3>@Yk8K^ zf<}jxMxPq3S1vm5wm3h^U?yitlmtfJfE5X58VRHl5ukGq&2srZQ-ooClU7e@1s^lJcG!#vlb5d^!*GxT+ NV1{F=g+JsP8UR!XJAwcJ literal 0 HcmV?d00001 diff --git a/tests/data/nccm/data.py b/tests/data/nccm/data.py index 6a98ca3a2d0..2956f147033 100644 --- a/tests/data/nccm/data.py +++ b/tests/data/nccm/data.py @@ -5,7 +5,6 @@ import hashlib import os -import shutil import numpy as np import rasterio @@ -48,20 +47,14 @@ def create_file(path: str, dtype: str): if __name__ == "__main__": - dir = os.path.join(os.getcwd(), "13090442") - - if os.path.exists(dir) and os.path.isdir(dir): - shutil.rmtree(dir) - + dir = os.path.join(os.getcwd()) os.makedirs(dir, exist_ok=True) for file in files: create_file(os.path.join(dir, file), dtype="int8") - # Compress data - shutil.make_archive("13090442", "zip", ".", dir) - # Compute checksums - with open("13090442.zip", "rb") as f: - md5 = hashlib.md5(f.read()).hexdigest() - print(f"13090442.zip: {md5}") + for file in files: + with open(file, "rb") as f: + md5 = hashlib.md5(f.read()).hexdigest() + print(f"{file}: {md5}") diff --git a/tests/datasets/test_nccm.py b/tests/datasets/test_nccm.py index 6637da3e840..0d922d9d3d5 100644 --- a/tests/datasets/test_nccm.py +++ b/tests/datasets/test_nccm.py @@ -25,9 +25,19 @@ class TestNCCM: @pytest.fixture def dataset(self, monkeypatch: MonkeyPatch, tmp_path: Path) -> NCCM: monkeypatch.setattr(torchgeo.datasets.nccm, "download_url", download_url) - url = os.path.join("tests", "data", "nccm", "13090442.zip") + md5s = { + 2017: "ae5c390d0ffb8970d544b8a09142759f", + 2018: "0d453bdb8ea5b7318c33e62513760580", + 2019: "d4ab7ab00bb57623eafb6b27747e5639", + } + monkeypatch.setattr(NCCM, "md5s", md5s) + urls = { + 2017: os.path.join("tests", "data", "nccm", "CDL2017_clip.tif"), + 2018: os.path.join("tests", "data", "nccm", "CDL2018_clip1.tif"), + 2019: os.path.join("tests", "data", "nccm", "CDL2019_clip.tif"), + } + monkeypatch.setattr(NCCM, "urls", urls) transforms = nn.Identity() - monkeypatch.setattr(NCCM, "url", url) root = str(tmp_path) return NCCM(root, transforms=transforms, download=True, checksum=True) @@ -48,11 +58,8 @@ def test_or(self, dataset: NCCM) -> None: def test_already_extracted(self, dataset: NCCM) -> None: NCCM(dataset.paths, download=True) - def test_already_downloaded(self, tmp_path: Path) -> None: - pathname = os.path.join("tests", "data", "nccm", "13090442.zip") - root = str(tmp_path) - shutil.copy(pathname, root) - NCCM(root) + def test_already_downloaded(self, dataset: NCCM) -> None: + NCCM(dataset.paths, download=True) def test_plot(self, dataset: NCCM) -> None: query = dataset.bounds diff --git a/torchgeo/datasets/nccm.py b/torchgeo/datasets/nccm.py index 3a43ddddcc5..38a0d3eee91 100644 --- a/torchgeo/datasets/nccm.py +++ b/torchgeo/datasets/nccm.py @@ -3,8 +3,6 @@ """Northeastern China Crop Map Dataset.""" -import glob -import os from collections.abc import Iterable from typing import Any, Callable, Optional, Union @@ -14,7 +12,7 @@ from rasterio.crs import CRS from .geo import RasterDataset -from .utils import BoundingBox, DatasetNotFoundError, download_url, extract_archive +from .utils import BoundingBox, DatasetNotFoundError, download_url class NCCM(RasterDataset): @@ -55,12 +53,24 @@ class NCCM(RasterDataset): filename_regex = r"CDL(?P\d{4})_clip" filename_glob = "CDL*.*" - zipfile_glob = "13090442.zip" date_format = "%Y" is_image = False - url = "https://figshare.com/ndownloader/articles/13090442/versions/1" - md5 = "eae952f1b346d7e649d027e8139a76f5" + urls = { + 2019: "https://figshare.com/ndownloader/files/25070540", + 2018: "https://figshare.com/ndownloader/files/25070624", + 2017: "https://figshare.com/ndownloader/files/25070582", + } + md5s = { + 2019: "0d062bbd42e483fdc8239d22dba7020f", + 2018: "b3bb4894478d10786aa798fb11693ec1", + 2017: "d047fbe4a85341fa6248fd7e0badab6c", + } + fnames = { + 2019: "CDL2019_clip.tif", + 2018: "CDL2018_clip1.tif", + 2017: "CDL2017_clip.tif", + } cmap = { 0: (0, 255, 0, 255), @@ -75,6 +85,7 @@ def __init__( paths: Union[str, Iterable[str]] = "data", crs: Optional[CRS] = None, res: Optional[float] = None, + years: list[int] = [2019], transforms: Optional[Callable[[dict[str, Any]], dict[str, Any]]] = None, cache: bool = True, download: bool = False, @@ -88,6 +99,7 @@ def __init__( (defaults to the CRS of the first file found) res: resolution of the dataset in units of CRS (defaults to the resolution of the first file found) + years: list of years for which to use nccm layers transforms: a function/transform that takes an input sample and returns a transformed version cache: if True, cache file handle to speed up repeated sampling @@ -97,7 +109,12 @@ def __init__( Raises: DatasetNotFoundError: If dataset is not found and *download* is False. """ + assert set(years) <= self.md5s.keys(), ( + "NCCM data product only exists for the following years: " + f"{list(self.md5s.keys())}." + ) self.paths = paths + self.years = years self.download = download self.checksum = checksum self.ordinal_map = torch.full((max(self.cmap.keys()) + 1,), 4, dtype=self.dtype) @@ -128,37 +145,26 @@ def __getitem__(self, query: BoundingBox) -> dict[str, Any]: def _verify(self) -> None: """Verify the integrity of the dataset.""" - # Check if the extracted files already exist + # Check if the files already exist if self.files: return - # Check if the zip file has already been downloaded - assert isinstance(self.paths, str) - pathname = os.path.join(self.paths, "**", self.zipfile_glob) - if glob.glob(pathname, recursive=True): - self._extract() - return - # Check if the user requested to download the dataset if not self.download: raise DatasetNotFoundError(self) # Download the dataset self._download() - self._extract() def _download(self) -> None: """Download the dataset.""" - filename = "13090442.zip" - download_url( - self.url, self.paths, filename, md5=self.md5 if self.checksum else None - ) - - def _extract(self) -> None: - """Extract the dataset.""" - assert isinstance(self.paths, str) - pathname = os.path.join(self.paths, "**", self.zipfile_glob) - extract_archive(glob.glob(pathname, recursive=True)[0], self.paths) + for year in self.years: + download_url( + self.urls[year], + self.paths, + filename=self.fnames[year], + md5=self.md5s[year] if self.checksum else None, + ) def plot( self,