### Setup Development Environment Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Clone the repository and install dependencies to start working on the project. ```bash # Clone the repository git clone https://github.com/NarenKarthikBM/python-cdo-wrapper.git cd python-cdo-wrapper # Install with dev dependencies pip install -e ".[dev]" # Install pre-commit hooks pre-commit install ``` -------------------------------- ### Development Environment Setup Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/CONTRIBUTING.md Commands to clone the repository, set up a virtual environment, and install dependencies. ```bash # Clone your fork git clone https://github.com/YOUR_USERNAME/python-cdo-wrapper.git cd python-cdo-wrapper # Create virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install in development mode with all dependencies pip install -e ".[dev,test,docs]" # Install pre-commit hooks pre-commit install ``` -------------------------------- ### Install CDO Prerequisites Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md System-level installation commands for CDO on various platforms. ```bash # macOS (Homebrew) brew install cdo # Ubuntu/Debian sudo apt install cdo # Conda (recommended for HPC) conda install -c conda-forge cdo ``` -------------------------------- ### Install python-cdo-wrapper and CDO Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Installation commands for the library and the required CDO backend. ```bash # Install python-cdo-wrapper pip install python-cdo-wrapper>=1.0.0 # Install CDO if needed # macOS: brew install cdo # Linux: sudo apt install cdo # Conda: conda install -c conda-forge cdo ``` -------------------------------- ### Shapefile Support Installation Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Install the python-cdo-wrapper with shapefile support using pip. ```bash pip install python-cdo-wrapper[shapefiles] ``` -------------------------------- ### Install Python CDO Wrapper Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Command to install the package via pip. ```bash pip install python-cdo-wrapper ``` -------------------------------- ### Testing Guidelines Example Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/CONTRIBUTING.md Example of unit and integration tests using pytest. ```python import pytest from python_cdo_wrapper.core import _is_text_command def test_is_text_command_returns_true_for_sinfo(): """Test that sinfo is correctly identified as a text command.""" assert _is_text_command("sinfo data.nc") is True def test_is_text_command_returns_false_for_yearmean(): """Test that yearmean is correctly identified as a data command.""" assert _is_text_command("yearmean data.nc") is False @pytest.mark.integration def test_cdo_sinfo_returns_string(sample_nc_file): """Integration test requiring CDO to be installed.""" from python_cdo_wrapper import cdo result = cdo(f"sinfo {sample_nc_file}") assert isinstance(result, str) ``` -------------------------------- ### Initialize CDOQuery Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Start a lazy query builder by specifying the input file. ```python query = cdo.query("data.nc") ``` -------------------------------- ### Initialize CDO with Custom Paths Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Configure the CDO wrapper to use a specific binary installation or a custom temporary directory. ```python from python_cdo_wrapper import CDO # Use specific CDO installation cdo = CDO(cdo_path="/usr/local/bin/cdo") # Use custom temp directory cdo = CDO(temp_dir="/path/to/temp") ``` -------------------------------- ### Google-style Docstring Example Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/CONTRIBUTING.md Template for writing Google-style docstrings for public APIs. ```python def my_function(param1: str, param2: int = 10) -> bool: """ Short description of the function. Longer description if needed, explaining the function's behavior, edge cases, etc. Args: param1: Description of param1. param2: Description of param2. Defaults to 10. Returns: Description of return value. Raises: ValueError: When param1 is empty. Example: >>> my_function("test", 5) True """ ``` -------------------------------- ### Legacy API - Getting File Information (v0.2.x) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Shows how to get file information using the legacy `cdo()` function. ```APIDOC ## Getting File Information (Legacy v0.2.x) ### Description This section demonstrates how to retrieve file structure and grid information using the legacy `cdo()` function from the `python-cdo-wrapper` library. ### Method `cdo()` function with specific commands. ### Endpoint N/A (Legacy function calls) ### Parameters #### `cdo()` Parameters - **command** (str) - Required - The CDO command to execute (e.g., 'sinfo', 'griddes'). - **filename** (str) - Required - Path to the NetCDF file. - **return_dict** (bool) - Optional - If True, returns the output as a dictionary. ### Request Example ```python from python_cdo_wrapper import cdo # File structure info info = cdo("sinfo data.nc") print(info) # Grid description grid = cdo("griddes data.nc") print(grid) # Structured output (v0.2.x feature) grid_dict = cdo("griddes data.nc", return_dict=True) print(grid_dict["gridtype"]) ``` ### Response - Returns the raw output of the CDO command as a string, or a dictionary if `return_dict` is True. ``` -------------------------------- ### v1.0.0 Lazy Evaluation Example Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Demonstrates building a query first and executing it later using the v1.0.0 API. Use `.get_command()` to inspect the command before execution. ```python # v1.0.0: Build first, execute later query = cdo.query("data.nc").select_var("tas").year_mean() print(query.get_command()) # Inspect before running ds = query.compute() # Execute when ready ``` -------------------------------- ### Import python-cdo-wrapper libraries Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Standard imports for the library and environment setup. ```python """ Import required libraries and check environment. """ # Standard library imports import numpy as np import xarray as xr # Import python-cdo-wrapper v1.0.0 API from python_cdo_wrapper import CDO, F from python_cdo_wrapper.types import GridSpec ``` -------------------------------- ### Structured Info Commands (v1.0.0) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Provides examples for retrieving structured information about NetCDF files using `sinfo`, `griddes`, `vlist`, and `partab`. ```APIDOC ## Structured File Information (v1.0.0) ### Description This section details how to obtain structured metadata from NetCDF files using various CDO commands exposed through the `python-cdo-wrapper` library. ### Method `CDO.sinfo()`, `CDO.griddes()`, `CDO.vlist()`, `CDO.partab()` ### Endpoint N/A (Library methods) ### Parameters #### `sinfo` Parameters - **filename** (str) - Required - Path to the NetCDF file. #### `griddes` Parameters - **filename** (str) - Required - Path to the NetCDF file. #### `vlist` Parameters - **filename** (str) - Required - Path to the NetCDF file. #### `partab` Parameters - **filename** (str) - Required - Path to the NetCDF file. ### Request Example ```python from python_cdo_wrapper import CDO cdo = CDO() # Get structured file information info = cdo.sinfo("data.nc") # Returns SinfoResult dataclass print(info.var_names) # ['tas', 'pr', 'psl'] print(info.nvar) # 3 print(info.time_range) # ('2020-01-01', '2022-12-31') print(info.file_format) # 'NetCDF' # Grid information grid = cdo.griddes("data.nc") # Returns GriddesResult print(grid.grids[0].gridtype) # 'lonlat' print(grid.grids[0].xsize) # 360 print(grid.grids[0].ysize) # 180 # Variable list vlist = cdo.vlist("data.nc") # Returns VlistResult for var in vlist.variables: print(f"{var.name}: {var.longname} [{var.units}]") # Parameter table partab = cdo.partab("data.nc") # Returns PartabResult for param in partab.parameters: print(f"{param.code}: {param.name}") ``` ### Response - **`sinfo`**: Returns an `SinfoResult` object with attributes like `var_names`, `nvar`, `time_range`, `file_format`. - **`griddes`**: Returns a `GriddesResult` object containing grid details. - **`vlist`**: Returns a `VlistResult` object with a list of `Variable` objects. - **`partab`**: Returns a `PartabResult` object with a list of `Parameter` objects. ``` -------------------------------- ### Query Introspection: Explain Pipeline Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Build a base query and get a human-readable description of the CDO pipeline. ```python from python_cdo_wrapper import CDO cdo = CDO() # Build base query base = ( cdo.query("era5_global.nc") .select_var("tas") .select_year(2020, 2021, 2022) ) print(base.explain()) # Output: Human-readable description of pipeline ``` -------------------------------- ### Comprehensive v1.0.0 API Usage Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Detailed examples covering lazy query chaining, anomaly calculations, structured info commands, and query terminators. ```python from python_cdo_wrapper import CDO, F cdo = CDO() # ============================================================ # PRIMARY API: Django ORM-style lazy query chaining # ============================================================ # Build a lazy query - nothing executed yet query = ( cdo.query("data.nc") .select_var("tas") .select_year(2020, 2021, 2022) .year_mean() .field_mean() ) # Inspect before running print(query.get_command()) # Output: "cdo -fldmean -yearmean -selyear,2020,2021,2022 -selname,tas data.nc" # Execute and get xarray.Dataset ds = query.compute() # ============================================================ # ONE-LINER ANOMALY CALCULATION with F() # ============================================================ anomaly = cdo.query("monthly_data.nc").sub(F("climatology.nc")).compute() # Standardized anomaly: (data - mean) / std std_anomaly = ( cdo.query("data.nc") .sub(F("climatology.nc")) .div(F("std_dev.nc")) .compute() ) # ============================================================ # STRUCTURED INFO COMMANDS (CDO class methods) # ============================================================ info = cdo.sinfo("data.nc") # Returns SinfoResult dataclass print(info.var_names) # ['tas', 'pr', 'psl'] print(info.nvar) # 3 print(info.time_range) # ('2020-01-01', '2022-12-31') grid = cdo.griddes("data.nc") # Returns GriddesResult print(grid.grids[0].gridtype) # 'lonlat' # ============================================================ # INFO OPERATORS AS QUERY TERMINATORS (NEW!) # ============================================================ # Get info about processed data - no need for intermediate files! vars = cdo.query("data.nc").year_mean().showname() # ['tas', 'pr'] n_times = cdo.query("data.nc").select_year(2020).ntime() # 12 grid = cdo.query("data.nc").remap_bil("r180x90").griddes() # GriddesResult ``` -------------------------------- ### Verify CDO installation Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Check for CDO availability and version compatibility. ```python """ Check CDO installation and version. Verifies that CDO >= 1.9.8 is available for F() function support. """ from python_cdo_wrapper.utils import get_cdo_version try: version = get_cdo_version() print(f"βœ… CDO installed: {version}") except Exception as e: print(f"❌ CDO not found: {e}") ``` -------------------------------- ### Build and Inspect CDO Queries Source: https://context7.com/narenkarthikbm/python-cdo-wrapper/llms.txt Build lazy CDO queries using chainable methods. Inspect the generated CDO command with .get_command() or get a human-readable explanation with .explain() before execution. ```python from python_cdo_wrapper import CDO cdo = CDO() # Build a lazy query - nothing executed yet query = ( cdo.query("data.nc") .select_var("tas") .select_year(2020, 2021, 2022) .year_mean() .field_mean() ) # Inspect the CDO command before execution print(query.get_command()) # Output: "cdo -fldmean -yearmean -selyear,2020,2021,2022 -selname,tas data.nc" # Get human-readable explanation print(query.explain()) # Output: # Input: data.nc # 1. selname(tas) # 2. selyear(2020, 2021, 2022) # 3. yearmean() # 4. fldmean() # Execute and get xarray.Dataset ds = query.compute() # Save to file instead path = query.to_file("output.nc") ``` -------------------------------- ### Masking and Aggregation Examples Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Demonstrates chaining CDO operators for common data processing tasks like masking by shapefile and calculating yearly means. ```APIDOC ## Chaining Operators with Masking and Aggregation ### Description This section shows how to chain CDO operators to perform complex data processing tasks, such as masking data with a shapefile and then calculating yearly or field means. ### Method Chainable methods on the CDO object. ### Endpoint N/A (This represents a sequence of operations within the library) ### Parameters N/A for the overall chaining concept, parameters are specific to individual operators. ### Request Example ```python # Chain with other operators yearly_regional = ( cdo.query("daily_data.nc") .mask_by_shapefile("west_africa.shp") .year_mean() .field_mean() .compute() ) # Custom coordinate names masked = cdo.query("data.nc").mask_by_shapefile( "region.shp", lat_name="latitude", lon_name="longitude" ).compute() ``` ### Response N/A (Results are typically stored in variables or saved to files.) ``` -------------------------------- ### v0.x Simple Statistical Operation Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Example of performing a simple statistical operation (yearmean) using the v0.x function-based API. ```python from python_cdo_wrapper import cdo ds, log = cdo("yearmean input.nc") ``` -------------------------------- ### Get File Information (sinfo) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md v0.x returns text output or a dictionary requiring manual parsing. v1.0.0 returns a structured dataclass with type-safe access to attributes. ```python # Text output info = cdo("sinfo data.nc") print(info) # Parse text manually # Or structured dict info_dict = cdo("sinfo data.nc", return_dict=True) print(info_dict["variables"]) ``` ```python # Structured dataclass (native) info = cdo.sinfo("data.nc") # Returns SinfoResult # Type-safe access print(info.var_names) # ['tas', 'pr', 'psl'] print(info.nvar) # 3 print(info.time_range) # ('2020-01-01', '2022-12-31') print(info.file_format) # 'NetCDF' # Access variables for var in info.variables: print(f"{var.name}: {var.longname} [{var.units}]") ``` -------------------------------- ### Inspect CDO Query Details Before Execution Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Inspect a query to preview the generated CDO command, get a human-readable explanation, and list all operations in the pipeline for debugging. ```python # Build a query query = ( cdo.query("sample_data.nc") .select_var("tas") .select_level(850) .select_year(2020, 2021, 2022) .year_mean() .field_mean() ) # 1. Get the raw CDO command print("πŸ” Generated CDO Command:") print("=" * 70) print(query.get_command()) # 2. Get human-readable explanation print("\nπŸ“‹ Human-Readable Explanation:") print("=" * 70) print(query.explain()) # 3. List all operations in the pipeline print("\nπŸ”§ Pipeline Operations:") print("=" * 70) for i, op in enumerate(query.get_operations(), 1): print(f" {i}. {op.name}: {op.to_cdo_fragment()}") print("\nπŸ’‘ This transparency helps you understand and debug complex queries!") ``` -------------------------------- ### Build and Check Package Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Commands for building the package and verifying the distribution. ```bash # Build package hatch build # Check package twine check dist/* ``` -------------------------------- ### Structured Info Commands Demo Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Demonstrates using structured info commands like sinfo(), griddes(), vlist(), and partab() to retrieve file information as Python dataclasses. ```python print("ℹ️ Structured Info Commands Demo\n") # 1. sinfo - Complete file information print("1️⃣ File Information (sinfo):") info = cdo.sinfo("sample_data.nc") print(f" Type: {type(info).__name__}") print(f" File format: {info.file_format}") print(f" Number of variables: {info.nvar}") print(f" Variable names: {info.var_names}") print(f" Time range: {info.time_range}") print(" Variables details:") for var in info.variables: if var.name: print(f" - {var.name}: {var.longname} [{var.units}]") # 2. griddes - Grid information print("\n2️⃣ Grid Information (griddes):") grid = cdo.griddes("sample_data.nc") print(f" Type: {type(grid).__name__}") print(f" Number of grids: {len(grid.grids)}") if grid.grids: g = grid.grids[0] print(f" Grid type: {g.gridtype}") print(f" Size: {g.xsize} Γ— {g.ysize}") if hasattr(g, "xinc") and g.xinc: print(f" Resolution: {g.xinc}Β° Γ— {g.yinc}Β°") # 3. vlist - Variable list print("\n3️⃣ Variable List (vlist):") vlist = cdo.vlist("sample_data.nc") print(f" Type: {type(vlist).__name__}") print(" Variables:") for var in vlist.variables: print(f" - {var.name}: Code {var.code}") # 4. partab - Parameter table print("\n4️⃣ Parameter Table (partab):") partab = cdo.partab("sample_data.nc") print(f" Type: {type(partab).__name__}") print(f" Number of parameters: {len(partab.parameters)}") for param in partab.parameters[:3]: # Show first 3 print(f" - Code {param.code}: {param.name} [{param.units}]") print("\nβœ… All structured info commands working!") print("\nπŸ’‘ Benefits:") print(" - Type-safe access to all fields") print(" - IDE autocompletion") print(" - No string parsing required") print(" - Helper methods (e.g., info.var_names, info.time_range)") ``` -------------------------------- ### v1.0.0 Import and Initialization Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Demonstrates the import of the `CDO` class and its initialization for use in v1.0.0. ```python from python_cdo_wrapper import CDO cdo = CDO() ``` -------------------------------- ### Chain Processing and Get Metadata Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Chain multiple CDO query operations and retrieve a list of dates after selection. ```python dates = ( cdo.query("data.nc") .select_var("tas") .select_year(2020, 2021) .showdate() # Returns list of dates after selection ) ``` -------------------------------- ### Compare CDO Approaches: v0.x vs v1.0.0 Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Illustrates the difference between the old string-based CDO commands and the new query API for calculating European winter mean temperature. The v1.0.0 approach offers better readability, type safety, and introspection. ```python print("βš–οΈ v0.x vs v1.0.0 Comparison\n") print("=" * 70) print("\nπŸ“ Task: Calculate European winter mean temperature\n") print("❌ v0.x approach (string-based):") print("-" * 70) print("from python_cdo_wrapper import cdo") print("") print( 'ds, log = cdo("-fldmean -yearmean -selseason,DJF -sellonlatbox,-10,40,35,70 -sellevel,1000 -selname,tas input.nc")' ) print("") print("Issues:") print(" - Hard to read (one long string)") print(" - Parameter order matters") print(" - No type checking") print(" - No IDE autocompletion") print(" - Can't inspect before execution") print("\nβœ… v1.0.0 approach (query API):") print("-" * 70) print("from python_cdo_wrapper import CDO") print("") print("cdo = CDO()") print("") print("query = (") print(" cdo.query('input.nc')") print(" .select_var('tas')") print(" .select_level(1000)") print(" .select_region(lon1=-10, lon2=40, lat1=35, lat2=70)") print(" .select_season('DJF')") print(" .year_mean()") print(" .field_mean()") print(")") print("") print("print(query.get_command()) # Inspect first!") print("ds = query.compute()") print("") print("Benefits:") print(" βœ… Self-documenting code") print(" βœ… Named parameters (order-independent)") print(" βœ… Full type checking") print(" βœ… IDE autocompletion") print(" βœ… Inspect before execution") print(" βœ… Clone and branch for variations") print("\n" + "=" * 70) # Actual execution to prove it works result = ( cdo.query("sample_data.nc") .select_var("tas") .select_level(1000) .select_region(lon1=-10, lon2=40, lat1=35, lat2=70) .select_season("DJF") .year_mean() .field_mean() .compute() ) print("\nβœ… v1.0.0 query executed successfully!") print(f" Result shape: {result.dims}") print(f" Mean temperature: {float(result.tas.mean().values):.2f} K") ``` -------------------------------- ### v1.0.0 Query Reusability Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Demonstrates creating a base query in v1.0.0 and then branching it for different analyses, promoting code reuse. ```python # v1.0.0: Create base query, branch for different analyses base = cdo.query("data.nc").select_var("tas") annual = base.clone().year_mean().compute() monthly = base.clone().month_mean().compute() ``` -------------------------------- ### Migrate from v0.x to v1.0 Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Comparison between the legacy string-based API and the new ORM-style API. ```python # v0.x - String-based API (STILL WORKS!) from python_cdo_wrapper import cdo ds, log = cdo("yearmean -selname,tas data.nc") # v1.0 - Django ORM-style API (RECOMMENDED) from python_cdo_wrapper import CDO cdo = CDO() ds = cdo.query("data.nc").select_var("tas").year_mean().compute() # v1.0 - Anomaly calculation made easy from python_cdo_wrapper import F anomaly = cdo.query("data.nc").sub(F("climatology.nc")).compute() ``` -------------------------------- ### Exception Handling Source: https://context7.com/narenkarthikbm/python-cdo-wrapper/llms.txt Demonstrates how to handle specific library exceptions for robust error management. ```python from python_cdo_wrapper import ( CDO, CDOError, CDOExecutionError, CDOValidationError, CDOFileNotFoundError, CDOParseError, ) cdo = CDO() # Handle execution errors try: ds = cdo.query("data.nc").select_var("nonexistent").compute() except CDOExecutionError as e: print(f"Command failed: {e.command}") print(f"Return code: {e.returncode}") print(f"Stderr: {e.stderr}") # Handle validation errors try: ds = cdo.query("data.nc").select_month(13).compute() # Invalid month except CDOValidationError as e: print(f"Invalid parameter: {e.parameter}") print(f"Value: {e.value}") print(f"Expected: {e.expected}") # Handle file not found try: ds = cdo.query("nonexistent.nc").compute() except CDOFileNotFoundError as e: print(f"File not found: {e.file_path}") ``` -------------------------------- ### Advanced Query Methods Demo Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Demonstrates Django-inspired shortcuts for common query operations like first(), last(), count(), exists(), and values(). ```python print("πŸš€ Advanced Query Methods Demo\n") base_query = cdo.query("sample_data.nc").select_var("tas") # 1. first() - Get first timestep print("1️⃣ Get first timestep:") first = base_query.clone().first() print(f" Shape: {first.dims}") print(f" Time: {first.time.values}") # 2. last() - Get last timestep print("\n2️⃣ Get last timestep:") last = base_query.clone().last() print(f" Shape: {last.dims}") print(f" Time: {last.time.values}") # 3. count() - Get number of timesteps print("\n3️⃣ Count timesteps:") n_timesteps = base_query.clone().count() print(f" Number of timesteps: {n_timesteps}") print(f" Type: {type(n_timesteps)}") # 4. exists() - Check if data exists print("\n4️⃣ Check if data exists:") exists = base_query.clone().exists() print(f" Data exists: {exists}") print(f" Type: {type(exists)}") # 5. values() - Alias for select_var() print("\n5️⃣ Select variables with .values():") ds = cdo.query("sample_data.nc").values("tas", "pr").compute() print(f" Variables: {list(ds.data_vars)}") print("\nβœ… Advanced query methods working!") ``` -------------------------------- ### Get Grid Information (griddes) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md v0.x returns text or a dictionary. v1.0.0 returns a structured GriddesResult object for easy access to grid properties. ```python grid = cdo("griddes data.nc") # Parse text output # Or grid_dict = cdo("griddes data.nc", return_dict=True) print(grid_dict["gridtype"]) ``` ```python grid = cdo.griddes("data.nc") # Returns GriddesResult print(grid.grids[0].gridtype) # 'lonlat' print(grid.grids[0].xsize) # 360 print(grid.grids[0].ysize) # 180 print(grid.grids[0].xinc) # 1.0 ``` -------------------------------- ### Query Introspection: Advanced Query Methods Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Utilize advanced query methods to get the first/last timestep, count timesteps, or check for data existence. ```python from python_cdo_wrapper import CDO cdo = CDO() # Build base query base = ( cdo.query("era5_global.nc") .select_var("tas") .select_year(2020, 2021, 2022) ) # Advanced query methods (Django-like) first_timestep = base.first() # Get first timestep only last_timestep = base.last() # Get last timestep only num_timesteps = base.count() # Get number of timesteps has_data = base.exists() # Check if data exists ``` -------------------------------- ### Execute a CDO Query and Get Results Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Execute a previously built CDO query using the `.compute()` method to retrieve results as an xarray Dataset. ```python # NOW execute the query result = query.compute() print("βœ… Query executed successfully!") print(f"\nπŸ“¦ Result type: {type(result)}") print(f"\nπŸ“ Dimensions: {dict(result.dims)}") print(f"πŸ“Š Variables: {list(result.data_vars)}") print(f"πŸ“ Coordinates: {list(result.coords)}") print(f"\n🌑️ Mean temperature: {float(result.tas.mean().values):.2f} K") ``` -------------------------------- ### Execute a complete climate analysis workflow Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb A comprehensive pipeline using query chaining, seasonal filtering, and anomaly calculation to analyze European winter temperature trends. ```python print("🌍 Real-World Analysis: European Winter Temperature Trends\n") print("=" * 60) # Step 1: Extract European winter (DJF) surface temperature print("\nπŸ“ Step 1: Extract European winter temperature") europe_winter = ( cdo.query("sample_data.nc") .select_var("tas") .select_level(1000) .select_region(lon1=-10, lon2=40, lat1=35, lat2=70) .select_season("DJF") ) print(f" Command: {europe_winter.get_command()[:80]}...") # Step 2: Calculate annual winter means print("\nπŸ“Š Step 2: Calculate annual winter means") annual_winter = europe_winter.clone().year_mean().field_mean().compute() print(f" Years: {len(annual_winter.time)}") print(" Mean temperatures:") for i, temp in enumerate(annual_winter.tas.values): year = 2020 + i print(f" {year}: {float(temp):.2f} K ({float(temp) - 273.15:.2f} Β°C)") # Step 3: Calculate spatial pattern print("\nπŸ—ΊοΈ Step 3: Calculate winter climatology (spatial pattern)") winter_clim = europe_winter.clone().time_mean().compute() print(f" Climatology shape: {winter_clim.dims}") print(f" Spatial mean: {float(winter_clim.tas.mean().values):.2f} K") print(f" Spatial std: {float(winter_clim.tas.std().values):.2f} K") # Step 4: Calculate anomalies from climatology print("\nπŸ“‰ Step 4: Calculate winter anomalies") winter_clim.to_netcdf("europe_winter_clim.nc") anomalies = ( europe_winter.clone() .sub(F("europe_winter_clim.nc")) .year_mean() .field_mean() .compute() ) print(" Anomalies (relative to 3-year mean):") for i, anom in enumerate(anomalies.tas.values): year = 2020 + i sign = "+" if float(anom) >= 0 else "" print(f" {year}: {sign}{float(anom):.3f} K") # Step 5: Calculate variability print("\nπŸ“Š Step 5: Analyze spatial variability") winter_std = europe_winter.clone().time_std().compute() print(f" Temporal std (spatial map): {winter_std.dims}") print(f" Mean variability: {float(winter_std.tas.mean().values):.2f} K") print(f" Max variability: {float(winter_std.tas.max().values):.2f} K") print("\n" + "=" * 60) print("βœ… Complete analysis workflow executed!") print("\nπŸ’‘ This entire analysis used:") print(" - Query chaining for readable pipelines") print(" - Query branching for multiple analyses") print(" - F() function for anomaly calculation") print(" - Lazy evaluation with .compute()") print("\n🎯 Total lines of code: ~15 (vs. 50+ with traditional approach!)") ``` -------------------------------- ### Initialize CDO Wrapper Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Instantiate the CDO class to interface with the CDO executable. ```python from python_cdo_wrapper import CDO cdo = CDO(cdo_path="cdo", temp_dir=None) ``` -------------------------------- ### v1.0.0 Readable Chaining vs. v0.x String Commands Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Compares the v0.x string-based command execution with the v1.0.0 self-documenting chained API for complex operations. ```python # v0.x: Hard to read string ds, log = cdo("-fldmean -yearmean -selyear,2020,2021,2022 -selname,tas data.nc") ``` ```python # v1.0.0: Self-documenting ds = ( cdo.query("data.nc") .select_var("tas") .select_year(2020, 2021, 2022) .year_mean() .field_mean() .compute() ) ``` -------------------------------- ### Calculate Model Bias (Complex Binary Operation) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md v0.x requires a complex multi-step process for model bias calculation. The example shows calculating the mean of model data. ```python # Process model model_mean, _ = cdo("-fldmean -yearmean -selname,tas model.nc", output_file="model_mean.nc") ``` -------------------------------- ### Query Templates Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Define reusable analysis patterns and bind them to different files or variables. ```python from python_cdo_wrapper import CDOQueryTemplate # Define template annual_global_mean = ( CDOQueryTemplate() .select_var("{var}") .year_mean() .field_mean() ) # Apply to multiple files/variables tas_mean = annual_global_mean.bind(cdo, "era5.nc", var="tas").compute() pr_mean = annual_global_mean.bind(cdo, "era5.nc", var="pr").compute() ``` -------------------------------- ### Get Variable List (vlist) Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md v0.x returns text output. v1.0.0 returns a structured VlistResult object, allowing direct access to variable details like name, longname, units, and code. ```python vlist = cdo("vlist data.nc") # Parse text output ``` ```python vlist = cdo.vlist("data.nc") # Returns VlistResult for var in vlist.variables: print(f"{var.name}: {var.longname}") print(f" Units: {var.units}") print(f" Code: {var.code}") ``` -------------------------------- ### Code Style and Quality Commands Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/CONTRIBUTING.md Commands for formatting code, linting, and type checking. ```bash # Format code ruff format . # Check for lint errors ruff check . # Auto-fix lint errors where possible ruff check --fix . # Type checking mypy python_cdo_wrapper ``` -------------------------------- ### Get Structured File Information with CDO Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Retrieve structured information about a NetCDF file using CDO's sinfo, griddes, vlist, and partab commands. This provides details on variables, grid, and parameters. ```python from python_cdo_wrapper import CDO cdo = CDO() # Get structured file information info = cdo.sinfo("data.nc") # Returns SinfoResult dataclass print(info.var_names) # ['tas', 'pr', 'psl'] print(info.nvar) # 3 print(info.time_range) # ('2020-01-01', '2022-12-31') print(info.file_format) # 'NetCDF' # Grid information grid = cdo.griddes("data.nc") # Returns GriddesResult print(grid.grids[0].gridtype) # 'lonlat' print(grid.grids[0].xsize) # 360 print(grid.grids[0].ysize) # 180 # Variable list vlist = cdo.vlist("data.nc") # Returns VlistResult for var in vlist.variables: print(f"{var.name}: {var.longname} [{var.units}]") # Parameter table partab = cdo.partab("data.nc") # Returns PartabResult for param in partab.parameters: print(f"{param.code}: {param.name}") ``` -------------------------------- ### Perform basic file operations with CDO Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Demonstrates splitting NetCDF files by year or variable and merging them back together. ```python # 1. Split by year print("1️⃣ Split by year:") cdo.splityear("sample_data.nc", prefix="year_") print(" Created: year_2020.nc, year_2021.nc, year_2022.nc") # 2. Merge time series print("\n2️⃣ Merge time series:") merged = cdo.mergetime("year_2020.nc", "year_2021.nc", "year_2022.nc") print(f" Merged shape: {merged.dims}") print(f" Time range: {merged.time[0].values} to {merged.time[-1].values}") # 3. Split by variable print("\n3️⃣ Split by variable:") cdo.splitname("sample_data.nc", prefix="var_") print(" Created: var_tas.nc, var_pr.nc") # 4. Merge variables print("\n4️⃣ Merge variables:") merged_vars = cdo.merge("var_tas.nc", "var_pr.nc") print(f" Variables: {list(merged_vars.data_vars)}") print("\nβœ… File operations working!") ``` -------------------------------- ### Build and Execute CDO Pipelines Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Demonstrates the Django ORM-style query API for chaining CDO operations and calculating anomalies. ```python from python_cdo_wrapper import CDO, F cdo = CDO() # πŸ”— Chainable query building (lazy evaluation) ds = ( cdo.query("data.nc") .select_var("tas") .select_year(2020, 2021, 2022) .year_mean() .field_mean() .compute() ) # 🎯 One-liner anomaly calculation with F() anomaly = cdo.query("monthly_data.nc").sub(F("climatology.nc")).compute() # πŸ” Inspect before execution query = cdo.query("data.nc").select_var("tas").year_mean() print(query.get_command()) # "cdo -yearmean -selname,tas data.nc" ``` -------------------------------- ### Regional Analysis Workflow Comparison Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Comparison between legacy multi-step file processing and the new v1.0.0 fluent pipeline. ```python # v0.x: # Multiple steps, intermediate files ds1, _ = cdo("-sellonlatbox,-10,30,35,70 input.nc", output_file="europe.nc") ds2, _ = cdo("-selname,tas europe.nc", output_file="europe_tas.nc") ds3, _ = cdo("-yearmean europe_tas.nc", output_file="europe_tas_annual.nc") result, _ = cdo("-fldmean europe_tas_annual.nc") ``` ```python # v1.0.0: # Single readable pipeline result = ( cdo.query("input.nc") .select_var("tas") .select_region(-10, 30, 35, 70) .year_mean() .field_mean() .compute() ) ``` -------------------------------- ### Legacy API Usage Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Maintain compatibility with v0.x code. ```python from python_cdo_wrapper import cdo # Note: lowercase 'cdo' # All v0.x code works unchanged ds, log = cdo("yearmean input.nc") ``` -------------------------------- ### Cite the Package Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md BibTeX citation for the Python CDO Wrapper. ```bibtex @software{python_cdo_wrapper, title = {Python CDO Wrapper}, author = {B M Naren Karthik}, year = {2024}, url = {https://github.com/NarenKarthikBM/python-cdo-wrapper}, } ``` -------------------------------- ### Backward Compatibility Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/MIGRATION_GUIDE.md Legacy v0.x API usage remains fully supported in v1.0.0. ```python # v0.x code still works in v1.0.0 from python_cdo_wrapper import cdo ds, log = cdo("yearmean input.nc") info = cdo("sinfo data.nc") grid_dict = cdo("griddes data.nc", return_dict=True) ``` -------------------------------- ### Calculate Seasonal Climatology and Anomalies Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/README.md Shows how to generate a climatology file and use it to compute seasonal anomalies in a single chain. ```python from python_cdo_wrapper import CDO, F cdo = CDO() # Step 1: Create seasonal climatology climatology = ( cdo.query("historical_1981-2010.nc") .select_var("tas") .season_mean() .time_mean() # Average over all years .to_file("seasonal_clim.nc") ) # Step 2: Calculate seasonal anomalies (ONE LINE!) anomalies = ( cdo.query("current_data.nc") .select_var("tas") .season_mean() .sub(F("seasonal_clim.nc")) .compute("seasonal_anomalies.nc") ) ``` -------------------------------- ### Demonstrate CDO Query Branching with .clone() Source: https://github.com/narenkarthikbm/python-cdo-wrapper/blob/main/examples/v1.0.0-demo.ipynb Create variations from a base CDO query using `.clone()` for comparative analyses, such as different temporal aggregations. ```python # Create a base query with common operations base = ( cdo.query("sample_data.nc") .select_var("tas") .select_level(1000) # Surface level .select_region(lon1=-10, lon2=40, lat1=35, lat2=70) # Europe ) print("🌳 Base Query Created") print("=" * 70) print(f"Description: European surface temperature") print(f"Command: {base.get_command()}") # Branch 1: Annual means print("\nπŸ“Š Branch 1: Annual Means") print("-" * 70) annual_mean = base.clone().year_mean().field_mean().compute() print(f"βœ… Computed annual means for {len(annual_mean.time)} years") print(f" Values: {[f'{float(v):.2f}' for v in annual_mean.tas.values]} K") # Branch 2: Monthly climatology print("\nπŸ“Š Branch 2: Monthly Climatology") print("-" * 70) monthly_mean = base.clone().month_mean().field_mean().compute() print("βœ… Computed monthly climatology") print(f" Shape: {dict(monthly_mean.dims)}") print(f" Coldest month: {float(monthly_mean.tas.min().values):.2f} K") print(f" Warmest month: {float(monthly_mean.tas.max().values):.2f} K") ```