diff --git a/bin/test_dump.py b/bin/test_dump.py new file mode 100644 index 0000000000000000000000000000000000000000..8fdb9ed16e5d11890124ba4a79bf94cf52707e31 --- /dev/null +++ b/bin/test_dump.py @@ -0,0 +1,16 @@ +import pykat + +kat = pykat.finesse.kat() + +kat.parseCommands(""" +bs bs1 0.5 0.5 0 0 n1 dump n3 dump +""") + +print "BEFORE" +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")) + +print "AFTER" +print "".join(kat.generateKatScript()) diff --git a/bin/test_hom.py b/bin/test_hom.py new file mode 100644 index 0000000000000000000000000000000000000000..49e51c02f97e220522f5095473160fd19033a557 --- /dev/null +++ b/bin/test_hom.py @@ -0,0 +1,16 @@ +import pykat + +kat = pykat.finesse.kat() + +kat.parseCommands(""" +l l1 1 0 80 n1 +l l2 1 0 90 n4 + +bs bs1 0.5 0.5 0 0 n1 n2 n3 n4 + +fsig noise l1 amp 1 0 1 + +hd hd1 0 n2 n3 + +xaxis hd1 phase lin 0 360 1000 +""") \ No newline at end of file diff --git a/pykat/detectors.py b/pykat/detectors.py index 8e7ec5add156757190ccff9ae51c2e8fd41cc491..3cb0d8fbe0127ba2a7bf482e512860d8884d2a3f 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -11,32 +11,52 @@ from pykat.utils import * from pykat.gui.graphics import * from pykat.node_network import * from pykat.param import Param - +import collections import pykat.exceptions as pkex import warnings import copy -class Detector(object) : - def __init__(self, name, node=None): +class BaseDetector(object) : + + def __init__(self, name, nodes=None, max_nodes=1): + self.__name = name self._svgItem = None self._kat = None self.noplot = False self.enabled = True self.tag = None - self.__node = None self._params = [] self._mask = {} self.__scale = None self.__removed = False - self.__requested_node = None - if node != None: - if node[-1]=='*': - self._alternate_beam = True - node=node[:-1] - - self.__requested_node = node + self._alternate_beam = [] + self._nodes = [] + self._requested_nodes = [] + + if nodes != None: + if isinstance(nodes, collections.Iterable): + if len(nodes) > max_nodes: + raise pkex.BasePyKatException("Tried to set too many nodes, %s, maximum number is %i." %(str(nodes),max_nodes)) + + for n in nodes: + if n[-1]=='*': + self._alternate_beam.append(True) + n = n[:-1] + else: + self._alternate_beam.append(False) + + self._requested_nodes.append(n) + else: + # if we don't have a collection + if nodes[-1]=='*': + self._alternate_beam.append(True) + nodes = nodes[:-1] + else: + self._alternate_beam.append(False) + + self._requested_nodes.append(nodes) def _register_param(self, param): self._params.append(param) @@ -44,8 +64,9 @@ class Detector(object) : def _on_kat_add(self, kat): self._kat = kat - if self.__requested_node != None: - self.__node = kat.nodes.createNode(self.__requested_node) + for rn in self._requested_nodes: + if rn != None: + self._nodes.append(kat.nodes.createNode(rn)) def remove(self): if self.__removed: @@ -66,7 +87,6 @@ class Detector(object) : def getQGraphicsItem(self): return None - @property def removed(self): return self.__removed @@ -75,15 +95,6 @@ class Detector(object) : @scale.setter def scale(self, value): self.__scale = value - - @property - def node(self): return self.__node - @node.setter - def node(self, value): - if value in self._kat.nodes: - self.__node = self._kat.nodes[value] - else: - raise pkex.BasePyKatException("There is no node called " + value) @property def name(self): return self.__name @@ -91,19 +102,61 @@ class Detector(object) : def __str__(self): return self.name def mask(self, n, m, factor): - id = str(n)+"_"+str(m) + _id = str(n)+"_"+str(m) # if the mask is 1 then remove this so it doesn't get # printed as by default the value is 1.0 - if id in self._mask and factor == 1.0: - del self._mask[id] + if _id in self._mask and factor == 1.0: + del self._mask[_id] + + self._mask[_id] = factor + + def _set_node(value, index): + if self._kat == None: + raise pkex.BasePyKatException("This detector has not been added to a kat object yet") + else: + if value[-1] == '*': + self._alternate_beam[index] = True + value = value[:-1] + else: + self._alternate_beam[index] = False + + if value in self._kat.nodes: + self._nodes[index] = self._kat.nodes[value] + else: + raise pkex.BasePyKatException("There is no node called " + value + " in the kat object this detector is attached to.") + +class Detector1(BaseDetector): + + @property + def node(self): return self.__nodes[0] + @node.setter + def node(self, value): + self._set_node(value, 0) + + +class Detector2(BaseDetector): + + @property + def node1(self): return self.__nodes[0] + @node1.setter + def node(self, value): + self._set_node(value, 0) + + @property + def node2(self): return self.__nodes[1] + @node2.setter + def node(self, value): + self._set_node(value, 1) + + + - self._mask[id] = factor -class ad(Detector): +class ad(Detector1): def __init__(self, name, frequency, node_name, mode=None, alternate_beam=False): - Detector.__init__(self, name, node_name) + BaseDetector.__init__(self, name, node_name) self.mode = mode self.alternate_beam = alternate_beam self.__f = Param("f", self, frequency) @@ -154,10 +207,10 @@ class ad(Detector): return rtn -class gouy(Detector): +class gouy(Detector1): def __init__(self, name, direction, spaces): - Detector.__init__(self, name) + BaseDetector.__init__(self, name) self.spaces = copy.copy(spaces) self.direction = direction self.alternate_beam = False @@ -202,11 +255,11 @@ class gouy(Detector): -class bp(Detector): +class bp(Detector1): acceptedParameters = ['w', 'w0', 'z', 'zr', 'g', 'r', 'q'] def __init__(self, name, direction, parameter, node, alternate_beam=False): - Detector.__init__(self, name, node) + BaseDetector.__init__(self, name, node) self.parameter = parameter self.direction = direction self.alternate_beam = alternate_beam @@ -258,10 +311,10 @@ class bp(Detector): return rtn -class pd(Detector): +class pd(Detector1): def __init__(self, name, num_demods, node_name, senstype=None, alternate_beam=False, pdtype=None, **kwargs): - Detector.__init__(self, name, node_name) + BaseDetector.__init__(self, name, node_name) self.__num_demods = num_demods self.__senstype = senstype @@ -451,7 +504,7 @@ class pd(Detector): rtn.append("pd{0}{1} {2}{3} {4}{5}".format(senstype, self.num_demods, self.name, fphi_str, self.node.name, alt_str)) if self.scale != None: - rtn.append("scale {1} {0:.16g}".format(self.name, self.scale)) + rtn.append("scale {1} {0}".format(self.name, self.scale)) if self.pdtype != None: rtn.append("pdtype {0} {1}".format(self.name, self.pdtype)) @@ -558,7 +611,7 @@ class qnoised(pd): rtn.append("qnoised{5} {0} {1} {2} {3}{4}".format(self.name, self.num_demods, fphi_str, self.node.name, alt_str, senstype)) if self.scale != None: - rtn.append("scale {1} {0:.16g}".format(self.name, self.scale)) + rtn.append("scale {1} {0}".format(self.name, self.scale)) for p in self._params: rtn.extend(p.getFinesseText()) @@ -651,17 +704,17 @@ class qshot(pd): rtn.append("qshot{5} {0} {1} {2} {3}{4}".format(self.name, self.num_demods, fphi_str, self.node.name, alt_str,senstype)) if self.scale != None: - rtn.append("scale {1} {0:.16g}".format(self.name, self.scale)) + rtn.append("scale {1} {0}".format(self.name, self.scale)) for p in self._params: rtn.extend(p.getFinesseText()) return rtn -def xd(Detector): +def xd(Detector1): def __init__(self, name, node_name, component, motion): - Detector.__init__(name, None) + BaseDetector.__init__(name, None) self.__motion = motion self.__component = component @@ -688,11 +741,51 @@ def xd(Detector): rtn.append("xd {0} {1} {2}".format(self.name, self.component, self.motion)) if self.scale != None: - rtn.append("scale {1} {0:.16g}".format(self.name, self.scale)) + rtn.append("scale {1} {0}".format(self.name, self.scale)) for p in self._params: rtn.extend(p.getFinesseText()) return rtn - \ No newline at end of file + +class hd(Detector2): + + def __init__(self, name, phase, node1_name, node2_name): + BaseDetector.__init__(self, name, (node1_name, node2_name), max_nodes=2) + + self.__homangle = Param("phase", self, None) + + @property + def phase(self): return self.__phase + @phase.setter + def phase(self, value): self.__phase.value = value + + def parseAttributes(self, values): + raise pkex.BasePyKatException("hd detector %s has no attributes to set" % self.name) + + @staticmethod + def parseFinesseText(text): + values = text.split() + + return hd(values[1], float(values[2]), str(values[3]), str(values[4])) + + def getFinesseText(self): + rtn = [] + + if self.enabled: + n1 = self.nodes[0].name + n2 = self.nodes[1].name + + if self.__alternate_beam1[0]: n1 += "*" + if self.__alternate_beam2[1]: n2 += "*" + + rtn.append("hd {0} {1} {2} {3}".format(self.name, self.phase, n1, n2)) + + if self.scale != None: + rtn.append("scale {1} {0}".format(self.name, self.scale)) + + for p in self._params: + rtn.extend(p.getFinesseText()) + + return rtn \ No newline at end of file diff --git a/pykat/finesse.py b/pykat/finesse.py index 82db500ce7f4d94a997a2d202576a743400d097e..dbaabb5cbfdbf93b7b987f2ea4d0a0d2c0fe15dd 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -43,7 +43,7 @@ import re from collections import namedtuple, OrderedDict from pykat.node_network import NodeNetwork -from pykat.detectors import Detector +from pykat.detectors import BaseDetector as Detector from pykat.components import Component from pykat.commands import Command, xaxis from pykat.gui.gui import pyKatGUI @@ -634,6 +634,8 @@ class kat(object): obj = pykat.detectors.qnoised.parseFinesseText(line) elif(first == "xaxis" or first == "xaxis*"): obj = pykat.commands.xaxis.parseFinesseText(line) + elif(first[0:2] == "hd"): + obj = pykat.detectors.hd.parseFinesseText(line) elif(first == "x2axis" or first == "x2axis*"): obj = pykat.commands.x2axis.parseFinesseText(line) elif(first == "gauss" or first == "gauss*" or first == "gauss**"): @@ -1415,7 +1417,7 @@ class kat(object): def __del_detector(self, det): if not isinstance(det, Detector): - raise exceptions.ValueError("Argument is not of type Detector") + raise pkex.BasePyKatException("Argument is not of type Detector") name = det.name @@ -1428,7 +1430,7 @@ class kat(object): def __add_command(self, com): if not isinstance(com, Command): - raise exceptions.ValueError("Argument is not of type Command") + raise pkex.BasePyKatException("Argument is not of type Command") name = com.__class__.__name__ fget = lambda self: self.__get_command(name) @@ -1454,7 +1456,7 @@ class kat(object): def __add_component(self, comp): if not isinstance(comp, Component): - raise exceptions.ValueError("Argument is not of type Component") + raise pkex.BasePyKatException("Argument is not of type Component") fget = lambda self: self.__get_component(comp.name) @@ -1464,7 +1466,7 @@ class kat(object): def __del_component(self, comp): if not isinstance(comp, Component): - raise exceptions.ValueError("Argument is not of type Component") + raise pkex.BasePyKatException("Argument is not of type Component") delattr(self.__class__, comp.name) delattr(self, '__comp_' + comp.name) diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py index fe11ba34b9c44bfc0c1eb0f213ca8bc31438a844..bef360d9953a22f6ecd454f56771ef1c70805f46 100644 --- a/pykat/gui/gui.py +++ b/pykat/gui/gui.py @@ -6,7 +6,7 @@ Created on Tue Jan 29 11:35:48 2013 """ from pykat.components import Component, space -from pykat.detectors import Detector +from pykat.detectors import BaseDetector as Detector from PyQt4 import QtGui, QtCore from PyQt4.Qt import * diff --git a/pykat/node_network.py b/pykat/node_network.py index fa9f282c0f99f0cf4b641aeaa8f6260084fb5663..81f7189b0d3a4c866e7563db98f126f16f2b7762 100644 --- a/pykat/node_network.py +++ b/pykat/node_network.py @@ -8,7 +8,7 @@ import exceptions import pykat.gui.graphics import pykat.exceptions as pkex from pykat.components import Component -from pykat.detectors import Detector +from pykat.detectors import BaseDetector as Detector from pykat.utilities.optics.gaussian_beams import beam_param class NodeNetwork(object): @@ -34,7 +34,7 @@ class NodeNetwork(object): , e.g. connected, disconnected, name change, etc. """ if not isinstance(comp, Component): - raise exceptions.ValueError("comp argument is not of type Component") + raise pkex.BasePyKatException("comp argument is not of type Component") if comp.id in self.__componentNodes: raise pkex.BasePyKatException("Component has already been registered") @@ -86,6 +86,7 @@ class NodeNetwork(object): self.__componentCallback[comp.id]() def connectNodeToComp(self, node, comp, do_callback=True): + if node.id in self.__nodeComponents: comps = self.__nodeComponents[node.id] else: @@ -109,7 +110,7 @@ class NodeNetwork(object): def createNode(self, node_name): if node_name == 'dump': - return DumpNode() + return DumpNode(self) if node_name in self.__nodes: # then this node already exists @@ -142,23 +143,24 @@ class NodeNetwork(object): def removeNode(self, node): - if not isinstance(node,Node): - raise exceptions.ValueError("node argument is not of type Node") + if not isinstance(node, Node): + raise pkex.BasePyKatException("node argument is not of type Node") - if node.name not in self.__nodes: - raise exceptions.RuntimeError("Trying to remove node {0} when it has not been added".format(node.name)) + if not isinstance(node, DumpNode) and node.name not in self.__nodes: + raise pkex.BasePyKatException("Trying to remove node {0} when it has not been added".format(node.name)) 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 still") + raise pkex.BasePyKatException("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") + raise pkex.BasePyKatException("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] + if not isinstance(node, DumpNode): + self.__remove_node_attr(node) + del self.__nodes[node.name] + del self.__nodeComponents[node.id] def hasNode(self, name): return (name in self.__nodes) @@ -206,7 +208,7 @@ class NodeNetwork(object): def __add_node_attr(self, node): if not isinstance(node, Node): - raise exceptions.ValueError("Argument is not of type Node") + raise pkex.BasePyKatException("Argument is not of type Node") name = node.name fget = lambda self: self.__get_node_attr(name) @@ -216,7 +218,7 @@ class NodeNetwork(object): def __remove_node_attr(self, node): if not isinstance(node, Node): - raise exceptions.ValueError("Argument is not of type Node") + raise pkex.BasePyKatException("Argument is not of type Node") name = node.name delattr(self, '__node_' + name) @@ -265,7 +267,7 @@ class NodeNetwork(object): rn = currcomp.nodes[2] tn = currcomp.nodes[1] else: - raise exceptions.ValueError("Node not attached in path find to BS") + raise pkex.BasePyKatException("Node not attached in path find to BS") nextcomp = None @@ -513,9 +515,9 @@ class Node(object): class DumpNode(Node): __total_dump_node_id = 0 - def __init__(self): + def __init__(self, network): DumpNode.__total_dump_node_id -= 1 - Node.__init__(self, 'dump', None, DumpNode.__total_dump_node_id) + Node.__init__(self, 'dump', network, DumpNode.__total_dump_node_id) self._isDump = True