From d91c2dd60dc4a79396d4fa3e4374e4171976e782 Mon Sep 17 00:00:00 2001 From: lodersky Date: Fri, 15 Mar 2024 15:57:09 +0800 Subject: [PATCH] Update python packages * Update all packages to the latest version * Changed code accordingly * Some warnings are remaining, have to be handled in the future --- run_intertemporal.py | 68 +++++++++++++++++------------------ run_single_year.py | 2 +- runme.py | 3 +- urbs-env.yml | 25 +++++++------ urbs/features/BuySellPrice.py | 4 +-- urbs/features/storage.py | 11 +++--- urbs/features/transmission.py | 20 ++++++----- urbs/input.py | 4 +-- urbs/model.py | 30 ++++++++++------ urbs/output.py | 22 ++++++------ urbs/plot.py | 30 ++++++++-------- urbs/pyomoio.py | 60 ++++++++++++++++--------------- urbs/report.py | 12 +++---- 13 files changed, 153 insertions(+), 138 deletions(-) diff --git a/run_intertemporal.py b/run_intertemporal.py index 468542cb..da666d0e 100644 --- a/run_intertemporal.py +++ b/run_intertemporal.py @@ -25,31 +25,31 @@ objective = 'cost' # set either 'cost' or 'CO2' as objective # Choose Solver (cplex, glpk, gurobi, ...) -solver = 'glpk' +solver = 'gurobi' # simulation timesteps -(offset, length) = (0, 8760) # time step selection +(offset, length) = (0, 24) # time step selection timesteps = range(offset, offset+length+1) dt = 1 # length of each time step (unit: hours) # detailed reporting commodity/sites report_tuples = [ - (year, 'North', 'Elec'), - (year, 'Mid', 'Elec'), - (year, 'South', 'Elec'), - (year, ['North', 'Mid', 'South'], 'Elec'), - (year+5, 'North', 'Elec'), - (year+5, 'Mid', 'Elec'), - (year+5, 'South', 'Elec'), - (year+5, ['North', 'Mid', 'South'], 'Elec'), - (year+10, 'North', 'Elec'), - (year+10, 'Mid', 'Elec'), - (year+10, 'South', 'Elec'), - (year+10, ['North', 'Mid', 'South'], 'Elec'), - (year+15, 'North', 'Elec'), - (year+15, 'Mid', 'Elec'), - (year+15, 'South', 'Elec'), - (year+15, ['North', 'Mid', 'South'], 'Elec'), + (2019, 'North', 'Elec'), + (2019, 'Mid', 'Elec'), + (2019, 'South', 'Elec'), + (2019, ['North', 'Mid', 'South'], 'Elec'), + (2024, 'North', 'Elec'), + (2024, 'Mid', 'Elec'), + (2024, 'South', 'Elec'), + (2024, ['North', 'Mid', 'South'], 'Elec'), + (2029, 'North', 'Elec'), + (2029, 'Mid', 'Elec'), + (2029, 'South', 'Elec'), + (2029, ['North', 'Mid', 'South'], 'Elec'), + (2034, 'North', 'Elec'), + (2034, 'Mid', 'Elec'), + (2034, 'South', 'Elec'), + (2034, ['North', 'Mid', 'South'], 'Elec'), ] # optional: define names for sites in report_tuples @@ -57,22 +57,22 @@ # plotting commodities/sites plot_tuples = [ - (year, 'North', 'Elec'), - (year, 'Mid', 'Elec'), - (year, 'South', 'Elec'), - (year, ['North', 'Mid', 'South'], 'Elec'), - (year+5, 'North', 'Elec'), - (year+5, 'Mid', 'Elec'), - (year+5, 'South', 'Elec'), - (year+5, ['North', 'Mid', 'South'], 'Elec'), - (year+10, 'North', 'Elec'), - (year+10, 'Mid', 'Elec'), - (year+10, 'South', 'Elec'), - (year+10, ['North', 'Mid', 'South'], 'Elec'), - (year+15, 'North', 'Elec'), - (year+15, 'Mid', 'Elec'), - (year+15, 'South', 'Elec'), - (year+15, ['North', 'Mid', 'South'], 'Elec'), + (2019, 'North', 'Elec'), + (2019, 'Mid', 'Elec'), + (2019, 'South', 'Elec'), + (2019, ['North', 'Mid', 'South'], 'Elec'), + (2024, 'North', 'Elec'), + (2024, 'Mid', 'Elec'), + (2024, 'South', 'Elec'), + (2024, ['North', 'Mid', 'South'], 'Elec'), + (2029, 'North', 'Elec'), + (2029, 'Mid', 'Elec'), + (2029, 'South', 'Elec'), + (2029, ['North', 'Mid', 'South'], 'Elec'), + (2034, 'North', 'Elec'), + (2034, 'Mid', 'Elec'), + (2034, 'South', 'Elec'), + (2034, ['North', 'Mid', 'South'], 'Elec'), ] # optional: define names for sites in plot_tuples diff --git a/run_single_year.py b/run_single_year.py index d9d4f043..87e52c67 100644 --- a/run_single_year.py +++ b/run_single_year.py @@ -25,7 +25,7 @@ objective = 'cost' # set either 'cost' or 'CO2' as objective # Choose Solver (cplex, glpk, gurobi, ...) -solver = 'glpk' +solver = 'gurobi' # simulation timesteps (offset, length) = (0, 20) # time step selection diff --git a/runme.py b/runme.py index 3201b40e..549ac146 100644 --- a/runme.py +++ b/runme.py @@ -2,7 +2,6 @@ import shutil import urbs - input_files = 'single_year_example.xlsx' # for single year file name, for intertemporal folder name input_dir = 'Input' input_path = os.path.join(input_dir, input_files) @@ -22,7 +21,7 @@ objective = 'cost' # set either 'cost' or 'CO2' as objective # Choose Solver (cplex, glpk, gurobi, ...) -solver = 'glpk' +solver = 'gurobi' # simulation timesteps (offset, length) = (3500, 24) # time step selection diff --git a/urbs-env.yml b/urbs-env.yml index 67ebd605..a3787fa3 100644 --- a/urbs-env.yml +++ b/urbs-env.yml @@ -1,17 +1,16 @@ -name: urbs +name: urbs-env channels: - - defaults - conda-forge dependencies: - - python=3.6 - - numpy=1.17.3 - - matplotlib=3.1.1 - - pandas=0.24.2 - - pandas-datareader=0.8.1 - - pytables=3.6.1 - - openpyxl=3.0.1 - - xlrd=1.2.0 - - pyomo=5.6.7 + - python=3.12.2 + - numpy=1.26.4 + - matplotlib=3.8.3 + - pandas=2.2.1 + - pandas-datareader=0.10.0 + - pytables=3.9.2 + - openpyxl=3.1.2 + - xlrd=2.0.1 + - pyomo=6.7.1 - glpk - - psutil=5.6.5 - - pyutilib=5.8.0 + - psutil=5.9.8 + - pyutilib=6.0.0 diff --git a/urbs/features/BuySellPrice.py b/urbs/features/BuySellPrice.py index f1203262..977d5856 100644 --- a/urbs/features/BuySellPrice.py +++ b/urbs/features/BuySellPrice.py @@ -130,8 +130,8 @@ def search_sell_buy_tuple(m, stf, sit_in, pro_in, coin): Returns: a process """ - pro_output_tuples = [x for x in list(m.pro_output_tuples.value) if x[1] == sit_in] - pro_input_tuples = [x for x in list(m.pro_input_tuples.value) if x[1] == sit_in] + pro_output_tuples = [x for x in list(m.pro_output_tuples.data()) if x[1] == sit_in] + pro_input_tuples = [x for x in list(m.pro_input_tuples.data()) if x[1] == sit_in] # search the output commodities for the "buy" process # buy_out = (stf, site, output_commodity) buy_out = set([(x[0], x[1], x[3]) diff --git a/urbs/features/storage.py b/urbs/features/storage.py index a6f418aa..7b3e39a7 100644 --- a/urbs/features/storage.py +++ b/urbs/features/storage.py @@ -5,9 +5,10 @@ def add_storage(m): # storage (e.g. hydrogen, pump storage) - indexlist = set() + indexlist = list() for key in m.storage_dict["eff-in"]: - indexlist.add(tuple(key)[2]) + if key[2] not in indexlist: + indexlist.append(key[2]) m.sto = pyomo.Set( initialize=indexlist, doc='Set of storage technologies') @@ -245,14 +246,14 @@ def res_storage_capacity_rule(m, stf, sit, sto, com): # forced minimun storage content in final timestep t[len(m.t)] # content[t=1] == storage capacity * fraction <= content[t=final] def def_initial_storage_state_rule(m, stf, sit, sto, com): - return (m.e_sto_con[m.t[1], stf, sit, sto, com] == + return (m.e_sto_con[m.t.at(1), stf, sit, sto, com] == m.cap_sto_c[stf, sit, sto, com] * m.storage_dict['init'][(stf, sit, sto, com)]) def res_storage_state_cyclicity_rule(m, stf, sit, sto, com): - return (m.e_sto_con[m.t[1], stf, sit, sto, com] <= - m.e_sto_con[m.t[len(m.t)], stf, sit, sto, com]) + return (m.e_sto_con[m.t.at(1), stf, sit, sto, com] <= + m.e_sto_con[m.t.at(len(m.t)), stf, sit, sto, com]) def def_storage_energy_power_ratio_rule(m, stf, sit, sto, com): diff --git a/urbs/features/transmission.py b/urbs/features/transmission.py index a1e9a762..de96ec50 100644 --- a/urbs/features/transmission.py +++ b/urbs/features/transmission.py @@ -23,15 +23,16 @@ def remove_duplicate_transmission(transmission_keys): i -= 1 break i += 1 - return set(tra_tuple_list) + return list(tra_tuple_list) def add_transmission(m): # tranmission (e.g. hvac, hvdc, pipeline...) - indexlist = set() + indexlist = list() for key in m.transmission_dict["eff"]: - indexlist.add(tuple(key)[3]) + if key[3] not in indexlist: + indexlist.append(key[3]) m.tra = pyomo.Set( initialize=indexlist, doc='Set of transmission technologies') @@ -117,20 +118,21 @@ def add_transmission(m): # adds the transmission features to model with DCPF model features def add_transmission_dc(m): # defining transmission tuple sets for transport and DCPF model separately - tra_tuples = set() - tra_tuples_dc = set() + tra_tuples = list() + tra_tuples_dc = list() for key in m.transmission_dict['reactance']: - tra_tuples.add(tuple(key)) + tra_tuples.append(key) for key in m.transmission_dc_dict['reactance']: - tra_tuples_dc.add(tuple(key)) + tra_tuples_dc.append(key) tra_tuples_tp = tra_tuples - tra_tuples_dc tra_tuples_dc = remove_duplicate_transmission(tra_tuples_dc) tra_tuples = tra_tuples_dc | tra_tuples_tp # tranmission (e.g. hvac, hvdc, pipeline...) - indexlist = set() + indexlist = list() for key in m.transmission_dict["eff"]: - indexlist.add(tuple(key)[3]) + if key[3] not in indexlist: + indexlist.append(key[3]) m.tra = pyomo.Set( initialize=indexlist, doc='Set of transmission technologies') diff --git a/urbs/input.py b/urbs/input.py index 2db93450..c8e699ce 100644 --- a/urbs/input.py +++ b/urbs/input.py @@ -47,7 +47,7 @@ def read_input(input_files, year): global_prop = xls.parse('Global').set_index(['Property']) # create support timeframe index if ('Support timeframe' in - xls.parse('Global').set_index('Property').value): + global_prop.value): support_timeframe = ( global_prop.loc['Support timeframe']['value']) global_prop = ( @@ -174,7 +174,7 @@ def read_input(input_files, year): # sort nested indexes to make direct assignments work for key in data: - if isinstance(data[key].index, pd.core.index.MultiIndex): + if isinstance(data[key].index, pd.MultiIndex): data[key].sort_index(inplace=True) return data diff --git a/urbs/model.py b/urbs/model.py index 2e0754dd..f5bef09c 100644 --- a/urbs/model.py +++ b/urbs/model.py @@ -38,6 +38,7 @@ def create_model(data, dt=1, timesteps=None, objective='cost', # costs are annual by default, variable costs are scaled by weight) and # among different simulation durations meaningful. m.weight = pyomo.Param( + within=pyomo.Reals, initialize=float(8760) / ((len(m.timesteps) - 1) * dt), doc='Pre-factor for variable costs and emissions for an annual result') @@ -45,11 +46,13 @@ def create_model(data, dt=1, timesteps=None, objective='cost', # converts between energy (storage content, e_sto_con) and power (all other # quantities that start with "e_") m.dt = pyomo.Param( + within=pyomo.Reals, initialize=dt, doc='Time step duration (in hours), default: 1') # import objective function information m.obj = pyomo.Param( + within=pyomo.Any, initialize=objective, doc='Specification of minimized quantity, default: "cost"') @@ -62,6 +65,7 @@ def create_model(data, dt=1, timesteps=None, objective='cost', # generate ordered time step sets m.t = pyomo.Set( + within=pyomo.Reals, initialize=m.timesteps, ordered=True, doc='Set of timesteps') @@ -74,41 +78,47 @@ def create_model(data, dt=1, timesteps=None, objective='cost', doc='Set of modelled timesteps') # support timeframes (e.g. 2020, 2030...) - indexlist = set() + indexlist = list() for key in m.commodity_dict["price"]: - indexlist.add(tuple(key)[0]) + if key[0] not in indexlist: + indexlist.append(key[0]) m.stf = pyomo.Set( + within=pyomo.Reals, initialize=indexlist, doc='Set of modeled support timeframes (e.g. years)') # site (e.g. north, middle, south...) - indexlist = set() + indexlist = list() for key in m.commodity_dict["price"]: - indexlist.add(tuple(key)[1]) + if key[1] not in indexlist: + indexlist.append(key[1]) m.sit = pyomo.Set( initialize=indexlist, doc='Set of sites') # commodity (e.g. solar, wind, coal...) - indexlist = set() + indexlist = list() for key in m.commodity_dict["price"]: - indexlist.add(tuple(key)[2]) + if key[2] not in indexlist: + indexlist.append(key[2]) m.com = pyomo.Set( initialize=indexlist, doc='Set of commodities') # commodity type (i.e. SupIm, Demand, Stock, Env) - indexlist = set() + indexlist = list() for key in m.commodity_dict["price"]: - indexlist.add(tuple(key)[3]) + if key[3] not in indexlist: + indexlist.append(key[3]) m.com_type = pyomo.Set( initialize=indexlist, doc='Set of commodity types') # process (e.g. Wind turbine, Gas plant, Photovoltaics...) - indexlist = set() + indexlist = list() for key in m.process_dict["inv-cost"]: - indexlist.add(tuple(key)[2]) + if key[2] not in indexlist: + indexlist.append(key[2]) m.pro = pyomo.Set( initialize=indexlist, doc='Set of conversion processes') diff --git a/urbs/output.py b/urbs/output.py index e27035ee..edec2d42 100644 --- a/urbs/output.py +++ b/urbs/output.py @@ -112,7 +112,7 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): # STOCK eco = get_entity(instance, 'e_co_stock') try: - eco = eco.xs([stf, com, 'Stock'], level=['stf', 'com', 'com_type']) + eco = eco.xs((stf, com, 'Stock'), level=['stf', 'com', 'com_type']) stock = eco.unstack()[sites].sum(axis=1) except KeyError: stock = pd.Series(0, index=timesteps) @@ -121,7 +121,7 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): # PROCESS created = get_entity(instance, 'e_pro_out') try: - created = created.xs([stf, com], level=['stf', 'com']).loc[timesteps] + created = created.xs((stf, com), level=['stf', 'com']).loc[timesteps] created = created.unstack(level='sit')[sites].fillna(0).sum(axis=1) created = created.unstack(level='pro') created = drop_all_zero_columns(created) @@ -130,7 +130,7 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): consumed = get_entity(instance, 'e_pro_in') try: - consumed = consumed.xs([stf, com], level=['stf', 'com']).loc[timesteps] + consumed = consumed.xs((stf, com), level=['stf', 'com']).loc[timesteps] consumed = consumed.unstack(level='sit')[sites].fillna(0).sum(axis=1) consumed = consumed.unstack(level='pro') consumed = drop_all_zero_columns(consumed) @@ -154,7 +154,7 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): imported = imported[imported >= 0] imported = pd.concat([imported, minus_imported]) imported = imported.loc[timesteps].xs( - [stf, com], level=['stf', 'com']) + (stf, com), level=['stf', 'com']) imported = imported.unstack(level='tra').sum(axis=1) imported = imported.unstack( level='sit_')[sites].fillna(0).sum( @@ -177,7 +177,7 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): exported = exported[exported >= 0] exported = pd.concat([exported, minus_exported]) exported = exported.loc[timesteps].xs( - [stf, com], level=['stf', 'com']) + (stf, com), level=['stf', 'com']) exported = exported.unstack(level='tra').sum(axis=1) exported = exported.unstack( level='sit')[sites].fillna(0).sum( @@ -209,9 +209,9 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): # select all entries with desired commodity co stored = get_entities(instance, ['e_sto_con', 'e_sto_in', 'e_sto_out']) try: - stored = stored.loc[timesteps].xs([stf, com], level=['stf', 'com']) + stored = stored.loc[timesteps].xs((stf, com), level=['stf', 'com']) stored = stored.groupby(level=['t', 'sit']).sum() - stored = stored.loc[(slice(None), sites), :].sum(level='t') + stored = stored.loc[(slice(None), sites), :].groupby('t').sum() stored.columns = ['Level', 'Stored', 'Retrieved'] except (KeyError, ValueError): stored = pd.DataFrame(0, index=timesteps, @@ -232,8 +232,8 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): # for sit in m.dsm_site_tuples: try: # select commodity - dsmup = dsmup.xs([stf, com], level=['stf', 'com']) - dsmdo = dsmdo.xs([stf, com], level=['stf', 'com']) + dsmup = dsmup.xs((stf, com), level=['stf', 'com']) + dsmdo = dsmdo.xs((stf, com), level=['stf', 'com']) # select sites dsmup = dsmup.unstack()[sites].sum(axis=1) @@ -264,9 +264,9 @@ def get_timeseries(instance, stf, com, sites, timesteps=None): try: voltage_angle = get_entity(instance, 'voltage_angle') - voltage_angle = voltage_angle.xs([stf], level=['stf']).loc[timesteps] + voltage_angle = voltage_angle.xs(stf, level=['stf']).loc[timesteps] voltage_angle = voltage_angle.unstack(level='sit')[sites] - except (KeyError, AttributeError): + except (KeyError, AttributeError, TypeError): voltage_angle = pd.DataFrame(index=timesteps) voltage_angle.name = 'Voltage Angle' diff --git a/urbs/plot.py b/urbs/plot.py index 0e15b794..a59a510b 100644 --- a/urbs/plot.py +++ b/urbs/plot.py @@ -91,8 +91,8 @@ def plot(prob, stf, com, sit, dt, timesteps, timesteps_plot, timesteps = sorted(get_entity(prob, 'tm').index) # convert timesteps to hour series for the plots - hoursteps = timesteps * dt[0] - hoursteps_plot = timesteps_plot * dt[0] + hoursteps = timesteps * dt.iloc[0] + hoursteps_plot = timesteps_plot * dt.iloc[0] if is_string(sit): # wrap single site in 1-element list for consistent behaviour @@ -163,7 +163,7 @@ def plot(prob, stf, com, sit, dt, timesteps, timesteps_plot, # stack plot for consumed commodities (divided by dt for power) sp00 = ax0.stackplot(hoursteps[1:], - -consumed.values.T / dt[0], + -consumed.values.T / dt.iloc[0], labels=tuple(consumed.columns), linewidth=0.15) # color @@ -177,7 +177,7 @@ def plot(prob, stf, com, sit, dt, timesteps, timesteps_plot, # stack plot for created commodities (divided by dt for power) sp0 = ax0.stackplot(hoursteps[1:], - created.values.T / dt[0], + created.values.T / dt.iloc[0], labels=tuple(created.columns), linewidth=0.15) @@ -223,12 +223,12 @@ def plot(prob, stf, com, sit, dt, timesteps, timesteps_plot, # PLOT DEMAND # line plot for demand (unshifted) commodities (divided by dt for power) - ax0.plot(hoursteps, original.values / dt[0], linewidth=0.8, + ax0.plot(hoursteps, original.values / dt.iloc[0], linewidth=0.8, color=to_color('Unshifted')) # line plot for demand (in case of DSM mode: shifted) commodities # (divided by dt for power) - ax0.plot(hoursteps[1:], demand.values / dt[0], linewidth=1.0, + ax0.plot(hoursteps[1:], demand.values / dt.iloc[0], linewidth=1.0, color=to_color('Shifted')) # PLOT STORAGE @@ -274,18 +274,18 @@ def plot(prob, stf, com, sit, dt, timesteps, timesteps_plot, ax2.set_ylabel('{} ({})'.format(power_name, power_unit)) # make xtick distance duration-dependent - if len(timesteps_plot) > 26 * 168 / dt[0]: # time horizon > half a year - steps_between_ticks = int(168 * 4 / dt[0]) # tick every four weeks + if len(timesteps_plot) > 26 * 168 / dt.iloc[0]: # time horizon > half a year + steps_between_ticks = int(168 * 4 / dt.iloc[0]) # tick every four weeks if steps_between_ticks == 0: steps_between_ticks = 1 # tick every timestep - elif len(timesteps_plot) > 3 * 168 / dt[0]: # time horizon > three weeks - steps_between_ticks = int(168 / dt[0]) # tick every week - elif len(timesteps_plot) > 2 * 24 / dt[0]: # time horizon > two days - steps_between_ticks = int(24 / dt[0]) # tick every day - elif len(timesteps_plot) > 24 / dt[0]: # time horizon > a day - steps_between_ticks = int(6 / dt[0]) # tick every six hours + elif len(timesteps_plot) > 3 * 168 / dt.iloc[0]: # time horizon > three weeks + steps_between_ticks = int(168 / dt.iloc[0]) # tick every week + elif len(timesteps_plot) > 2 * 24 / dt.iloc[0]: # time horizon > two days + steps_between_ticks = int(24 / dt.iloc[0]) # tick every day + elif len(timesteps_plot) > 24 / dt.iloc[0]: # time horizon > a day + steps_between_ticks = int(6 / dt.iloc[0]) # tick every six hours else: # time horizon <= a day - steps_between_ticks = int(3 / dt[0]) # tick every three hours + steps_between_ticks = int(3 / dt.iloc[0]) # tick every three hours hoursteps_plot_ = hoursteps_plot[(steps_between_ticks - 1):] hoursteps_plot_ = hoursteps_plot_[::steps_between_ticks] # take hole h's diff --git a/urbs/pyomoio.py b/urbs/pyomoio.py index c136d17f..34eecd7a 100644 --- a/urbs/pyomoio.py +++ b/urbs/pyomoio.py @@ -27,10 +27,10 @@ def get_entity(instance, name): # extract values if isinstance(entity, pyomo.Set): if entity.dimen > 1: - results = pd.DataFrame([v + (1,) for v in entity.value]) + results = pd.DataFrame([v + (1,) for v in entity.data()]) else: # Pyomo sets don't have values, only elements - results = pd.DataFrame([(v, 1) for v in entity.value]) + results = pd.DataFrame([(v, 1) for v in entity.data()]) # for unconstrained sets, the column label is identical to their index # hence, make index equal to entity name and append underscore to name @@ -43,25 +43,25 @@ def get_entity(instance, name): elif isinstance(entity, pyomo.Param): if entity.dim() > 1: results = pd.DataFrame( - [v[0] + (v[1],) for v in entity.iteritems()]) + [v[0] + (v[1],) for v in entity.items()]) elif entity.dim() == 1: results = pd.DataFrame( - [(v[0], v[1]) for v in entity.iteritems()]) + [(v[0], v[1]) for v in entity.items()]) else: results = pd.DataFrame( - [(v[0], v[1].value) for v in entity.iteritems()]) + [(v[0], v[1].value) for v in entity.items()]) labels = ['None'] elif isinstance(entity, pyomo.Expression): if entity.dim() > 1: results = pd.DataFrame( - [v[0]+(v[1](),) for v in entity.iteritems()]) + [v[0]+(v[1](),) for v in entity.items()]) elif entity.dim() == 1: results = pd.DataFrame( - [(v[0], v[1]()) for v in entity.iteritems()]) + [(v[0], v[1]()) for v in entity.items()]) else: results = pd.DataFrame( - [(v[0], v[1]()) for v in entity.iteritems()]) + [(v[0], v[1]()) for v in entity.items()]) labels = ['None'] elif isinstance(entity, pyomo.Constraint): @@ -70,15 +70,15 @@ def get_entity(instance, name): # an existing dual variable # in that case add to results results = pd.DataFrame( - [key + (instance.dual[entity.__getitem__(key)],) + [key + (instance.dual[entity.at(key)],) for (id, key) in entity.id_index_map().items() if id in instance.dual._dict.keys()]) elif entity.dim() == 1: results = pd.DataFrame( - [(v[0], instance.dual[v[1]]) for v in entity.iteritems()]) + [(v[0], instance.dual[v[1]]) for v in entity.items()]) else: results = pd.DataFrame( - [(v[0], instance.dual[v[1]]) for v in entity.iteritems()]) + [(v[0], instance.dual[v[1]]) for v in entity.items()]) labels = ['None'] else: @@ -87,15 +87,15 @@ def get_entity(instance, name): # concatenate index tuples with value if entity has # multidimensional indices v[0] results = pd.DataFrame( - [v[0] + (v[1].value,) for v in entity.iteritems()]) + [v[0] + (v[1].value,) for v in entity.items()]) elif entity.dim() == 1: # otherwise, create tuple from scalar index v[0] results = pd.DataFrame( - [(v[0], v[1].value) for v in entity.iteritems()]) + [(v[0], v[1].value) for v in entity.items()]) else: # assert(entity.dim() == 0) results = pd.DataFrame( - [(v[0], v[1].value) for v in entity.iteritems()]) + [(v[0], v[1].value) for v in entity.items()]) labels = ['None'] # check for duplicate onset names and append one to several "_" to make @@ -140,10 +140,10 @@ def get_entities(instance, names): else: index_names_before = df.index.names - df = df.join(other, how='outer') + df = df.join(other.reindex(df.index), how='outer') if index_names_before != df.index.names: - df.index.names = index_names_before + df.index.names = index_names_before return df @@ -171,7 +171,7 @@ def list_entities(instance, entity_type): # helper function to discern entities by type def filter_by_type(entity, entity_type): if entity_type == 'set': - return isinstance(entity, pyomo.Set) and not entity.virtual + return isinstance(entity, pyomo.Set) elif entity_type == 'par': return isinstance(entity, pyomo.Param) elif entity_type == 'var': @@ -232,41 +232,45 @@ def _get_onset_names(entity): # N-dimensional set tuples, possibly with nested set tuples within if entity.domain: # retreive list of domain sets, which itself could be nested - domains = entity.domain.set_tuple + domains = entity.domain.subsets(expand_all_set_operators=True) else: try: # if no domain attribute exists, some - domains = entity.set_tuple + domains = entity.subsets(expand_all_set_operators=True) except AttributeError: # if that fails, too, a constructed (union, difference, # intersection, ...) set exists. In that case, the # attribute _setA holds the domain for the base set try: - domains = entity._setA.domain.set_tuple + domains = entity._setA.domain.subsets(expand_all_set_operators=True) except AttributeError: # if that fails, too, a constructed (union, difference, # intersection, ...) set exists. In that case, the # attribute _setB holds the domain for the base set - domains = entity._setB.domain.set_tuple + domains = entity._setB.domain.subsets(expand_all_set_operators=True) for domain_set in domains: labels.extend(_get_onset_names(domain_set)) elif entity.dimen == 1: - if entity.domain: - # 1D subset; add domain name - labels.append(entity.domain.name) - else: + labels.append(entity.name) + #if entity.domain == pyomo.Any: + # pass + #elif entity.domain: + # 1D subset; add entity name + # labels.append(entity.name) + #else: # unrestricted set; add entity name - labels.append(entity.name) + # labels.append(entity.name) else: # no domain, so no labels needed pass elif isinstance(entity, (pyomo.Param, pyomo.Var, pyomo.Expression, pyomo.Constraint, pyomo.Objective)): - if entity.dim() > 0 and entity._index: - labels = _get_onset_names(entity._index) + + if entity.dim() > 0 and entity._index_set: + labels = _get_onset_names(entity._index_set) else: # zero dimensions, so no onset labels pass diff --git a/urbs/report.py b/urbs/report.py index 7cd3e22f..ad4e4821 100644 --- a/urbs/report.py +++ b/urbs/report.py @@ -26,10 +26,10 @@ def report(instance, filename, report_tuples=None, report_sites_name={}): with pd.ExcelWriter(filename) as writer: # write constants to spreadsheet - costs.to_frame().to_excel(writer, 'Costs') - cpro.to_excel(writer, 'Process caps') - ctra.to_excel(writer, 'Transmission caps') - csto.to_excel(writer, 'Storage caps') + costs.to_frame().to_excel(writer, sheet_name='Costs') + cpro.to_excel(writer, sheet_name='Process caps') + ctra.to_excel(writer, sheet_name='Transmission caps') + csto.to_excel(writer, sheet_name='Storage caps') # initialize timeseries tableaus energies = [] @@ -103,7 +103,7 @@ def report(instance, filename, report_tuples=None, report_sites_name={}): if timeseries: # concatenate Commodity sums energy = pd.concat(energies, axis=1).fillna(0) - energy.to_excel(writer, 'Commodity sums') + energy.to_excel(writer, sheet_name='Commodity sums') # write timeseries to individual sheets for stf, sit, com in report_tuples: @@ -113,4 +113,4 @@ def report(instance, filename, report_tuples=None, report_sites_name={}): sheet_name = "{}.{}.{} timeseries".format( stf, report_sites_name[sit], com)[:31] timeseries[(stf, report_sites_name[sit], com)].to_excel( - writer, sheet_name) + writer, sheet_name=sheet_name)