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

adding in ability to remove components/detectors/commands

parent 6ae54931
......@@ -35,7 +35,7 @@ def callback(lkat, maxphi):
inter = pylibkat.interferometer.in_dll(lkat, "inter")
m1 = inter.mirror_list[0]
m2 = inter.mirror_list[1]
m2 = inter.mirror_list[1]
circ = inter.output_data_list[0]
......@@ -54,7 +54,6 @@ def callback(lkat, maxphi):
print "Process: Maximum power =", circ.re
print "Process: Mirror tuning =", m1.phi
cmd = """
l l1 1 0 n1
s s1 1 n1 n2
......@@ -75,7 +74,7 @@ kat = pykat.finesse.kat()
kat.parseCommands(cmd)
maxphi = Value('d', 100)
maxphi = Value('d', 0)
p = kat.getProcess(callback, maxphi=maxphi)
p.start()
......
......@@ -15,9 +15,10 @@ from collections import namedtuple
from pykat.utilities.optics.gaussian_beams import gauss_param
class Command(object):
def __init__(self):
self.tag = None
tag = None
__removed = False
def getFinesseText(self):
""" Base class for individual finesse optical components """
raise NotImplementedError("This function is not implemented")
......@@ -32,8 +33,17 @@ class Command(object):
"""
self._kat = kat
def remove(self):
self._kat.remove(self)
self.__removed = True
@property
def removed(self): return self.__removed
class cavity(Command):
def __init__(self, name, c1, n1, c2, n2):
super(Command, self).__init__()
self.__name = name
self.__c1 = c1
self.__c2 = c2
......@@ -84,6 +94,7 @@ class tf(Command):
fQ = namedtuple('fQ', ['f', 'Q'])
def __init__(self, name, poles, zeros):
super(Command, self).__init__()
pass
class xaxis(Command):
......@@ -92,6 +103,9 @@ class xaxis(Command):
and interface to the xaxis command in FINESSE.
"""
@property
def name(self): return self._axis_type
def __init__(self, scale, limits, param, steps, comp=None, axis_type="xaxis"):
"""
Typical usage:
......@@ -102,6 +116,8 @@ class xaxis(Command):
steps is the number of points to compute between upper and lower limits.
"""
super(Command, self).__init__()
self._axis_type = axis_type
self.x = putter("x1")
......@@ -140,7 +156,7 @@ class xaxis(Command):
raise pkex.BasePyKatException("param argument is not of type Param")
else:
self.__param = param
self.__comp = param._owner.name
self.__comp = param._owner().name
@property
def param(self): return self.__param
......@@ -150,7 +166,7 @@ class xaxis(Command):
raise pkex.BasePyKatException("param argument is not of type Param")
else:
self.__param = value
self.__comp = value._owner.name
self.__comp = value._owner().name
@staticmethod
def parseFinesseText(text):
......
......@@ -16,41 +16,41 @@ import pykat.gui.graphics
from pykat.gui.graphics import *
from pykat.SIfloat import *
from pykat.param import Param, AttrParam
import weakref
import pykat.exceptions as pkex
next_component_id = 1
class NodeGaussSetter(object):
def __init__(self, component, node):
self.__comp = component
self.__node = node
self.__comp = weakref.ref(component)
self.__node = weakref.ref(node)
@property
def node(self):
return self.__node
return self.__node()
@property
def q(self):
return self.__node.qx
return self.__node().qx
@q.setter
def q(self, value):
self.__node.setGauss(self.__comp, complex(value))
self.__node().setGauss(self.__comp(), complex(value))
@property
def qx(self):
return self.__node.qx
return self.__node().qx
@qx.setter
def qx(self, value):
self.__node.setGauss(self.__comp, complex(value))
self.__node().setGauss(self.__comp(), complex(value))
@property
def qy(self):
return self.__node.qy
return self.__node().qy
@qy.setter
def qy(self, value):
self.__node.setGauss(self.__comp, self.qx, complex(value))
self.__node().setGauss(self.__comp(), self.qx, complex(value))
class Component(object):
__metaclass__ = abc.ABCMeta
......@@ -62,6 +62,7 @@ class Component(object):
self._kat = None
self.tag = None
self._params = []
self.__removed = False
# store a unique ID for this component
global next_component_id
......@@ -106,7 +107,7 @@ class Component(object):
ns = self.__dict__[key]
delattr(self, '__nodesetter_' + ns.node.name)
delattr(self.__class__, ns.node.name)
for node in self.nodes:
if type(node) != pykat.node_network.DumpNode:
ns = NodeGaussSetter(self, node)
......@@ -141,6 +142,9 @@ class Component(object):
def getQGraphicsItem(self):
return None
@property
def removed(self): return self.__removed
@property
def nodes(self): return self._kat.nodes.getComponentNodes(self)
......@@ -152,6 +156,13 @@ class Component(object):
def __str__(self): return self.name
def remove(self):
self._kat.remove(self)
del self._params[:]
self.__removed = True
class AbstractMirrorComponent(Component):
__metaclass__ = abc.ABCMeta
......
......@@ -27,7 +27,8 @@ class Detector(object) :
self._params = []
self._mask = {}
self.__scale = None
self.__removed = False
if node != None:
if node[-1]=='*':
self._alternate_beam = True
......@@ -39,9 +40,19 @@ class Detector(object) :
self._params.append(param)
def _on_kat_add(self, kat):
self._kat = kat
if self.__requested_node != None:
self.__node = kat.nodes.createNode(self.__requested_node)
def remove(self):
if self.__removed:
raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name))
else:
self._kat.remove(self)
self.__removed = True
@staticmethod
def parseFinesseText(text):
raise NotImplementedError("This function is not implemented")
......@@ -53,6 +64,10 @@ class Detector(object) :
def getQGraphicsItem(self):
return None
@property
def removed(self): return self.__removed
@property
def scale(self): return self.__scale
@scale.setter
......
......@@ -164,18 +164,27 @@ class Signals(object):
self.__name = name
self.__amplitude = Param("amp", self, SIfloat(amplitude))
self.__phase = Param("phase", self, SIfloat(phase))
self.__removed = False
# unfortunatenly the target names for fsig are not the same as the
# various parameter names of the components, e.g. mirror xbeta is x
# for fsig. So we need to check here what type of component we are targetting
# and then based on the parameter specfied get the name
if not param.canFsig:
raise pkex.BasePyKatException("Cannot fsig parameter {1} on component {0}".format(str(param._owner), param.name))
raise pkex.BasePyKatException("Cannot fsig parameter {1} on component {0}".format(str(param._owner().name), param.name))
def _register_param(self, param):
self._params.append(param)
@property
def removed(self): return self.__removed
def remove(self):
if self.__removed:
raise pkex.BasePyKatException("Signal {0} has already been marked as removed".format(self.name))
else:
self._kat.remove(self)
@property
def name(self): return self.__name
......@@ -194,7 +203,7 @@ class Signals(object):
def target(self): return self.__target.fsig_name
@property
def owner(self): return self.__target._owner.name
def owner(self): return self.__target._owner().name
def getFinesseText(self):
rtn = []
......@@ -211,10 +220,18 @@ class Signals(object):
# so need to get the name of at least one of them
# as if you tune one you tune them all
if len(self.targets) == 0:
return "signal"
return "fsignal"
else:
return self.targets[0].name
@property
def removed(self): return False # we can never remove the Signal object altogethr just the
# individual fsig targets
def remove(self):
for t in self.targets:
self._kat.remove(self)
@property
def f(self): return self.__f
@f.setter
......@@ -236,11 +253,10 @@ class Signals(object):
raise pkex.BasePyKatException("No target was specified for signal to be applied")
if name == None:
name = "sig_" +target._owner.name + "_" + target.name
name = "sig_" + target._owner().name + "_" + target.name
self.targets.append(Signals.fsig(target, name, amplitude, phase))
def getFinesseText(self):
rtn = []
......@@ -794,6 +810,30 @@ class kat(object):
if self.verbose: print ""
if self.verbose: print "Finished in " + str(datetime.datetime.now()-start)
def remove(self, obj):
if not (obj.name in self.__components or obj.name in self.__detectors or obj.name in self.__commands):
raise pkex.BasePyKatException("{0} is not currently in the simulation".format(obj.name))
if obj.removed:
raise pkex.BasePyKatException("{0} has already been removed".format(obj.name))
if isinstance(obj, Component):
del self.__components[obj.name]
self.__del_component(obj)
self.nodes.removeComponent(obj)
elif isinstance(obj, Command):
del self.__commands[obj.name]
self.__del_command(obj)
elif isinstance(obj, Detector):
del self.__detectors[obj.name]
self.__del_detector(obj)
for b in self.__blocks:
if obj in self.__blocks[b].contents:
self.__blocks[b].contents.remove(obj)
import gc
print gc.get_referrers(obj)
def add(self, obj):
try:
......@@ -1060,8 +1100,18 @@ class kat(object):
fget = lambda self: self.__get_detector(name)
setattr(self.__class__, name, property(fget))
setattr(self, '__det_' + name, det)
setattr(self, '__det_' + name, det)
def __del_detector(self, det):
if not isinstance(det, Detector):
raise exceptions.ValueError("Argument is not of type Detector")
name = det.name
delattr(self.__class__, name)
delattr(self, '__det_' + name)
def __get_detector(self, name):
return getattr(self, '__det_' + name)
......@@ -1076,6 +1126,15 @@ class kat(object):
setattr(self.__class__, name, property(fget))
setattr(self, '__com_' + name, com)
def __del_command(self, com):
if not isinstance(com, Command):
raise exceptions.ValueError("Argument is not of type Command")
name = com.__class__.__name__
delattr(self.__class__, name)
delattr(self, '__com_' + name)
def __get_command(self, name):
return getattr(self, '__com_' + name)
......@@ -1088,7 +1147,15 @@ class kat(object):
setattr(self.__class__, comp.name, property(fget))
setattr(self, '__comp_' + comp.name, comp)
def __del_component(self, comp):
if not isinstance(comp, Component):
raise exceptions.ValueError("Argument is not of type Component")
delattr(self.__class__, comp.name)
delattr(self, '__comp_' + comp.name)
def __get_component(self, name):
return getattr(self, '__comp_' + name)
......
......@@ -63,15 +63,18 @@ class NodeNetwork(object):
new_node_comps = list(node_new.components)
new_node_comps[new_node_comps.index(None)] = comp
self.__nodeComponents[node_new.id] = tuple(new_node_comps)
del new_node_comps
# remove component from old node list
old_node_comps = list(node_old.components)
old_node_comps[old_node_comps.index(comp)] = None
self.__nodeComponents[node_old.id] = tuple(old_node_comps)
del old_node_comps
comp_nodes = list(comp.nodes)
comp_nodes[comp_nodes.index(node_old)] = node_new
self.__componentNodes[comp.id] = tuple(comp_nodes)
del comp_nodes
# if old node is no longer connected to anything then delete it
if node_old.components.count(None) == 2:
......@@ -116,6 +119,23 @@ class NodeNetwork(object):
self.__nodes[node_name] = n
self.__nodeComponents[n.id] = (None, None)
return n
def removeComponent(self, comp):
C = self.__componentNodes[comp.id]
for n in C:
if comp in self.__nodeComponents[n.id]:
l = list(self.__nodeComponents[n.id])
l[l.index(comp)] = None
self.__nodeComponents[n.id] = tuple(l)
if l.count(None) == 2:
self.removeNode(n)
del l
del self.__componentCallback[comp.id]
del self.__componentNodes[comp.id]
def removeNode(self, node):
......@@ -128,13 +148,14 @@ class NodeNetwork(object):
C = self.getNodeComponents(node)
if C[0] is not None or C[1] is not None:
raise exceptions.RuntimeError("Cannot remove a node which is attached to components")
raise exceptions.RuntimeError("Cannot remove a node which is attached to components still")
if len(node.getDetectors()) > 0:
raise exceptions.RuntimeError("Cannot remove a node which is attached to detectors still")
self.__remove_node_attr(node)
del self.__nodes[node.name]
del self.__nodeComponents[node.id]
def hasNode(self, name):
return (name in self.__nodes)
......
import abc
import pykat.exceptions as pkex
import weakref
class putable(object):
"""
Objects that inherit this should be able to have something `put` to it.
......@@ -59,11 +60,11 @@ class Param(putable, putter):
def __init__(self, name, owner, value, canFsig=False, fsig_name=None, isPutable=True, isPutter=True, isTunable=True, var_name=None):
self._name = name
self._owner = owner
self._owner = weakref.ref(owner)
self._value = value
self._isPutter = isPutter
self._isTunable = isTunable
self._owner._register_param(self)
self._owner()._register_param(self)
self._canFsig = False
if canFsig:
......@@ -96,15 +97,35 @@ class Param(putable, putter):
def isTuneable(self): return self._isTunable
@property
def value(self): return self._value
def value(self):
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
else:
return self._value
@value.setter
def value(self, value):
self._value = value
def __str__(self): return str(self.value)
def __float__(self): return self.value
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
else:
self._value = value
def __str__(self):
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
else:
return str(self.value)
def __float__(self):
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
else:
return self.value
def getFinesseText(self):
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
rtn = []
if self.isPutable: rtn.extend(self._getPutFinesseText())
......@@ -112,7 +133,7 @@ class Param(putable, putter):
# if this parameter is being put somewhere then we need to
# set it as a variable
if self.isPutter and self.put_count > 0:
rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner.name, param=self.name))
rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner().name, param=self.name))
return rtn
......@@ -172,10 +193,13 @@ class AttrParam(Param):
If the value pf the parameter is not 0 the attr command will be printed.
"""
def getFinesseText(self):
if self._owner().removed:
raise pkex.BasePyKatException("{0} has been removed from the simulation".format(self._owner().name))
rtn = []
if self.value != None:
rtn.append("attr {0} {1} {2}".format(self._owner.name, self.name, self.value))
rtn.append("attr {0} {1} {2}".format(self._owner().name, self.name, self.value))
rtn.extend(super(AttrParam, self).getFinesseText())
......
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