Skip to content
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

Open
wants to merge 173 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
ef5e909
test
orosoman-dstl Jan 9, 2023
e448647
building blocks
orosoman-dstl Jan 9, 2023
fa1d881
add architecture density and test for density function
spike-dstl Jan 10, 2023
54e1468
Change structure, expand Architecture class
orosoman-dstl Jan 10, 2023
c30fa92
add progress on plot function in architecture class
spike-dstl Jan 13, 2023
506c1ab
Create basic functionality for Architecture.plot method
orosoman-dstl Jan 19, 2023
c6eb678
Add shape colour functionality
spike-dstl Jan 30, 2023
82db2bd
Node title font size and kind of working node labelling system
spike-dstl Jan 30, 2023
4c11c41
Architecture.plot expansion. Allows specification of position, node s…
orosoman-dstl Jan 30, 2023
cebf0dd
Improvement to plot function
spike-dstl Jan 31, 2023
d567c40
Add SensorSuite function
spike-dstl Feb 2, 2023
c84aa39
Beginning of data measurement and propagation for architectures.
orosoman-dstl Feb 6, 2023
50d4701
Fixes to code
spike-dstl Feb 7, 2023
8f31038
Rough propogation for network architectures.
orosoman-dstl Feb 20, 2023
cb6ddf0
bug fixes/neatening for Node.update
orosoman-dstl Feb 21, 2023
727a2c6
making architectures gooder
orosoman-dstl Feb 24, 2023
fb63b3b
bug/fixes for Node.process(). Made SingleProbabilityHypothesis hashable
orosoman-dstl Mar 7, 2023
f5c7e47
Quick fix to architecture _set_dict() method
orosoman-dstl Mar 8, 2023
9324470
add message class
spike-dstl Mar 8, 2023
f1f9d31
Add send_message and open_message functions
spike-dstl Mar 14, 2023
176f91f
Add latency, Edge, Edges
orosoman-dstl Mar 14, 2023
05d2027
Adjustments to send_message and update_message functions to account f…
spike-dstl Mar 15, 2023
4aa0e1b
Further changes to Message and Edge classes.
orosoman-dstl Mar 17, 2023
4a318e1
added fixture to test_architecture
orosoman-dstl Mar 20, 2023
3b74502
halfway to fixing architecture propagation
orosoman-dstl Mar 27, 2023
60d85be
minor test changes and dictionary key change
spike-dstl Mar 23, 2023
66e1231
small changes
orosoman-dstl Mar 28, 2023
a2484b9
bug fixing towards correct measurement
orosoman-dstl Mar 28, 2023
e6fb87b
bug fixing towards correct measurement again
orosoman-dstl Apr 5, 2023
6ccd89c
bug fixin
orosoman-dstl Apr 17, 2023
8630329
propagation now works fully without latency
orosoman-dstl Apr 17, 2023
a07cf0f
bug fixin
orosoman-dstl May 2, 2023
b412716
data is passed only along direct edges
orosoman-dstl May 2, 2023
0e95ad2
MultiTargetFusionTracker started
orosoman-dstl May 2, 2023
99c879c
Debugging with latency successful
orosoman-dstl May 4, 2023
79bdc7a
Move into new architecture sub-module. Begin implementation of threading
orosoman-dstl May 12, 2023
846ba16
Changes to improve plot aesthetics
spike-dstl May 15, 2023
ccb6689
Bug fix to base.py to allow circular imports
spike-dstl May 19, 2023
ebfe7b1
Progress on fusion algorithm
spike-dstl May 25, 2023
d91d2cb
more tracker progress
spike-dstl May 30, 2023
1259fcc
Notes and minor tweaks on fusion tracker
orosoman-dstl Jun 20, 2023
98f576c
Notes and minor tweaks on fusion tracker 2
orosoman-dstl Jun 28, 2023
37afe45
Fusion Tracker updates
spike-dstl Jul 6, 2023
6768800
More work on tracker, still not working
spike-dstl Jul 6, 2023
dba51f5
Add automated hierarchical node positioning for fusion architectures …
spike-dstl Aug 21, 2023
c66d70a
sketch changes to tracker
orosoman-dstl Jul 26, 2023
f20967b
sketch of fusion tracker
orosoman-dstl Jul 28, 2023
2809e5d
Convert stonesoup.architectures from a directory to a Python Package.…
spike-dstl Aug 21, 2023
8007d40
Add tests for architecture.py, small fixes to other architecture file…
spike-dstl Aug 22, 2023
6e8eaec
Delete stonesoup.architecture directory file after replacement with p…
spike-dstl Aug 22, 2023
033426f
neatening of architectures
orosoman-dstl Aug 22, 2023
6594649
Add thread for tracker for FusionNode
sdhiscocks Aug 22, 2023
d22f2fb
Add plot_style parameter to Architecture plot function to allow hiera…
spike-dstl Aug 23, 2023
d0e3cf9
Add more tests for architecture.py
spike-dstl Aug 23, 2023
1bfb83a
renaming to sender/recipient terminology in architectures module
orosoman-dstl Aug 23, 2023
f3d7583
Change logic of InformationArchitecture.is_centralised() to use corre…
spike-dstl Aug 23, 2023
26cc798
beginning tests for node and edge class including conftest file
orosoman-dstl Aug 23, 2023
3bc9ddf
Various modifications for track to track fusion
sdhiscocks Aug 23, 2023
7f4fc10
completion of test_edge_init, additions to architectures conftests
orosoman-dstl Aug 23, 2023
a1be94d
Tests for all plotting and helper functions in stonesoup.architecture…
spike-dstl Aug 23, 2023
063a4bc
Fix issue with duplicating tracks in architectures
sdhiscocks Aug 23, 2023
b8720f4
add to architectures test_edge
orosoman-dstl Aug 24, 2023
bfaae80
minor test_edge changes
orosoman-dstl Aug 24, 2023
7f7cdb8
Move test_architecture.py fixtures to conftest.py and reconfigure tes…
spike-dstl Aug 24, 2023
d375fc4
Allow monitoring of queue consumption for fuse node queues
sdhiscocks Aug 24, 2023
3559ab7
Add a WIP wrapper for switching between two updaters
sdhiscocks Aug 24, 2023
fea112b
Add docstrings to architecture.__init__.py
spike-dstl Aug 24, 2023
b47a61e
test_edge mostly finished
orosoman-dstl Aug 24, 2023
822baf9
Make interface for FusionQueue clearer
sdhiscocks Aug 24, 2023
c22a10f
Allow architecture latency to be any type of number
sdhiscocks Aug 24, 2023
42a50e4
Fix logic with FusionNode in architectures
sdhiscocks Aug 24, 2023
46dc20e
finished test_edge in architectures
orosoman-dstl Aug 24, 2023
6e07082
Added fixtures for fusion network to conftest.py and further tests to…
spike-dstl Aug 24, 2023
f9d05da
finished test_edge in architectures
orosoman-dstl Aug 24, 2023
0204992
Remove timeout constraint on FuseNode in architectures
sdhiscocks Aug 24, 2023
daf46c9
Tests for architecture.__init__.py except for .propagate()
spike-dstl Aug 24, 2023
bf42cc7
finished test_functions
orosoman-dstl Aug 24, 2023
abbee37
Add tests for propagate function, test fails currently
spike-dstl Aug 25, 2023
4125148
Fix propagate tests, Flake8 errors
spike-dstl Aug 25, 2023
3529f9a
finished test_node
orosoman-dstl Aug 25, 2023
6d9c4b7
add networkx and graphviz to requirements
orosoman-dstl Aug 25, 2023
876b34a
Change to how DOT code is written in plot() function
spike-dstl Sep 4, 2023
8288bf3
Version 1 of architecture tutorial. Fixes to allow nodes to be plotted.
spike-dstl Sep 4, 2023
958a2a3
Add pydot to requirements. Updates to architecture plot() and relevan…
spike-dstl Sep 5, 2023
31c4238
Progress on NetworkArchitecture
spike-dstl Oct 16, 2023
f208d5a
NetworkArchitecture propagate() added functionality for nodes that do…
spike-dstl Oct 16, 2023
d8c7ee4
Additional functionality to NetworkArchitecture to enable passing of …
spike-dstl Oct 19, 2023
1439679
Fixes to NetworkArchitecture() to consider edge cases, added tests fo…
spike-dstl Oct 24, 2023
c02db32
Added architecture tutorials: Introduction to Architectures in Stone …
spike-dstl Nov 6, 2023
42df16f
Add use_arival_time property to Achitecture class to allow simulation…
spike-dstl Nov 30, 2023
b5596fe
Add metric table generator for comparing two tracks to a truth
spike-dstl Dec 4, 2023
a390776
Deepcopy datapieces to allow fusion node to recieve both induvidually…
spike-dstl Dec 4, 2023
33d2f72
Minor changes to docs prose
orosoman-dstl Dec 5, 2023
04396d5
Fix image loading in architecture tutorial 3
spike-dstl Dec 5, 2023
9c0e7ee
Fix grammar for architecture documentation
orosoman-dstl Dec 11, 2023
7958015
minor additional spelling and grammar fixes
orosoman-dstl Dec 11, 2023
b5a7c15
Update CircleCI build to include architectures dependencies
jswright-dstl Dec 12, 2023
f0db7b3
Clean up comments and documentation. Get rid of an unnecessary function
orosoman-dstl Dec 15, 2023
7ecbe2a
Fix minor bug in typing
orosoman-dstl Dec 15, 2023
f88368d
Fix failing test by changing method of adjusting data timestamps when…
spike-dstl Dec 21, 2023
d79dfbb
Fix short underlines causing bug in architectures tutorials
spike-dstl Dec 21, 2023
6bcf76f
Change Edge.unsent_data() method to consider edges rather than recipi…
spike-dstl Dec 21, 2023
6aa9a4b
Filter for duplicate data on fusion queue, update network arch propag…
spike-dstl Dec 21, 2023
0317589
Simplify some architecture plotting and enable display in docs
sdhiscocks Jan 22, 2024
09491da
Install graphviz on CircleCI to render architecture diagrams
sdhiscocks Jan 22, 2024
de6a516
Use node labels when plotting in info./net. architecture example
sdhiscocks Jan 26, 2024
6eb99e6
Fix architecture tutorial thumbnail images and remove old images
sdhiscocks Feb 9, 2024
277ba18
Fix architecture tutorial doc build warnings
sdhiscocks Feb 9, 2024
4f380ac
Add InformationArchitectureGenerator and NetworkArchitectureGenerator…
spike-dstl Feb 22, 2024
127aed2
Simplify node label generation and avoid duplicate node names
sdhiscocks Feb 26, 2024
3a200fd
Fixes to generator to produce more realistic decentralised graphs
spike-dstl Feb 28, 2024
af4be32
Progress on MultiArchitectureGenerators
spike-dstl Mar 19, 2024
5f31187
Functionality added to ArchitectureGenerator classes to allow creatio…
spike-dstl Apr 3, 2024
780bcc5
Bug fixes for ArchitectureGenerator classes
spike-dstl Apr 4, 2024
8c8e11d
Add tests for architecture generators
spike-dstl Apr 5, 2024
1eaf361
Add node labels to nodes generated by ArchitectureGenerator classes
spike-dstl Apr 10, 2024
583f215
Add detail to architecture tutorials
spike-dstl Apr 15, 2024
08a13a0
progress towards architecture generator bugs
spike-dstl Apr 15, 2024
bef7265
Fix bug in Architecture.propagate causing unintended lag/OOSM
spike-dstl Apr 17, 2024
378e755
Rework to ArchitectureGenerator logic to produce more feasible archit…
spike-dstl Apr 18, 2024
a8993f6
Merge branch 'architecture_generator' into architecture_repr
spike-dstl Apr 23, 2024
7d92bd2
Apply easier to address suggestions from #903 code review
orosoman-dstl Apr 23, 2024
c539359
Change to SiapDiffTableGenerator to allow more than 2 sets of metrics
spike-dstl Apr 24, 2024
fed2f5a
Merge branch 'architecture_repr' of https://github.com/dstl/Stone-Sou…
spike-dstl Apr 24, 2024
c79c2a5
Update Architecture tutorials to newer versions
spike-dstl May 2, 2024
19f08fa
Minor title change
Aug 22, 2024
d3f9f97
Remove commented cell from architecture tutorial 3
spike-dstl Aug 27, 2024
c175a64
Merge branch 'main' into architecture_repr
spike-dstl Aug 27, 2024
10d96e0
Update architecture branch to use new radar sensor resolution parameter.
spike-dstl Aug 27, 2024
babf8d4
Update stonesoup/architecture/__init__.py
orosoman-dstl Aug 28, 2024
2d6dba4
Update stonesoup/architecture/__init__.py
orosoman-dstl Aug 28, 2024
2707f9c
Update stonesoup/architecture/__init__.py
orosoman-dstl Aug 28, 2024
498b051
Update stonesoup/architecture/__init__.py
orosoman-dstl Aug 28, 2024
6f837f6
fix indent bug
orosoman-dstl Aug 28, 2024
019979a
flake-8 fixes
orosoman-dstl Aug 28, 2024
e993ad9
"Address review comments. Remove unnecessary code"
orosoman-dstl Aug 30, 2024
b3ba8cf
remove tests for fusion tracker
orosoman-dstl Aug 30, 2024
1fae468
Use timedelta to add to a datetime
orosoman-dstl Aug 30, 2024
df8ba83
Slicing GroundTruthPath converts back to StateMutableSequence - corre…
orosoman-dstl Aug 30, 2024
2a95fd0
cleanup and mopve towards tests passing
orosoman-dstl Aug 30, 2024
7166770
minor changes
orosoman-dstl Aug 30, 2024
95319c0
Fix bug caused by timedelta rounding to zero, Update fully propagated…
spike-dstl Sep 2, 2024
b26a993
Fix bug with Edge.unsent_data not accepting RepeaterNodes
spike-dstl Sep 2, 2024
f64d0ea
Fix flake-8 errors on Architecture module after bug fixes
spike-dstl Sep 2, 2024
a03822d
Add docstrings to architecture.__init__.py
spike-dstl Sep 5, 2024
0da6703
Improved coverage on arhitecture tests
spike-dstl Sep 5, 2024
8c794b5
improve coverage
orosoman-dstl Sep 6, 2024
b511737
fix error in test_edge.py
orosoman-dstl Sep 6, 2024
ffd7fc1
Fix to test_message_destinations. Add test_update_messages() to test …
spike-dstl Sep 9, 2024
35e814c
Improve coverage of architecture.node.
spike-dstl Sep 9, 2024
bd622b8
remove unnecessary RuntimeError check in FusionQueue
orosoman-dstl Sep 9, 2024
c334831
Fix architecture tests
sdhiscocks Sep 16, 2024
a4e16d3
fix flake8 and tutorial prose
orosoman-dstl Sep 16, 2024
6ac1984
flake8
orosoman-dstl Sep 16, 2024
ae5f690
bullet point fix
orosoman-dstl Sep 16, 2024
0d33ffd
bullet points...
orosoman-dstl Sep 16, 2024
4d55517
bullet points...
orosoman-dstl Sep 16, 2024
96ab028
bullet points...
orosoman-dstl Sep 16, 2024
6ab5d3b
Add description to architecture tutorial 3
spike-dstl Sep 17, 2024
9bec8ba
minor grammar fixes
orosoman-dstl Sep 17, 2024
01e00d8
backslash needed
orosoman-dstl Sep 17, 2024
f597e16
Arch Tutorial 3: Replace Siap metrics with covariance based metric.
spike-dstl Sep 20, 2024
2888d30
refine architecture tutorial 3
orosoman-dstl Sep 22, 2024
7077bee
fix bullet points againnn
orosoman-dstl Sep 23, 2024
62dd910
fix bullet points againnnnn
orosoman-dstl Sep 23, 2024
f9fabc1
fix list
orosoman-dstl Sep 23, 2024
3e651ae
fix list
orosoman-dstl Sep 23, 2024
f142cd1
bug fix
orosoman-dstl Sep 24, 2024
56ba870
match propogates architecture
orosoman-dstl Sep 25, 2024
494de0b
flake8
orosoman-dstl Sep 25, 2024
7c661aa
the
orosoman-dstl Sep 25, 2024
74808f9
fix list formatting
orosoman-dstl Sep 27, 2024
49dd925
formatting
orosoman-dstl Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rough propogation for network architectures.
  • Loading branch information
