1+ from numpy .random import rand
12from pytest import fixture , mark
23
34YEAR = 2030
45
56
67@fixture
7- def _demand (demand_share ):
8- return demand_share
8+ def objective_data (technologies , market , demand_share ):
9+ """Creates the complete dataset needed for objective calculations.
10+
11+ The transformation follows these steps:
12+ 1. Extract year-specific data from technologies and market
13+ 2. Transform technology data to asset level with replacement dimension
14+ 3. Transform price data to asset level
15+ 4. Add any additional variables needed for specific objectives
16+
17+ Returns:
18+ dict: Contains all necessary data for objective calculations:
19+ - technologies: Technology parameters with replacement dimension
20+ - prices: Prices relevant to each asset
21+ - demand: Demand share data
22+ """
23+ from muse .utilities import broadcast_over_assets
924
25+ # Step 1: Extract year-specific data
26+ tech_year = technologies .sel (year = YEAR ).rename (technology = "replacement" )
27+ prices_year = market .prices .sel (year = YEAR )
1028
11- @fixture
12- def _technologies (technologies , demand_share ):
13- from muse .utilities import broadcast_over_assets
29+ # Step 2 & 3: Transform to asset level
30+ tech_assets = broadcast_over_assets (tech_year , demand_share )
31+ prices_assets = broadcast_over_assets (
32+ prices_year , demand_share , installed_as_year = False
33+ )
1434
15- techs = technologies .sel (year = YEAR ).rename (technology = "replacement" )
16- return broadcast_over_assets (techs , demand_share )
35+ # Step 4: Add computed variables needed by some objectives
36+ tech_assets ["comfort" ] = _add_var (tech_assets , "replacement" )
37+ tech_assets ["efficiency" ] = _add_var (tech_assets , "replacement" )
38+ tech_assets ["scaling_size" ] = _add_var (tech_assets , "replacement" )
1739
40+ return {
41+ "technologies" : tech_assets ,
42+ "prices" : prices_assets ,
43+ "demand" : demand_share ,
44+ }
1845
19- @fixture
20- def _prices (market , demand_share ):
21- from muse .utilities import broadcast_over_assets
2246
23- prices = market .prices .sel (year = YEAR )
24- return broadcast_over_assets (prices , demand_share , installed_as_year = False )
47+ def _add_var (coordinates , * dims , factor = 100.0 ):
48+ """Helper function to add random variables with specified dimensions."""
49+ shape = tuple (len (coordinates [u ]) for u in dims )
50+ return dims , (rand (* shape ) * factor ).astype (type (factor ))
2551
2652
27- def test_fixtures (_technologies , _demand , _prices ):
28- """Validating that the fixtures have appropriate dimensions."""
29- assert set (_technologies .dims ) == {"asset" , "commodity" , "replacement" }
30- assert set (_demand .dims ) == {"asset" , "commodity" , "timeslice" }
31- assert set (_prices .dims ) == {"asset" , "commodity" , "timeslice" }
53+ def test_fixtures (objective_data ):
54+ """Validating that the fixture data has appropriate dimensions."""
55+ assert set (objective_data ["technologies" ].dims ) == {
56+ "asset" ,
57+ "commodity" ,
58+ "replacement" ,
59+ }
60+ assert set (objective_data ["demand" ].dims ) == {"asset" , "commodity" , "timeslice" }
61+ assert set (objective_data ["prices" ].dims ) == {"asset" , "commodity" , "timeslice" }
3262
3363
3464@mark .usefixtures ("save_registries" )
@@ -51,7 +81,7 @@ def b_objective(*args, **kwargs):
5181
5282
5383@mark .usefixtures ("save_registries" )
54- def test_computing_objectives (_technologies , _demand , _prices ):
84+ def test_computing_objectives (objective_data ):
5585 from muse .objectives import factory , register_objective
5686
5787 @register_objective
@@ -78,20 +108,27 @@ def second(technologies, demand, assets=None, *args, **kwargs):
78108
79109 # Test first objective with/without switch
80110 objectives = factory ("first" )(
81- technologies = _technologies , demand = _demand , prices = _prices , switch = True
111+ technologies = objective_data ["technologies" ],
112+ demand = objective_data ["demand" ],
113+ prices = objective_data ["prices" ],
114+ switch = True ,
82115 )
83116 assert set (objectives .data_vars ) == {"first" }
84117 assert (objectives .first == 1 ).all ()
118+
85119 objectives = factory ("first" )(
86- technologies = _technologies , demand = _demand , prices = _prices , switch = False
120+ technologies = objective_data ["technologies" ],
121+ demand = objective_data ["demand" ],
122+ prices = objective_data ["prices" ],
123+ switch = False ,
87124 )
88125 assert (objectives .first == 2 ).all ()
89126
90127 # Test multiple objectives
91128 objectives = factory (["first" , "second" ])(
92- technologies = _technologies ,
93- demand = _demand ,
94- prices = _prices ,
129+ technologies = objective_data [ "technologies" ] ,
130+ demand = objective_data [ "demand" ] ,
131+ prices = objective_data [ "prices" ] ,
95132 switch = False ,
96133 assets = 0 ,
97134 )
@@ -103,109 +140,133 @@ def second(technologies, demand, assets=None, *args, **kwargs):
103140 assert (objectives .second .isel (asset = 1 ) == 5 ).all ()
104141
105142
106- def test_comfort (_technologies , _demand ):
143+ def test_comfort (objective_data ):
107144 from muse .objectives import comfort
108145
109- _technologies ["comfort" ] = add_var (_technologies , "replacement" )
110- result = comfort (_technologies , _demand )
146+ result = comfort (objective_data ["technologies" ], objective_data ["demand" ])
111147 assert set (result .dims ) == {"replacement" , "asset" }
112148
113149
114- def test_efficiency (_technologies , _demand ):
150+ def test_efficiency (objective_data ):
115151 from muse .objectives import efficiency
116152
117- _technologies ["efficiency" ] = add_var (_technologies , "replacement" )
118- result = efficiency (_technologies , _demand )
153+ result = efficiency (objective_data ["technologies" ], objective_data ["demand" ])
119154 assert set (result .dims ) == {"replacement" , "asset" }
120155
121156
122- def test_capacity_to_service_demand (_technologies , _demand ):
157+ def test_capacity_to_service_demand (objective_data ):
123158 from muse .objectives import capacity_to_service_demand
124159
125- result = capacity_to_service_demand (_technologies , _demand )
160+ result = capacity_to_service_demand (
161+ objective_data ["technologies" ], objective_data ["demand" ]
162+ )
126163 assert set (result .dims ) == {"replacement" , "asset" }
127164
128165
129- def test_capacity_in_use (_technologies , _demand ):
166+ def test_capacity_in_use (objective_data ):
130167 from muse .objectives import capacity_in_use
131168
132- result = capacity_in_use (_technologies , _demand )
169+ result = capacity_in_use (objective_data [ "technologies" ], objective_data [ "demand" ] )
133170 assert set (result .dims ) == {"replacement" , "asset" }
134171
135172
136- def test_consumption (_technologies , _demand , _prices ):
173+ def test_consumption (objective_data ):
137174 from muse .objectives import consumption
138175
139- result = consumption (_technologies , _demand , _prices )
176+ result = consumption (
177+ objective_data ["technologies" ],
178+ objective_data ["demand" ],
179+ objective_data ["prices" ],
180+ )
140181 assert set (result .dims ) == {"replacement" , "asset" , "timeslice" }
141182
142183
143- def test_fixed_costs (_technologies , _demand ):
184+ def test_fixed_costs (objective_data ):
144185 from muse .objectives import fixed_costs
145186
146- result = fixed_costs (_technologies , _demand )
187+ result = fixed_costs (objective_data [ "technologies" ], objective_data [ "demand" ] )
147188 assert set (result .dims ) == {"replacement" , "asset" }
148189
149190
150- def test_capital_costs (_technologies , _demand ):
191+ def test_capital_costs (objective_data ):
151192 from muse .objectives import capital_costs
152193
153- _technologies ["scaling_size" ] = add_var (_technologies , "replacement" )
154- result = capital_costs (_technologies , _demand )
194+ result = capital_costs (objective_data ["technologies" ], objective_data ["demand" ])
155195 assert set (result .dims ) == {"replacement" , "asset" }
156196
157197
158- def test_emission_cost (_technologies , _demand , _prices ):
198+ def test_emission_cost (objective_data ):
159199 from muse .objectives import emission_cost
160200
161- result = emission_cost (_technologies , _demand , _prices )
201+ result = emission_cost (
202+ objective_data ["technologies" ],
203+ objective_data ["demand" ],
204+ objective_data ["prices" ],
205+ )
162206 assert set (result .dims ) == {"replacement" , "asset" , "timeslice" }
163207
164208
165- def test_fuel_consumption_cost (_technologies , _demand , _prices ):
209+ def test_fuel_consumption_cost (objective_data ):
166210 from muse .objectives import fuel_consumption_cost
167211
168- result = fuel_consumption_cost (_technologies , _demand , _prices )
212+ result = fuel_consumption_cost (
213+ objective_data ["technologies" ],
214+ objective_data ["demand" ],
215+ objective_data ["prices" ],
216+ )
169217 assert set (result .dims ) == {"replacement" , "asset" , "timeslice" }
170218
171219
172- def test_annual_levelized_cost_of_energy (_technologies , _demand , _prices ):
220+ def test_annual_levelized_cost_of_energy (objective_data ):
173221 from muse .objectives import annual_levelized_cost_of_energy
174222
175- result = annual_levelized_cost_of_energy (_technologies , _demand , _prices )
223+ result = annual_levelized_cost_of_energy (
224+ objective_data ["technologies" ],
225+ objective_data ["demand" ],
226+ objective_data ["prices" ],
227+ )
176228 assert set (result .dims ) == {"replacement" , "asset" }
177229
178230
179- def test_lifetime_levelized_cost_of_energy (_technologies , _demand , _prices ):
231+ def test_lifetime_levelized_cost_of_energy (objective_data ):
180232 from muse .objectives import lifetime_levelized_cost_of_energy
181233
182- result = lifetime_levelized_cost_of_energy (_technologies , _demand , _prices )
234+ result = lifetime_levelized_cost_of_energy (
235+ objective_data ["technologies" ],
236+ objective_data ["demand" ],
237+ objective_data ["prices" ],
238+ )
183239 assert set (result .dims ) == {"replacement" , "asset" }
184240
185241
186- def test_net_present_value (_technologies , _demand , _prices ):
242+ def test_net_present_value (objective_data ):
187243 from muse .objectives import net_present_value
188244
189- result = net_present_value (_technologies , _demand , _prices )
245+ result = net_present_value (
246+ objective_data ["technologies" ],
247+ objective_data ["demand" ],
248+ objective_data ["prices" ],
249+ )
190250 assert set (result .dims ) == {"replacement" , "asset" }
191251
192252
193- def test_net_present_cost (_technologies , _demand , _prices ):
253+ def test_net_present_cost (objective_data ):
194254 from muse .objectives import net_present_cost
195255
196- result = net_present_cost (_technologies , _demand , _prices )
256+ result = net_present_cost (
257+ objective_data ["technologies" ],
258+ objective_data ["demand" ],
259+ objective_data ["prices" ],
260+ )
197261 assert set (result .dims ) == {"replacement" , "asset" }
198262
199263
200- def test_equivalent_annual_cost (_technologies , _demand , _prices ):
264+ def test_equivalent_annual_cost (objective_data ):
201265 from muse .objectives import equivalent_annual_cost
202266
203- result = equivalent_annual_cost (_technologies , _demand , _prices )
267+ result = equivalent_annual_cost (
268+ objective_data ["technologies" ],
269+ objective_data ["demand" ],
270+ objective_data ["prices" ],
271+ )
204272 assert set (result .dims ) == {"replacement" , "asset" }
205-
206-
207- def add_var (coordinates , * dims , factor = 100.0 ):
208- from numpy .random import rand
209-
210- shape = tuple (len (coordinates [u ]) for u in dims )
211- return dims , (rand (* shape ) * factor ).astype (type (factor ))
0 commit comments