Skip to content

Commit

Permalink
renamed function
Browse files Browse the repository at this point in the history
renamed add_network function to add_components_from_network
also moved function to follow existing add function (for adding single components)
updated tests to match function rename
  • Loading branch information
jessLryan committed Nov 30, 2023
1 parent 142f024 commit 1f595a5
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 81 deletions.
160 changes: 82 additions & 78 deletions pypsa/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,85 +593,7 @@ def set_snapshots(
lambda self: self._snapshots, set_snapshots, doc="Time steps of the network"
)

def add_network(
self, other, components_to_skip=None, inplace=False, with_time=True
):
"""
Function: Add components from network "other" into this network.
Notes:
If two components in different networks have the same ID value then the component in
the new network will not be added into this network.
For static data:
If a component in the new network does not have values for attributes present in
this network then default values are set. If a component in the new network has attributes
which are not present in this network then these attributes will not be present in the
final network.
For time-varying data:
If time-varying data is added, the new data must have identical snapshots and snapshot weightings.
Parameters
----------
other : pypsa.Network
network whose components are to be added to this network
components_to_skip : list-like, default None
list of names of components which are not to be added e.g. "Bus"
inplace : boolean, default False
if True, new components are added into current network in-place, otherwise
a new network containing the components of both networks is returned
with_time : bool, default True
if False, only static data is merged

Returns
-------
new_network : pypsa.Network
network containing components of both input networks, or None if inplace=True
"""
to_skip = ["Network"]
if components_to_skip:
to_skip.update(components_to_skip)
if other.srid != self.srid:
logger.warning(
f"Warning: spatial Reference System Indentifier {other.srid} for new network not equal to value {self.srid} of existing network. Original value will be used."
)
if with_time:
snapshots_aligned = self.snapshots.equals(other.snapshots)
weightings_aligned = self.snapshot_weightings.equals(
other.snapshot_weightings
)
assert (
snapshots_aligned and weightings_aligned
), "Error, snapshots or snapshot weightings do not agree, cannot add network with time-varying attributes."

new_network = self if inplace else self.copy()

for component in other.iterate_components(other.components.keys() - to_skip):
# we do not add components whose ID is present in this network
index_list = list(
set(component.df.index) - set(self.df(component.name).index)
)
if set(index_list) != set(component.df.index) and component.name not in [
"LineType",
"TransformerType",
]:
logger.warning(
f"Warning: components of type {component.name} in new network have duplicate IDs in existing network. These components will not be added"
)
# import static data for component
df_to_add = component.df[component.df.index.isin(index_list)]
new_network.import_components_from_dataframe(df_to_add, component.name)
if with_time:
# import time series data for component
for attr, df in component.pnl.items():
df_to_add = df.loc[:, df.columns.isin(index_list)]
new_network.import_series_from_dataframe(df, component.name, attr)
return None if inplace else new_network

@property
def snapshot_weightings(self):
Expand Down Expand Up @@ -1035,6 +957,88 @@ def add(self, class_name, name, **kwargs):
"in network.buses"
)


def add_components_from_network(
self, other, components_to_skip=None, inplace=False, with_time=True
):
"""
Function: Add components from network "other" into this network.
Notes:
If two components in different networks have the same ID value then the component in
the new network will not be added into this network.
For static data:
If a component in the new network does not have values for attributes present in
this network then default values are set. If a component in the new network has attributes
which are not present in this network then these attributes will not be present in the
final network.
For time-varying data:
If time-varying data is added, the new data must have identical snapshots and snapshot weightings.
Parameters
----------
other : pypsa.Network
network whose components are to be added to this network
components_to_skip : list-like, default None
list of names of components which are not to be added e.g. "Bus"
inplace : boolean, default False
if True, new components are added into current network in-place, otherwise
a new network containing the components of both networks is returned
with_time : bool, default True
if False, only static data is merged
Returns
-------
new_network : pypsa.Network
network containing components of both input networks, or None if inplace=True
"""
to_skip = ["Network"]
if components_to_skip:
to_skip.update(components_to_skip)
if other.srid != self.srid:
logger.warning(
f"Warning: spatial Reference System Indentifier {other.srid} for new network not equal to value {self.srid} of existing network. Original value will be used."
)
if with_time:
snapshots_aligned = self.snapshots.equals(other.snapshots)
weightings_aligned = self.snapshot_weightings.equals(
other.snapshot_weightings
)
assert (
snapshots_aligned and weightings_aligned
), "Error, snapshots or snapshot weightings do not agree, cannot add network with time-varying attributes."

new_network = self if inplace else self.copy()

for component in other.iterate_components(other.components.keys() - to_skip):
# we do not add components whose ID is present in this network
index_list = list(
set(component.df.index) - set(self.df(component.name).index)
)
if set(index_list) != set(component.df.index) and component.name not in [
"LineType",
"TransformerType",
]:
logger.warning(
f"Warning: components of type {component.name} in new network have duplicate IDs in existing network. These components will not be added"
)
# import static data for component
df_to_add = component.df[component.df.index.isin(index_list)]
new_network.import_components_from_dataframe(df_to_add, component.name)
if with_time:
# import time series data for component
for attr, df in component.pnl.items():
df_to_add = df.loc[:, df.columns.isin(index_list)]
new_network.import_series_from_dataframe(df, component.name, attr)
return None if inplace else new_network


def remove(self, class_name, name):
"""
Removes a single component from the network.
Expand Down
10 changes: 7 additions & 3 deletions test/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,9 @@ def test_add_network_static_inplace(ac_dc_network, empty_network_5_buses):
THEN the first network should now contain its original buses and
also the buses in the second network
"""
ac_dc_network.add_network(empty_network_5_buses, inplace=True, with_time=False)
ac_dc_network.add_components_from_network(
empty_network_5_buses, inplace=True, with_time=False
)
buses_now = ac_dc_network.buses.index
buses_added_network = empty_network_5_buses.buses.index

Expand All @@ -263,7 +265,7 @@ def test_add_network_static_not_inplace(ac_dc_network, empty_network_5_buses):
the first network and the second network
"""

new_network = ac_dc_network.add_network(
new_network = ac_dc_network.add_components_from_network(
empty_network_5_buses, inplace=False, with_time=False
)

Expand Down Expand Up @@ -304,7 +306,9 @@ def test_add_network_with_time_inplace():
buses_added_to.add(f"bus_added_to_{i}")
network_added_to.add("Bus", f"bus_added_to_{i}", p=[1, 2, 3])

network_added_to.add_network(network_to_add, inplace=True, with_time=True)
network_added_to.add_components_from_network(
network_to_add, inplace=True, with_time=True
)

buses_t_now = set(network_added_to.buses_t["p"].columns.values)
# check that the first network now contains time-varying data
Expand Down

0 comments on commit 1f595a5

Please sign in to comment.