orosoman-dstl authored and spike-dstl committed Nov 29, 2023
commit 8f31038b86f89aadc4cfcc209b94fec87131a122
2 changes: 1 addition & 1 deletion stonesoup/tracker/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class MultiTargetTracker(Tracker):
----------
"""
initiator: Initiator = Property(doc="Initiator used to initialise the track.")
deleter: Deleter = Property(doc="Initiator used to initialise the track.")
deleter: Deleter = Property(doc="Deleter used to delete tracks.")
detector: DetectionReader = Property(doc="Detector used to generate detection objects.")
data_associator: DataAssociator = Property(
doc="Association algorithm to pair predictions to detections")
Expand Down
186 changes: 164 additions & 22 deletions stonesoup/types/architecture.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
from abc import abstractmethod
from ..base import Property
from ..base import Property, Base
from .base import Type
from ..sensor.sensor import Sensor
from ..types.groundtruth import GroundTruthState
from ..types.detection import TrueDetection, Clutter, Detection
from ..types.hypothesis import Hypothesis
from ..types.track import Track
from ..hypothesiser.base import Hypothesiser
from ..hypothesiser.probability import PDAHypothesiser
from ..predictor.base import Predictor
from ..updater.base import Updater
from ..dataassociator.base import DataAssociator
from ..initiator.base import Initiator
from ..deleter.base import Deleter

from typing import List, Collection, Tuple, Set, Union, Dict
import numpy as np
import networkx as nx
import graphviz
from string import ascii_uppercase as auc
from datetime import datetime
from datetime import datetime, timedelta


class Node(Type):
Expand All @@ -28,22 +36,27 @@ class Node(Type):
shape: str = Property(
default=None,
doc='Shape used to display nodes')
data_held: Dict[datetime, Union[Detection, Hypothesis]] = Property(
data_held: Dict[datetime, Set[Detection]] = Property(
default=None,
doc='Data or information held by this node')
doc='Raw sensor data (Detection objects) held by this node')
hypotheses_held: Dict[Track, Dict[datetime, Set[Hypothesis]]] = Property(
default=None,
doc='Processed information (Hypothesis objects) held by this node')

def __init__(self,*args, **kwargs):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.data_held:
self.data_held = dict()

def update(self, time, data):
if not isinstance(data, Detection) and not isinstance(data, Hypothesis):
raise TypeError("Data must be a Detection or Hypothesis")
if not isinstance(time, datetime):
raise TypeError("Time must be a datetime object")
if data not in self.data_held:
self.data_held[time] = data
if not isinstance(data, Detection):
raise TypeError("Data provided without Track must be a Detection")
if time in self.data_held:
self.data_held[time].add(data)
else:
self.data_held[time] = {data}


class SensorNode(Node):
Expand All @@ -60,14 +73,96 @@ def __init__(self, *args, **kwargs):

class ProcessingNode(Node):
"""A node that does not measure new data, but does process data it receives"""
# Latency property could go here
predictor: Predictor = Property(
doc="The predictor used by this node. ")
updater: Updater = Property(
doc="The updater used by this node. ")
hypothesiser: Hypothesiser = Property(
doc="The hypothesiser used by this node. ")
data_associator: DataAssociator = Property(
doc="The data associator used by this node. ")
initiator: Initiator = Property(
doc="The initiator used by this node")
deleter: Deleter = Property(
doc="The deleter used by this node")

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.colour:
self.colour = '#006400'
if not self.shape:
self.shape = 'hexagon'

self.processed_data = dict() # Subset of data_held containing data that has been processed
self.unprocessed_data = dict() # Data that has not been processed yet
self.processed_hypotheses = dict() # Dict[track: Dict[datetime, Set[Hypothesis]]]
self.unprocessed_hypotheses = dict() # Hypotheses which have not yet been used
self.tracks = {} # Set of tracks this Node has recorded

def process(self):
for time in self.unprocessed_data:
detections = self.unprocessed_data[time]
detect_hypotheses = self.data_associator.associate(self.tracks, detections, time)

associated_detections = set()
for track in self.tracks:
detect_hypothesis = detect_hypotheses[track]
try:
track_hypotheses = self.unprocessed_hypotheses[track][time]
hypothesis = mean_combine({detect_hypothesis} + track_hypotheses, time)
except KeyError: # If there aren't any, use the one we have from our detections
hypothesis = detect_hypothesis

if hypothesis.measurement:
post = self.updater.update(hypothesis)
track.append(post)
associated_detections.add(hypothesis.measurement)
else: # Keep prediction
track.append(hypothesis.prediction)

# Create or delete tracks
self.tracks -= self.deleter.delete_tracks(self.tracks)
self.tracks |= self.initiator.initiate(
detections - associated_detections, time)

# Send the unprocessed data that was just processed to processed_data
for time in self.unprocessed_data:
for data in self.unprocessed_data[time]:
if time in self.processed_data:
self.processed_data[time].add(data)
else:
self.processed_data[time] = {data}
# And same for hypotheses. We must ensure that we create sets before adding to them
for track in self.unprocessed_hypotheses:
for time in self.unprocessed_hypotheses[track]:
for data in self.unprocessed_hypotheses[track][time]:
if track in self.processed_hypotheses:
if time in self.processed_hypotheses[track]:
self.processed_hypotheses[track][time].add(data)
else:
self.hypotheses_held[track][time] = {data}
else:
self.hypotheses_held[track] = {time: data}
self.unprocessed_data = []
self.unprocessed_hypotheses = []
return

def update(self, time, data, track=None):
if not track:
super().update(time, data)
else:
if not isinstance(time, datetime):
raise TypeError("Time must be a datetime object")
if not isinstance(data, Hypothesis):
raise TypeError("Data provided with Track must be a Hypothesis")
if track in self.hypotheses_held:
if time in self.hypotheses_held[track]:
self.hypotheses_held[track][time].add(data)
else:
self.hypotheses_held[track][time] = {data}
else:
self.hypotheses_held[track] = {time: {data}}


class SensorProcessingNode(SensorNode, ProcessingNode):
"""A node that is both a sensor and also processes data"""
Expand Down Expand Up @@ -133,7 +228,8 @@ def __init__(self, *args, **kwargs):
"if you wish to override this requirement")

# Set attributes such as label, colour, shape, etc for each node
last_letters = {'SensorNode': '', 'ProcessingNode': '', 'RepeaterNode': ''}
last_letters = {'SensorNode': '', 'ProcessingNode': '', 'SensorProcessingNode': '',
'RepeaterNode': ''}
for node in self.di_graph.nodes:
if node.label:
label = node.label
Expand Down Expand Up @@ -175,11 +271,19 @@ def all_nodes(self):

@property
def sensor_nodes(self):
sensors = set()
sensor_nodes = set()
for node in self.all_nodes:
if isinstance(node, SensorNode):
sensors.add(node.sensor)
return sensors
sensor_nodes.add(node)
return sensor_nodes

@property
def processing_nodes(self):
processing = set()
for node in self.all_nodes:
if isinstance(node, ProcessingNode):
processing.add(node)
return processing

def plot(self, dir_path, filename=None, use_positions=False, plot_title=False,
bgcolour="lightgray", node_style="filled"):
Expand Down Expand Up @@ -274,29 +378,42 @@ def measure(self, ground_truths: Set[GroundTruthState], noise: Union[bool, np.nd
all_detections[sensor_node] = sensor_node.sensor.measure(ground_truths, noise,
**kwargs)

attributes_dict = {attribute_name: sensor_node.sensor.__getattribute__(attribute_name)
for attribute_name in self.attributes_inform}
# Borrowed below from SensorSuite. I don't think it's necessary, but might be something
# we need. If so, will need to define self.attributes_inform

for detection in all_detections[sensor_node]:
detection.metadata.update(attributes_dict)
# attributes_dict = \
# {attribute_name: sensor_node.sensor.__getattribute__(attribute_name)
# for attribute_name in self.attributes_inform}
#
# for detection in all_detections[sensor_node]:
# detection.metadata.update(attributes_dict)

for data in all_detections[sensor_node]:
# The sensor acquires its own data instantly
sensor_node.update(self.current_time, data)

return all_detections

def propagate(self, time_increment: float, failed_edges: Collection = None):
def propagate(self, time_increment: float, failed_edges: Collection = []):
"""Performs a single step of the propagation of the measurements through the network"""
self.current_time += datetime.timedelta(seconds=time_increment)
self.current_time += timedelta(seconds=time_increment)
for node in self.all_nodes:
for descendant in self.descendants(node):
if (node, descendant) in failed_edges:
# The network architecture / some outside factor prevents information from node
# being transferred to other
continue
for data in node.data_held:
descendant.update(self.current_time, data)
if node.data_held:
for time in node.data_held:
for data in node.data_held[time]:
descendant.update(time, data)
if node.hypotheses_held:
for track in node.hypotheses_held:
for time in node.hypotheses_held[track]:
for data in node.hypotheses_held[track][time]:
descendant.update(time, data, track)
for node in self.processing_nodes:
node.process()


class NetworkArchitecture(Architecture):
Expand Down Expand Up @@ -356,3 +473,28 @@ def _default_letters(type_letters) -> str:
letters_list[-1 - count] = auc[auc.index(current_letter) + 1]
new_letters = ''.join(letters_list)
return new_letters


def mean_combine(objects: List, current_time: datetime = None):
"""Combine a list of objects of the same type by averaging all numbers"""
this_type = type(objects[0])
if any(type(obj) is not this_type for obj in objects):
raise TypeError("Objects must be of identical type")

new_values = dict()
for name in type(objects[0]).properties:
value = getattr(objects[0], name)
if isinstance(value, (int, float, complex)) and not isinstance(value, bool):
# average em all
new_values[name] = np.mean([getattr(obj, name) for obj in objects])
elif isinstance(value, datetime):
# Take the input time, as we likely want the current simulation time
new_values[name] = current_time
elif isinstance(value, Base): # if it's a Stone Soup object
# recurse
new_values[name] = mean_combine([getattr(obj, name) for obj in objects])
else:
# just take 1st value
new_values[name] = getattr(objects[0], name)

return this_type.__init__(**new_values)
Loading