@@ -43,7 +43,7 @@ def extract_tilefrac(tilefrac, tilenum, landfrac=None, lev=None):
4343 Land fraction variable (fractional, 0-1) representing the proportion
4444 of each grid cell that is land. Required for proper calculation.
4545 lev : str, optional
46- Name of vegetation type key from mod_mapping dictionary to add as a
46+ Name of vegetation type key from mod_mapping dictionary to add as a
4747 dimension to output array. Used for CMOR character-type variables.
4848 Examples: "typebare", "typecrop", "typetree", etc.
4949
@@ -64,11 +64,11 @@ def extract_tilefrac(tilefrac, tilenum, landfrac=None, lev=None):
6464 Examples
6565 --------
6666 Extract crop fraction as percentage:
67-
67+
6868 >>> crop_percent = extract_tilefrac(tilefrac, 9, landfrac)
69-
69+
7070 Extract combined grass types with vegetation type dimension:
71-
71+
7272 >>> grass_percent = extract_tilefrac(tilefrac, [6, 7], landfrac, lev="typenatgr")
7373
7474 Notes
@@ -82,7 +82,7 @@ def extract_tilefrac(tilefrac, tilenum, landfrac=None, lev=None):
8282 # Vegetation type mapping for CMOR character variables
8383 mod_mapping = {
8484 "typebare" : "bare_ground" ,
85- "typeburnt" : "burnt_vegetation" ,
85+ "typeburnt" : "burnt_vegetation" ,
8686 "typec3pft" : "c3_plant_functional_types" ,
8787 "typec3crop" : "crops_of_c3_plant_functional_types" ,
8888 "typec3natg" : "natural_grasses_of_c3_plant_functional_types" ,
@@ -112,9 +112,9 @@ def extract_tilefrac(tilefrac, tilenum, landfrac=None, lev=None):
112112 "typesirdg" : "sea_ice_ridges" ,
113113 "typetree" : "trees" ,
114114 "typeveg" : "vegetation" ,
115- "typewetla" : "wetland"
115+ "typewetla" : "wetland" ,
116116 }
117-
117+
118118 pseudo_level = tilefrac .dims [1 ]
119119 tilefrac = tilefrac .rename ({pseudo_level : "pseudo_level" })
120120 if isinstance (tilenum , int ):
@@ -125,48 +125,45 @@ def extract_tilefrac(tilefrac, tilenum, landfrac=None, lev=None):
125125 raise Exception ("E: tile number must be an integer or list" )
126126 if landfrac is None :
127127 raise Exception ("E: landfrac not defined" )
128-
128+
129129 # Convert to percentage
130130 vout = vout * landfrac * 100.0
131-
131+
132132 # Add vegetation type dimension if requested
133133 if lev :
134134 if lev not in mod_mapping :
135135 raise Exception (f"E: vegetation type '{ lev } ' not found in mod_mapping" )
136-
136+
137137 # Create character coordinate for the type dimension
138138 type_string = mod_mapping [lev ]
139139 strlen = len (type_string )
140-
140+
141141 # Convert string to character array for NetCDF
142- char_data = np .array ([c .encode (' utf-8' ) for c in type_string ], dtype = 'S1' )
143-
142+ char_data = np .array ([c .encode (" utf-8" ) for c in type_string ], dtype = "S1" )
143+
144144 # Import xarray locally
145145 import xarray as xr
146-
146+
147147 # Create 2D character array: typebare(typebare=1, strlen=N)
148148 char_2d = char_data .reshape (1 , - 1 )
149-
149+
150150 # Add the type dimension to the data variable
151151 vout = vout .expand_dims (dim = {lev : 1 })
152-
152+
153153 # Create character coordinate
154154 type_coord = xr .DataArray (
155155 char_2d ,
156- dims = [lev , ' strlen' ],
156+ dims = [lev , " strlen" ],
157157 coords = {
158158 lev : [0 ], # Single index for the type dimension
159- ' strlen' : np .arange (strlen )
159+ " strlen" : np .arange (strlen ),
160160 },
161- attrs = {
162- 'long_name' : 'surface type' ,
163- 'standard_name' : 'area_type'
164- }
161+ attrs = {"long_name" : "surface type" , "standard_name" : "area_type" },
165162 )
166-
163+
167164 # Assign the character coordinate to the type dimension
168165 vout = vout .assign_coords ({lev : type_coord })
169-
166+
170167 return vout .fillna (0 )
171168
172169
@@ -224,11 +221,11 @@ def calc_landcover(var, model):
224221 Examples
225222 --------
226223 Calculate CABLE vegetation fractions as percentage:
227-
224+
228225 >>> landcover_pct = calc_landcover([tilefrac, landfrac], "cable")
229-
226+
230227 Calculate CMIP6 land categories as percentage:
231-
228+
232229 >>> landcover_pct = calc_landcover([tilefrac, landfrac], "cmip6")
233230
234231 Notes
@@ -239,7 +236,7 @@ def calc_landcover(var, model):
239236 - CMIP6 model includes 4 broad categories (primary/secondary land, pastures, crops, urban)
240237 - Result represents actual land coverage accounting for land/ocean fraction
241238 - Missing values are filled with zeros for consistent output
242-
239+
243240 Vegetation Types by Model:
244241 - CABLE: Evergreen/Deciduous Forests, Shrub, C3/C4 Grass, Crops, Tundra, etc.
245242 - CMIP6: Primary/Secondary Land, Pastures, Crops, Urban
@@ -280,7 +277,7 @@ def calc_landcover(var, model):
280277def weighted_tile_sum (var , tilefrac , landfrac = 1.0 ):
281278 """
282279 Returns variable weighted by tile fractions and summed over tiles.
283-
280+
284281 This function performs tile-weighted integration by multiplying each tile
285282 value by its fractional coverage, summing across all tiles, and scaling
286283 by land fraction to get the grid-cell integrated value.
@@ -309,7 +306,7 @@ def weighted_tile_sum(var, tilefrac, landfrac=1.0):
309306def calc_cland_with_wood_products (carbon_pools_sum , wood_pools_sum , tilefrac , landfrac ):
310307 """
311308 Calculate total land carbon including wood products with correct weighting.
312-
309+
313310 Parameters:
314311 - carbon_pools_sum: Sum of variables 851-860 (to be weighted by tilefrac)
315312 - wood_pools_sum: Sum of variables 898-900 (no tilefrac weighting)
@@ -321,10 +318,10 @@ def calc_cland_with_wood_products(carbon_pools_sum, wood_pools_sum, tilefrac, la
321318 # Carbon pools: multiply by tilefrac then sum over tiles
322319 carbon_weighted = carbon_pools_sum * tilefrac
323320 carbon_sum = carbon_weighted .sum (dim = pseudo_level )
324-
321+
325322 # Wood products: sum over tiles only (no tilefrac multiplication)
326323 wood_sum = wood_pools_sum .sum (dim = pseudo_level )
327-
324+
328325 # Combine and apply land fraction, convert to kg m-2 (divide by 1000)
329326 total = ((carbon_sum + wood_sum ) / 1000.0 ) * landfrac
330327 return total
@@ -333,31 +330,31 @@ def calc_cland_with_wood_products(carbon_pools_sum, wood_pools_sum, tilefrac, la
333330def calc_mass_pool_kg_m2 (var , tilefrac , landfrac ):
334331 """
335332 Calculate mass pool variable (carbon, nitrogen, etc.) with unit conversion to kg m-2.
336-
333+
337334 This function provides a generalized calculation for any mass pool variable
338335 that requires tile weighting, spatial integration, and unit conversion.
339-
336+
340337 Parameters
341338 ----------
342339 var : xarray.DataArray
343340 Mass pool variable (in g m-2) to be weighted by tilefrac and converted.
344341 Must have a pseudo-level dimension representing tiles.
345- tilefrac : xarray.DataArray
342+ tilefrac : xarray.DataArray
346343 Variable defining tiles' fractions (fractional, 0-1).
347344 landfrac : xarray.DataArray
348345 Land fraction (fractional, 0-1).
349-
346+
350347 Returns
351348 -------
352349 xarray.DataArray
353350 Mass pool variable in kg m-2, weighted by tile fractions and land fraction.
354351 """
355352 pseudo_level = var .dims [1 ]
356-
353+
357354 # Weight by tilefrac then sum over tiles
358355 weighted = var * tilefrac
359356 summed = weighted .sum (dim = pseudo_level )
360-
357+
361358 # Apply land fraction and convert to kg m-2 (divide by 1000)
362359 result = (summed / 1000.0 ) * landfrac
363360 return result
@@ -366,10 +363,10 @@ def calc_mass_pool_kg_m2(var, tilefrac, landfrac):
366363def calc_carbon_pool_kg_m2 (var , tilefrac , landfrac ):
367364 """
368365 Calculate individual carbon pool variable with unit conversion to kg m-2.
369-
366+
370367 This function is an alias for calc_mass_pool_kg_m2 to maintain backward
371368 compatibility with existing carbon pool calculations.
372-
369+
373370 Parameters
374371 ----------
375372 var : xarray.DataArray
@@ -378,7 +375,7 @@ def calc_carbon_pool_kg_m2(var, tilefrac, landfrac):
378375 Variable defining tiles' fractions.
379376 landfrac : xarray.DataArray
380377 Land fraction variable.
381-
378+
382379 Returns
383380 -------
384381 xarray.DataArray
0 commit comments