diff --git a/pykat/__init__.py b/pykat/__init__.py index 1474e2085f64e36af0c16e10995e65b851a2fd58..c9e969613df36ace84e1595297f4c1b5117d0241 100644 --- a/pykat/__init__.py +++ b/pykat/__init__.py @@ -3,7 +3,7 @@ from __future__ import division from __future__ import print_function from __future__ import unicode_literals -__version__ = "1.0.8" +__version__ = "1.0.11" # This flag is used to switch on the gui features in pkat at import time USE_GUI = False diff --git a/pykat/commands.py b/pykat/commands.py index 241f7b7d971efec41b6e3f0d382845bb70c8613a..f146667019f1d6142fa7cf597341c5708c0d61ca 100644 --- a/pykat/commands.py +++ b/pykat/commands.py @@ -34,7 +34,23 @@ class Command(object): self.tag = None self.__removed = False self.__name = name.strip("*") + self._putters = [] + + def __deepcopy__(self, memo): + """ + When deep copying a kat object we need to take into account + the instance specific properties. + """ + + cls = self.__class__ + result = cls.__new__(cls) + result.__dict__ = copy.deepcopy(self.__dict__, memo) + for _ in result._putters: + _._updateOwner(result) + + return result + def getFinesseText(self): """ Base class for individual finesse optical components """ raise NotImplementedError("This function is not implemented") @@ -48,10 +64,30 @@ class Command(object): Called when this component has been added to a kat object """ self._kat = kat + + for _ in self._putters: + kat.registerVariable(_.name, _) - def remove(self): - self._kat.remove(self) + def _on_kat_remove(self): self.__removed = True + + for i in range(len(self._putters)): + _ = self._putters[i] + + self._kat.unregisterVariable(_.name) + _.clearPuts() + + for i in range(len(self._putters)): + del self._putters[0] + + del self._putters[:] + + + def remove(self): + if self.__removed: + raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) + else: + self._kat.remove(self) @property def name(self): return self.__name @@ -95,14 +131,19 @@ class func(Command): self.value = value self.noplot = False + self.enabled = True + + self.output = putter(name, self) + self._putters.append(self.output) def getFinesseText(self): rtn = [] - if self.noplot: - rtn.append("noplot " + self.name) + if self.enabled: + if self.noplot: + rtn.append("noplot " + self.name) - rtn.append("func {name} = {value}".format(name=self.name, value=str(self.value))) + rtn.append("func {name} = {value}".format(name=self.name, value=str(self.value))) return rtn @@ -118,10 +159,7 @@ class func(Command): return func(v2[0].split()[1], v2[1]) else: raise pkex.BasePyKatException("'{0}' not a valid Finesse func command".format(line)) - - - - + class lock(Command): def __init__(self, name, variable, gain, accuracy, singleLock=False): @@ -132,6 +170,10 @@ class lock(Command): self.__accuracy = accuracy self.singleLock = singleLock self.enabled = True + + + self.output = putter(name, self) + self._putters.append(self.output) @staticmethod @@ -278,7 +320,78 @@ class gauss(object): kat.nodes[node].setGauss(kat.components[component], gp) else: kat.nodes[node].setGauss(kat.components[component], gpx, gpy) - + +# class tf(Command): +# +# class fQ(object): +# def __init__(self, f, Q, tf): +# assert(tf is not None) +# self._tf = tf +# self.__f = Param("f", self, None, canFsig=False, isPutable=True, isPutter=False, isTunable=True) +# self.__Q = Param("Q", self, None, canFsig=False, isPutable=True, isPutter=False, isTunable=True) +# +# def _register_param(self, param): +# self._tf._params.append(param) +# +# @property +# def f(self): return self.__f +# @f.setter +# def f(self,value): self.__f.value = SIfloat(value) +# +# @property +# def Q(self): return self.__Q +# @Q.setter +# def Q(self,value): self.__Q.value = SIfloat(value) +# +# def __init__(self, name): +# Command.__init__(self, name, False) +# self.zeros = [] +# self.poles = [] +# self.gain = 1 +# self.phase = 0 +# self._params = [] +# +# def addPole(self,f, Q): +# self.poles.append(tf.fQ(SIfloat(f), SIfloat(Q), self)) +# +# def addZero(self,f, Q): +# self.zeros.append(tf.fQ(SIfloat(f), SIfloat(Q), self)) +# +# @staticmethod +# def parseFinesseText(text): +# values = text.split() +# +# if ((len(values)-4) % 3) != 0: +# raise pkex.BasePyKatException("Transfer function Finesse code format incorrect '{0}'".format(text)) +# +# _tf = tf(values[1]) +# +# _tf.gain = SIfloat(values[2]) +# _tf.phase = SIfloat(values[3]) +# +# N = int((len(values)-4) / 3) +# +# for i in range(1,N+1): +# if values[i*3+1] == 'p': +# _tf.addPole(SIfloat(values[i*3+2]), SIfloat(values[i*3+3])) +# elif values[i*3+1] == 'z': +# _tf.addZero(SIfloat(values[i*3+2]), SIfloat(values[i*3+3])) +# else: +# raise pkex.BasePyKatException("Transfer function pole/zero Finesse code format incorrect '{0}'".format(text)) +# +# return _tf +# +# def getFinesseText(self): +# rtn = "tf {name} {gain} {phase} ".format(name=self.name,gain=self.gain,phase=self.phase) +# +# for p in self.poles: +# rtn += "p {f} {Q} ".format(f=p.f, Q=p.Q) +# +# for z in self.zeros: +# rtn += "p {f} {Q} ".format(f=z.f, Q=z.Q) +# +# return rtn + class tf(Command): class fQ(object): @@ -298,7 +411,7 @@ class tf(Command): def addZero(self,f, Q): self.zeros.append(tf.fQ(SIfloat(f), SIfloat(Q))) - + @staticmethod def parseFinesseText(text): values = text.split() @@ -354,9 +467,12 @@ class xaxis(Command): self._axis_type = axis_type - self.x = putter("x1") - self.mx = putter("mx1") + self.x = putter("x1", self) + self.mx = putter("mx1", self) + self._putters.append(self.x) + self._putters.append(self.mx) + if scale == "lin": scale = Scale.linear elif scale == "log": @@ -433,8 +549,11 @@ class xaxis(Command): class x2axis(xaxis): def __init__(self, scale, limits, param, steps, comp=None, axis_type="x2axis"): xaxis.__init__(self, scale, limits, param, steps, comp=comp, axis_type=axis_type) - self.x = putter("x2") - self.mx = putter("mx2") + self.x = putter("x2", self) + self.mx = putter("mx2", self) + + self._putters.append(self.x) + self._putters.append(self.mx) @staticmethod def parseFinesseText(text): diff --git a/pykat/components.py b/pykat/components.py index da2aca3589843796d08e75acbc291754c4de4c42..d61b8df346516b37db92f0b84f850ec303f1ce73 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -84,7 +84,7 @@ class NodeGaussSetter(object): def qy(self, value): self.__node().setGauss(self.__comp(), self.qx, complex(value)) -id___ = 0 +id_____pykat_class = 0 class Component(object): __metaclass__ = abc.ABCMeta @@ -93,9 +93,9 @@ class Component(object): # This creates an instance specific class for the component # this enables us to add properties to instances rather than # all classes - global id___ - id___ += 1 - cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___)) + global id_____pykat_class + id_____pykat_class += 1 + cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id_____pykat_class)) cnew = type(cnew_name, (cls,), {}) @@ -130,6 +130,9 @@ class Component(object): result = self.__class__.__new__(self.__class__.__base__) result.__dict__ = copy.deepcopy(self.__dict__, memo) + for _ in result._params: + _._updateOwner(result) + return result def _register_param(self, param): @@ -162,7 +165,17 @@ class Component(object): self._kat = kat kat.nodes.registerComponentNodes(self, self._requested_node_names, self.__on_node_change) + + def _on_kat_remove(self): + # inform all parameters that we have removed its owner + # so that it can then warn about any puts/vars/xaxis + for p in self._params: + p._onOwnerRemoved() + del self._params[:] + + self.__removed = True + def __on_node_change(self): # need to update the node gauss parameter setter members self.__update_node_setters() @@ -237,16 +250,10 @@ class Component(object): def __str__(self): return self.name def remove(self): - self._kat.remove(self) - - # inform all parameters that we have removed its owner - # so that it can then warn about any puts/vars/xaxis - for p in self._params: - p._onOwnerRemoved() - - del self._params[:] - - self.__removed = True + if self.__removed: + raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) + else: + self._kat.remove(self) def getOptivisParameterDict(self): if len(self._params) == 0: @@ -497,8 +504,8 @@ class mirror(AbstractMirrorComponent): return mirror(values[0], values[4], values[5], T=None, R=values[1], L=values[2], phi=values[3]) def getFinesseText(self): - if self.R+self.T+self.L > 1: - raise pkex.BasePyKatException("Mirror {0} has R+T+L > 1".format(self.name)) + if abs(self.R + self.T + self.L - 1) > 1e-14: + raise pkex.BasePyKatException("Mirror {0} has R+T+L = {1}, must equal 1 +- 1e-14".format(self.name, self.R+self.T+self.L)) rtn = [] @@ -632,8 +639,8 @@ class beamSplitter(AbstractMirrorComponent): values[1], None, values[2], values[3], values[4]) def getFinesseText(self): - if self.R+self.T+self.L > 1: - raise pkex.BasePyKatException("Beamsplitter {0} has R+T+L > 1".format(self.name)) + if abs(self.R + self.T + self.L - 1) > 1e-14: + raise pkex.BasePyKatException("Beamsplitter {0} has R+T+L = {1}, must equal 1 +- 1e-14".format(self.name, self.R+self.T+self.L)) rtn = [] @@ -1320,7 +1327,7 @@ class laser(Component): return self._svgItem class squeezer(Component): - def __init__(self, name, node, f=0, db=0, angle=0, phase=0): + def __init__(self, name, node, f=0, db=0, angle=0, phase=0, entangled_carrier=False): Component.__init__(self,name) self._requested_node_names.append(node) @@ -1330,6 +1337,7 @@ class squeezer(Component): self.__db = Param("db", self, SIfloat(db), canFsig=False, fsig_name="r") self.__angle = Param("angle", self, SIfloat(angle), canFsig=False, fsig_name="angle") self._svgItem = None + self.entangled_carrier = entangled_carrier @property def db(self): return self.__db @@ -1357,19 +1365,26 @@ class squeezer(Component): @staticmethod def parseFinesseText(text): values = text.split() - - if values[0] != "sq": + + if values[0][:2] != "sq": raise pkex.BasePyKatException("'{0}' not a valid Finesse squeezer command".format(text)) + entangled_carrier = values[0].endswith("*") + values.pop(0) # remove initial value if len(values) == 5: - return squeezer(values[0], values[4], f=values[1], db=values[2], angle=values[3]) + return squeezer(values[0], values[4], f=values[1], + db=values[2], angle=values[3], + entangled_carrier=entangled_carrier) else: raise exceptions.FinesseParse("Squeezer Finesse code format incorrect '{0}'".format(text)) def getFinesseText(self): - rtn = ['sq {0} {1} {2} {3} {4}'.format(self.name, self.f.value, self.db.value, self.angle.value, self.nodes[0].name)] + if self.entangled_carrier: + rtn = ['sq* {0} {1} {2} {3} {4}'.format(self.name, self.f.value, self.db.value, self.angle.value, self.nodes[0].name)] + else: + rtn = ['sq {0} {1} {2} {3} {4}'.format(self.name, self.f.value, self.db.value, self.angle.value, self.nodes[0].name)] for p in self._params: rtn.extend(p.getFinesseText()) diff --git a/pykat/detectors.py b/pykat/detectors.py index 4b1b7db9da74b87992b12a4593debfd3955ee040..f3195d08a753f2eb8fd448da9a4192c4b96786ea 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -31,7 +31,7 @@ if USE_GUI: import pykat.gui.resources from pykat.gui.graphics import * -id___ = 0 +id_____pykat_class = 0 class BaseDetector(object) : """ @@ -45,9 +45,9 @@ class BaseDetector(object) : # This creates an instance specific class for the component # this enables us to add properties to instances rather than # all classes - global id___ - id___ += 1 - cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___)) + global id_____pykat_class + id_____pykat_class += 1 + cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id_____pykat_class)) cnew = type(cnew_name, (cls,), {}) @@ -120,6 +120,9 @@ class BaseDetector(object) : if rn != None: self._nodes.append(kat.nodes.createNode(rn)) + def _on_kat_remove(self): + self.__removed = True + def remove(self): if self.__removed: raise pkex.BasePyKatException("{0} has already been marked as removed".format(self.name)) @@ -465,7 +468,7 @@ class gouy(Detector1): class bp(Detector1): - acceptedParameters = ['w', 'w0', 'z', 'zr', 'g', 'r', 'q'] + acceptedParameters = ['w', 'w0', 'z', 'zr', 'g', 'r', 'q', 'Rc'] def __init__(self, name, direction, parameter, node, alternate_beam=False): BaseDetector.__init__(self, name, node) diff --git a/pykat/finesse.py b/pykat/finesse.py index cdb5a2ae1a44a2db553661393bfba3ee6229e0e3..45ccb84f8ef77b2b594f8c7e12c489054b818e6a 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -320,7 +320,7 @@ class katRun(object): """ import matplotlib.pyplot as pyplot import pykat.plotting as plt - + if not show: pyplot.ioff() @@ -328,6 +328,9 @@ class katRun(object): kat.verbose = False kat.parseCommands(self.katScript) + if kat.noxaxis == True: + raise pkex.BasePyKatException("This kat object has noxaxis=True, so there is nothing to plot.") + if yaxis is not None: kat.yaxis = yaxis @@ -745,6 +748,7 @@ class kat(object): self.vacuum = [] self.__prevrunfilename = None self.printmatrix = None + self.__variables = {} # initialise default block self.__currentTag= NO_BLOCK @@ -996,8 +1000,8 @@ class kat(object): sys.exit(1) else: return - - for o in self.__blocks[name].contents: + + for o in self.__blocks[name].contents.copy(): self.remove(o) del self.__blocks[name] @@ -1005,6 +1009,31 @@ class kat(object): def __str__(self): return "".join(self.generateKatScript()) + def getVariable(self, name): + if name not in self.__variables: + raise pkex.BasePyKatException("Finesse variable `$%s` does not exist." % name) + + return self.__variables[name] + + def registerVariable(self, name, putter): + if '$' in name: + raise pkex.BasePyKatException("Finesse variable name `%s` should not include the `$` symbol as it is added internally." % name) + + assert(putter is not None) + assert(name == putter.name) + + if name in self.__variables: + raise pkex.BasePyKatException("Finesse variable name `%s` already exists." % name) + + self.__variables[name] = putter + + def unregisterVariable(self, name): + del self.__variables[name] + + def printVariables(self): + for key in self.__variables: + print("$" + key, "::::", "owner =", self.__variables[key].owner.name, ", use count =", self.__variables[key].putCount) + def parseCommands(self, commands, blocks=None, addToBlock=None): try: if addToBlock is not None and blocks is not None: @@ -1077,7 +1106,7 @@ class kat(object): obj = pykat.components.space.parseFinesseText(line) elif(first == "l"): obj = pykat.components.laser.parseFinesseText(line) - elif(first == "sq"): + elif(first[:2] == "sq"): obj = pykat.components.squeezer.parseFinesseText(line) elif(first[0:2] == "bs"): obj = pykat.components.beamSplitter.parseFinesseText(line) @@ -1182,6 +1211,8 @@ class kat(object): after_process.append((line, self.__currentTag)) elif(first == "noplot"): after_process.append((line, self.__currentTag)) + elif(first == "put" or first == "put*"): + after_process.append((line, self.__currentTag)) else: if self.verbose: print ("Parsing `{0}` into pykat object not implemented yet, added as extra line.".format(line)) @@ -1231,7 +1262,41 @@ class kat(object): raise pkex.BasePyKatException("noplot command `{0}` refers to non-existing detector".format(line)) getattr(self, rest).noplot = True + + elif (first == "put" or first =="put*"): + alt = first == "put*" + + values = line.split() + obj = values[1] + target = values[2] + variable = values[3] + try: + if not hasattr(self, obj): + raise pkex.BasePyKatException("put command `{0}` refers to non-existing component".format(line)) + + obj = getattr(self, obj) + + if not hasattr(obj, target): + raise pkex.BasePyKatException("put command component `{0}` does not have a parameter `{1}`".format(line, target)) + + target = getattr(obj, target) + + if not target.isPutable: + raise pkex.BasePyKatException("put command `{0}` parameter `{1}` cannot be put to".format(line, target)) + + target.put(self.getVariable(variable.replace('$', '')), alt) + + except pkex.BasePyKatException as ex: + if self.verbose: + print("Warning: ", ex.msg) + print ("Parsing `{0}` into pykat object not implemented yet, added as extra line.".format(line)) + + obj = line + # manually add the line to the block contents + self.__blocks[block].contents.append(line) + + elif (first == "scale"): v = line.split() accepted = ["psd","psd_hf","asd","asd_hf","meter", "ampere", "deg", "rad", "1/deg", "1/rad",] @@ -1368,7 +1433,7 @@ class kat(object): except pkex.BasePyKatException as ex: - pkex.PrintError("Error parsing line: '%s':"% line, ex) + pkex.PrintError("Pykat error parsing line: '%s':"% line, ex) sys.exit(1) def saveScript(self, filename=None): @@ -1600,12 +1665,11 @@ class kat(object): a = line.split(':', 1) if a[0].isdigit(): - #print("Found %s" % a[0]) - values = a[1].split() - + node_name = values[1].split("(")[0] - + component_name = values[2].split("(")[0] + line1x = ifile.readline().replace('(','').replace(')','') line2x = ifile.readline().replace('(','').replace(')','') line1y = ifile.readline().replace('(','').replace(')','') @@ -1617,7 +1681,9 @@ class kat(object): qx = spqx[0].split("=")[1].replace('i','j').replace(' ','') qy = spqy[0].split("=")[1].replace('i','j').replace(' ','') - traceData[-1][node_name] = (pykat.beam_param(q=complex(qx)), pykat.beam_param(q=complex(qy))) + traceData[-1][node_name] = (pykat.beam_param(q=complex(qx), wavelength=self.lambda0), + pykat.beam_param(q=complex(qy), wavelength=self.lambda0), + component_name) finally: ifile.close() @@ -1641,14 +1707,14 @@ class kat(object): #if len(self.detectors.keys()) > 0: if hasattr(self, "x2axis") and self.noxaxis == False: - [r.x,r.y,r.z,hdr] = self.readOutFile(outfile) + [r.x, r.y, r.z, hdr] = self.readOutFile(outfile) r.xlabel = hdr[0] r.ylabel = hdr[1] r.zlabels = [s.strip() for s in hdr[2:]] #r.zlabels = map(str.strip, hdr[2:]) else: - [r.x,r.y,hdr] = self.readOutFile(outfile) + [r.x, r.y, hdr] = self.readOutFile(outfile) r.xlabel = hdr[0] r.ylabels = [s.strip() for s in hdr[1:]] @@ -1759,6 +1825,9 @@ class kat(object): del nodes + if hasattr(obj, "_on_kat_remove"): + obj._on_kat_remove() + #import gc #print (gc.get_referrers(obj)) diff --git a/pykat/param.py b/pykat/param.py index 264de77b1e3e13d2f01da656a3fb3b04b7ab474d..6644407a2a00d859ef9b6e9d9ad52257b88b2cc3 100644 --- a/pykat/param.py +++ b/pykat/param.py @@ -12,7 +12,8 @@ class putable(object): Objects that inherit this should be able to have something `put` to it. Essentially this means you could write Finesse commands like - put this parameter value + param.put(kat.xaxis.x) + """ __metaclass__ = abc.ABCMeta @@ -20,45 +21,96 @@ class putable(object): self._parameter_name = parameter_name self._component_name = component_name self._putter = None + self._alt = False self._isPutable = isPutable @property def isPutable(self): return self._isPutable - def put(self, var): - - if not isinstance(var, putter): - raise pkex.BasePyKatException("var was not something that can be `put` as a value") + def put(self, var, alt=False): + if not self._isPutable: + raise pkex.BasePyKatException("Can't put to this object") + + if var is not None and not isinstance(var, putter): + raise pkex.BasePyKatException("`%s` was not something that can be `put` to a parameter" % str(var)) - if self._putter != None: - self._putter.put_count -= 1 - self._putter.putees.remove(self) + # Remove existing puts + if self._putter is not None: + self._putter.unregister(self) self._putter = var + + self._alt = alt - if var != None: - self._putter.put_count += 1 - self._putter.putees.append(self) + if var is not None: + self._putter.register(self) def _getPutFinesseText(self): rtn = [] - # if something is being put to this - if self._putter != None: - rtn.append("put {comp} {param} ${value}".format(comp=self._component_name, param=self._parameter_name, value=self._putter.put_name())) + + if self._isPutable and self._putter is not None: + putter_enabled = True + + if hasattr(self._putter.owner, 'enabled'): + putter_enabled = self._putter.owner.enabled + + if putter_enabled: + if self._alt: + alt = '*' + else: + alt = '' + + # if something is being put to this + rtn.append("put{alt} {comp} {param} ${value}".format(alt=alt, comp=self._component_name, param=self._parameter_name, value=self._putter.put_name())) return rtn - + + class putter(object): """ If an object can be put to something that is putable it should inherit this object. """ - def __init__(self, put_name, isPutter=True): + def __init__(self, put_name, owner, isPutter=True): self._put_name = put_name self.put_count = 0 self._isPutter = isPutter self.putees = [] # list of params that this puts to + + assert(owner is not None) + self.__owner = weakref.ref(owner) + + def _updateOwner(self, newOwner): + del self.__owner + self.__owner = weakref.ref(newOwner) + + def clearPuts(self): + for _ in self.putees.copy(): + _.put(None) + + def register(self, toput): + if not self._isPutter: + raise pkex.BasePyKatException("This object can't put") + + self.put_count += 1 + self.putees.append(toput) + + def unregister(self, item): + if not self._isPutter: + raise pkex.BasePyKatException("This object can't put") + + self.put_count -= 1 + self.putees.remove(item) + + @property + def owner(self): return self.__owner() + + @property + def name(self): return self._put_name + + @property + def putCount(self): return self.put_count @property def isPutter(self): return self._isPutter @@ -68,39 +120,33 @@ class putter(object): class Param(putable, putter): - def __init__(self, name, owner, value, canFsig=False, fsig_name=None, isPutable=True, isPutter=True, isTunable=True, var_name=None): + def __init__(self, name, owner, value, canFsig=False, fsig_name=None, isPutable=True, isPutter=True, isTunable=True, var_name=None, register=True): self._name = name + self._registered = register self._owner = weakref.ref(owner) self._value = value self._isPutter = isPutter self._isTunable = isTunable - self._owner()._register_param(self) self._canFsig = False + if self._registered: + self._owner()._register_param(self) + if canFsig: self._canFsig = True - + if fsig_name is None: raise pkex.BasePyKatException("If parameter is a possible fsig target the fsig_name argument must be set") - + self.__fsig_name = fsig_name if isPutter: if var_name is None: var_name = "var_{0}_{1}".format(owner.name, name) - putter.__init__(self, var_name, isPutter) + putter.__init__(self, var_name, owner, isPutter) putable.__init__(self, owner.name, name, isPutable) - - def _updateOwner(self, newOwner): - """ - This updates the internal weak reference to link a parameter to who owns it. - Should only be called by the __deepcopy__ component method to ensure things - are kept up to date. - """ - del self._owner - self._owner = weakref.ref(newOwner) @property def canFsig(self): return self._canFsig @@ -162,7 +208,16 @@ class Param(putable, putter): rtn.append("set {put_name} {comp} {param}".format(put_name=self.put_name(), comp=self._owner().name, param=self.name)) return rtn - + + def _updateOwner(self, newOwner): + """ + This updates the internal weak reference to link a parameter to who owns it. + Should only be called by the __deepcopy__ component method to ensure things + are kept up to date. + """ + del self._owner + self._owner = weakref.ref(newOwner) + def _onOwnerRemoved(self): #if this param can be put somewhere we need to check if it is if self.isPutable: diff --git a/test/test_scripts/random/test_unicode_printing.py b/test/test_scripts/random/test_unicode_printing.py index 2afb8c3fc2c3720af478ac8d67d7859aad9fb364..42b544852bb341ddbca14611c2b7c1288f7a5773 100644 --- a/test/test_scripts/random/test_unicode_printing.py +++ b/test/test_scripts/random/test_unicode_printing.py @@ -13,9 +13,11 @@ kat.loadKatFile("LHO_IFO_maxtem2.kat") # load the conf kat.parseKatCode( "fsig sig1 ETMXHR 10 180") kat.parseKatCode( "fsig sig1 ETMYHR 10 0") kat.parseKatCode( "pd1 myomc 10 nOMC_HROC_trans") -kat.parseKatCode( "put myomc f1 $x1") # to follow kat.parseKatCode( "xaxis sig1 f log 10 1k 10") +kat.parseKatCode( "put myomc f1 $x1") # to follow kat.parseKatCode( "yaxis abs:deg") kat.verbose = True out = kat.run() # do the computation -result.append(out['myomc']) # append the result \ No newline at end of file +result.append(out['myomc']) # append the result + +print("PASSED") \ No newline at end of file diff --git a/test/test_scripts/structural/test_deepcopying_references.py b/test/test_scripts/structural/test_deepcopying_references.py index a82b0613cc47eac50f8ba3897899a513286e5d6c..2d3fc7f41ed55a947966d56388d9dbe9c3a8ccf4 100644 --- a/test/test_scripts/structural/test_deepcopying_references.py +++ b/test/test_scripts/structural/test_deepcopying_references.py @@ -25,6 +25,9 @@ assert(kat0.nodes.n0 != kat1.nodes.n0) assert(kat0.o1 != kat1.o1) assert(kat0.o1.__class__ != kat1.o1.__class__) +assert(kat0.m1.phi.owner == kat0.m1) +assert(kat1.m1.phi.owner == kat1.m1) + # use is to compare if two params are the same object as equals is override to compare the value assert(kat0.o1.f1 is not kat1.o1.f1) assert(kat0.o1.f1 == kat1.o1.f1) diff --git a/test/test_scripts/structural/test_lambda0_beam_param.py b/test/test_scripts/structural/test_lambda0_beam_param.py new file mode 100644 index 0000000000000000000000000000000000000000..ac78e97028cfb9309901452a88c2fa5f906d0de0 --- /dev/null +++ b/test/test_scripts/structural/test_lambda0_beam_param.py @@ -0,0 +1,46 @@ +# Submitted by Sebastian. +# Checks that trace data output returns the same beamsize when a different default wavelength is used + +from pykat import finesse + +kat_code = """ +l laser 1 0 0 n1 +s s1 10 1 n1 n2 + +m2 mITM 0.9 0.0 0 n2 n3 +attr mITM Rc -2.0 +s scav 1 n3 n4 +m2 mETM 0.9 0.0 0 n4 n5 +attr mETM Rc 2.0 + +cav myCav mITM n3 mETM n4 + +s s3 1 n5 n6 + +pd pd_trans n6 + +noxaxis +yaxis abs:deg # move detector frequency with xaxis +""" + +kat = finesse.kat() +kat.verbose = False +kat.lambda0 = 1550e-9 +kat.parseKatCode(kat_code) +kat.maxtem = 0 +kat.trace = 2 +out, T = kat.run(getTraceData=True) + +print (out.stdout) + +bp = T[0]['n4'][0] + +# this is not overwritten to 1550nm as above +print('beam_param.wavelength: {:.0f}nm'.format(bp.wavelength*1e9)) +# therefore this is wrong +print('w0 from beam_param.w0: {:.2f}um'.format(bp.w0*1e6)) +# and this does not really work as the wavelength cancels out +# for z=0 and therefore the waist does not change +print('w0 from beam_param.beamsize(): {:.2f}um'.format(bp.beamsize(z=0, wavelength=1550e-9)*1e6)) + +assert(bp.w0 == bp.beamsize(z=0, wavelength=1550e-9)) \ No newline at end of file diff --git a/test/test_scripts/structural/test_properties.py b/test/test_scripts/structural/test_properties.tbf similarity index 100% rename from test/test_scripts/structural/test_properties.py rename to test/test_scripts/structural/test_properties.tbf diff --git a/work_in_progress/optivis_ex.py b/work_in_progress/optivis_ex.py index a0806ee1153766503aa12d129b3f553aa12730e3..d291127588a872dc2af9783077db9b3bd383836e 100644 --- a/work_in_progress/optivis_ex.py +++ b/work_in_progress/optivis_ex.py @@ -22,6 +22,7 @@ attr m1 Rc -500 attr m2 Rc 500 cav c1 m1 n4b m2 n7a +pd P n5b maxtem 0 noxaxis """)