Commit dc470f85 authored by Andreas Freise's avatar Andreas Freise
Browse files

trying to fix wrong commit from some time ago, still needs fixing.

parent 864005dd
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
__version__ = "0.6.2"
# This flag is used to switch on the gui features in pkat at import time
USE_GUI = False
HAS_OPTIVIS = False
import imp
try:
imp.find_module('optivis')
HAS_OPTIVIS = True
except ImportError:
HAS_OPTIVIS = False
import pykat.exceptions as pkex
......
......@@ -9,7 +9,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from pykat import USE_GUI, NoGUIException
from pykat import USE_GUI, HAS_OPTIVIS, NoGUIException
import pykat.external.six as six
......@@ -21,15 +21,22 @@ import pykat
from pykat.node_network import *
from pykat.exceptions import *
import abc
import copy
from collections import OrderedDict
if HAS_OPTIVIS:
import optivis.bench.components as optivis_components
from optivis.view.canvas import OptivisCanvasItemDataType
from optivis.bench.labels import Label as optivis_label
from optivis.geometry import Coordinates as optivis_coord
import PyQt4
from pykat.SIfloat import *
from pykat.param import Param, AttrParam
import weakref
import pykat.exceptions as pkex
from copy import deepcopy
next_component_id = 1
from pykat import USE_GUI, NoGUIException
next_component_id = 1
if USE_GUI:
import pykat.gui.resources
......@@ -78,8 +85,16 @@ class NodeGaussSetter(object):
class Component(object):
__metaclass__ = abc.ABCMeta
def __init__(self, name):
def __new__(cls, *args, **kwargs):
# This creates an instance specific class for the component
# this enables us to add properties to instances rather than
# all classes
return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
def __init__(self, name=None):
self._optivis_component = None
self.__name = name
self._svgItem = None
self._requested_node_names = []
......@@ -88,18 +103,26 @@ class Component(object):
self._params = []
self.__removed = False
self._default_fsig_param = None
self.optivisLabelContent = None
# store a unique ID for this component
global next_component_id
self.__id = next_component_id
next_component_id += 1
# This creates an instance specific class for the component
# this enables us to add properties to instances rather than
# all classes
cls = type(self)
self.__class__ = type(cls.__name__, (cls,), {})
def __deepcopy__(self, memo):
"""
When deep copying a kat object we need to take into account
the instance specific properties.
"""
result = self.__class__.__new__(self.__class__)
result.__dict__ = copy.deepcopy(self.__dict__, memo)
result.__update_node_setters
return result
def _register_param(self, param):
self._params.append(param)
......@@ -209,20 +232,38 @@ class Component(object):
del self._params[:]
self.__removed = True
def __deepcopy__(self, memo):
cls = self.__class__
result = cls.__new__(cls)
memo[id(self)] = result
def getOptivisParameterDict(self):
if len(self._params) == 0:
return None
d = OrderedDict()
for k, v in self.__dict__.items():
setattr(result, k, deepcopy(v, memo))
for p in self._params:
d[p.name] = OptivisCanvasItemDataType.TEXTBOX
for p in result._params:
p._updateOwner(result)
return d
return result
def getOptivisTooltip(self):
tooltip = "Name: %s" % self.name
for p in self._params:
if p.value is not None:
tooltip += "\n%s = %s" %(p.name, str(p.value))
return tooltip
def setOptivisLabelContent(self):
"""
Sets default Optivis label contents
"""
if self.optivisLabelContent is None:
self.optivisLabelContent = {}
self.optivisLabelContent["Name"] = self.name
class AbstractMirrorComponent(Component):
__metaclass__ = abc.ABCMeta
......@@ -258,12 +299,12 @@ class AbstractMirrorComponent(Component):
self.__rxmech = AttrParam("rxmech", self, rxmech)
self.__rymech = AttrParam("rymech", self, rymech)
self.__z = Param("z", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="z")
self.__rx = Param("rx", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="rx")
self.__ry = Param("ry", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="ry")
self.__Fz = Param("Fz", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Fz")
self.__Frx = Param("Frx", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Frx")
self.__Fry = Param("Fry", self, 0, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Fry")
self.__z = Param("z", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="z")
self.__rx = Param("rx", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="rx")
self.__ry = Param("ry", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="ry")
self.__Fz = Param("Fz", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Fz")
self.__Frx = Param("Frx", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Frx")
self.__Fry = Param("Fry", self, None, canFsig=True, isPutable=False, isPutter=False, isTunable=False, fsig_name="Fry")
self._default_fsig_param = self.__phi
......@@ -449,6 +490,37 @@ class mirror(AbstractMirrorComponent):
rtn.extend(p.getFinesseText())
return rtn
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.CavityMirror(name=self.name, aoi=0, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
lbl = optivis_label(text="", position=optivis_coord(0, -1), item=self._optivis_component)
lbl.content["Name"] = self.name
self._optivis_component.labels.append(lbl)
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output not %s" % mode)
if mode == "input":
if kat_node is self.nodes[0]:
return self._optivis_component.getInputNode("fr")
else:
return self._optivis_component.getInputNode("bk")
elif mode == "output":
if kat_node is self.nodes[0]:
return self._optivis_component.getOutputNode("fr")
else:
return self._optivis_component.getOutputNode("bk")
def getQGraphicsItem(self):
if not USE_GUI:
......@@ -482,7 +554,40 @@ class beamSplitter(AbstractMirrorComponent):
self.alpha = values[key]
else:
raise pkex.BasePyKatException("No attribute {0} for mirrors".format(key))
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.BeamSplitter(name=self.name, aoi=-self.alpha, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output")
if mode == "input":
if kat_node is self.nodes[0]:
return self._optivis_component.getInputNode("frA")
elif kat_node is self.nodes[1]:
return self._optivis_component.getInputNode("frB")
elif kat_node is self.nodes[2]:
return self._optivis_component.getInputNode("bkB")
elif kat_node is self.nodes[3]:
return self._optivis_component.getInputNode("bkA")
elif mode == "output":
if kat_node is self.nodes[0]:
return self._optivis_component.getOutputNode("frB")
elif kat_node is self.nodes[1]:
return self._optivis_component.getOutputNode("frA")
elif kat_node is self.nodes[2]:
return self._optivis_component.getOutputNode("bkA")
elif kat_node is self.nodes[3]:
return self._optivis_component.getOutputNode("bkB")
@staticmethod
def parseFinesseText(text):
values = text.split()
......@@ -579,6 +684,18 @@ class space(Component):
@gy.setter
def gy(self,value): self.__gy.value = SIfloat(value)
def connectingComponents(self):
"""
Returns the two components that this space connects.
"""
a = list(self.nodes[0].components + self.nodes[1].components)
a = [value for value in a if value != self]
if len(a) != 2:
raise pkex.BasePyKatException("Space should only connect 2 components")
return a
def parseAttributes(self, values):
for key in values.keys():
......@@ -802,7 +919,33 @@ class isolator(Component):
rtn.extend(p.getFinesseText())
return rtn
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.FaradayIsolator(name=self.name, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output")
if mode == "input":
if kat_node is self.nodes[0]:
return self._optivis_component.getInputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getInputNode("bk")
elif mode == "output":
if kat_node is self.nodes[0]:
return self._optivis_component.getnOutputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getOutputNode("bk")
def getQGraphicsItem(self):
if not USE_GUI:
raise NoGUIException
......@@ -847,7 +990,32 @@ class lens(Component):
rtn.extend(p.getFinesseText())
return rtn
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.ConvexLens(name=self.name, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output")
if mode == "input":
if kat_node is self.nodes[0]:
return self._optivis_component.getInputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getInputNode("bk")
elif mode == "output":
if kat_node is self.nodes[0]:
return self._optivis_component.getnOutputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getOutputNode("bk")
def getQGraphicsItem(self):
if not USE_GUI:
raise NoGUIException
......@@ -929,6 +1097,31 @@ class modulator(Component):
return rtn
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.ElectroopticModulator(name=self.name, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output")
if mode == "input":
if kat_node is self.nodes[0]:
return self._optivis_component.getInputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getInputNode("bk")
elif mode == "output":
if kat_node is self.nodes[0]:
return self._optivis_component.getnOutputNode("fr")
elif kat_node is self.nodes[1]:
return self._optivis_component.getOutputNode("bk")
def getQGraphicsItem(self):
if not USE_GUI:
raise NoGUIException
......@@ -998,7 +1191,29 @@ class laser(Component):
rtn.extend(p.getFinesseText())
return rtn
def getOptivisComponent(self):
self.setOptivisLabelContent()
if self._optivis_component is None:
self._optivis_component = optivis_components.Laser(name=self.name, tooltip=self.getOptivisTooltip, paramList=self.getOptivisParameterDict(), pykatObject=weakref.ref(self))
lbl = optivis_label(text="", position=optivis_coord(0, -1), item=self._optivis_component)
lbl.content["Name"] = self.name
self._optivis_component.labels.append(lbl)
return self._optivis_component
def getOptivisNode(self, mode, kat_node):
mode = mode.lower()
if mode != "input" and mode.lower() != "output":
raise pkex.BasePyKatException("Mode must be either input or output")
if mode == "input":
return None
elif mode == "output":
return self._optivis_component.getOutputNode("out")
def getQGraphicsItem(self):
if not USE_GUI:
raise NoGUIException
......
......@@ -11,11 +11,11 @@ from __future__ import unicode_literals
import pykat.external.six as six
if six.PY2:
import exceptions
import exceptions
import abc
from pykat.node_network import *
from pykat.param import Param
from pykat.param import Param, AttrParam
from pykat.SIfloat import SIfloat
import pykat.external.six as six
......@@ -356,7 +356,13 @@ class bp(Detector1):
class pd(Detector1):
def __init__(self, name, num_demods, node_name, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
def __new__(cls, *args, **kwargs):
# This creates an instance specific class for the component
# this enables us to add properties to instances rather than
# all classes
return object.__new__(type(cls.__name__, (cls,), {}), *args, **kwargs)
def __init__(self, name=None, num_demods=1, node_name=None, senstype=None, alternate_beam=False, pdtype=None, **kwargs):
BaseDetector.__init__(self, name, node_name)
self.__num_demods = num_demods
......@@ -402,12 +408,25 @@ class pd(Detector1):
elif i<num_demods-1:
raise pkex.BasePyKatException("Missing demodulation phase {0} (phi{0})".format(i+1))
# define new class for assigning new attributes
cls = type(self)
self.__class__ = type(cls.__name__, (cls,), {})
self.__set_demod_attrs()
def __deepcopy__(self, memo):
"""
When deep copying a kat object we need to take into account
the instance specific properties.
"""
result = pd(self.name, self.num_demods, self.node.name)
memo[id(self)] = result
result.__dict__ = copy.deepcopy(self.__dict__, memo)
# Find all properties in class we are copying
# and deep copy these to the new class instance
for x in self.__class__.__dict__.items():
if isinstance(x[1], property):
setattr(result.__class__, x[0], x[1])
return result
@property
def senstype(self): return self.__senstype
@senstype.setter
......@@ -666,8 +685,8 @@ class qnoised(pd):
class qshot(pd):
def __init__(self, name, num_demods, node_name, alternate_beam=False, **kwargs):
super(qnoised, self).__init__(name, num_demods, node_name, alternate_beam=alternate_beam, pdtype=None, senstype=None, **kwargs)
super(qshot, self).__init__(name, num_demods, node_name, alternate_beam=alternate_beam, pdtype=None, senstype=None, **kwargs)
@pd.pdtype.setter
def pdtype(self, value):
raise pkex.BasePyKatException("Setting pdtype is not possible with qshot detectors")
......
......@@ -34,6 +34,7 @@ import subprocess
import tempfile
import numpy as np
import datetime
import time
import pickle
import pykat
import warnings
......@@ -63,6 +64,8 @@ except ImportError: # not 2.6+ or is 3.x
print("boom")
pass
"""
from math import erfc, pi
from collections import namedtuple, OrderedDict
from pykat.node_network import NodeNetwork
......@@ -76,7 +79,13 @@ import pykat.external.six as six
import pykat.exceptions as pkex
from pykat import USE_GUI, NoGUIException
from pykat import USE_GUI, HAS_OPTIVIS, NoGUIException
if HAS_OPTIVIS:
from optivis.bench.labels import Label as optivis_label
from optivis.geometry import Coordinates as optivis_coord
import PyQt4
if USE_GUI:
from pykat.gui.gui import pyKatGUI
......@@ -174,9 +183,16 @@ def f__lkat_trace_callback(lkat, trace_info, getCavities, getNodes, getSpaces):
gouyy = space.gouy_y)
def GUILength(L):
"""
Should scale the lengths in some way to handle km and mm for time being
"""
return L # * ( 40 * erfc(L/400.0) + 0.01)
class katRun(object):
def __init__(self):
self.runDateTime = datetime.datetime.now()
self.runtime = None
self.StartDateTime = datetime.datetime.now()
self.x = None
self.y = None
self.xlabel = None
......@@ -185,7 +201,7 @@ class katRun(object):
self.katVersion = None
self.yaxis = None
def plot(self):
def plot(self, logy=False):
import pylab
pylab.plot(self.x, self.y)
......@@ -206,9 +222,10 @@ class katRun(object):
def __getitem__(self, value):
idx = [i for i in range(len(self.ylabels)) if self.ylabels[i].split()[0] == str(value)]
out = None
if len(idx) > 0:
out = self.y[:, idx]
#out = self.y[:, idx]
if len(idx) == 1:
if self.yaxis == "abs:deg":
......@@ -220,7 +237,10 @@ class katRun(object):
out = self.y[:, idx[0]] * np.exp(1j*math.pi*self.y[:, idx[1]]/180.0)
elif self.yaxis == "re:im":
out = self.y[:, idx[0]] + 1j*self.y[:, idx[1]]
if out == None:
out = self.y[:, idx]
if out.size == 1:
return out[0].squeeze()
else:
......@@ -230,7 +250,8 @@ class katRun(object):
class katRun2D(object):
def __init__(self):
self.runDateTime = datetime.datetime.now()
self.runtime
self.startDateTime = datetime.datetime.now()
self.x = None
self.y = None
self.z = None
......@@ -270,7 +291,7 @@ class Signals(object):
self.__phase = Param("phase", self, SIfloat(phase))
self.__removed = False
self.__signal = signal
# 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
......@@ -397,11 +418,19 @@ class Block:
Constant = namedtuple('Constant', 'name, value, usedBy')
class kat(object):
def __init__(self, kat_file=None, kat_code=None, katdir="", katname="", tempdir=None, tempname=None):
cls = type(self)
self.__class__ = type(cls.__name__, (cls,), {})
def __new__(cls, *args, **kwargs):
# This may seem like an arbitrary step but here we are creating a
# new class that is a base class of itself. This is because when
# the kat object adds new components it also adds properties for
# each of these. There properties are unique to each kat object,
# but properties are part of the class definition. Thus if two
# kat objects share the same class definition they also have the
# same properties regardless of whether they have the actual
# object added to it. So we create an instance specific class.
return object.__new__(type(pykat.finesse.kat.__name__, (pykat.finesse.
kat,), {}), *args, **kwargs)
def __init__(self, kat_file=None, kat_code=None, katdir="", katname="", tempdir=None, tempname=None):
self.scene = None # scene object for GUI
self.verbose = True
......@@ -512,9 +541,9 @@ class kat(object):
def phase(self,value): self.__phase = int(value)
@property
def getPerformanceData(self): return self.__time_code
@getPerformanceData.setter
def getPerformanceData(self,value): self.__time_code = bool(value)
def timeCode(self): return self.__time_code
@timeCode.setter
def timeCode(self,value): self.__time_code = bool(value)
@property
def components(self):
......@@ -730,9 +759,9 @@ class kat(object):
raise pkex.BasePyKatException("maxtem command `{0}` is incorrect.".format(line))
else:
if v[1] == "off":
self.maxtem = -1
self.maxtem = -1
else:
self.maxtem = int(v[1])