From 423705cb6af94048b9893927c2ec2772f263956d Mon Sep 17 00:00:00 2001 From: James Varndell Date: Thu, 16 Jul 2026 14:07:56 +0100 Subject: [PATCH 1/3] Tweaks to default zorders --- src/earthkit/plots/data/styles/schema.yml | 7 ++++ src/earthkit/plots/resample/reproject.py | 40 +++++++++++------------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/earthkit/plots/data/styles/schema.yml b/src/earthkit/plots/data/styles/schema.yml index a07eefa3..5968163d 100644 --- a/src/earthkit/plots/data/styles/schema.yml +++ b/src/earthkit/plots/data/styles/schema.yml @@ -187,10 +187,12 @@ coastlines: linewidth: 0.75 edgecolor: "#555555" facecolor: none + zorder: 2 borders: linewidth: 0.5 edgecolor: "#999999" facecolor: none + zorder: 1 special_styles: - key: BRK_A3 values: ["B57"] @@ -211,17 +213,20 @@ unit_boundaries: linewidth: 0.5 edgecolor: [0.3, 0.3, 0.3] facecolor: none + zorder: 1 disputed_boundaries: linestyle: [0, [5, 1]] linewidth: 0.5 edgecolor: [0.75, 0.2, 0.2] facecolor: none + zorder: 1 administrative_areas: linestyle: "-" linewidth: 0.25 edgecolor: [0.6, 0.6, 0.6] resolution: high facecolor: none + zorder: 1 roads: linestyle: "-" linewidth: 0.5 @@ -237,9 +242,11 @@ ocean: color: "#f9f9f9" rivers: edgecolor: "#97B6E1" + zorder: 1 lakes: facecolor: "#A5D5F2" edgecolor: "#97B6E1" + zorder: 1 shapes: facecolor: steelblue linewidth: 0.5 diff --git a/src/earthkit/plots/resample/reproject.py b/src/earthkit/plots/resample/reproject.py index 47d9d8b6..e21f94ae 100644 --- a/src/earthkit/plots/resample/reproject.py +++ b/src/earthkit/plots/resample/reproject.py @@ -14,7 +14,7 @@ ) HAS_CUPY = True - logger.info("CuPy detected - GPU acceleration available for reprojection") + logger.debug("CuPy detected - GPU acceleration available for reprojection") except ImportError: cp = None CuPyRegularGridInterpolator = None @@ -37,7 +37,7 @@ def enable_gpu_acceleration(): global USE_GPU if HAS_CUPY: USE_GPU = True - logger.info("GPU acceleration ENABLED for reprojection") + logger.debug("GPU acceleration ENABLED for reprojection") else: logger.warning("GPU acceleration requested but CuPy is not available. Install cupy to enable GPU support.") @@ -46,7 +46,7 @@ def disable_gpu_acceleration(): """Disable GPU acceleration for reprojection (use CPU).""" global USE_GPU USE_GPU = False - logger.info("GPU acceleration DISABLED for reprojection") + logger.debug("GPU acceleration DISABLED for reprojection") def _get_crs_cache_key(crs): @@ -79,13 +79,13 @@ def _get_cached_transformer(crs_src, crs_target): transformer = Transformer.from_crs(crs_target, crs_src, always_xy=True) _TRANSFORMER_CACHE[cache_key] = transformer if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Created NEW transformer for {type(crs_src).__name__} → " f"{type(crs_target).__name__} (cache size: {len(_TRANSFORMER_CACHE)})" ) else: if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Using CACHED transformer for {type(crs_src).__name__} → " f"{type(crs_target).__name__}" ) @@ -202,7 +202,7 @@ def reproject_to_grid( gpu_enabled = False if ENABLE_TIMING and gpu_enabled: - logger.info(" [TIMING] reproject: Using GPU acceleration") + logger.debug(" [TIMING] reproject: Using GPU acceleration") # Choose array library based on GPU setting xp = cp if gpu_enabled else np @@ -214,14 +214,14 @@ def reproject_to_grid( y_tgt_1d = xp.linspace(ymin, ymax, ny) x_tgt, y_tgt = xp.meshgrid(x_tgt_1d, y_tgt_1d) if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: Build target grid: {(time.time() - t0) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: Build target grid: {(time.time() - t0) * 1000:.2f}ms") # Get cached transformer: target CRS → source CRS # This is expensive (100-300ms) so we cache transformers by CRS type + parameters t0 = time.time() if ENABLE_TIMING else None transformer = _get_cached_transformer(crs_src, crs_target) if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: Get/create transformer: {(time.time() - t0) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: Get/create transformer: {(time.time() - t0) * 1000:.2f}ms") # Transform the target grid into source coordinates # Note: pyproj transformer works with CPU arrays, so convert if using GPU @@ -237,14 +237,14 @@ def reproject_to_grid( if use_parallel: x_src_reproj_cpu, y_src_reproj_cpu = _transform_coordinates_parallel(transformer, x_tgt_cpu, y_tgt_cpu) if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Transform coordinates (parallel, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) else: x_src_reproj_cpu, y_src_reproj_cpu = transformer.transform(x_tgt_cpu, y_tgt_cpu) if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Transform coordinates (serial, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) @@ -254,14 +254,14 @@ def reproject_to_grid( if use_parallel: x_src_reproj, y_src_reproj = _transform_coordinates_parallel(transformer, x_tgt, y_tgt) if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Transform coordinates (parallel, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) else: x_src_reproj, y_src_reproj = transformer.transform(x_tgt, y_tgt) if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Transform coordinates (serial, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) @@ -343,7 +343,7 @@ def reproject_to_grid( x_reproj_norm = (x_src_reproj - x0) % x_diff + x0 if ENABLE_TIMING: - logger.info( + logger.debug( f" [TIMING] reproject: Coordinate normalization (NumPy): {(time.time() - t1) * 1000:.2f}ms" ) @@ -360,7 +360,7 @@ def reproject_to_grid( z_src_gpu[:, 0][:, None], ]) # first column appended right if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: Prepare periodic wrapping: {(time.time() - t1) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: Prepare periodic wrapping: {(time.time() - t1) * 1000:.2f}ms") t1 = time.time() if ENABLE_TIMING else None if gpu_enabled: @@ -380,7 +380,7 @@ def reproject_to_grid( z_tgt = interp(pts).reshape(ny, nx) if ENABLE_TIMING: device_str = "GPU" if gpu_enabled else "CPU" - logger.info( + logger.debug( f" [TIMING] reproject: RegularGridInterpolator ({device_str}, periodic):" f" {(time.time() - t1) * 1000:.2f}ms" ) @@ -409,7 +409,7 @@ def reproject_to_grid( z_tgt = interp(pts).reshape(ny, nx) if ENABLE_TIMING: device_str = "GPU" if gpu_enabled else "CPU" - logger.info( + logger.debug( f" [TIMING] reproject: RegularGridInterpolator ({device_str}, non-periodic):" f" {(time.time() - t1) * 1000:.2f}ms" ) @@ -446,10 +446,10 @@ def reproject_to_grid( z_tgt = cp.asarray(z_tgt_cpu) if gpu_enabled else z_tgt_cpu if ENABLE_TIMING: interp_name = "NearestNDInterpolator" if method == "nearest" else "LinearNDInterpolator" - logger.info(f" [TIMING] reproject: {interp_name} (scattered, CPU): {(time.time() - t1) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: {interp_name} (scattered, CPU): {(time.time() - t1) * 1000:.2f}ms") if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: TOTAL interpolation: {(time.time() - t0) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: TOTAL interpolation: {(time.time() - t0) * 1000:.2f}ms") # Convert GPU arrays back to CPU for return if gpu_enabled: @@ -458,10 +458,10 @@ def reproject_to_grid( y_tgt = cp.asnumpy(y_tgt) z_tgt = cp.asnumpy(z_tgt) if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: GPU→CPU transfer: {(time.time() - t0) * 1000:.2f}ms") + logger.debug(f" [TIMING] reproject: GPU→CPU transfer: {(time.time() - t0) * 1000:.2f}ms") if ENABLE_TIMING: - logger.info(f" [TIMING] reproject: === TOTAL reproject_to_grid: {(time.time() - t_start) * 1000:.2f}ms ===") + logger.debug(f" [TIMING] reproject: === TOTAL reproject_to_grid: {(time.time() - t_start) * 1000:.2f}ms ===") return x_tgt, y_tgt, z_tgt From 0200a72c8bd75b6f538c755de89a842a1775ff78 Mon Sep 17 00:00:00 2001 From: James Varndell Date: Thu, 16 Jul 2026 14:13:55 +0100 Subject: [PATCH 2/3] Undo log level changes; committed to wrong branch --- src/earthkit/plots/resample/reproject.py | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/earthkit/plots/resample/reproject.py b/src/earthkit/plots/resample/reproject.py index e21f94ae..47d9d8b6 100644 --- a/src/earthkit/plots/resample/reproject.py +++ b/src/earthkit/plots/resample/reproject.py @@ -14,7 +14,7 @@ ) HAS_CUPY = True - logger.debug("CuPy detected - GPU acceleration available for reprojection") + logger.info("CuPy detected - GPU acceleration available for reprojection") except ImportError: cp = None CuPyRegularGridInterpolator = None @@ -37,7 +37,7 @@ def enable_gpu_acceleration(): global USE_GPU if HAS_CUPY: USE_GPU = True - logger.debug("GPU acceleration ENABLED for reprojection") + logger.info("GPU acceleration ENABLED for reprojection") else: logger.warning("GPU acceleration requested but CuPy is not available. Install cupy to enable GPU support.") @@ -46,7 +46,7 @@ def disable_gpu_acceleration(): """Disable GPU acceleration for reprojection (use CPU).""" global USE_GPU USE_GPU = False - logger.debug("GPU acceleration DISABLED for reprojection") + logger.info("GPU acceleration DISABLED for reprojection") def _get_crs_cache_key(crs): @@ -79,13 +79,13 @@ def _get_cached_transformer(crs_src, crs_target): transformer = Transformer.from_crs(crs_target, crs_src, always_xy=True) _TRANSFORMER_CACHE[cache_key] = transformer if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Created NEW transformer for {type(crs_src).__name__} → " f"{type(crs_target).__name__} (cache size: {len(_TRANSFORMER_CACHE)})" ) else: if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Using CACHED transformer for {type(crs_src).__name__} → " f"{type(crs_target).__name__}" ) @@ -202,7 +202,7 @@ def reproject_to_grid( gpu_enabled = False if ENABLE_TIMING and gpu_enabled: - logger.debug(" [TIMING] reproject: Using GPU acceleration") + logger.info(" [TIMING] reproject: Using GPU acceleration") # Choose array library based on GPU setting xp = cp if gpu_enabled else np @@ -214,14 +214,14 @@ def reproject_to_grid( y_tgt_1d = xp.linspace(ymin, ymax, ny) x_tgt, y_tgt = xp.meshgrid(x_tgt_1d, y_tgt_1d) if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: Build target grid: {(time.time() - t0) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: Build target grid: {(time.time() - t0) * 1000:.2f}ms") # Get cached transformer: target CRS → source CRS # This is expensive (100-300ms) so we cache transformers by CRS type + parameters t0 = time.time() if ENABLE_TIMING else None transformer = _get_cached_transformer(crs_src, crs_target) if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: Get/create transformer: {(time.time() - t0) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: Get/create transformer: {(time.time() - t0) * 1000:.2f}ms") # Transform the target grid into source coordinates # Note: pyproj transformer works with CPU arrays, so convert if using GPU @@ -237,14 +237,14 @@ def reproject_to_grid( if use_parallel: x_src_reproj_cpu, y_src_reproj_cpu = _transform_coordinates_parallel(transformer, x_tgt_cpu, y_tgt_cpu) if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Transform coordinates (parallel, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) else: x_src_reproj_cpu, y_src_reproj_cpu = transformer.transform(x_tgt_cpu, y_tgt_cpu) if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Transform coordinates (serial, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) @@ -254,14 +254,14 @@ def reproject_to_grid( if use_parallel: x_src_reproj, y_src_reproj = _transform_coordinates_parallel(transformer, x_tgt, y_tgt) if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Transform coordinates (parallel, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) else: x_src_reproj, y_src_reproj = transformer.transform(x_tgt, y_tgt) if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Transform coordinates (serial, {grid_size} points):" f" {(time.time() - t0) * 1000:.2f}ms" ) @@ -343,7 +343,7 @@ def reproject_to_grid( x_reproj_norm = (x_src_reproj - x0) % x_diff + x0 if ENABLE_TIMING: - logger.debug( + logger.info( f" [TIMING] reproject: Coordinate normalization (NumPy): {(time.time() - t1) * 1000:.2f}ms" ) @@ -360,7 +360,7 @@ def reproject_to_grid( z_src_gpu[:, 0][:, None], ]) # first column appended right if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: Prepare periodic wrapping: {(time.time() - t1) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: Prepare periodic wrapping: {(time.time() - t1) * 1000:.2f}ms") t1 = time.time() if ENABLE_TIMING else None if gpu_enabled: @@ -380,7 +380,7 @@ def reproject_to_grid( z_tgt = interp(pts).reshape(ny, nx) if ENABLE_TIMING: device_str = "GPU" if gpu_enabled else "CPU" - logger.debug( + logger.info( f" [TIMING] reproject: RegularGridInterpolator ({device_str}, periodic):" f" {(time.time() - t1) * 1000:.2f}ms" ) @@ -409,7 +409,7 @@ def reproject_to_grid( z_tgt = interp(pts).reshape(ny, nx) if ENABLE_TIMING: device_str = "GPU" if gpu_enabled else "CPU" - logger.debug( + logger.info( f" [TIMING] reproject: RegularGridInterpolator ({device_str}, non-periodic):" f" {(time.time() - t1) * 1000:.2f}ms" ) @@ -446,10 +446,10 @@ def reproject_to_grid( z_tgt = cp.asarray(z_tgt_cpu) if gpu_enabled else z_tgt_cpu if ENABLE_TIMING: interp_name = "NearestNDInterpolator" if method == "nearest" else "LinearNDInterpolator" - logger.debug(f" [TIMING] reproject: {interp_name} (scattered, CPU): {(time.time() - t1) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: {interp_name} (scattered, CPU): {(time.time() - t1) * 1000:.2f}ms") if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: TOTAL interpolation: {(time.time() - t0) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: TOTAL interpolation: {(time.time() - t0) * 1000:.2f}ms") # Convert GPU arrays back to CPU for return if gpu_enabled: @@ -458,10 +458,10 @@ def reproject_to_grid( y_tgt = cp.asnumpy(y_tgt) z_tgt = cp.asnumpy(z_tgt) if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: GPU→CPU transfer: {(time.time() - t0) * 1000:.2f}ms") + logger.info(f" [TIMING] reproject: GPU→CPU transfer: {(time.time() - t0) * 1000:.2f}ms") if ENABLE_TIMING: - logger.debug(f" [TIMING] reproject: === TOTAL reproject_to_grid: {(time.time() - t_start) * 1000:.2f}ms ===") + logger.info(f" [TIMING] reproject: === TOTAL reproject_to_grid: {(time.time() - t_start) * 1000:.2f}ms ===") return x_tgt, y_tgt, z_tgt From fcc6760fdc1c916db3fcbb3cbd3d867d08bd1b41 Mon Sep 17 00:00:00 2001 From: James Varndell Date: Thu, 16 Jul 2026 14:20:31 +0100 Subject: [PATCH 3/3] Increase zorders to be 2 by default --- src/earthkit/plots/data/styles/schema.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/earthkit/plots/data/styles/schema.yml b/src/earthkit/plots/data/styles/schema.yml index 5968163d..2108fb61 100644 --- a/src/earthkit/plots/data/styles/schema.yml +++ b/src/earthkit/plots/data/styles/schema.yml @@ -192,7 +192,7 @@ borders: linewidth: 0.5 edgecolor: "#999999" facecolor: none - zorder: 1 + zorder: 2 special_styles: - key: BRK_A3 values: ["B57"] @@ -203,7 +203,7 @@ borders: kwargs: alpha: 0 countries: - zorder: 0 + zorder: 1 linestyle: "-" linewidth: 0.5 edgecolor: white @@ -213,20 +213,20 @@ unit_boundaries: linewidth: 0.5 edgecolor: [0.3, 0.3, 0.3] facecolor: none - zorder: 1 + zorder: 2 disputed_boundaries: linestyle: [0, [5, 1]] linewidth: 0.5 edgecolor: [0.75, 0.2, 0.2] facecolor: none - zorder: 1 + zorder: 2 administrative_areas: linestyle: "-" linewidth: 0.25 edgecolor: [0.6, 0.6, 0.6] resolution: high facecolor: none - zorder: 1 + zorder: 2 roads: linestyle: "-" linewidth: 0.5 @@ -238,15 +238,16 @@ land: color: "#e8e8e8" urban_areas: color: "#d1d1d1" + zorder: 2 ocean: color: "#f9f9f9" rivers: edgecolor: "#97B6E1" - zorder: 1 + zorder: 2 lakes: facecolor: "#A5D5F2" edgecolor: "#97B6E1" - zorder: 1 + zorder: 2 shapes: facecolor: steelblue linewidth: 0.5