# -*- coding: utf-8 -*-
# © 2017-2019, ETH Zurich, Institut für Theoretische Physik
# Author: Dominik Gresch <greschd@gmx.ch>
"""
Defines the container classes for object shapes.
"""
from types import SimpleNamespace
import numpy as np
import networkx as nx
from fsc.export import export
from fsc.hdf5_io import SimpleHDF5Mapping, subscribe_hdf5, to_hdf5, from_hdf5
[docs]@export
@subscribe_hdf5('nodefinder.nodal_point')
class NodalPoint(SimpleNamespace, SimpleHDF5Mapping):
"""
Shape class defining a nodal point.
Attributes
----------
position : tuple(float)
The position of the point.
"""
HDF5_ATTRIBUTES = ['position']
def __init__(self, position):
self.position = position
[docs]@export
@subscribe_hdf5('nodefinder.nodal_line')
class NodalLine(SimpleNamespace):
"""
Shape class defining a nodal line.
Attributes
----------
graph : networkx.Graph
A graph describing the line.
"""
def __init__(self, graph, degree_count):
self.graph = graph
self.degree_count = degree_count
def __repr__(self):
return 'NodalLine(graph=<{} nodes, {} edges>, degree_count={}, shape_name=\'{}\')'.format(
len(self.graph.nodes), len(self.graph.edges), self.degree_count,
self.shape_name
)
[docs] def to_hdf5(self, hdf5_handle):
"""
Serialize the object and store in under the given HDF5 handle.
"""
graph_group = hdf5_handle.create_group('graph')
graph_group['nodes'] = np.array(list(self.graph.nodes))
if self.graph.edges:
graph_group['edges'] = np.array(list(self.graph.edges))
degree_count_group = hdf5_handle.create_group('degree_count')
to_hdf5(self.degree_count, degree_count_group)
[docs] @classmethod
def from_hdf5(cls, hdf5_handle):
"""
Derialize the object from the given HDF5 handle.
"""
graph_group = hdf5_handle['graph']
graph = nx.Graph()
graph.add_nodes_from([tuple(n) for n in graph_group['nodes']])
if 'edges' in graph_group:
graph.add_edges_from([(tuple(p1), tuple(p2))
for p1, p2 in graph_group['edges']])
degree_count = from_hdf5(hdf5_handle['degree_count'])
return cls(graph=graph, degree_count=degree_count)
@property
def shape_name(self):
"""
Describes the shape of the line, as inferred from the degree count.
"""
shape_lookup = {
tuple(): 'CLOSED LOOP',
((1, 2), ): 'OPEN LINE',
}
return shape_lookup.get(
tuple(sorted(self.degree_count.items())), 'UNKNOWN'
)