diff --git a/pykat/commands.py b/pykat/commands.py index 4559d315b314f6e1c87c6de82546c0372f0d4d7c..70f949cbd0cb022ef39d1a762a78d05d2b9e0bb5 100644 --- a/pykat/commands.py +++ b/pykat/commands.py @@ -34,6 +34,14 @@ class xaxis(Command): def __init__(self, kat, scale, limits, comp, param, steps): + if scale == "lin": + scale = Scale.linear + elif scale == "log": + scale = Scale.logarithmic + elif isinstance(scale, str): + # else we have a string but not a recognisable one + raise exceptions.ValueError("scale argument '{0}' is not valid, must be 'lin' or 'log'".format(scale)) + if scale != Scale.linear and scale != Scale.logarithmic: raise exceptions.ValueError("scale is not Scale.linear or Scale.logarithmic") diff --git a/pykat/components.py b/pykat/components.py index a000fed4efa6305a446704e4b149a1b05ba1a369..a9bd94f737d820d93a88bf62f7e771ceb2d1b8e1 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -144,7 +144,7 @@ class mirror(Component): def getQGraphicsItem(self): if self._svgItem == None: self._svgItem = ComponentQGraphicsItem(":/resources/mirror_flat.svg",self - ,[(-20,0,self.node1),(20,0,self.node2)]) + ,[(-4,15,self.node1),(14,15,self.node2)]) return self._svgItem @@ -215,7 +215,8 @@ class laser(Component): def getQGraphicsItem(self): if self._svgItem == None: - self._svgItem = ComponentQGraphicsItem(":/resources/laser.svg",self,[(70,0,self.node)]) + self._svgItem = ComponentQGraphicsItem(":/resources/laser.svg", + self,[(65,25,self.node)]) return self._svgItem diff --git a/pykat/finesse.py b/pykat/finesse.py index 064e11bc4e2b7e91051701290db230ad19ee6ead..3e6cddbc13ab8ba54ed5b6e84d0f693faaa650d1 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -56,14 +56,16 @@ class katRun(object): class kat(object): - def __init__(self): + def __init__(self, katexe=""): + self.scene = None # scene object for GUI self.__components = {} self.__detectors = {} self.__commands = {} self.__gui = None self.nodes = NodeNetwork(self) - + self.__katexe = katexe + # Various self.__phase = None self.__maxtem = None @@ -90,26 +92,32 @@ class kat(object): It returns a katRun object which is populated with the various data from the simulation run. """ - - # Get the environment variable for where Finesse is stored - self.__finesse_dir = os.environ.get('FINESSE_DIR') - - if self.__finesse_dir == None : - raise MissingFinesseEnvVar() - r = katRun() - r.katScript = "".join(self.generateKatScript()) + r.katScript = "".join(self.generateKatScript()) - katfile = tempfile.TemporaryFile(suffix=".kat") - katfile.writelines(r.katScript) - katfile.flush() + if len(self.__katexe) == 0: + # Get the environment variable for where Finesse is stored + self.__finesse_dir = os.environ.get('FINESSE_DIR') + + + if self.__finesse_dir == None : + raise MissingFinesseEnvVar() - kat_exec = os.path.join(self.__finesse_dir,'kat.exe') + kat_exec = os.path.join(self.__finesse_dir,'kat.exe') + + else: + kat_exec = self.__katexe + # check if kat file exists and it is executable by user if not (os.path.isfile(kat_exec) and os.access(kat_exec, os.X_OK)): raise MissingFinesse() + # create a kat file which we will write the script into + katfile = tempfile.TemporaryFile(suffix=".kat") + katfile.writelines(r.katScript) + katfile.flush() + kat_exec = "{0} {1}".format(kat_exec, katfile.name) p=subprocess.Popen(kat_exec, @@ -118,12 +126,14 @@ class kat(object): [out,err] = p.communicate() + # get the version number ix = out.find('build ') + 6 ix2 = out.find(')',ix) r.katVersion = out[ix:ix2] r.runDateTime = datetime.datetime.now() + # if something has gone wrong, print err regardless if p.returncode != 0: print err return None diff --git a/pykat/gui/graphics.py b/pykat/gui/graphics.py index 515a5efa1f289ca03f50af2cc988653bb6936ffc..fef8789df576c02f2df26c402fb54de8eb080862 100644 --- a/pykat/gui/graphics.py +++ b/pykat/gui/graphics.py @@ -32,7 +32,7 @@ class SpaceQGraphicsItem(QGraphicsLineItem): item = QGraphicsTextItem(self.__space.name, self) rect = item.boundingRect() - item.setPos(-0.5*rect.width(),-0.5*rect.height()) + item.setPos(-0.5*rect.width(),0*rect.height()) self.refresh() @@ -42,50 +42,63 @@ class SpaceQGraphicsItem(QGraphicsLineItem): if self.__n1 == None: self.__n1 = NodeQGraphicItem(nodes[0],0,0,-nsize/2,-nsize/2,nsize,nsize,self) self.__n1.setPen(QPen(Qt.black)) - - x1 = self.__n1.x - y1 = self.__n1.y conn = nodes[0].amIConnected(self.__space) if conn[0]: - self.__n1.setVisible(False) - # now check if a connected component was returned too if conn[1] != None: - # so this node should be attached to something - # in this case we get the position of their node - # and draw the the line from their - itm=conn[1].getQGraphicsItem() - x1 = itm.x() + itm.nodedx[conn[2]][0] - y1 = itm.y() + itm.nodedx[conn[2]][1] - else: - self.__n1.setBrush(QBrush(Qt.red)) + self.__n1.setVisible(False) + # now check if a connected component was returned too + if conn[1] != None: + # so this node should be attached to something + # in this case we get the position of their node + # and draw the the line from their + itm=conn[1].getQGraphicsItem() + x1 = itm.x() + itm.nodedx[conn[2]][0] + y1 = itm.y() + itm.nodedx[conn[2]][1] + else: + self.__n1.setVisible(True) + self.__n1.setBrush(QBrush(Qt.red)) + x1 = 0 + y1 = 0 if self.__n2 == None: self.__n2 = NodeQGraphicItem(nodes[1],0,0,-nsize/2,-nsize/2,nsize,nsize,self) self.__n2.setPen(QPen(Qt.black)) - - x2 = self.__n2.x - y2 = self.__n2.y - + conn = nodes[1].amIConnected(self.__space) if conn[0]: - self.__n2.setVisible(False) - # now check if a connected component was returned too if conn[1] != None: - # so this node should be attached to something - # in this case we get the position of their node - # and draw the the line from their - itm=conn[1].getQGraphicsItem() - x2 = itm.x() + itm.nodedx[conn[2]][0] - y2 = itm.y() + itm.nodedx[conn[2]][1] - else: - self.__n2.setBrush(QBrush(Qt.red)) + self.__n2.setVisible(False) + # now check if a connected component was returned too + if conn[1] != None: + # so this node should be attached to something + # in this case we get the position of their node + # and draw the the line from their + itm=conn[1].getQGraphicsItem() + x2 = itm.x() + itm.nodedx[conn[2]][0] + y2 = itm.y() + itm.nodedx[conn[2]][1] + else: + self.__n2.setVisible(True) + self.__n2.setBrush(QBrush(Qt.red)) + p = self.__n2.pos() + x2 = -p.x() + y2 = -p.y() + + p = QPointF((x1-x2)*0.5,(y1-y2)*0.5) + self.setPos(x1 - p.x(), y1 - p.y()) - self.setLine(x1,y1,x2,y2) - self.setPen(QPen(Qt.red, 3)) + # if the nodes are visible then reposition them in the + # component reference frame + if self.__n1.isVisible(): + self.__n1.setPos(QPointF(p.x(),p.y())) + if self.__n2.isVisible(): + self.__n2.setPos(QPointF(p.x()+x2-x1, p.y()+y2-y1)) + + self.setLine(p.x(), p.y(), p.x()+x2-x1, p.y()+y2-y1) + self.setPen(QPen(Qt.red, 3)) class ComponentQGraphicsItem(QGraphicsSvgItem): @@ -98,7 +111,7 @@ class ComponentQGraphicsItem(QGraphicsSvgItem): # used for refreshing the spaces between components self.setFlags(QGraphicsItem.ItemSendsGeometryChanges) self.nodedx = [] # stores the node square offsets - + item = QGraphicsTextItem(component.name,self) rect = item.boundingRect() item.setPos(-0.5*rect.width(),40-0.5*rect.height()) @@ -119,8 +132,6 @@ class ComponentQGraphicsItem(QGraphicsSvgItem): if conn[0] and isinstance(conn[1], pykat.components.space): conn[1].getQGraphicsItem().refresh() - - - + return QGraphicsSvgItem.itemChange(self, change, value) \ No newline at end of file diff --git a/pykat/gui/gui.py b/pykat/gui/gui.py index e512423f8347e130638027b753f0791a78928a68..7e64e331b435733570c21ad099fa8c399b234422 100644 --- a/pykat/gui/gui.py +++ b/pykat/gui/gui.py @@ -27,23 +27,22 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow): self.setupUi(self) self.graphicsView = pyKatGraphicsView(self.centralwidget) self.graphicsView.setObjectName("graphicsView") + self.graphicsView.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1) # create a new scene - self.__scene = QGraphicsScene() - self.graphicsView.setRenderHint(QtGui.QPainter.Antialiasing) + if kat.scene == None: + kat.scene = pyKatGraphicsScene() - brush = QBrush() - brush.setStyle(Qt.CrossPattern) - brush.setColor(QColor(230,230,230)) - self.__scene.setBackgroundBrush(brush) + self.__scene = kat.scene - self.actionExport_to_SVG.triggered.connect(lambda: self.exportToSVG()) - self.actionClose.triggered.connect(lambda: self.close) - # add scene to the graphics view self.graphicsView.setScene(self.__scene) + self.graphicsView.setRenderHint(QtGui.QPainter.Antialiasing) + self.actionExport_to_SVG.triggered.connect(lambda: self.exportToSVG()) + self.actionClose.triggered.connect(lambda: self.close) + self._kat = kat def main(self): @@ -65,7 +64,7 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow): # svg rendering. Important to make sure when rendering to # svg file that it is in a vector format. Gradients however # don't work... - #itm.setCacheMode(QGraphicsItem.NoCache) + itm.setCacheMode(QGraphicsItem.NoCache) self.__scene.addItem(itm) def exportToSVG(self): @@ -83,6 +82,33 @@ class pyKatGUI(QtGui.QMainWindow, qt_gui.Ui_MainWindow): self.statusbar.showMessage("Complete: Saved to 'output.svg'") +class pyKatGraphicsScene(QGraphicsScene): + def drawBackground(self, painter, rect): + size = 10 + painter.setPen(QPen(QColor(200,200,255,255),0.5)) + + start = round(rect.top(), size) + + if start > rect.top(): + start =- size + + y = start - size + + while y < rect.bottom(): + y += size + painter.drawLine(rect.left(),y, rect.right(), y) + + start = round(rect.left(), size) + + if start > rect.left(): + start =- size + + y = start - size + + while y < rect.right(): + y += size + painter.drawLine(y, rect.top(), y, rect.bottom()) + class pyKatGraphicsView(QGraphicsView): def __init__(self,val): QGraphicsView.__init__(self,val) @@ -130,7 +156,15 @@ class pyKatGraphicsView(QGraphicsView): self.__selected_item = item self.__prev_pt = pt - + elif isinstance(item, NodeQGraphicItem): + if item == None: + self.__selected_item = None + self.__prev_pt = None + else: + if isinstance(item.parentItem(),SpaceQGraphicsItem): + self.__selected_item = item + self.__prev_pt = pt + def mouseReleaseEvent(self, ev): self.__selected_item = None self.setCursor(QCursor(Qt.ArrowCursor)) @@ -148,6 +182,8 @@ class pyKatGraphicsView(QGraphicsView): #item.moveBy(pt.x()-pt_.x(), pt.y()-pt_.y()) # then snap to some integer value snap = 10.0 + + item.setPos(int(round(pt.x()/snap)*snap),int(round(pt.y()/snap)*snap)) self.__prev_pt = pt diff --git a/pykat/gui/resources/laser.svg b/pykat/gui/resources/laser.svg index 191bc778952e45b4d61ff127305b369b264fc27f..5d52974e9d38db02211bb8fe493630caeea93d44 100644 --- a/pykat/gui/resources/laser.svg +++ b/pykat/gui/resources/laser.svg @@ -12,12 +12,12 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="61.6875" - height="46.09375" + width="31.691147" + height="23.680061" id="svg2" version="1.1" - inkscape:version="0.48.2 r9819" - sodipodi:docname="photodiode_green.svg"> + inkscape:version="0.48.4 r9939" + sodipodi:docname="laser.svg"> <defs id="defs4"> <radialGradient @@ -175,9 +175,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.7" - inkscape:cx="251.20165" - inkscape:cy="360.64339" + inkscape:zoom="2.8" + inkscape:cx="-12.108973" + inkscape:cy="61.791231" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -206,9 +206,9 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-222.10571,-761.33936)"> + transform="translate(-237.10206,-772.54371)"> <g - transform="matrix(-1,0,0,-1,283.79321,807.43311)" + transform="matrix(-0.51373694,0,0,-0.51373694,268.79321,796.22377)" id="g5721" i:layer="yes" i:dimmedPercent="50" diff --git a/scripts/test_kat.py b/scripts/test_kat.py index 5b4cf27754233b60864f588f847eff1cfd6c4c56..4418d7165f63a1a7d32e2ddc6de11b731cf1e1b0 100644 --- a/scripts/test_kat.py +++ b/scripts/test_kat.py @@ -12,10 +12,11 @@ kat = finesse.kat() laser(kat,'l1','n1',1) space(kat,'s1','n1','n2',1) -mirror(kat,'m1','n2','n3',0.8,0.2) -space(kat,'s2','n3','n4',1) -mirror(kat,'m2','n4','n5',0.7,0.3) +mirror(kat,'m1','n2','n3',R=0.8,T=0.2) +space(kat,'s2','n3','n4',L=1) +mirror(kat,'m2','n4','n5',R=0.7,T=0.3) cavity(kat, 'cav1','m1','n3','m2','n4') +space(kat,'s3','n5','n6',L=1) photodiode(kat,'pd_cav','n4') photodiode(kat,'pd_ref','n2')