~tfardet/nngt-developers

NNGT: IO: graphml support for missing attributes v2 SUPERSEDED

~tfardet: 1
 IO: graphml support for missing attributes

 5 files changed, 85 insertions(+), 1 deletions(-)
#628054 .build.yml failed
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~tfardet/nngt-developers/patches/26510/mbox | git am -3
Learn more about email & git

[PATCH NNGT v2] IO: graphml support for missing attributes Export this patch

From: Tanguy Fardet <tanguyfardet@protonmail.com>

---
 nngt/io/loading_helpers.py             | 20 ++++++++++++++++-
 nngt/lib/converters.py                 |  9 ++++++++
 nngt/simulation/nest_utils.py          |  4 ++++
 testing/Networks/missing_attrs.graphml | 31 ++++++++++++++++++++++++++
 testing/test_io.py                     | 22 ++++++++++++++++++
 5 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 testing/Networks/missing_attrs.graphml

diff --git a/nngt/io/loading_helpers.py b/nngt/io/loading_helpers.py
index c07b18d..1448a4b 100755
--- a/nngt/io/loading_helpers.py
+++ b/nngt/io/loading_helpers.py
@@ -30,7 +30,7 @@ import types
import numpy as np

from ..lib.converters import (_np_dtype, _to_int, _to_string, _to_list,
                              _string_from_object, _python_type)
                              _string_from_object, _python_type, _default_value)


__all__ = [
@@ -389,9 +389,16 @@ def _get_edges_graphml(lst_lines, attributes, *args, di_attributes=None,

        key_to_name = di_notif["eattr_keytoname"]

        eattrs = {k: v for k, v in
                  zip(di_notif["edge_attributes"], di_notif["edge_attr_types"])}

        for attr in elt.findall("data", ns):
            name = key_to_name[attr.get("key")]
            di_attributes[name].append(convertor[name](attr.text))
            del eattrs[name]

        for k, v in eattrs.items():
            di_attributes[k].append(_default_value(v))

    return edges

@@ -429,13 +436,24 @@ def _get_node_attr(di_notif, separator, fmt=None, lines=None, convertor=None):
        ns = di_notif["namespace"]
        key_to_name = di_notif["nattr_keytoname"]

        nattrs = {k: v for k, v in
                  zip(di_notif["node_attributes"], di_notif["node_attr_types"])}

        for elt in di_notif["nodes"]:
            all_attrs = nattrs.copy()

            for attr in elt.findall("data", ns):
                name = key_to_name[attr.get("key")]

                if name not in di_nattr:
                    di_nattr[name] = []

                del all_attrs[name]

                di_nattr[name].append(convertor[name](attr.text))

            for k, v in all_attrs.items():
                di_nattr[k].append(_default_value(v))
    else:
        # edge list and neighbors formatting
        nattr_name = {str("na_" + k): k for k in di_notif["node_attributes"]}
diff --git a/nngt/lib/converters.py b/nngt/lib/converters.py
index 041e371..97b6b73 100755
--- a/nngt/lib/converters.py
+++ b/nngt/lib/converters.py
@@ -122,3 +122,12 @@ def _type_converter(attribute_type):
        return attribute_type

    return _np_dtype(attribute_type)


def _default_value(attribute_type):
    if attribute_type in ("double", "float", "real"):
        return np.NaN
    elif attribute_type in ("int", "integer"):
        return 0

    return ""
diff --git a/nngt/simulation/nest_utils.py b/nngt/simulation/nest_utils.py
index 9da02b9..70f43f1 100755
--- a/nngt/simulation/nest_utils.py
+++ b/nngt/simulation/nest_utils.py
@@ -295,8 +295,12 @@ def randomize_neural_states(network, instructions, groups=None, nodes=None,
    if nodes is not None and groups is not None:
        raise InvalidArgument('`nodes` and `groups` cannot be set together.')
    elif groups is not None:
        if isinstance(groups, nngt.Group):
            groups = [groups]

        for group in groups:
            gids.extend(group.nest_gids)

        gids = list(set(gids))
    else:
        gids.extend(
diff --git a/testing/Networks/missing_attrs.graphml b/testing/Networks/missing_attrs.graphml
new file mode 100644
index 0000000..198ae07
--- /dev/null
+++ b/testing/Networks/missing_attrs.graphml
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
         http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<!-- Created by igraph -->
  <key id="v_name" for="node" attr.name="name" attr.type="string"/>
  <key id="e_weight" for="edge" attr.name="eattr" attr.type="double"/>
  <graph id="G" edgedefault="directed">
    <node id="n0">
      <data key="v_name">A</data>
    </node>
    <node id="n1"></node>
    <node id="n2">
      <data key="v_name">C</data>
    </node>
    <node id="n3">
      <data key="v_name">D</data>
    </node>
    <edge source="n0" target="n1">
      <data key="e_weight">4</data>
    </edge>
    <edge source="n0" target="n2">
      <data key="e_weight">1</data>
    </edge>
    <edge source="n2" target="n3"></edge>
    <edge source="n3" target="n1">
      <data key="e_weight">0.5</data>
    </edge>
  </graph>
</graphml>
diff --git a/testing/test_io.py b/testing/test_io.py
index c5bc047..3e86011 100644
--- a/testing/test_io.py
+++ b/testing/test_io.py
@@ -302,6 +302,27 @@ def test_node_attributes():
                              h.node_attributes["size"])


@pytest.mark.mpi_skip
def test_partial_graphml():
    '''
    Check that the GraphML file loads fine if some attributes are missing.
    '''
    g = nngt.load_from_file(os.path.join(current_dir,
                                         "Networks/missing_attrs.graphml"))

    nattrs = {0: "A", 1: "", 2: "C", 3: "D"}
    eattrs = {(0, 1): 4, (0, 2): 1, (2, 3): np.NaN, (3, 1): 0.5}

    for n, name in nattrs.items():
        assert g.node_attributes["name"][n] == name

    for e, value in eattrs.items():
        if np.isnan(value):
            assert np.isnan(g.get_edge_attributes(edges=e, name="eattr"))
        else:
            assert g.get_edge_attributes(edges=e, name="eattr") == value


# ---------- #
# Test suite #
# ---------- #
@@ -315,4 +336,5 @@ if __name__ == "__main__":
        test_structure()
        test_node_attributes()
        test_spatial()
        test_partial_graphml()
        unittest.main()
-- 
2.32.0
NNGT/patches/.build.yml: FAILED in 7m13s

[IO: graphml support for missing attributes][0] v2 from [~tfardet][1]

[0]: https://lists.sr.ht/~tfardet/nngt-developers/patches/26510
[1]: mailto:tanguyfardet@protonmail.com

✗ #628054 FAILED NNGT/patches/.build.yml https://builds.sr.ht/~tfardet/job/628054