31
31
from .util import wildcard
32
32
33
33
if TYPE_CHECKING :
34
- from genno .core .key import KeyLike # TODO Import from genno.types
35
34
from genno .types import AnyQuantity
36
35
37
36
from message_ix_models .types import ParameterData
40
39
41
40
log = logging .getLogger (__name__ )
42
41
43
- #: Shorthand for tags on keys
42
+ #: Shorthand for tags on keys.
44
43
Li = "::LDV+ixmp"
45
44
46
45
#: Target key that collects all data generated in this module.
@@ -200,9 +199,9 @@ def prepare_computer(c: Computer):
200
199
else :
201
200
c .apply (
202
201
prepare_tech_econ ,
203
- k_efficiency = k .eff [2 ],
204
- k_inv_cost = "inv_cost:n-t-y:LDV+exo" ,
205
- k_fix_cost = "fix_cost:n-t-y:LDV+exo" ,
202
+ efficiency = k .eff [2 ],
203
+ inv_cost = Key ( "inv_cost:n-t-y:LDV+exo" ) ,
204
+ fix_cost = Key ( "fix_cost:n-t-y:LDV+exo" ) ,
206
205
)
207
206
208
207
# Usage
@@ -257,6 +256,10 @@ def prepare_computer(c: Computer):
257
256
c .add ("transport_data" , __name__ , key = TARGET )
258
257
259
258
259
+ #: Common, fixed values for :func:`.prepare_tech_econ` and :func:`.get_dummy`.
260
+ COMMON = dict (mode = "all" , time = "year" , time_dest = "year" , time_origin = "year" )
261
+
262
+ #: Mapping from short dimension IDs to MESSAGE index names.
260
263
DIMS = dict (
261
264
commodity = "c" ,
262
265
level = "l" ,
@@ -267,80 +270,73 @@ def prepare_computer(c: Computer):
267
270
year_act = "ya" ,
268
271
year_vtg = "yv" ,
269
272
)
270
- COMMON = dict (mode = "all" , time = "year" , time_dest = "year" , time_origin = "year" )
271
273
272
274
273
275
def prepare_tech_econ (
274
- c : Computer ,
275
- * ,
276
- k_efficiency : "KeyLike" ,
277
- k_inv_cost : "KeyLike" ,
278
- k_fix_cost : "KeyLike" ,
276
+ c : Computer , * , efficiency : Key , inv_cost : Key , fix_cost : Key
279
277
) -> None :
280
278
"""Prepare `c` to calculate techno-economic parameters for LDVs.
281
279
282
280
This prepares `k_target` to return a data structure with MESSAGE-ready data for the
283
281
parameters ``input``, ``ouput``, ``fix_cost``, and ``inv_cost``.
284
282
"""
285
- # Collection of KeySeq for starting-points
286
- k = Keys (input = Key ("input::LDV" ), output = Key ("output::LDV" ))
287
-
288
283
# Identify periods to include
289
284
# FIXME Avoid hard-coding this period
290
285
c .add ("y::LDV" , lambda y : list (filter (lambda x : 1995 <= x , y )), "y" )
291
286
292
287
# Create base quantity for "output" parameter
293
- nty = tuple ("nty" )
294
- c .add (k .output [0 ] * nty , wildcard (1.0 , "Gv km" , nty ))
295
- for i , coords in enumerate (["n::ex world" , "t::LDV" , "y::model" ]):
296
- c .add (
297
- k .output [i + 1 ] * nty ,
298
- "broadcast_wildcard" ,
299
- k .output [i ] * nty ,
300
- coords ,
301
- dim = coords [0 ],
302
- )
303
-
304
- ### Convert input, output to MESSAGE data structure
305
- for par_name , base , ks , i in (
306
- ("input" , k_efficiency , k .input , 0 ),
307
- ("output" , k .output [3 ] * nty , k .output , 4 ),
288
+ k = output_base = Key ("output:n-t-y:LDV" )
289
+ c .add (k [0 ], wildcard (1.0 , "Gv km" , k .dims ))
290
+
291
+ # Broadcast over (n, t, y) dimensions
292
+ coords = ["n::ex world" , "t::LDV" , "y::model" ]
293
+ c .add (k [1 ], "broadcast_wildcard" , k [0 ], * coords , dim = k .dims )
294
+
295
+ # Broadcast `exo.input_share` over (c, t) dimensions. This produces a large Quantity
296
+ # with 1.0 everywhere except explicit entries in the input data file.
297
+ # NB Order matters here
298
+ k = exo .input_share
299
+ coords = ["t::LDV" , "c::transport+base" , "y::model" ]
300
+ c .add (k [0 ], "broadcast_wildcard" , k , * coords , dim = k .dims )
301
+
302
+ # Multiply by `bcast_tcl.input` to keep only the entries that correspond to actual
303
+ # input commodities of particular technologies.
304
+ input_bcast = c .add ("input broadcast::LDV" , "mul" , k [0 ], bcast_tcl .input )
305
+
306
+ ### Convert input and output to MESSAGE data structure
307
+ for par_name , base , bcast in (
308
+ ("input" , efficiency , input_bcast ),
309
+ ("output" , output_base [1 ], bcast_tcl .output ),
308
310
):
311
+ k = Key (par_name , base .dims , "LDV" )
312
+
309
313
# Extend data over missing periods in the model horizon
310
- c .add (ks [ i ], "extend_y" , base , "y::LDV" )
314
+ c .add (k [ 0 ], "extend_y" , base , "y::LDV" )
311
315
312
- # Produce the full quantity for input/output efficiency
313
- prev = c .add (ks [i + 1 ], "mul" , ks [i ], getattr (bcast_tcl , par_name ), bcast_y .all )
316
+ # Broadcast from (y) to (yv, ya) dims to produce the full quantity for
317
+ # input/output efficiency
318
+ prev = c .add (k [1 ], "mul" , k [0 ], bcast , bcast_y .all )
314
319
315
320
# Convert to ixmp/MESSAGEix-structured pd.DataFrame
316
- # NB quote() is necessary with dask 2024.11.0, not with earlier versions
317
- c .add (ks [i + 2 ], "as_message_df" , prev , name = par_name , dims = DIMS , common = COMMON )
321
+ c .add (k [2 ], "as_message_df" , prev , name = par_name , dims = DIMS , common = COMMON )
318
322
319
- # Convert to target units
320
- _add (c , par_name , convert_units , ks [ i + 2 ], "transport info" )
323
+ # Convert to target units and append to `TARGET`
324
+ _add (c , par_name , convert_units , k [ 2 ], "transport info" )
321
325
322
326
### Transform costs
323
- for par_name , base in (("fix_cost" , k_fix_cost ), ("inv_cost" , k_inv_cost )):
324
- prev = c .add (
325
- f"{ par_name } ::LDV+0" ,
326
- "interpolate" ,
327
- base ,
328
- "y::coords" ,
329
- kwargs = dict (fill_value = "extrapolate" ),
330
- )
327
+ kw = dict (fill_value = "extrapolate" )
328
+ for name , base in (("fix_cost" , fix_cost ), ("inv_cost" , inv_cost )):
329
+ prev = c .add (f"{ par_name } ::LDV+0" , "interpolate" , base , "y::coords" , kwargs = kw )
331
330
prev = c .add (f"{ par_name } ::LDV+1" , "mul" , prev , bcast_y .all )
332
- _add (
333
- c , par_name , "as_message_df" , prev , name = par_name , dims = DIMS , common = COMMON
334
- )
331
+ _add (c , name , "as_message_df" , prev , name = par_name , dims = DIMS , common = COMMON )
335
332
336
333
### Compute CO₂ emissions factors
337
-
338
334
# Extract the 'input' data frame
339
- k . other = Key ("other::LDV" )
340
- c .add (k . other [0 ], itemgetter ("input" ), f"input{ Li } " )
335
+ other = Key ("other::LDV" )
336
+ c .add (other [0 ], itemgetter ("input" ), f"input{ Li } " )
341
337
342
- # Use ef_for_input
343
- _add (c , "emission_factor" , ef_for_input , "context" , k . other [0 ], species = "CO2" )
338
+ # Apply ef_for_input; append to `TARGET`
339
+ _add (c , "emission_factor" , ef_for_input , "context" , other [0 ], species = "CO2" )
344
340
345
341
346
342
def get_dummy (context ) -> "ParameterData" :
0 commit comments