Working with networks¶
Adding networks¶
Before a network can be added, a project must first be created. See Working with projects.
Networks are made up of nodes, links and scenarios, and can be created with any number of each.
We use the word resource
to describe things in hydra that can have attributes (see Attributes). Resources include
Projects, Networks, Nodes, Links and Groups. A group is a grouping of nodes and/or links within a network. Groups are used to categorise sub-sections of a network, for example political jurisdictions.
The simplest way to get started is to add an ‘empty’ network
#Assume we have created a project
project_id = my_project.id
net = self.client.factory.create('hyd:Network')
#necessary info:
net.name = "An empty network"
net.description = "A network with no nodes, links or data (scenarios)"
net.project_id = project.id
A network also has a ‘layout’ attribute, which can be any XML encoding. This is used to help apps (the user interface) to store app-specific information about the network
#Some helpful stuff for the UI, encoded in XML
net.layout = {'background_colour': 'blue'}
Having defined the network, it is added
#add network
empty_net = client.service.add_network(net)
#The new project now has an ID
print empty_net.id
print empty_net.nodes # None
print empty_net.links # None
print empty_net.scenarios # None
print empty_net.attributes # None
Retrieving Networks¶
Existing networks can be retrieved in a few ways: The simplest and most common is by ID
my_network = client.service.get_network(my_network_id)
If you don’t know the ID, but know the name, you can still find the network, but you must know the project ID
my_network = client.service.get_network_by_name(my_project_id, "An empty network")
Failing that, just ask for all the networks a given project
my_networks = client.service.get_networks(project_id)
Deleting Networks¶
If a project is being clogged up with too many networks, the networks can be deleted
client.service.delete_network(network_id)
however, this will not permenantly delete the project. It will still
be retrievable using get_network
but it will not be returned in get_networks
. A network can be reactivated by calling
client.service.activate_network(network_id)
To delete a network peremenantly, use
client.service.purge_network(network_id)
Warning This cannot be undone and all sub-nodes, links, scenarios and attributes will also be purged. This may also include the deletion of data (see Working with datasets).
Sharing Networks¶
It is not uncommon for multiple people to work on the same network, so to facilitate this, Hydra allows users to share networks with other users
#connect...
my_user_id = 1
friend_1_user_id = 2
friend_2_user_id = 3
my_network_id = 999
client.service.share_network(my_network_id, [friend_1_user_id, friend_2_user_id], 'Y', 'N')
In this example, user 1 is sharing network 999 with two other users. The first ‘Y’ parameter indicates that the network is ‘read only’, while the second indicates that the users are not allowed to re-share the network with other users.
Nodes, Links and Groups¶
Nodes¶
Nodes and links are the fundamental structure of a network. As mentioned, they are resources, so they can have attributes.
A node is defined like this
node1 = self.client.factory.create('hyd:Node')
node1.name = "Node 1",
node1.description = "A node representing a water resource",
node1.x = 10
node1.y = 10
node2 = self.client.factory.create('hyd:Node')
node2.name = "Node 2",
node2.description = "A node representing another water resource",
node2.x = 20
node2.y = 20
A common approach is to add nodes to a new network before creating it. From our previous examples:
net = self.client.factory.create('hyd:Network')
#...create node1 and node2...
nodes = self.client.factory.create('hyd:NodeArray')
nodes.Node.append(node1)
nodes.Node.append(node2)
net.nodes = nodes
net_with_nodes = client.service.add_network(net)
Nodes and links can be added to a network in two ways: # Adding the node directly
network_id = 999
my_new_node = client.service.add_node(network_id, node1)
print my_new_node.id #will give a newly created ID
# Retrieving the network, adding the node, then updating the network. As the server must process the entire incoming network to see what has changed, this should only be done if multiple changes are being made at the same time.
my_network = client.service.get_network(999)
my_network.nodes.Node.append(node1)
client.service.update_network(my_network)
Links¶
Links connect nodes and can be added to a network in much the same way as nodes. The only complication in adding links is that the linking is done based on node ID, so nodes have to exist in the network before they can be added. Using the nodes we defined earlier:
net = self.client.factory.create('hyd:Network')
#...define network information...
#...create node1 and node2...
nodes = self.client.factory.create('hyd:NodeArray')
nodes.Node.append(node1)
nodes.Node.append(node2)
net.nodes = nodes
#Add the network which gives IDs to each of the nodes.
net_with_nodes = client.service.add_network(net)
#Get the node IDS
node_1_id = net_with_nodes.nodes.Node[0].id
node_2_id = net_with_nodes.nodes.Node[1].id
#Link the nodes
link1 = self.client.factory.create('hyd:Link')
link1.name = "Link 1",
link1.description = "A link between two water resources",
link1.node_1_id = node_1_id
link1.node_2_id = node_2_id
links.Link.append(link1)
net.links = links
net_with_nodes_and_links = client.service.update_network(net)
This is clearly not a good solution, as we have to send the network to the server twice. To get around this, Hydra provides a mechanism whereby links can be defined on nodes even if they don’t yet exist on the server yet. TO achieve this, we use negative IDS
net = self.client.factory.create('hyd:Network')
#...define network information...
#...create node1 and node2...
nodes = self.client.factory.create('hyd:NodeArray')
node1.id = -1
node2.id = -2
nodes.Node.append(node1)
nodes.Node.append(node2)
net.nodes = nodes
#Link the nodes
link1 = self.client.factory.create('hyd:Link')
link1.name = "Link 1",
link1.description = "A link between two water resources",
link1.node_1_id = -1
link1.node_2_id = -2
links.Link.append(link1)
net.links = links
net_with_nodes_and_links = client.service.add_network(net)
The add_network function will recognise that the IDS on the nodes
and links are negative, generate positive IDS and link everything correctly. This
approach also works when adding nodes & links to an existing network. Just use
negative IDS to refer to other resources locally and let the server sort out
the IDS when update_network
is called.
Groups¶
A group
, or resource group
is not a structural part of a network. Instead
it allows nodes, links to be grouped together into high-level containers.
One example might be where a network representing a river might contain several
political juristidictions, where different rules may apply.
The contents of a group are called items
or resource group items
. Group
items are defined on a scenario-by-scenario basis. See Working with scenarios.
Groups are still resources, however, and act in much the same way as nodes and links.
Adding a group to a new network:
#...define network with nodes and links...
groups = self.client.factory.create('hyd:ResourceGroupArray')
group = self.client.factory.create('hyd:ResourceGroup')
group.id = -1
group.name = "Test Group"
group.description = "Test group description"
groups.ResourceGroup.append(group)
net.resourcegroups = groups
net_with_nodes_links_groups = client.service.add_network(net)
Notice that this group has a negative ID. This is set so the group items know which group they are in. ALso notice that this uses ‘-1’ even though this ID is also used on the node ID we set earlier. This doesn’t matter so long as there is consistency between nodes and between groups.
Groups can also be added using add_resourcegroup
#...define network with nodes and links...
net_with_nodes_and_links = client.service.add_network(net)
group = self.client.factory.create('hyd:ResourceGroup')
group.id = -1
group.name = "Test Group"
group.description = "Test group description"
new_group = client.service.add_resourcegroup(net.id, group)
Or update the network
#...define network with nodes and links...
net_with_nodes_and_links = client.service.add_network(net)
group = self.client.factory.create('hyd:ResourceGroup')
group.id = -1
group.name = "Test Group"
group.description = "Test group description"
net.resourcegroups.ResourceGroup.append(group)
net_with_nodes_links_groups = client.service.update_network(net)
Deletion of a group is done using delete_resourcegroup
group_id = 123
self.client.service.delete_resourcegroup(group_id)
and activate it again...
group_id = 123
self.client.service.activate_resourcegroup(group_id)
and finally purge it
group_id = 123
self.client.service.purge_resourcegroup(group_id)