Commit a5e17bb1 authored by Daniel Brown's avatar Daniel Brown
Browse files

more fixing of network node functions, adding some documentation in too

parent d75cff35
......@@ -12,5 +12,12 @@ print "".join(kat.generateKatScript())
kat.nodes.replaceNode(kat.bs1, kat.bs1.nodes[3], kat.nodes.createNode("test4"))
kat.nodes.replaceNode(kat.bs1, kat.bs1.nodes[1], kat.nodes.createNode("test2"))
kat.nodes.replaceNode(kat.bs1, "n1", kat.nodes.createNode("test1"))
kat.nodes.replaceNode(kat.bs1, "n3", kat.nodes.createNode("dump"))
kat.nodes.replaceNode(kat.bs1, "test1", kat.nodes.createNode("dump"))
print "AFTER"
print "".join(kat.generateKatScript())
......@@ -235,3 +235,7 @@ class x2axis(xaxis):
raise pkex.BasePyKatException("xaxis Finesse code format incorrect '{0}'".format(text))
return x2axis(values[2], [values[3], values[4]], values[1], values[5], comp=values[0],axis_type=axis_type)
class lock(Command):
......@@ -22,6 +22,8 @@ class BaseDetector(object) :
This base class can handled detectors connected to multiple nodes.
__metaclass__ = abc.ABCMeta
def __init__(self, name, nodes=None, max_nodes=1):
self.__name = name
......@@ -1046,7 +1046,7 @@ class kat(object):
if isinstance(obj, Component):
del self.__components[]
elif isinstance(obj, Command):
del self.__commands[]
......@@ -1111,7 +1111,7 @@ class kat(object):
return (Mcarrier, Msignal)
def hasNamedObject(self, name):
return name in self.__components or name in self.__detectors or name in self.__commands
......@@ -1186,6 +1186,13 @@ class kat(object):
return [x, y, hdr]
def removeLine(self, fragment) :
This will search all blocks by default and search for the string
fragment specified and remove it. This will only remove non-parsed
commands, it will not remove commands that have already been parsed
into the pykat structure, such as mirrors and beamsplitters, use the
kat.remove(...) function for that purpose.
for key in self.__blocks:
objs = self.__blocks[key].contents
for obj in objs:
......@@ -1194,7 +1201,15 @@ class kat(object):
print " ** removing line '{0}'".format(obj)
def addLine(self, line, block=NO_BLOCK) :
This will forcefully add a line of FINESSE code to a particular block
if specfied. This command will not undergo any parsing so it will remain
as just a string. This of course can create possible conflicts with other
pykat object that create similar commands so becareful.
def generateKatScript(self) :
""" Generates the kat file which can then be run """
......@@ -43,7 +43,7 @@ class NodeNetwork(object):
for name in node_names:
n = self.createNode(name)
self.connectNodeToComp(n, comp, do_callback=False)
self.__connectNodeToComp(n, comp, do_callback=False)
self.__componentNodes[] = tuple(list)
......@@ -52,14 +52,39 @@ class NodeNetwork(object):
def replaceNode(self, comp, node_old, node_new):
For a particular pykat component this will replace a node that is currently
connected to it with another. This can be used to dynamically change layouts
once components have been read into the pykat.finesse.kat object.
node_old is the node that is attached to the component. This will accept
str - name of a node
pykat.node_network.Node - The direct node object
pykat.components.NodeGaussSetter - the node object that is used to set gaussian parameters
This will call a components __on_node_change callback function to let it know that the nodes
connected to it have changed.
if node_new.components.count(None) == 0:
if isinstance(node_old, str):
node_old = self.__kat.nodes[node_old]
if isinstance(node_new, str):
node_new = self.__kat.nodes[node_new]
if isinstance(node_old, pykat.components.NodeGaussSetter):
node_old = node_old.node
if isinstance(node_new, pykat.components.NodeGaussSetter):
node_new = node_new.node
if not node_new.isDump and node_new.components.count(None) == 0:
raise pkex.BasePyKatException("New node already connected to two components")
if comp not in node_old.components:
raise pkex.BasePyKatException("Old node not attached to component")
if comp in node_new.components:
if not node_new.isDump and comp in node_new.components:
raise pkex.BasePyKatException("New node already attached to component")
# add component to new node component list
......@@ -82,11 +107,15 @@ class NodeNetwork(object):
# if old node is no longer connected to anything then delete it
if node_old.components.count(None) == 2:
# Call component callback to let it know that we have changed the
# nodes attached to it
def connectNodeToComp(self, node, comp, do_callback=True):
def __connectNodeToComp(self, node, comp, do_callback=True):
This is an internal function used to create connections between nodes
if in self.__nodeComponents:
comps = self.__nodeComponents[]
......@@ -109,22 +138,41 @@ class NodeNetwork(object):
if do_callback: self.__componentCallback[]()
def createNode(self, node_name):
if node_name == 'dump':
return DumpNode(self)
This creates a new node object. It won't be connected to anything or added to a
pykat.finesse.kat object until it is specifically attached to a particular
component. This should be used in conjunction with kat.nodes.replaceNode to
add a new node into a system, as every component will already have the nodes
setup, including dump nodes.
This will return a dump node if the name of the node is "dump" (case senstive)
if node_name in self.__nodes:
if node_name != 'dump' and node_name in self.__nodes:
# then this node already exists
return self.__nodes[node_name]
n = Node(node_name, self, self.__node_id)
if node_name == 'dump':
n = DumpNode(self)
n = Node(node_name, self, self.__node_id)
self.__node_id += 1
self.__add_node_attr(n) # add node as a member of this object, e.g. kat.nodes.n
self.__nodes[node_name] = n
self.__nodeComponents[] = (None, None)
if not n.isDump:
self.__add_node_attr(n) # add node as a member of this object, e.g. kat.nodes.n
self.__nodes[node_name] = n
return n
def removeComponent(self, comp):
def _removeComponent(self, comp):
This is an internal function that shouldn't be used directly. This removes
a particular component from the node network. For this to work it has to be
detached from all other connections first.
C = self.__componentNodes[]
for n in C:
......@@ -142,7 +190,25 @@ class NodeNetwork(object):
del self.__componentNodes[]
def removeNode(self, node):
This will remove a particular node object from the network. The node in question
must be fully detached from all components and connections first. This function is
called by replaceNode directly so a replaced node, that is no longer connected to
anything, is removed automatically.
node_old is the node that is attached to the component. This will accept
str - name of a node
pykat.node_network.Node - The direct node object
pykat.components.NodeGaussSetter - the node object that is used to set gaussian parameters
if isinstance(node, str):
node = self.__kat.nodes[node]
if isinstance(node, pykat.components.NodeGaussSetter):
node = node.node
if not isinstance(node, Node):
raise pkex.BasePyKatException("node argument is not of type Node")
......@@ -160,49 +226,32 @@ class NodeNetwork(object):
if not isinstance(node, DumpNode):
del self.__nodes[]
del self.__nodeComponents[]
del self.__nodeComponents[]
def hasNode(self, name):
return (name in self.__nodes)
def getNodes(self):
Returns a copy of the node dictionary, this is for infomration purposes any edits won't make
any changes to the node network.
return self.__nodes.copy()
def dumpInfo(self):
for name in self.__nodes:
n = self.__nodes[name]
items = n.getComponents()
comp = items[0][:]
det = items[1]
if comp[0] == None:
comp1 = 'dump'
comp1 = comp[0].name
if comp[1] == None:
comp2 = 'dump'
comp2 = comp[1].name
detectors = ""
if len(det) > 0:
detectors = "Detectors: "
for d in det:
detectors = detectors + + " "
print "node: {0} connected:{1} {2}->{3} {4}".format(,n.isConnected(),comp1, comp2, detectors)
def getComponentNodes(self, comp):
This function returns a tuple of the nodes connected to the component specified.
For information only, you cannot edit the connections using this function.
return self.__componentNodes[]
def getNodeComponents(self, node):
This function returns a tuple of the components connected to the node specified.
For information only, you cannot edit the connections using this function.
return self.__nodeComponents[]
def __add_node_attr(self, node):
......@@ -218,7 +267,7 @@ class NodeNetwork(object):
def __remove_node_attr(self, node):
if not isinstance(node, Node):
raise pkex.BasePyKatException("Argument is not of type Node")
kat.nodes.replaceNode(kat.bs1, "n1", kat.nodes.createNode("test1"))
name =
delattr(self, '__node_' + name)
......@@ -228,7 +277,10 @@ class NodeNetwork(object):
return getattr(self, '__node_' + name)
def __getitem__(self, value):
return self.__nodes[str(value)]
if str(value) in self.__nodes:
return self.__nodes[str(value)]
raise pkex.BasePyKatException("The node '%s' could not be found in the network." % str(value))
def __contains__(self, value):
return value in self.__nodes
......@@ -334,7 +386,26 @@ class NodeNetwork(object):
return self.__nodeSearch(nextnode, nextcomp, branches, tnode)
def getComponentsBetween(self, from_node, to_node):
This function will trace the path between the two nodes specified and return a list
of the components it finds between them.
if isinstance(from_node, str):
from_node = self.__kat.nodes[from_node]
if isinstance(from_node, pykat.components.NodeGaussSetter):
from_node = from_node.node
if isinstance(to_node, str):
to_node = self.__kat.nodes[to_node]
if isinstance(to_node, pykat.components.NodeGaussSetter):
to_node = to_node.node
if to_node == from_node:
return []
if from_node not in self.__nodes:
raise pkex.BasePyKatException("Node {0} cannot be found in this kat object".format(from_node))
Supports Markdown
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