diff --git a/pykat/components.py b/pykat/components.py index 52f32aa05d0a49d6d32921b1cfa1b4174b533bc9..613bb171d2a339d2413fe0b9d9b582920154311c 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -901,13 +901,14 @@ class grating(Component): return self._svgItem class isolator(Component): - def __init__(self, name, node1, node2, S = 0, node3="dump"): + def __init__(self, name, node1, node2, S = 0, node3="dump", option=0): Component.__init__(self, name) self._requested_node_names.append(node1) self._requested_node_names.append(node2) self._requested_node_names.append(node3) self._svgItem = None + self._option = option self.__S = Param("S",self,SIfloat(S)) @@ -920,20 +921,30 @@ class isolator(Component): def parseFinesseText(text): values = text.split() - if values[0] != "isol": + if values[0] != "isol" and values[0] != "isol*": raise pkex.BasePyKatException("'{0}' not a valid Finesse isolator command".format(text)) + if values[0].endswith('*'): + option = 1 + else: + option = 0 + values.pop(0) # remove initial value if len(values) == 4: - return isolator(values[0], values[2], values[3], values[1]) + return isolator(values[0], values[2], values[3], values[1], option=option) elif len(values) == 5: - return isolator(values[0], values[2], values[3], node3=values[4], S=values[1]) + return isolator(values[0], values[2], values[3], node3=values[4], S=values[1], option=option) else: raise pkex.BasePyKatException("Isolator Finesse code format incorrect '{0}'".format(text)) def getFinesseText(self): - rtn = ['isol {0} {1} {2} {3} {4}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name)] + if self._option == 0: + cmd = "isol" + elif self._option == 1: + cmd = "isol*" + + rtn = ['{cmd} {0} {1} {2} {3} {4}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name, self.nodes[2].name, cmd=cmd)] for p in self._params: rtn.extend(p.getFinesseText()) diff --git a/pykat/finesse.py b/pykat/finesse.py index 109fd27bcdf81f28174824494140b93595ab575d..760c0723d1c3994bccc61ce8e5c97ebee5fe2617 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -1107,7 +1107,7 @@ class kat(object): except pkex.BasePyKatException as ex: print (ex) - def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False): + def run(self, printout=0, printerr=0, plot=None, save_output=False, save_kat=False, kat_name=None, cmd_args=None, getTraceData=False, rethrowExceptions=False): """ Runs the current simulation setup that has been built thus far. It returns a katRun or katRun2D object which is populated with the various @@ -1124,6 +1124,8 @@ class kat(object): that Finesse performs, the keys are the node names and the values are the x and y beam parameters. If no tracing is done a None is returned. + + rethrowExceptions - if true exceptions will be thrown again rather than being excepted and calling sys.exit() """ start = datetime.datetime.now() @@ -1423,9 +1425,16 @@ class kat(object): except KeyboardInterrupt as ex: print("Keyboard interrupt caught, stopped simulation.") except pkex.FinesseRunError as ex: - pkex.PrintError("Error from Finesse:", ex) + if rethrowExceptions: + raise ex + else: + pkex.PrintError("Error from Finesse:", ex) + except pkex.BasePyKatException as ex: - pkex.PrintError("Error from pykat:", ex) + if rethrowExceptions: + raise ex + else: + pkex.PrintError("Error from pykat:", ex) finally: if self.verbose: print ("") if self.verbose: print ("Finished in " + str(datetime.datetime.now()-start)) @@ -1500,11 +1509,11 @@ class kat(object): for c in self.components.values(): for n in c.nodes: if n.isDump: - while hasattr(kat.nodes, node_name): + while hasattr(self.nodes, node_name): node_name = "%s_%i" % (str(undumped_name_prefix), i) i += 1 - self.nodes.replaceNode(c, n, self.nodes.createNode(node_name % i)) + self.nodes.replaceNode(c, n, self.nodes.createNode(node_name)) def getMatrices(self): diff --git a/pykat/optics/maps.py b/pykat/optics/maps.py index 8dd6ee902107c51dffe448150d16e3180203497e..1f170879f7a91666bf4e1eea3ba9bd48c9717909 100644 --- a/pykat/optics/maps.py +++ b/pykat/optics/maps.py @@ -1076,6 +1076,8 @@ def read_map(filename, mapFormat='finesse', scaling=1.0e-9): data = np.loadtxt(filename, dtype=np.float64,ndmin=2,comments='%') + return surfacemap(name, maptype, size, center, step, scaling, data) + # Converts raw zygo and ligo mirror maps to the finesse # format. Based on the matlab scripts 'FT_read_zygo_map.m' and # 'FT_read_ligo_map.m'. @@ -1288,15 +1290,15 @@ def read_map(filename, mapFormat='finesse', scaling=1.0e-9): # Changing NaN to zeros. Just to be able to plot the # map with surfacemap.plot(). data[isNan] = 0 - + + return surfacemap(name, maptype, size, center, step, scaling, data, notNan) # TODO: Add options for reading virgo maps, and .xyz zygo # maps (need .xys file for this). Binary ligo-maps? # The intensity data is not used to anything here. Remove # or add to pykat? - return surfacemap(name, maptype, size, center, step, - scaling, data, notNan) + def rnm(n,m,rho): diff --git a/pykat/parallel.py b/pykat/parallel.py new file mode 100644 index 0000000000000000000000000000000000000000..5f790e3aaec12940f344e6bbcf1db4ead55eb83f --- /dev/null +++ b/pykat/parallel.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Jan 27 09:56:53 2013 + +PyKat - Python interface and wrapper for FINESSE +Copyright (C) 2013 Daniel David Brown + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Contact at ddb@star.sr.bham.ac.uk + +@author: Daniel Brown +""" + +from IPython.parallel import Client +import sys +import os + +def _run(commands, pwd): + import os + os.chdir(pwd) + + import pykat + + kat = pykat.finesse.kat() + kat.parseCommands(commands) + out = kat.run(rethrowExceptions=True) + + return out + +class parakat(object): + """ + Uses the ipython clustering for running kat objects in parallel. + + To use this you must have started an ipython cluster on your computer. + From a new terminal use the command: + + ipcluster start -n 4 + + This will start a cluster with 4 workers. + + To run a kat object use: + + pk = parakat() + pk.run(kat1) + pk.run(kat2) + pk.run(kat3) + + outs = pk.getResults() + + The list 'outs' will contain the katRun object you'd normal get if you + had just called, kat1.run(), etc. The results list is matched to order + in which you run the kats. + + If you need to stop long running kat processes the chances are you will + also need to kill the ipython cluster process, as sometimes they carry + on running. + """ + + def __init__(self): + self._rc = Client() + self._lview = self._rc.load_balanced_view() + self._lview.block = False + self._results = [] + + def run(self, kat): + self._results.append(self._lview.apply_async(_run, "".join(kat.generateKatScript()), os.getcwd())) + + def getResults(self): + out = [] + + self._lview.wait(self._results) + + for done in self._results: + out.append(done.get()) + + return out