-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Information and Network Architectures #903
base: main
Are you sure you want to change the base?
Conversation
…tyle, background colour
9c2cba7
to
ffd7fc1
Compare
doc="An Edges object containing all edges. For A to be connected to B we would have an " | ||
"Edge with edge_pair=(A, B) in this object.") | ||
current_time: datetime = Property( | ||
default=datetime.now(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If current_time
is None
this is set to datetime.now()
in the __init__
method, but the default value is still datetime.now()
. Is this correct?
for leaf_node in self.leaf_nodes: | ||
try: | ||
shortest_path = self.shortest_path_dict[leaf_node][node] | ||
if node != leaf_node or shortest_path != 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a scenario where one of node != leaf_node
or shortest_path != 0
is true but not the other?
else: | ||
return 1 | ||
except KeyError: | ||
non_leaves += 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non_leaves is unused
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
if any([isinstance(node, RepeaterNode) for node in self.all_nodes]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "if len(self.repeater_nodes) != 0:" achieve the same result?
self.information_arch = InformationArchitecture( | ||
edges=self.information_architecture_edges, current_time=self.current_time) | ||
else: | ||
self.information_arch = InformationArchitecture(self.edges, self.current_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should self.information_architecture_edges be set to self.edges?
if edge.recipient not in self.information_arch.all_nodes: | ||
edge.update_messages(self.current_time, to_network_node=True, | ||
use_arrival_time=self.use_arrival_time) | ||
else: | ||
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if edge.recipient not in self.information_arch.all_nodes: | |
edge.update_messages(self.current_time, to_network_node=True, | |
use_arrival_time=self.use_arrival_time) | |
else: | |
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time) | |
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time, | |
to_network_node=(edge.recipient not in self.information_arch.all_nodes)) |
if edge.recipient not in self.information_arch.all_nodes: | ||
edge.update_messages(self.current_time, to_network_node=True, | ||
use_arrival_time=self.use_arrival_time) | ||
else: | ||
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if edge.recipient not in self.information_arch.all_nodes: | |
edge.update_messages(self.current_time, to_network_node=True, | |
use_arrival_time=self.use_arrival_time) | |
else: | |
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time) | |
edge.update_messages(self.current_time, use_arrival_time=self.use_arrival_time, | |
to_network_node=(edge.recipient not in self.information_arch.all_nodes)) |
try: | ||
shortest_path = self.shortest_path_dict[leaf_node][node] | ||
if node != leaf_node or shortest_path != 0: | ||
node_leaves.add(leaf_node) | ||
else: | ||
return 1 | ||
except KeyError: | ||
non_leaves += 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try: | |
shortest_path = self.shortest_path_dict[leaf_node][node] | |
if node != leaf_node or shortest_path != 0: | |
node_leaves.add(leaf_node) | |
else: | |
return 1 | |
except KeyError: | |
non_leaves += 1 | |
try: | |
shortest_path = self.shortest_path_dict[leaf_node][node] | |
except KeyError: | |
non_leaves += 1 | |
else: | |
if node != leaf_node or shortest_path != 0: | |
node_leaves.add(leaf_node) | |
else: | |
return 1 |
An else clause should be used to move code that isn't expected to cause an exception out of the try-except
metrics: Collection[Collection[MetricGenerator]] = Property(doc="Set of metrics to put in the " | ||
"table") | ||
|
||
metrics_labels: Collection[str] = Property(doc='List of titles for ', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sentence is unfinished
|
||
class SIAPDiffTableGenerator(Base): | ||
""" | ||
Given two sets of metric generators, the SiapDiffTableGenerator returns a table displaying the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to specify two sets?
@@ -135,3 +135,112 @@ def set_default_descriptions(self): | |||
"SIAP ID Correctness": "Fraction of true objects with correct ID assignment", | |||
"SIAP ID Ambiguity": "Fraction of true objects with ambiguous ID assignment" | |||
} | |||
|
|||
|
|||
class SIAPDiffTableGenerator(Base): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible for this to inherit from SIAPTableGenerator to save from having to redefine set_default_descriptions and set_default_targets
def update(self, time_pertaining, time_arrived, data_piece, category, track=None, | ||
use_arrival_time=False): | ||
"""Updates this :class:`~.Node`'s :attr:`~.data_held` using a new data piece. """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add typings to docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this or the other two pngs still being used?
n_archs: int = Property( | ||
doc="Tuple containing a minimum and maximum value for the number of routes created in the " | ||
"network architecture to represent a single edge in the information architecture.", | ||
default=2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring seems inaccurate
# Method 3: Identical Information and Network Architectures | ||
net_arch3 = NetworkArchitecture(edges=info_edges) | ||
assert net_arch3.information_arch.edges == info_edges | ||
assert net_arch3.edges == info_edges |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
possibly add "method 4: Providing only network architecture edges" to generate the info edges
assert (nodes['a'], nodes['b']) in edges_list.edge_list | ||
assert (nodes['a'], nodes['b']) in edges_list.edge_list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repeated line?
# Check node types | ||
assert len(arch.fusion_nodes) == sum([2, 1]) | ||
assert len(arch.sensor_nodes) == sum([2, 2]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert arch.is_hierarchical |
It would make sense to add a check that the "hierarchical" type generates a hierarchical architecture
|
||
# Test invalid time inputs | ||
with pytest.raises(TypeError): | ||
A.update(dt0, dt0, 'faux DataPiece', 'created') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test should included a valid data piece to show that its the time causing the fail
Introducing the long-awaited architecture module! Thus far, multi-sensor tracking in Stone Soup has operated on the assumption that data from multiple sensors can be fused together seamlessly, but this addition allows experimentation with different architectures.
As there are a fair chunk of new components, we've provided documentation in the form of three tutorials, which I'd recommend starting with to aid your understanding.