Skip to content

Node


In the TransitionZero platform, all data is indexed to a Node. Each node represents the geographic centroid of a modelled region. Nodes are used to represent useful physical and administrative boundaries and can range from individual physical assets through to entire countries and continents. This flexibility allows TransitionZero users to access data at all levels of aggregation via the TransitionZero platform .

OSeMOSYS Global: An open-source, open data global electricity system model generator The image shows how nodes represent the geographic centroid of a modeled region. The edges represent where there is interconnection between the nodes. Source: OSeMOSYS Global: An open-source, open data global electricity system model generator

In the physics of systems modelling, Nodes are discrete units around which the continuity of energy and materials is constrained. In other words, at every node in a systems model, the input plus supply to the node must equal the output plus demand.

To access data for nodes, you can use this Jupyter Notebook on Github.

See also: Geometry


Bases: NodeBase

Nodes can be loaded directly with their id:

germany = Node.from_id("DEU")
Source code in tz/client/node.py
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class Node(schemas.NodeBase):

    """
    <!--
    The Node class enables access to geospatially-referenced data of a given node.
    Nodes are the fundamental building blocks of systems models, and can represent
    administrative areas like countries or continents, or physical assets like
    power stations or substations. TransitionZero indexes all data to nodes so
    it can easily be used to design and validate systems models.
    -->

    Nodes can be loaded directly with their id:

    ```python
    germany = Node.from_id("DEU")
    ```

    """

    _geometry: Optional[Geometry] = None
    _assets: Optional[AssetCollection] = None
    _children: Optional[list["Node"]] = None
    _parents: Optional[list["Node"]] = None
    _gross_capacity: Optional[Dict[str, Dict[str, Dict[str, float]]]] = None

    @classmethod
    def from_id(cls, id: str) -> "Node":
        """Initialise Node from `id` as a positional argument"""
        node = api.nodes.get(ids=id)[0]
        return cls(**node.model_dump())

    @classmethod
    def search(
        cls,
        alias: str,
        threshold: float = 0.5,
        node_type: str | None = None,
        limit: int = 10,
        page: int = 0,
    ) -> list["Node"]:
        """
        Search for nodes using an alias.

        ```python
        germany_nodes = Node.search("Germany")
        ```

        Args:
            alias (str): The target alias to search.
            threshold (float): The desired confidence in the search result.
            node_type (str): filter search to a specific node type.
            limit (int): The maximum number of search results to return per page.
            page (int): The page number of search results to return.

        Returns:
            List[Node]: A list of Node objects.
        """

        search_results = api.aliases.get(
            alias=alias,
            threshold=threshold,
            node_type=node_type,
            includes="node",
            limit=limit,
            page=page,
        )

        return [
            cls(**alias.node.model_dump())  # type: ignore[union-attr]
            for alias in search_results.aliases
        ]

    @property
    def assets(self) -> AssetCollection:
        """An collection of assets located in (or connected to) this node."""
        if self._assets is None:
            self._assets = AssetCollection.from_parent_node(node_id=self.id)
        return self._assets

    @classmethod
    def _get_children(cls, ids):
        node_data = api.nodes.get(ids=ids, includes="children")
        return [cls(**child.model_dump()) for child in node_data[0].children]

    @classmethod
    def _get_parents(cls, ids):
        node_data = api.nodes.get(ids=ids, includes="parents")
        return [cls(**parent.model_dump()) for parent in node_data[0].parents]

    @property
    def children(self) -> list["Node"]:
        """A set of nodes which are the heirarchical children of this node."""
        if self._children is None:
            self._children = self._get_children(self.id)
            return self._children
        return self._children

    @property
    def parents(self) -> list["Node"]:
        """A set of nodes which are the heirarchical ancestors of this node."""
        if self._parents is None:
            self._parents = self._get_parents(self.id)
            return self._parents
        return self._parents

    @classmethod
    def _get_geometry(cls, ids) -> Geometry:
        return Geometry.get(ids)

    @property
    def geometry(self) -> Geometry:
        """The node's geometry in WGS84 coordinate reference system."""
        if self._geometry is None:
            self._geometry = self._get_geometry(self.id)
            return self._geometry
        else:
            return self._geometry

    def __str__(self) -> str:
        return f"Node: {self.name_primary_en} (id={self.id})"

assets: AssetCollection property

An collection of assets located in (or connected to) this node.

children: list[Node] property

A set of nodes which are the heirarchical children of this node.

geometry: Geometry property

The node's geometry in WGS84 coordinate reference system.

parents: list[Node] property

A set of nodes which are the heirarchical ancestors of this node.

from_id(id) classmethod

Initialise Node from id as a positional argument

Source code in tz/client/node.py
36
37
38
39
40
@classmethod
def from_id(cls, id: str) -> "Node":
    """Initialise Node from `id` as a positional argument"""
    node = api.nodes.get(ids=id)[0]
    return cls(**node.model_dump())

search(alias, threshold=0.5, node_type=None, limit=10, page=0) classmethod

Search for nodes using an alias.

germany_nodes = Node.search("Germany")

Parameters:

Name Type Description Default
alias str

The target alias to search.

required
threshold float

The desired confidence in the search result.

0.5
node_type str

filter search to a specific node type.

None
limit int

The maximum number of search results to return per page.

10
page int

The page number of search results to return.

0

Returns:

Type Description
list[Node]

List[Node]: A list of Node objects.

Source code in tz/client/node.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@classmethod
def search(
    cls,
    alias: str,
    threshold: float = 0.5,
    node_type: str | None = None,
    limit: int = 10,
    page: int = 0,
) -> list["Node"]:
    """
    Search for nodes using an alias.

    ```python
    germany_nodes = Node.search("Germany")
    ```

    Args:
        alias (str): The target alias to search.
        threshold (float): The desired confidence in the search result.
        node_type (str): filter search to a specific node type.
        limit (int): The maximum number of search results to return per page.
        page (int): The page number of search results to return.

    Returns:
        List[Node]: A list of Node objects.
    """

    search_results = api.aliases.get(
        alias=alias,
        threshold=threshold,
        node_type=node_type,
        includes="node",
        limit=limit,
        page=page,
    )

    return [
        cls(**alias.node.model_dump())  # type: ignore[union-attr]
        for alias in search_results.aliases
    ]