Commit 4ec7929a authored by Samuel Rowlinson's avatar Samuel Rowlinson

Fixed a bug in make_changing_forest which resulted in duplicate trees in some cases

Now performing the necessary post-processing of obtained broadest changing sub-trees,
setting parents as appropriate and removing single branch trees whose parents have
already been set on another changing tree.
parent cbab95fa
......@@ -482,7 +482,7 @@ cdef class BaseSimulation:
ws.update()
cdef void compute_knm_matrices(self):
cdef KnmConnectorWorkspace ws
cdef KnmConnectorWorkspace ws
for ws in self.to_scatter_matrix_compute:
ws.update_changing_knm_workspaces()
ws.compute_scattering_matrices()
......@@ -633,11 +633,14 @@ cdef class BaseSimulation:
# the next few calls as trace data is required for these
cdef TraceForest model_trace_forest = self.model._trace_forest
if self.is_modal and not self.is_audio:
# Make sure the model trace forest gets re-planted
# when building a new simulation
self.model._rebuild_trace_forest = True
self.model.beam_trace(**self.model.beam_trace_args)
self.retrace = self.model.retrace
if self.retrace and self.is_modal and not self.is_audio:
# construct the forest of changing trace trees - need to do this
# Construct the forest of changing trace trees - need to do this
# here as the _get_workspace method of Connectors requires the
# simulation trace_forest field to be initialised when making
# the refill flags
......@@ -801,13 +804,6 @@ cdef class BaseSimulation:
tree = self.trace_forest.forest[tree_idx]
self._setup_single_trace_tree(tree)
# Also need to set the parent node_id as this will be used
# in the beam tracing propagation routine
if tree.parent is not None:
self.trace_forest.forest[tree_idx] = tree.parent
tree.parent.node_id = self.node_id(tree.parent.node)
tree.parent.opp_node_id = self.node_id(tree.parent.node.opposite)
if self.trace_forest.N_trees:
LOGGER.info("Determined changing trace trees:%s", self.trace_forest.draw())
......@@ -1071,7 +1067,7 @@ cdef class BaseSimulation:
if isinstance(ws, KnmConnectorWorkspace):
(<KnmConnectorWorkspace> ws).initialise_knm_workspaces()
self.to_scatter_matrix_compute.append(ws)
self.workspaces.append(ws) # store all workspaces here
if isinstance(ws, ConnectorWorkspace):
......
......@@ -452,6 +452,12 @@ cdef class TraceForest:
return self.model.network.nodes[name]["weakref"]()
cdef TraceForest make_changing_forest(self):
"""Constructs a new TraceForest from this forest, consisting
of only the trees which will have changing beam parameters.
This method is called in BaseSimulation._initialise for setting
up the simulation trace forest used for efficient beam tracing.
"""
cdef:
Py_ssize_t tree_idx
TraceTree tree
......@@ -461,8 +467,31 @@ cdef class TraceForest:
for tree_idx in range(self.N_trees):
tree = self.forest[tree_idx]
# From this tree, obtain the broadest sub-trees which
# will have changing beam parameters
changing_trees.extend(tree.get_broadest_changing_subtrees())
cdef Py_ssize_t Nchanging_nominal = len(changing_trees)
cdef set roots = set() # Parents of changing trees
cdef set trees_to_remove = set()
for tree_idx in range(Nchanging_nominal):
tree = changing_trees[tree_idx]
# Now set each changing tree to the parent tree so that
# the root is used in beam tracing...
if tree.parent is not None:
# ... but only do this for parents not yet added
# otherwise could get duplicate trees
if tree.parent not in roots:
changing_trees[tree_idx] = tree.parent
roots.add(tree.parent)
else:
# This tree will already be encapsulated by the previous
# parent so just mark it to be removed
trees_to_remove.add(tree)
for tree in trees_to_remove:
changing_trees.remove(tree)
changing_forest.forest = changing_trees
changing_forest.N_trees = len(changing_trees)
changing_forest.symmetric = self.symmetric
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment