33import pandas as pd
44import xarray as xr
55
6+ from muse .timeslices import QuantityType
7+
68
79def read_inputs (data_dir ):
810 data = {}
@@ -42,17 +44,15 @@ def read_inputs(data_dir):
4244def read_timeslices_csv (buffer_ , con ):
4345 sql = """CREATE TABLE timeslices (
4446 id BIGINT PRIMARY KEY,
45- season VARCHAR,
47+ month VARCHAR,
4648 day VARCHAR,
47- time_of_day VARCHAR,
49+ hour VARCHAR,
4850 fraction DOUBLE CHECK (fraction >= 0 AND fraction <= 1),
4951 );
5052 """
5153 con .sql (sql )
5254 rel = con .read_csv (buffer_ , header = True , delimiter = "," ) # noqa: F841
53- con .sql (
54- "INSERT INTO timeslices SELECT id, season, day, time_of_day, fraction FROM rel;"
55- )
55+ con .sql ("INSERT INTO timeslices SELECT id, month, day, hour, fraction FROM rel;" )
5656 return con .sql ("SELECT * from timeslices" ).fetchnumpy ()
5757
5858
@@ -278,17 +278,19 @@ def calculate_initial_market(
278278 - If price data is not specified for a commodity/region combination, the price is
279279 zero
280280
281- """
282- from muse .timeslices import QuantityType , convert_timeslice
281+ Todo:
282+ - Allow data to be specified on a timeslice level (optional)
283+ - Interpolation, missing year field, flexible timeslice specification as above
283284
285+ """
284286 # Prepare dataframes
285287 df_trade = pd .DataFrame (commodity_trade ).set_index (["commodity" , "region" , "year" ])
286288 df_costs = (
287289 pd .DataFrame (commodity_costs )
288290 .set_index (["commodity" , "region" , "year" ])
289291 .rename (columns = {"value" : "prices" })
290292 )
291- df_timeslices = pd .DataFrame (timeslices ).set_index (["season " , "day" , "time_of_day " ])
293+ df_timeslices = pd .DataFrame (timeslices ).set_index (["month " , "day" , "hour " ])
292294
293295 # DataArray dimensions
294296 all_commodities = commodities ["id" ].astype (np .dtype ("str" ))
@@ -320,13 +322,17 @@ def calculate_initial_market(
320322 # Calculate static trade
321323 df_trade ["static_trade" ] = df_trade ["export" ] - df_trade ["import" ]
322324
323- # Create Data
324- df_full = df_costs .join (df_trade )
325- data = df_full .to_xarray ()
326- ts = df_timeslices .to_xarray ()["fraction" ]
327- ts = ts .stack (timeslice = ("season" , "day" , "time_of_day" ))
328- convert_timeslice (data , ts , QuantityType .EXTENSIVE )
325+ # Create xarray datasets
326+ xr_costs = df_costs .to_xarray ()
327+ xr_trade = df_trade .to_xarray ()
328+
329+ # Project over timeslices
330+ ts = df_timeslices .to_xarray ()["fraction" ].stack (timeslice = ("month" , "day" , "hour" ))
331+ xr_costs = project_timeslice (xr_costs , ts , QuantityType .EXTENSIVE )
332+ xr_trade = project_timeslice (xr_trade , ts , QuantityType .INTENSIVE )
329333
334+ # Combine data
335+ data = xr .merge ([xr_costs , xr_trade ])
330336 return data
331337
332338
@@ -353,3 +359,30 @@ def check_all_values_specified(
353359 ).all ():
354360 msg = "" # TODO
355361 raise DataValidationError (msg )
362+
363+
364+ def project_timeslice (
365+ data : xr .Dataset , timeslices : xr .DataArray , quantity_type : QuantityType
366+ ) -> xr .Dataset :
367+ """Project a dataset over a new timeslice dimension.
368+
369+ The projection can be done in one of two ways, depending on whether the
370+ quantity type is extensive or intensive. See `QuantityType`.
371+
372+ Args:
373+ data: Dataset to project
374+ timeslices: DataArray of timeslice levels, with values between 0 and 1
375+ representing the timeslice length (fraction of the year)
376+ quantity_type: Type of projection to perform. QuantityType.EXTENSIVE or
377+ QuantityType.INTENSIVE
378+
379+ Returns:
380+ Projected dataset
381+ """
382+ assert "timeslice" in timeslices .dims
383+ assert "timeslice" not in data .dims
384+
385+ if quantity_type is QuantityType .INTENSIVE :
386+ return data * timeslices
387+ if quantity_type is QuantityType .EXTENSIVE :
388+ return data * xr .ones_like (timeslices )
0 commit comments