diff --git a/examples/optivis_ex.py b/examples/optivis_ex.py new file mode 100644 index 0000000000000000000000000000000000000000..0259beb855d60b81a86335a02d13dff549d0a618 --- /dev/null +++ b/examples/optivis_ex.py @@ -0,0 +1,16 @@ +import pykat + +kat = pykat.finesse.kat() + +kat.parseCommands(""" +l l1 1 0 n0 +s s1 100 n0 n1 +m m1 1 0 0 n1 n2 +s s2 200 n2 n3 +bs bs1 1 0 45 45 n3 dump n4 dump +s s3 200 n4 n5 +m m2 1 0 0 n5 n6 +""") + +kat.optivis().show() + diff --git a/pykat/__init__.py b/pykat/__init__.py index 9b14f735d2213da106e9b1cd22c2b5be53a8cd38..44967d63970b0eac551f4968d7692b10457e3944 100644 --- a/pykat/__init__.py +++ b/pykat/__init__.py @@ -2,6 +2,14 @@ __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 diff --git a/pykat/components.py b/pykat/components.py index 7193049e4a4ec5df00b4b3f0fb7b35ceb1eca3bb..413a0123341ca964ef036a336b565617a8c5c798 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -5,6 +5,9 @@ Created on Mon Jan 28 11:10:01 2013 @author: Daniel """ from __future__ import print_function + +from pykat import USE_GUI, HAS_OPTIVIS, NoGUIException + import pykat.external.six as six if six.PY2: import exceptions @@ -15,6 +18,9 @@ from pykat.exceptions import * import abc import copy +if HAS_OPTIVIS: + import optivis.bench.components as optivis_components + from pykat.SIfloat import * from pykat.param import Param, AttrParam import weakref @@ -22,8 +28,6 @@ import pykat.exceptions as pkex next_component_id = 1 -from pykat import USE_GUI, NoGUIException - if USE_GUI: import pykat.gui.resources import pykat.gui.graphics @@ -80,6 +84,7 @@ class Component(object): def __init__(self, name=None): + self._optivis_component = None self.__name = name self._svgItem = None self._requested_node_names = [] @@ -444,6 +449,31 @@ class mirror(AbstractMirrorComponent): rtn.extend(p.getFinesseText()) return rtn + + def getOptivisComponent(self): + if self._optivis_component is None: + self._optivis_component = optivis_components.CavityMirror(name=self.name, aoi=0) + + 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: @@ -477,7 +507,38 @@ class beamSplitter(AbstractMirrorComponent): self.alpha = values[key] else: raise pkex.BasePyKatException("No attribute {0} for mirrors".format(key)) - + + def getOptivisComponent(self): + if self._optivis_component is None: + self._optivis_component = optivis_components.BeamSplitter(name=self.name, aoi=self.alpha) + + 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("bkA") + elif kat_node is self.nodes[3]: + return self._optivis_component.getInputNode("bkB") + elif mode == "output": + if kat_node is self.nodes[0]: + return self._optivis_component.getOutputNode("frA") + elif kat_node is self.nodes[1]: + return self._optivis_component.getOutputNode("frB") + 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() @@ -574,6 +635,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(): @@ -993,7 +1066,24 @@ class laser(Component): rtn.extend(p.getFinesseText()) return rtn - + + def getOptivisComponent(self): + if self._optivis_component is None: + self._optivis_component = optivis_components.Laser(name=self.name) + + 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 diff --git a/pykat/finesse.py b/pykat/finesse.py index b33974a86b1c22a9c636f7eae24f2722b77d3d24..a6d1085899c69262d00da823a6145c5c141d3f61 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -53,7 +53,7 @@ from pykat.param import Param, AttrParam import pykat.exceptions as pkex -from pykat import USE_GUI, NoGUIException +from pykat import USE_GUI, HAS_OPTIVIS, NoGUIException if USE_GUI: from pykat.gui.gui import pyKatGUI @@ -1444,6 +1444,49 @@ class kat(object): #out.append("pyterm no\n") return out + + def optivis(self): + if not HAS_OPTIVIS: + print("Optivis is not installed") + return None + + import optivis.scene as scene + import optivis.bench.links as links + import optivis.view.canvas as canvas + + scene = scene.Scene(title="Example 2", azimuth=180) + + # Run through once to add components, ignoring spaces + for c in self.getComponents(): + if isinstance(c, pykat.components.space): continue + print("Adding %s" % c.name) + optivis_op = getattr(c, "getOptivisComponent", None) + + if callable(optivis_op): + scene.addComponent(c.getOptivisComponent()) + + # Run through again to add links + for c in self.getComponents(): + if not isinstance(c, pykat.components.space): + continue + + a = c.connectingComponents() + + c1 = a[0].getOptivisComponent() + c2 = a[1].getOptivisComponent() + + no = a[0].getOptivisNode("Output", c.nodes[0]) + ni = a[1].getOptivisNode("Input", c.nodes[1]) + + if no is None or ni is None: + raise pkex.BasePyKatException("Optivis node is None") + + print("Link %s (%s) -> %s (%s)" %(a[0].name, no.name, a[1].name, ni.name)) + scene.addLink(links.Link(no, ni, c.L.value)) + + gui = canvas.Simple(scene=scene) + + return gui def openGUI(self): if not USE_GUI: @@ -1451,17 +1494,17 @@ class kat(object): else: self.app = QCoreApplication.instance() created = False - + if self.app == None: created = True self.app = QApplication([""]) - + if self.pykatgui == None: self.pykatgui = pyKatGUI(self) self.pykatgui.main() else: self.pykatgui.show() - + if created: self.app.exec_() def getComponents(self):