2020logger = logging .getLogger (__name__ )
2121
2222
23- def load_method (methods : pd .DataFrame , project_id : int , planning_horizon : int ) -> str :
23+ def check_method (method : str ) -> str :
24+ """
25+ Normalize and validate the CBA method name.
26+
27+ If the method is not recognized as either "pint" or "toot", a ValueError is raised.
28+ """
29+ method = method .lower ().strip ()
30+ if method not in ["pint" , "toot" ]:
31+ raise ValueError (f"Method must be 'pint' or 'toot', got: { method } " )
32+ return method
33+
34+
35+ def load_method (methods_fn : str , project_id : int , planning_horizon : int ) -> str :
36+ """
37+ Load the method for a specific project and planning horizon.
38+
39+ Parameters
40+ ----------
41+ methods_fn : str
42+ Path to the file defining the methods.
43+ project_id : int
44+ Project reference ID.
45+ planning_horizon : int
46+ Planning horizon
47+
48+ Returns
49+ -------
50+ str
51+ Method to be used to assess a project at a planning horizon.
52+
53+ """
54+ methods = pd .read_csv (methods_fn )
2455 row = methods [
2556 (methods ["project_id" ] == project_id )
2657 & (methods ["planning_horizon" ] == planning_horizon )
@@ -29,7 +60,7 @@ def load_method(methods: pd.DataFrame, project_id: int, planning_horizon: int) -
2960 raise ValueError (
3061 f"Missing CBA method for project { project_id } and horizon { planning_horizon } "
3162 )
32- return str (row ["method" ].iloc [0 ]). strip (). upper ( )
63+ return check_method (row ["method" ].iloc [0 ])
3364
3465
3566def apply_toot (
@@ -145,38 +176,37 @@ def apply_pint(
145176 configure_logging (snakemake )
146177 set_scenario_config (snakemake )
147178
148- n = pypsa .Network (snakemake .input .network )
179+ cba_project = snakemake .wildcards .cba_project
180+ planning_horizon = int (snakemake .wildcards .planning_horizons )
181+ methods_fn = snakemake .input .methods
149182 transmission_projects = pd .read_csv (snakemake .input .transmission_projects )
150- methods = pd .read_csv (snakemake .input .methods )
183+ n = pypsa .Network (snakemake .input .network )
184+ hurdle_costs = snakemake .params .hurdle_costs
185+ costs = pd .read_csv (snakemake .input .costs , index_col = 0 )
151186
152- cba_project = snakemake .wildcards .cba_project
153187 project_id = int (cba_project [1 :])
154- planning_horizon = int (snakemake .wildcards .planning_horizons )
155188 if planning_horizon not in [2030 , 2040 ]:
156189 logger .warning (
157190 "CBA methods are only available for 2030 or 2040. Using 2040 for planning horizon %s." ,
158191 snakemake .wildcards .planning_horizons ,
159192 )
160193 planning_horizon = 2040
161194
162- method = load_method (methods , project_id , planning_horizon )
163- hurdle_costs = snakemake .params .hurdle_costs
195+ method = load_method (methods_fn , project_id , planning_horizon )
164196 negative_toot_capacity = snakemake .config ["cba" ].get (
165197 "negative_toot_capacity" , "zero"
166198 )
167199
168- costs = pd .read_csv (snakemake .input .costs , index_col = 0 )
169-
170200 transmission_project = transmission_projects [
171201 transmission_projects ["project_id" ] == project_id
172202 ]
173203 assert not transmission_project .empty , (
174204 f"Transmission project { project_id } not found."
175205 )
176206
177- if method == "TOOT " :
207+ if method == "toot " :
178208 apply_toot (n , transmission_project , negative_toot_capacity )
179- elif method == "PINT " :
209+ elif method == "pint " :
180210 apply_pint (n , transmission_project , hurdle_costs , costs )
181211 else :
182212 raise ValueError (f"Unknown method { method } for project { project_id } " )
0 commit comments