From ccd51d40ed6630f7fdc064812c0d2ae1e13c8958 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Tue, 18 Apr 2023 12:20:07 +0200 Subject: [PATCH 01/14] allow direct input of --- ldndctools/cli/selector.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ldndctools/cli/selector.py b/ldndctools/cli/selector.py index 4d125b0..61c31d4 100644 --- a/ldndctools/cli/selector.py +++ b/ldndctools/cli/selector.py @@ -220,14 +220,18 @@ def ask(self): class CoordinateSelection: - def __init__(self, infile, lon_col="lon", lat_col="lat", id_col="ID"): - df = pd.read_csv(infile, delim_whitespace=True) - - self.lons = df[lon_col].values - self.lats = df[lat_col].values - self.ids = ( - df[id_col].values if id_col in list(df.columns) else range(len(self.lats)) - ) + + def __init__(self, infile=None, lon="lon", lat="lat", cid="ID"): + if infile: + df = pd.read_csv(infile, delim_whitespace=True) + + self.lons = df[lon].values + self.lats = df[lat].values + self.ids = df[cid].values if cid in list(df.columns) else range(len(self.lats)) + else: + self.lons = [lon] + self.lats = [lat] + self.ids = [cid] @property def selected(self): From 18f618d1b206fa07412aca24b535ec7b35eb3d96 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Tue, 18 Apr 2023 12:25:19 +0200 Subject: [PATCH 02/14] add arguments to main function --- ldndctools/dlsc.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/ldndctools/dlsc.py b/ldndctools/dlsc.py index d300c3c..27624c8 100755 --- a/ldndctools/dlsc.py +++ b/ldndctools/dlsc.py @@ -41,12 +41,17 @@ DPATH = Path(dpath) -def main(): +def main( **kwargs): # parse args args = cli() # read config - cfg = get_config(args.config) + if 'config' in kwargs: + cfg = kwargs['config'] + for k,v in cfg.items(): + setattr(args, k, v) + else: + cfg = get_config(args.config) # write config if args.storeconfig: @@ -81,7 +86,10 @@ def main(): bbox = None if args.bbox: - x1, y1, x2, y2 = [float(x) for x in args.bbox.split(",")] + if type( args.bbox) == list: + x1, y1, x2, y2 = args.bbox + else: + x1, y1, x2, y2 = [float(x) for x in args.bbox.split(",")] try: bbox = BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2) except ValidationError: From 975242289f18d46ecbc7a5f18a1dff2bfff8f065 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Tue, 18 Apr 2023 12:26:37 +0200 Subject: [PATCH 03/14] change log message --- ldndctools/extra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldndctools/extra.py b/ldndctools/extra.py index 64c176a..cfba563 100644 --- a/ldndctools/extra.py +++ b/ldndctools/extra.py @@ -91,7 +91,7 @@ def cfgfile_exists(cfgFile): cfgFile = _find_config() if not cfgfile_exists(cfgFile): - log.info("Copying config file") + log.info("Copying default config file") _copy_default_config() cfgFile = _find_config() From 3b9350c967712f53f36d15410a0f160db210eee2 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Tue, 18 Apr 2023 12:29:19 +0200 Subject: [PATCH 04/14] allow d selection --- ldndctools/io/xmlwriter.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ldndctools/io/xmlwriter.py b/ldndctools/io/xmlwriter.py index f0bc6ca..f67b2bf 100644 --- a/ldndctools/io/xmlwriter.py +++ b/ldndctools/io/xmlwriter.py @@ -71,9 +71,9 @@ def write( if status_widget: status_widget.warning("Preparing data") - if not all(v is None for v in [sample, id_selection, coords]): - # options currently not implemented - raise NotImplementedError + #if not all(v is None for v in [sample, id_selection, coords]): + # # options currently not implemented + # raise NotImplementedError ids: xr.DataArray = xr.zeros_like(self.mask, dtype=np.int32) @@ -91,7 +91,10 @@ def write( lat=self.soil.coords["lat"][j].values.item(), lon=self.soil.coords["lon"][i].values.item(), ) - # print(cid) + if id_selection: + if cid not in id_selection: + continue + ids[j, i] = cid Lcids.append(cid) Lix.append(i) From 288099ef712e51d2eae5430a311271517749fee3 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Tue, 18 Apr 2023 14:09:06 +0200 Subject: [PATCH 05/14] create bounding box from lat/lon pair --- ldndctools/dlsc.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ldndctools/dlsc.py b/ldndctools/dlsc.py index 27624c8..fc62101 100755 --- a/ldndctools/dlsc.py +++ b/ldndctools/dlsc.py @@ -85,6 +85,10 @@ def main( **kwargs): res = RES[args.resolution] bbox = None + + if ('lat' in args) and ('lon' in args): + setattr(args, 'bbox', [float(args.lon-0.5), float(args.lat-0.5), float(args.lon+0.5), float(args.lat+0.5)]) + log.info("Creating bounding box for coordinates specified.") if args.bbox: if type( args.bbox) == list: x1, y1, x2, y2 = args.bbox @@ -93,9 +97,9 @@ def main( **kwargs): try: bbox = BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2) except ValidationError: - print("Ilegal bounding box coordinates specified.") - print("required: x1,y1,x2,y2 [cond: x1 Date: Tue, 18 Apr 2023 14:38:40 +0200 Subject: [PATCH 06/14] create site input for slected coordinate only --- ldndctools/dlsc.py | 2 +- ldndctools/misc/create_data.py | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ldndctools/dlsc.py b/ldndctools/dlsc.py index fc62101..e9bf634 100755 --- a/ldndctools/dlsc.py +++ b/ldndctools/dlsc.py @@ -156,7 +156,7 @@ def main( **kwargs): log.info(selector.selected) with tqdm(total=1) as progressbar: - xml, nc = create_dataset(soil, selector, res, progressbar) + xml, nc = create_dataset(soil, selector, res, args, progressbar) open(cfg["outname"], "w").write(xml) ENCODING = { diff --git a/ldndctools/misc/create_data.py b/ldndctools/misc/create_data.py index 98d6dc2..3aaf10d 100644 --- a/ldndctools/misc/create_data.py +++ b/ldndctools/misc/create_data.py @@ -1,19 +1,25 @@ from typing import Any, Optional, Union +import logging import numpy as np import rioxarray # noqa import xarray as xr +from ldndctools.misc.geohash import coords2geohash_dec from ldndctools.cli.selector import CoordinateSelection, Selector from ldndctools.io.xmlwriter import SiteXmlWriter from ldndctools.misc.types import RES from ldndctools.sources.soil.soil_base import SoilDataset +log = logging.getLogger(__name__) + +log.setLevel("DEBUG") def create_dataset( soil: SoilDataset, selector: Union[Selector, CoordinateSelection], res: RES, + args, progressbar: Optional[Any] = None, status_widget: Optional[Any] = None, ): @@ -21,9 +27,9 @@ def create_dataset( # soil = soil.rio.write_crs(4326) if isinstance(selector, Selector): - print("Using Selector") + log.info("Using Selector") if selector.gdf_mask is None: - print("No valid data to process for this region/ bbox request.") + log.info("No valid data to process for this region/ bbox request.") exit(1) # clip region selection @@ -36,7 +42,12 @@ def create_dataset( soil.clip_mask(selector.gdf_mask.geometry, all_touched=True) xmlwriter = SiteXmlWriter(soil, res=res) - site_xml = xmlwriter.write(progressbar=progressbar, status_widget=status_widget) + if ('lat' in args) and ('lon' in args): + sel = soil._soil.sel(lat=args.lat, lon=args.lon, method='nearest') + cid = coords2geohash_dec( lat=sel["lat"].values.item(), lon=sel["lon"].values.item()) + site_xml = xmlwriter.write(progressbar=progressbar, status_widget=status_widget, id_selection=[cid]) + else: + site_xml = xmlwriter.write(progressbar=progressbar, status_widget=status_widget) else: # WARNING: THIS BRANCH IS DEFUNCT!!! From a86fdf084f031ba65f734f3f802869507784482a Mon Sep 17 00:00:00 2001 From: David Kraus Date: Wed, 19 Apr 2023 13:08:06 +0200 Subject: [PATCH 07/14] update requirements --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 96988a1..d5071bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,10 +2,10 @@ aiohttp >= 3.8.1 boto3 >= 1.20.49 dask[distributed] >= 2022.2.0 geopandas >= 0.10.2 -git+https://github.com/rasterio/rasterio.git +rasterio #cython >= 0.29.22 #cytoolz >= 0.11.2 -git+https://github.com/Toblerity/Fiona.git # required for 3.10 compat +fiona intake >= 0.6.5 intake-geopandas >= 0.4.0 intake-xarray >= 0.6.0 From a7642725023eafcef3f9b845646f63c8b90a427d Mon Sep 17 00:00:00 2001 From: David Kraus Date: Wed, 19 Apr 2023 15:44:17 +0200 Subject: [PATCH 08/14] change log level to info --- ldndctools/dlsc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ldndctools/dlsc.py b/ldndctools/dlsc.py index e9bf634..f8f4198 100755 --- a/ldndctools/dlsc.py +++ b/ldndctools/dlsc.py @@ -30,8 +30,7 @@ from ldndctools.sources.soil.soil_iscricwise import ISRICWISE_SoilDataset log = logging.getLogger(__name__) - -log.setLevel("DEBUG") +log.setLevel("INFO") NODATA = "-99.99" From 3fbfd3f30051417132b0f07af864fd4bcdfea166 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Thu, 20 Apr 2023 14:05:09 +0200 Subject: [PATCH 09/14] continue testing if Pytest coverage comment fails --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70c9793..556717f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,7 @@ jobs: pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=ldndctools tests/ | tee pytest-coverage.txt - name: Pytest coverage comment + continue-on-error: true uses: MishaKav/pytest-coverage-comment@main if: ${{ matrix.python-version == '3.10' }} with: From 83c5fe3ed3352de6d59c10f00eff9013a03fddf6 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Fri, 9 Feb 2024 11:40:05 +0100 Subject: [PATCH 10/14] allow dask for lazy data --- ldndctools/cdgen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ldndctools/cdgen.py b/ldndctools/cdgen.py index f9e8430..7dbe92e 100644 --- a/ldndctools/cdgen.py +++ b/ldndctools/cdgen.py @@ -161,7 +161,7 @@ def inner_func(x, lat, lon): def geohash_xr(mask: xr.DataArray) -> xr.DataArray: lon_xr = mask.lon.broadcast_like(mask) lat_xr = mask.lat.broadcast_like(mask) - data = xr.apply_ufunc(inner_func, mask, lat_xr, lon_xr, output_dtypes=[np.int64]) + data = xr.apply_ufunc(inner_func, mask, lat_xr, lon_xr, output_dtypes=[np.int64], dask="allowed") assert data.dtype == np.int64 return data From cc0d2e3e5df9b6c2dd6c67d1dcfa157b3b3236eb Mon Sep 17 00:00:00 2001 From: David Kraus Date: Fri, 9 Feb 2024 11:40:48 +0100 Subject: [PATCH 11/14] replace root_validator by model_validator --- ldndctools/misc/types.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/ldndctools/misc/types.py b/ldndctools/misc/types.py index ced5896..74a290e 100644 --- a/ldndctools/misc/types.py +++ b/ldndctools/misc/types.py @@ -2,7 +2,7 @@ from enum import Enum from typing import Optional -from pydantic import BaseModel, confloat, conint, root_validator, ValidationError +from pydantic import BaseModel, confloat, conint, model_validator, ValidationError from pydantic.dataclasses import dataclass from pydantic.json import pydantic_encoder @@ -40,17 +40,15 @@ class BoundingBox: y1: confloat(ge=-90, le=90) = -90 y2: confloat(ge=-90, le=90) = 90 - @root_validator(allow_reuse=True) + @model_validator(mode='after') def check_x1_smaller_x2(cls, values): - x1, x2 = values.get("x1"), values.get("x2") - if x1 >= x2: + if values.x1 >= values.x2: raise ValidationError("x1 must be smaller x2") return values - @root_validator(allow_reuse=True) + @model_validator(mode='after') def check_y1_smaller_y2(cls, values): - y1, y2 = values.get("y1"), values.get("y2") - if y1 >= y2: + if values.y1 >= values.y2: raise ValidationError("y1 must be smaller y2") return values @@ -97,7 +95,7 @@ class LayerData(BaseModel): class Config: validate_assignment = True - # @root_validator + # @model_validator # def check_wcmin_smaller_wcmax(cls, values): # wcmin, wcmax = values.get("wcmin"), values.get("wcmax") # if None not in [wcmin, wcmax]: @@ -105,7 +103,7 @@ class Config: # raise ValidationError("wcmin must be smaller wcmax") # return values - @root_validator(allow_reuse=True) + #@model_validator(mode='after') def check_texture_is_plausible(cls, values): sand, silt, clay = values.get("sand"), values.get("silt"), values.get("clay") args = [a for a in [sand, silt, clay] if a is not None] From 792a9fb8e8d677c772920fbc1b09c60415bed850 Mon Sep 17 00:00:00 2001 From: David Kraus Date: Fri, 9 Feb 2024 11:43:24 +0100 Subject: [PATCH 12/14] update catalog: port, ignore metadata --- data/catalog.yml | 13 +++++++------ ldndctools/misc/create_data.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/data/catalog.yml b/data/catalog.yml index fab0c3d..f729ce0 100644 --- a/data/catalog.yml +++ b/data/catalog.yml @@ -21,7 +21,8 @@ sources: anon: true default_fill_cache: false client_kwargs: - endpoint_url: 'https://s3.imk-ifu.kit.edu:8082' + endpoint_url: 'https://s3.imk-ifu.kit.edu:10443' + verify: False simplecache: cache_storage: '.cache' same_names: true @@ -63,7 +64,7 @@ sources: anon: true default_fill_cache: false client_kwargs: - endpoint_url: 'https://s3.imk-ifu.kit.edu:8082' + endpoint_url: 'https://s3.imk-ifu.kit.edu:10443' simplecache: cache_storage: '.cache' same_names: true @@ -73,12 +74,12 @@ sources: driver: zarr args: urlpath: 's3://era5land-zarr/data.zarr' - consolidated: True + consolidated: False storage_options: - use_ssl: False + use_ssl: True anon: True client_kwargs: - endpoint_url: 'https://s3.imk-ifu.kit.edu:8082' + endpoint_url: 'https://s3.imk-ifu.kit.edu:10443' verify: False @@ -100,7 +101,7 @@ sources: anon: true default_fill_cache: false client_kwargs: - endpoint_url: 'https://s3.imk-ifu.kit.edu:8082' + endpoint_url: 'https://s3.imk-ifu.kit.edu:10443' simplecache: cache_storage: '.cache' same_names: true diff --git a/ldndctools/misc/create_data.py b/ldndctools/misc/create_data.py index 3aaf10d..780644a 100644 --- a/ldndctools/misc/create_data.py +++ b/ldndctools/misc/create_data.py @@ -22,7 +22,7 @@ def create_dataset( args, progressbar: Optional[Any] = None, status_widget: Optional[Any] = None, -): + ): # soil = soil.load() # soil = soil.rio.write_crs(4326) From 92f573f395fb29d6b50e0f3421f53a33b8d1c72d Mon Sep 17 00:00:00 2001 From: Kraus Date: Thu, 22 May 2025 11:30:02 +0200 Subject: [PATCH 13/14] add examples --- data/catalog.yml | 29 ++++++++- data/ldndctools.conf | 4 +- examples/examples.conf | 26 ++++++++ examples/readme.txt | 2 + ldndctools/cdgen.py | 30 ++++++++- ldndctools/cli/cli.py | 2 +- ldndctools/dlsc.py | 97 ++++++++++++++++------------ ldndctools/misc/create_data.py | 17 ++++- ldndctools/misc/types.py | 2 +- ldndctools/sources/soil/soil_base.py | 8 +-- 10 files changed, 159 insertions(+), 58 deletions(-) create mode 100644 examples/examples.conf create mode 100644 examples/readme.txt diff --git a/data/catalog.yml b/data/catalog.yml index f729ce0..c7a0654 100644 --- a/data/catalog.yml +++ b/data/catalog.yml @@ -4,6 +4,30 @@ plugins: - module: intake_geopandas sources: + + soil_national: + name: 'SOIL national' + description: 'Default soil data for ldndctools (site file generation)' + driver: netcdf + parameters: + res: + default: 'LR' + allowed: ['LR', 'MR', 'HR'] + description: 'Resolution (LR, MR or HR).' + type: str + args: + urlpath: 'simplecache::s3://ldndcdata/GLOBAL_WISESOIL_S1_{{res}}.nc' + storage_options: + s3: + anon: true + default_fill_cache: false + client_kwargs: + endpoint_url: 'https://s3.imk-ifu.kit.edu:{{port}}' + verify: False + simplecache: + cache_storage: '.cache' + same_names: true + soil: name: 'SOIL' description: 'Default soil data for ldndctools (site file generation)' @@ -21,7 +45,7 @@ sources: anon: true default_fill_cache: false client_kwargs: - endpoint_url: 'https://s3.imk-ifu.kit.edu:10443' + endpoint_url: 'https://s3.imk-ifu.kit.edu:{{port}}' verify: False simplecache: cache_storage: '.cache' @@ -40,7 +64,7 @@ sources: description: 'Resolution (10, 50 or 110m).' type: int args: - urlpath: 'simplecache::https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/{{scale}}m/cultural/ne_{{scale}}m_admin_0_countries.zip' + urlpath: '/Users/kraus-d/projects/ldndctools-kraus/data/ne_50m_admin_0_countries.zip' use_fsspec: True storage_options: simplecache: @@ -74,7 +98,6 @@ sources: driver: zarr args: urlpath: 's3://era5land-zarr/data.zarr' - consolidated: False storage_options: use_ssl: True anon: True diff --git a/data/ldndctools.conf b/data/ldndctools.conf index 603455b..6557650 100644 --- a/data/ldndctools.conf +++ b/data/ldndctools.conf @@ -4,8 +4,8 @@ # author info info: - author: Christian Werner - email: christian.werner@kit.edu + author: David Kraus + email: david.kraus@kit.edu institution: IMK-IFU, Karlsruhe Institut of Technology, Garmisch-Partenkirchen, Germany # project info diff --git a/examples/examples.conf b/examples/examples.conf new file mode 100644 index 0000000..8d66824 --- /dev/null +++ b/examples/examples.conf @@ -0,0 +1,26 @@ +# default ldndctools.conf file +# +# + +# author info +info: + author: David Kraus + email: david.kraus@kit.edu + +# project info +project: + dataset: test + version: 0.1 + source: IMK-IFU, KIT + +soil: national +output: file #stream +outfile: test_out.xml +bbox: 44,44,45,45 +gui: False +file: None +interactive: False +resolution: 'HR' #LR +rcode: None +storeconfig: False +verbose: False diff --git a/examples/readme.txt b/examples/readme.txt new file mode 100644 index 0000000..c5032aa --- /dev/null +++ b/examples/readme.txt @@ -0,0 +1,2 @@ +Run on your terminal: +dlsc -c examples.conf \ No newline at end of file diff --git a/ldndctools/cdgen.py b/ldndctools/cdgen.py index 7dbe92e..e87a1a2 100644 --- a/ldndctools/cdgen.py +++ b/ldndctools/cdgen.py @@ -14,7 +14,7 @@ import pandas as pd import urllib3 import xarray as xr -from dask.distributed import Client +from dask.distributed import LocalCluster, Client from pydantic import ValidationError from ldndctools.misc.geohash import coords2geohash_dec @@ -50,9 +50,22 @@ def subset_climate_data( with resources.path("data", "catalog.yml") as cat: catalog = intake.open_catalog(str(cat)) + #load the data into a Dask Dataset ds = catalog["climate_era5land_hr"].to_dask() - + ds = xr.open_zarr( + store="s3://era5land-zarr/data.zarr", + consolidated=True, + storage_options={ + "anon": True, + "client_kwargs": { + "endpoint_url": "https://s3.imk-ifu.kit.edu:10443", + "verify": False + }, + "use_ssl": True, + }, + ) if mask is not None: + #match the latitude and longitude coordinates of ds mask = mask.interp(lat=ds["lat"], lon=ds["lon"]) ds = ds.where(mask>0) @@ -249,7 +262,14 @@ def conf(): def main(): - client = Client(dashboard_address=":1234") + + # Create a LocalCluster with 2 workers and set the dashboard address + cluster = LocalCluster(n_workers=2, memory_limit="2GB", dashboard_address=":1234") + + # Connect a Client to the LocalCluster + client = Client(cluster) + + #client = Client(dashboard_address=":1234") print(f"NOTE: You can see progress at {platform.node()}:1234 if bokeh is installed") @@ -258,6 +278,7 @@ def main(): bbox = get_boundingbox(args.bbox) mask = get_mask(args.mask) + print("subset climate") # mask = xr.open_dataset("VN_MISC5_V2.nc")["rice_rot"] # mask = xr.where(mask > 0, 1, np.nan) ds = subset_climate_data( @@ -268,6 +289,7 @@ def main(): date_max=args.date_max, ) + print("group") tavg_year = ds.tavg.groupby("time.year").mean(dim="time").mean(dim="year") tamp_year = ds.tavg.groupby("time.year").apply(amplitude).mean(dim="year") prec_year = ds.prec.groupby("time.year").sum(dim="time").mean(dim="year") @@ -307,6 +329,7 @@ def main(): # match coords (usually means take lat/ lon from ref dataset) ds = ds.assign_coords({"lat": stats.lat, "lon": stats.lon}) + print("df stats") df_stats = ( stats.to_dataframe() .dropna(subset=["tavg", "tamp", "wind"], how="all") @@ -314,6 +337,7 @@ def main(): ) # ignore prec for now + print("lookup") lookup: Dict[int, ClimateSiteStats] = {} for _, row in df_stats.iterrows(): lookup[int(row["geohash"])] = ClimateSiteStats( diff --git a/ldndctools/cli/cli.py b/ldndctools/cli/cli.py index c71bf61..4feb956 100644 --- a/ldndctools/cli/cli.py +++ b/ldndctools/cli/cli.py @@ -28,7 +28,7 @@ def __call__(self, parser, namespace, values=None, option_string=None): handlers = logging.getLogger().handlers for handler in handlers: if type(handler) is logging.StreamHandler: - handler.setLevel(logging.DEBUG) + handler.setLevel(logging.INFO) setattr(namespace, self.dest, True) diff --git a/ldndctools/dlsc.py b/ldndctools/dlsc.py index f8f4198..ed5528c 100755 --- a/ldndctools/dlsc.py +++ b/ldndctools/dlsc.py @@ -28,6 +28,7 @@ from ldndctools.misc.create_data import create_dataset from ldndctools.misc.types import BoundingBox, RES from ldndctools.sources.soil.soil_iscricwise import ISRICWISE_SoilDataset +from ldndctools.sources.soil.soil_national import NATIONAL_SoilDataset log = logging.getLogger(__name__) log.setLevel("INFO") @@ -36,8 +37,8 @@ # TODO: there has to be a better way here... # also, tqdm takes no effect -with resources.path("data", "") as dpath: - DPATH = Path(dpath) +#with resources.path("data", "") as dpath: +# DPATH = Path(dpath) def main( **kwargs): @@ -47,14 +48,13 @@ def main( **kwargs): # read config if 'config' in kwargs: cfg = kwargs['config'] - for k,v in cfg.items(): - setattr(args, k, v) else: cfg = get_config(args.config) # write config - if args.storeconfig: - set_config(cfg) + #if args.storeconfig: + # set_config(cfg) + # def _get_cfg_item(group, item, save="na"): # return cfg[group].get(item, save) @@ -69,9 +69,12 @@ def main( **kwargs): # SOURCE=_get_cfg_item("project", "source"), # ) - if (args.rcode is not None) or (args.file is not None): + if False: #(args.rcode is not None) or (args.file is not None): log.info("Non-interactive mode...") cfg["interactive"] = False + else: + pass + #log.info("Interactive mode...") # query environment or command flags for selection (non-interactive mode) args.rcode = os.environ.get("DLSC_REGION", args.rcode) @@ -81,18 +84,20 @@ def main( **kwargs): log.error(f"Wrong resolution: {args.resolution}. Use HR, MR or LR.") exit(-1) - res = RES[args.resolution] + res = RES[cfg["resolution"]] - bbox = None - if ('lat' in args) and ('lon' in args): - setattr(args, 'bbox', [float(args.lon-0.5), float(args.lat-0.5), float(args.lon+0.5), float(args.lat+0.5)]) + bbox = None + if ('lat' in cfg) and ('lon' in cfg): + cfg['bbox'] = [float(cfg["lon"]-1.0), float(cfg["lat"]-1.0), + float(cfg["lon"]+1.0), float(cfg["lat"]+1.0)] log.info("Creating bounding box for coordinates specified.") - if args.bbox: - if type( args.bbox) == list: - x1, y1, x2, y2 = args.bbox - else: - x1, y1, x2, y2 = [float(x) for x in args.bbox.split(",")] + + if cfg["bbox"]: + if type( cfg["bbox"]) == list: + x1, y1, x2, y2 = cfg["bbox"] + else: + x1, y1, x2, y2 = [float(x) for x in cfg["bbox"].split(",")] try: bbox = BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2) except ValidationError: @@ -100,19 +105,16 @@ def main( **kwargs): log.info("required: x1,y1,x2,y2 [cond: x1 0: + found = True + delta += 0.1 + if delta > 10: + log.info("No valid data to process for this region/ bbox request.") + exit(1) + cid = coords2geohash_dec( lat=sel["lat"].values.item(), lon=sel["lon"].values.item()) site_xml = xmlwriter.write(progressbar=progressbar, status_widget=status_widget, id_selection=[cid]) else: site_xml = xmlwriter.write(progressbar=progressbar, status_widget=status_widget) else: + log.info("Incorrect selector.") + exit(1) # WARNING: THIS BRANCH IS DEFUNCT!!! soil.clip_mask_box( minx=min(selector.lons), diff --git a/ldndctools/misc/types.py b/ldndctools/misc/types.py index 74a290e..95a00f8 100644 --- a/ldndctools/misc/types.py +++ b/ldndctools/misc/types.py @@ -56,7 +56,7 @@ def check_y1_smaller_y2(cls, values): NODATA = -99.99 -# map from isiric-wise fields and units to ldndc +# map from isric-wise fields and units to ldndc # ldndcname, conversion, significant digits nmap = { "TOTC": ("corg", 0.001, 5), diff --git a/ldndctools/sources/soil/soil_base.py b/ldndctools/sources/soil/soil_base.py index abd112f..c0356c5 100644 --- a/ldndctools/sources/soil/soil_base.py +++ b/ldndctools/sources/soil/soil_base.py @@ -85,10 +85,6 @@ def mask(self) -> Union[xr.DataArray, None]: @property def mask_3d(self) -> xr.DataArray: """return 3d mask to clip soildata""" - lev_max_idx = self.layer_mask.max(skipna=True).astype(int).item() - mask = (self.layer_mask.values >= np.arange(lev_max_idx)[:, None, None]).astype( - int - ) for v in self.original.data_vars: if len(self.original[v].squeeze(drop=True).shape) == 3: @@ -100,6 +96,10 @@ def mask_3d(self) -> xr.DataArray: mask_3d = xr.ones_like( self.original[v].sel(lat=self.layer_mask.lat, lon=self.layer_mask.lon) ) + + lev_max_idx = np.shape(mask_3d)[0] #self.layer_mask.max(skipna=True).astype(int).item() + mask = (self.layer_mask.values >= np.arange(lev_max_idx)[:, None, None]).astype(int) + mask_3d[:] = mask mask_3d = mask_3d.where(mask_3d == 1) return mask_3d From 42069ecdd8b63764ea6752307b3a4d22270582db Mon Sep 17 00:00:00 2001 From: Kraus Date: Thu, 22 May 2025 11:35:49 +0200 Subject: [PATCH 14/14] add documentation --- examples/examples.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/examples.conf b/examples/examples.conf index 8d66824..5090c3b 100644 --- a/examples/examples.conf +++ b/examples/examples.conf @@ -16,11 +16,11 @@ project: soil: national output: file #stream outfile: test_out.xml -bbox: 44,44,45,45 +bbox: 105,28,106,29 #[lon1,lat1,lon2,lat2] gui: False file: None interactive: False -resolution: 'HR' #LR +resolution: 'LR' #HR rcode: None storeconfig: False verbose: False