From bef02a67a879dfeedb43881fb2a6e28ae4528a59 Mon Sep 17 00:00:00 2001 From: Zach Radlicz Date: Wed, 3 Sep 2025 17:47:39 -0500 Subject: [PATCH 1/5] fixed multiple gridded data imports and issues --- src/rtgs_lab_tools/gridded_data/__init__.py | 7 ++++-- src/rtgs_lab_tools/gridded_data/cli.py | 24 ++++++++++----------- src/rtgs_lab_tools/gridded_data/gee.py | 1 + src/rtgs_lab_tools/gridded_data/utils.py | 14 ++++++++++++ 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/rtgs_lab_tools/gridded_data/__init__.py b/src/rtgs_lab_tools/gridded_data/__init__.py index 5fba05e8..3c898db6 100644 --- a/src/rtgs_lab_tools/gridded_data/__init__.py +++ b/src/rtgs_lab_tools/gridded_data/__init__.py @@ -1,7 +1,10 @@ """Gridded climate data access tools for RTGS Lab Tools.""" -# Import sources for immediate availability -from .utils import sources +# Import sources and functions for immediate availability +from .utils import sources, load_roi_json +from .gee import init_ee, list_GEE_vars, load_roi, search_images, download_GEE_point, download_GEE_raster +from .planet import quick_search, download_scenes, download_clipped_scenes +from .processors import extract_time_series # Empty __init__.py to avoid loading heavy dependencies at import time # Functions are imported directly from submodules when needed diff --git a/src/rtgs_lab_tools/gridded_data/cli.py b/src/rtgs_lab_tools/gridded_data/cli.py index bed2aae2..ce9aa9e9 100644 --- a/src/rtgs_lab_tools/gridded_data/cli.py +++ b/src/rtgs_lab_tools/gridded_data/cli.py @@ -67,11 +67,11 @@ def download_clipped_scenes( cli_ctx.setup("download-scenes", verbose, log_file, no_postgres_log) try: - from ..gridded_data import download_clipped_scenes, load_roi + from ..gridded_data import download_clipped_scenes, load_roi_json - # Load ROI from file + # Load ROI from file (Planet Labs doesn't use Earth Engine) if roi: - roi = load_roi(roi).getInfo() + roi = load_roi_json(roi) download_clipped_scenes( source=source, @@ -79,7 +79,7 @@ def download_clipped_scenes( roi=roi, start_date=start_date, end_date=end_date, - clouds=clouds, + clouds=int(clouds) if clouds else None, out_dir=out_dir, ) @@ -141,11 +141,11 @@ def download_scenes( cli_ctx.setup("download-scenes", verbose, log_file, no_postgres_log) try: - from ..gridded_data import download_scenes, load_roi + from ..gridded_data import download_scenes, load_roi_json - # Load ROI from file + # Load ROI from file (Planet Labs doesn't use Earth Engine) if roi: - roi = load_roi(roi).getInfo() + roi = load_roi_json(roi) download_scenes( source=source, @@ -153,7 +153,7 @@ def download_scenes( roi=roi, start_date=start_date, end_date=end_date, - clouds=clouds, + clouds=int(clouds) if clouds else None, out_dir=out_dir, ) @@ -211,11 +211,11 @@ def planet_search( cli_ctx.setup("planet-search", verbose, log_file, no_postgres_log) try: - from ..gridded_data import load_roi, quick_search + from ..gridded_data import load_roi_json, quick_search - # Load ROI from file + # Load ROI from file (Planet Labs doesn't use Earth Engine) if roi: - roi = load_roi(roi).getInfo() + roi = load_roi_json(roi) # print(roi_bounds) quick_search( @@ -223,7 +223,7 @@ def planet_search( roi=roi, start_date=start_date, end_date=end_date, - clouds=clouds, + clouds=int(clouds) if clouds else None, out_dir=out_dir, ) diff --git a/src/rtgs_lab_tools/gridded_data/gee.py b/src/rtgs_lab_tools/gridded_data/gee.py index b76a4c23..32444458 100644 --- a/src/rtgs_lab_tools/gridded_data/gee.py +++ b/src/rtgs_lab_tools/gridded_data/gee.py @@ -245,6 +245,7 @@ def clip_img(img): roi = roi.geometry() + qa_band = None # Initialize qa_band for climate datasets if name in qa_bands.keys(): qa_band = qa_bands[name] diff --git a/src/rtgs_lab_tools/gridded_data/utils.py b/src/rtgs_lab_tools/gridded_data/utils.py index 6c22b097..4bee0d79 100644 --- a/src/rtgs_lab_tools/gridded_data/utils.py +++ b/src/rtgs_lab_tools/gridded_data/utils.py @@ -21,3 +21,17 @@ "MYD": "state_1km", # Aqua "VIIRS": "QF1", } + + +def load_roi_json(path): + """Load ROI as plain JSON for Planet Labs (no Earth Engine)""" + import json + with open(path) as f: + roi_geom = json.load(f) + + # Convert to format Planet Labs functions expect + return { + "features": [{ + "geometry": roi_geom + }] + } From 3a5875f57c284dafa42a144038b83b9d05affb29 Mon Sep 17 00:00:00 2001 From: Zach Radlicz Date: Thu, 4 Sep 2025 10:21:16 -0500 Subject: [PATCH 2/5] additional gee improvements --- src/rtgs_lab_tools/gridded_data/gee.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rtgs_lab_tools/gridded_data/gee.py b/src/rtgs_lab_tools/gridded_data/gee.py index 32444458..636a6a31 100644 --- a/src/rtgs_lab_tools/gridded_data/gee.py +++ b/src/rtgs_lab_tools/gridded_data/gee.py @@ -197,6 +197,10 @@ def download_GEE_point(name, source, bands, roi, start_date, end_date, out_dir): size = collection.size().getInfo() print(f"Found {size} images to process") + + if size == 0: + print("No images found for the specified date range and location") + return None scale = collection.first().select(bands[0]).projection().nominalScale().getInfo() From 44dddfe479957c10b926e65c6f958f22400c1483 Mon Sep 17 00:00:00 2001 From: Zach Radlicz Date: Thu, 4 Sep 2025 10:26:18 -0500 Subject: [PATCH 3/5] implemented lazy loadingfor reduced load times --- src/rtgs_lab_tools/gridded_data/__init__.py | 44 ++++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/rtgs_lab_tools/gridded_data/__init__.py b/src/rtgs_lab_tools/gridded_data/__init__.py index 3c898db6..e1affa03 100644 --- a/src/rtgs_lab_tools/gridded_data/__init__.py +++ b/src/rtgs_lab_tools/gridded_data/__init__.py @@ -1,13 +1,45 @@ """Gridded climate data access tools for RTGS Lab Tools.""" -# Import sources and functions for immediate availability +# Only import lightweight utilities immediately from .utils import sources, load_roi_json -from .gee import init_ee, list_GEE_vars, load_roi, search_images, download_GEE_point, download_GEE_raster -from .planet import quick_search, download_scenes, download_clipped_scenes -from .processors import extract_time_series -# Empty __init__.py to avoid loading heavy dependencies at import time -# Functions are imported directly from submodules when needed +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + if name == "init_ee": + from .gee import init_ee + return init_ee + elif name == "list_GEE_vars": + from .gee import list_GEE_vars + return list_GEE_vars + elif name == "load_roi": + from .gee import load_roi + return load_roi + elif name == "search_images": + from .gee import search_images + return search_images + elif name == "download_GEE_point": + from .gee import download_GEE_point + return download_GEE_point + elif name == "download_GEE_raster": + from .gee import download_GEE_raster + return download_GEE_raster + elif name == "quick_search": + from .planet import quick_search + return quick_search + elif name == "download_scenes": + from .planet import download_scenes + return download_scenes + elif name == "download_clipped_scenes": + from .planet import download_clipped_scenes + return download_clipped_scenes + elif name == "extract_time_series": + from .processors import extract_time_series + return extract_time_series + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = [ "download_GEE_raster", From b3feb7bc7fbdbdad4db0a5c7b3cc352470584b3a Mon Sep 17 00:00:00 2001 From: Zach Radlicz Date: Thu, 4 Sep 2025 10:37:17 -0500 Subject: [PATCH 4/5] mplemented lazy loading in import heavy modules for decreased laod times --- .../agricultural_modeling/__init__.py | 98 ++++++++++++++----- src/rtgs_lab_tools/data_parser/__init__.py | 11 ++- .../device_configuration/__init__.py | 19 +++- src/rtgs_lab_tools/sensing_data/__init__.py | 36 +++++-- src/rtgs_lab_tools/visualization/__init__.py | 35 +++++-- 5 files changed, 152 insertions(+), 47 deletions(-) diff --git a/src/rtgs_lab_tools/agricultural_modeling/__init__.py b/src/rtgs_lab_tools/agricultural_modeling/__init__.py index 99de75d4..93150b25 100644 --- a/src/rtgs_lab_tools/agricultural_modeling/__init__.py +++ b/src/rtgs_lab_tools/agricultural_modeling/__init__.py @@ -11,31 +11,79 @@ Migrated from rtgsET library. """ -from .crop_parameters import get_crop_names, get_crop_parameters, get_crop_status -from .distance_speed import ( - degrees_to_radians, - feet_to_meters, - meters_per_second_to_miles_per_hour, - miles_per_hour_to_meters_per_second, -) -from .evapotranspiration import ( - calculate_reference_et, - get_required_columns, - validate_input_data, -) -from .growing_degree_days import ( - calculate_corn_heat_units, - calculate_gdd_modified, - calculate_gdd_original, -) -from .temperature import celsius_to_fahrenheit, fahrenheit_to_celsius -from .weather_api import ( - check_missing_dates, - date_chunks, - fetch_weather_data, - validate_coordinates, - validate_date_range, -) +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + # Crop parameters + if name == "get_crop_names": + from .crop_parameters import get_crop_names + return get_crop_names + elif name == "get_crop_parameters": + from .crop_parameters import get_crop_parameters + return get_crop_parameters + elif name == "get_crop_status": + from .crop_parameters import get_crop_status + return get_crop_status + # Distance and speed conversions + elif name == "degrees_to_radians": + from .distance_speed import degrees_to_radians + return degrees_to_radians + elif name == "feet_to_meters": + from .distance_speed import feet_to_meters + return feet_to_meters + elif name == "meters_per_second_to_miles_per_hour": + from .distance_speed import meters_per_second_to_miles_per_hour + return meters_per_second_to_miles_per_hour + elif name == "miles_per_hour_to_meters_per_second": + from .distance_speed import miles_per_hour_to_meters_per_second + return miles_per_hour_to_meters_per_second + # Evapotranspiration (heavy numpy/pandas dependencies) + elif name == "calculate_reference_et": + from .evapotranspiration import calculate_reference_et + return calculate_reference_et + elif name == "get_required_columns": + from .evapotranspiration import get_required_columns + return get_required_columns + elif name == "validate_input_data": + from .evapotranspiration import validate_input_data + return validate_input_data + # Growing degree days + elif name == "calculate_corn_heat_units": + from .growing_degree_days import calculate_corn_heat_units + return calculate_corn_heat_units + elif name == "calculate_gdd_modified": + from .growing_degree_days import calculate_gdd_modified + return calculate_gdd_modified + elif name == "calculate_gdd_original": + from .growing_degree_days import calculate_gdd_original + return calculate_gdd_original + # Temperature conversions (lightweight) + elif name == "celsius_to_fahrenheit": + from .temperature import celsius_to_fahrenheit + return celsius_to_fahrenheit + elif name == "fahrenheit_to_celsius": + from .temperature import fahrenheit_to_celsius + return fahrenheit_to_celsius + # Weather API utilities (requests dependency) + elif name == "check_missing_dates": + from .weather_api import check_missing_dates + return check_missing_dates + elif name == "date_chunks": + from .weather_api import date_chunks + return date_chunks + elif name == "fetch_weather_data": + from .weather_api import fetch_weather_data + return fetch_weather_data + elif name == "validate_coordinates": + from .weather_api import validate_coordinates + return validate_coordinates + elif name == "validate_date_range": + from .weather_api import validate_date_range + return validate_date_range + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = [ # Temperature conversions diff --git a/src/rtgs_lab_tools/data_parser/__init__.py b/src/rtgs_lab_tools/data_parser/__init__.py index a7dd6b0d..284a174b 100644 --- a/src/rtgs_lab_tools/data_parser/__init__.py +++ b/src/rtgs_lab_tools/data_parser/__init__.py @@ -1,5 +1,14 @@ """Universal JSON packet parser for historical packets based on device JSON schema tool for RTGS Lab Tools.""" -from .core import parse_gems_data +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + if name == "parse_gems_data": + from .core import parse_gems_data + return parse_gems_data + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = ["parse_gems_data"] diff --git a/src/rtgs_lab_tools/device_configuration/__init__.py b/src/rtgs_lab_tools/device_configuration/__init__.py index 859ea1f9..6dda520a 100644 --- a/src/rtgs_lab_tools/device_configuration/__init__.py +++ b/src/rtgs_lab_tools/device_configuration/__init__.py @@ -1,7 +1,20 @@ """Device configuration management tools for RTGS Lab Tools.""" -from .cli import device_configuration_cli -from .particle_client import ParticleClient -from .update_configuration import ParticleConfigUpdater +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + if name == "device_configuration_cli": + from .cli import device_configuration_cli + return device_configuration_cli + elif name == "ParticleClient": + from .particle_client import ParticleClient + return ParticleClient + elif name == "ParticleConfigUpdater": + from .update_configuration import ParticleConfigUpdater + return ParticleConfigUpdater + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = ["device_configuration_cli", "ParticleConfigUpdater", "ParticleClient"] diff --git a/src/rtgs_lab_tools/sensing_data/__init__.py b/src/rtgs_lab_tools/sensing_data/__init__.py index 7372f4b4..0befa470 100644 --- a/src/rtgs_lab_tools/sensing_data/__init__.py +++ b/src/rtgs_lab_tools/sensing_data/__init__.py @@ -1,13 +1,33 @@ """Sensing data tools for RTGS Lab Tools.""" -from .data_extractor import ( - extract_data, - get_nodes_for_project, - get_raw_data, - list_available_projects, - list_projects, -) -from .file_operations import create_zip_archive, save_data +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + if name == "extract_data": + from .data_extractor import extract_data + return extract_data + elif name == "get_nodes_for_project": + from .data_extractor import get_nodes_for_project + return get_nodes_for_project + elif name == "get_raw_data": + from .data_extractor import get_raw_data + return get_raw_data + elif name == "list_available_projects": + from .data_extractor import list_available_projects + return list_available_projects + elif name == "list_projects": + from .data_extractor import list_projects + return list_projects + elif name == "create_zip_archive": + from .file_operations import create_zip_archive + return create_zip_archive + elif name == "save_data": + from .file_operations import save_data + return save_data + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = [ "extract_data", diff --git a/src/rtgs_lab_tools/visualization/__init__.py b/src/rtgs_lab_tools/visualization/__init__.py index 792f3443..d53bde0c 100644 --- a/src/rtgs_lab_tools/visualization/__init__.py +++ b/src/rtgs_lab_tools/visualization/__init__.py @@ -1,15 +1,30 @@ """Visualization tools for RTGS Lab Tools.""" -from .data_utils import ( - detect_data_type, - get_available_measurements, - load_and_prepare_data, -) -from .time_series import ( - create_multi_parameter_plot, - create_time_series_plot, - plot_sensor_data, -) +# Heavy dependencies are imported lazily when needed +# This prevents long load times for simple commands like 'rtgs --help' + +def __getattr__(name): + """Lazy loading of heavy dependencies""" + if name == "create_time_series_plot": + from .time_series import create_time_series_plot + return create_time_series_plot + elif name == "create_multi_parameter_plot": + from .time_series import create_multi_parameter_plot + return create_multi_parameter_plot + elif name == "plot_sensor_data": + from .time_series import plot_sensor_data + return plot_sensor_data + elif name == "detect_data_type": + from .data_utils import detect_data_type + return detect_data_type + elif name == "get_available_measurements": + from .data_utils import get_available_measurements + return get_available_measurements + elif name == "load_and_prepare_data": + from .data_utils import load_and_prepare_data + return load_and_prepare_data + else: + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") __all__ = [ "create_time_series_plot", From 2f1c835eed55051ff59263cd60d5c9fa91acbf8d Mon Sep 17 00:00:00 2001 From: Zach Radlicz Date: Thu, 4 Sep 2025 12:40:06 -0500 Subject: [PATCH 5/5] formatting --- .../agricultural_modeling/__init__.py | 22 +++++++++++++++++++ src/rtgs_lab_tools/data_parser/__init__.py | 3 +++ .../device_configuration/__init__.py | 5 +++++ src/rtgs_lab_tools/gridded_data/__init__.py | 14 +++++++++++- src/rtgs_lab_tools/gridded_data/gee.py | 2 +- src/rtgs_lab_tools/gridded_data/utils.py | 9 +++----- src/rtgs_lab_tools/sensing_data/__init__.py | 9 ++++++++ src/rtgs_lab_tools/visualization/__init__.py | 8 +++++++ 8 files changed, 64 insertions(+), 8 deletions(-) diff --git a/src/rtgs_lab_tools/agricultural_modeling/__init__.py b/src/rtgs_lab_tools/agricultural_modeling/__init__.py index 93150b25..b7610634 100644 --- a/src/rtgs_lab_tools/agricultural_modeling/__init__.py +++ b/src/rtgs_lab_tools/agricultural_modeling/__init__.py @@ -14,77 +14,99 @@ # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" # Crop parameters if name == "get_crop_names": from .crop_parameters import get_crop_names + return get_crop_names elif name == "get_crop_parameters": from .crop_parameters import get_crop_parameters + return get_crop_parameters elif name == "get_crop_status": from .crop_parameters import get_crop_status + return get_crop_status # Distance and speed conversions elif name == "degrees_to_radians": from .distance_speed import degrees_to_radians + return degrees_to_radians elif name == "feet_to_meters": from .distance_speed import feet_to_meters + return feet_to_meters elif name == "meters_per_second_to_miles_per_hour": from .distance_speed import meters_per_second_to_miles_per_hour + return meters_per_second_to_miles_per_hour elif name == "miles_per_hour_to_meters_per_second": from .distance_speed import miles_per_hour_to_meters_per_second + return miles_per_hour_to_meters_per_second # Evapotranspiration (heavy numpy/pandas dependencies) elif name == "calculate_reference_et": from .evapotranspiration import calculate_reference_et + return calculate_reference_et elif name == "get_required_columns": from .evapotranspiration import get_required_columns + return get_required_columns elif name == "validate_input_data": from .evapotranspiration import validate_input_data + return validate_input_data # Growing degree days elif name == "calculate_corn_heat_units": from .growing_degree_days import calculate_corn_heat_units + return calculate_corn_heat_units elif name == "calculate_gdd_modified": from .growing_degree_days import calculate_gdd_modified + return calculate_gdd_modified elif name == "calculate_gdd_original": from .growing_degree_days import calculate_gdd_original + return calculate_gdd_original # Temperature conversions (lightweight) elif name == "celsius_to_fahrenheit": from .temperature import celsius_to_fahrenheit + return celsius_to_fahrenheit elif name == "fahrenheit_to_celsius": from .temperature import fahrenheit_to_celsius + return fahrenheit_to_celsius # Weather API utilities (requests dependency) elif name == "check_missing_dates": from .weather_api import check_missing_dates + return check_missing_dates elif name == "date_chunks": from .weather_api import date_chunks + return date_chunks elif name == "fetch_weather_data": from .weather_api import fetch_weather_data + return fetch_weather_data elif name == "validate_coordinates": from .weather_api import validate_coordinates + return validate_coordinates elif name == "validate_date_range": from .weather_api import validate_date_range + return validate_date_range else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = [ # Temperature conversions "celsius_to_fahrenheit", diff --git a/src/rtgs_lab_tools/data_parser/__init__.py b/src/rtgs_lab_tools/data_parser/__init__.py index 284a174b..8b15f3d8 100644 --- a/src/rtgs_lab_tools/data_parser/__init__.py +++ b/src/rtgs_lab_tools/data_parser/__init__.py @@ -3,12 +3,15 @@ # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" if name == "parse_gems_data": from .core import parse_gems_data + return parse_gems_data else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = ["parse_gems_data"] diff --git a/src/rtgs_lab_tools/device_configuration/__init__.py b/src/rtgs_lab_tools/device_configuration/__init__.py index 6dda520a..a9818250 100644 --- a/src/rtgs_lab_tools/device_configuration/__init__.py +++ b/src/rtgs_lab_tools/device_configuration/__init__.py @@ -3,18 +3,23 @@ # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" if name == "device_configuration_cli": from .cli import device_configuration_cli + return device_configuration_cli elif name == "ParticleClient": from .particle_client import ParticleClient + return ParticleClient elif name == "ParticleConfigUpdater": from .update_configuration import ParticleConfigUpdater + return ParticleConfigUpdater else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = ["device_configuration_cli", "ParticleConfigUpdater", "ParticleClient"] diff --git a/src/rtgs_lab_tools/gridded_data/__init__.py b/src/rtgs_lab_tools/gridded_data/__init__.py index e1affa03..ed498048 100644 --- a/src/rtgs_lab_tools/gridded_data/__init__.py +++ b/src/rtgs_lab_tools/gridded_data/__init__.py @@ -1,46 +1,58 @@ """Gridded climate data access tools for RTGS Lab Tools.""" # Only import lightweight utilities immediately -from .utils import sources, load_roi_json +from .utils import load_roi_json, sources # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" if name == "init_ee": from .gee import init_ee + return init_ee elif name == "list_GEE_vars": from .gee import list_GEE_vars + return list_GEE_vars elif name == "load_roi": from .gee import load_roi + return load_roi elif name == "search_images": from .gee import search_images + return search_images elif name == "download_GEE_point": from .gee import download_GEE_point + return download_GEE_point elif name == "download_GEE_raster": from .gee import download_GEE_raster + return download_GEE_raster elif name == "quick_search": from .planet import quick_search + return quick_search elif name == "download_scenes": from .planet import download_scenes + return download_scenes elif name == "download_clipped_scenes": from .planet import download_clipped_scenes + return download_clipped_scenes elif name == "extract_time_series": from .processors import extract_time_series + return extract_time_series else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = [ "download_GEE_raster", "download_GEE_point", diff --git a/src/rtgs_lab_tools/gridded_data/gee.py b/src/rtgs_lab_tools/gridded_data/gee.py index 636a6a31..3452403e 100644 --- a/src/rtgs_lab_tools/gridded_data/gee.py +++ b/src/rtgs_lab_tools/gridded_data/gee.py @@ -197,7 +197,7 @@ def download_GEE_point(name, source, bands, roi, start_date, end_date, out_dir): size = collection.size().getInfo() print(f"Found {size} images to process") - + if size == 0: print("No images found for the specified date range and location") return None diff --git a/src/rtgs_lab_tools/gridded_data/utils.py b/src/rtgs_lab_tools/gridded_data/utils.py index 4bee0d79..9fdba1d2 100644 --- a/src/rtgs_lab_tools/gridded_data/utils.py +++ b/src/rtgs_lab_tools/gridded_data/utils.py @@ -26,12 +26,9 @@ def load_roi_json(path): """Load ROI as plain JSON for Planet Labs (no Earth Engine)""" import json + with open(path) as f: roi_geom = json.load(f) - + # Convert to format Planet Labs functions expect - return { - "features": [{ - "geometry": roi_geom - }] - } + return {"features": [{"geometry": roi_geom}]} diff --git a/src/rtgs_lab_tools/sensing_data/__init__.py b/src/rtgs_lab_tools/sensing_data/__init__.py index 0befa470..05b04a94 100644 --- a/src/rtgs_lab_tools/sensing_data/__init__.py +++ b/src/rtgs_lab_tools/sensing_data/__init__.py @@ -3,32 +3,41 @@ # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" if name == "extract_data": from .data_extractor import extract_data + return extract_data elif name == "get_nodes_for_project": from .data_extractor import get_nodes_for_project + return get_nodes_for_project elif name == "get_raw_data": from .data_extractor import get_raw_data + return get_raw_data elif name == "list_available_projects": from .data_extractor import list_available_projects + return list_available_projects elif name == "list_projects": from .data_extractor import list_projects + return list_projects elif name == "create_zip_archive": from .file_operations import create_zip_archive + return create_zip_archive elif name == "save_data": from .file_operations import save_data + return save_data else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = [ "extract_data", "list_available_projects", diff --git a/src/rtgs_lab_tools/visualization/__init__.py b/src/rtgs_lab_tools/visualization/__init__.py index d53bde0c..1b2a2f07 100644 --- a/src/rtgs_lab_tools/visualization/__init__.py +++ b/src/rtgs_lab_tools/visualization/__init__.py @@ -3,29 +3,37 @@ # Heavy dependencies are imported lazily when needed # This prevents long load times for simple commands like 'rtgs --help' + def __getattr__(name): """Lazy loading of heavy dependencies""" if name == "create_time_series_plot": from .time_series import create_time_series_plot + return create_time_series_plot elif name == "create_multi_parameter_plot": from .time_series import create_multi_parameter_plot + return create_multi_parameter_plot elif name == "plot_sensor_data": from .time_series import plot_sensor_data + return plot_sensor_data elif name == "detect_data_type": from .data_utils import detect_data_type + return detect_data_type elif name == "get_available_measurements": from .data_utils import get_available_measurements + return get_available_measurements elif name == "load_and_prepare_data": from .data_utils import load_and_prepare_data + return load_and_prepare_data else: raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + __all__ = [ "create_time_series_plot", "create_multi_parameter_plot",