diff --git a/bin/test_plot.py b/bin/test_plot.py index 230d6eb3854b283baa413bd2ef04d3f5a7dac2b5..851d55079f0ac2d3f57b9b5416559de7f65bcdca 100644 --- a/bin/test_plot.py +++ b/bin/test_plot.py @@ -16,19 +16,16 @@ m m2 0.5 0.5 0 n4 n5 s s3 10 1 n5 n6 yaxis abs:deg + +pd pd_cav n3 + +cav c1 m1 n3 m2 n4 """ kat = finesse.kat() kat.parseCommands(code) -kat.add(cavity('cav1', 'm1', 'n3', 'm2', 'n4')) - -kat.add(photodiode('pd_ref','n2')) -kat.add(photodiode('pd_trs','n5')) -kat.add(photodiode('pd_cav','n4', num_demods=1, demods=[1])) - - kat.add(xaxis("lin", [0, 360], kat.m2.phi, 100)) kat.m1.Rcx = -1000.0 @@ -41,7 +38,7 @@ kat.maxtem = 0 out = kat.run(printout=0,printerr=0) pl.figure() -pl.plot(out.x, out["pd_cav"]) +pl.plot(out.x, out.y) pl.xlabel(out.xlabel) pl.ylabel("Intensity [W]") pl.legend(out.ylabels) diff --git a/pykat/components.py b/pykat/components.py index b54b28e7875101a999d805bc431b1584b0735e72..bc203fb9eb541735eb823ceb3af7f7950e22bc1c 100644 --- a/pykat/components.py +++ b/pykat/components.py @@ -365,7 +365,7 @@ class space(Component): self.__L = Param("L", self, SIfloat(L)) self.__n = Param("n", self, SIfloat(n)) - self.__g = AttrParam("g", self, g) + self.__g = AttrParam("g", self, g) self.__gx = AttrParam("gx", self, gx) self.__gy = AttrParam("gy", self, gy) @@ -558,11 +558,12 @@ class grating(Component): return self._QItem class isolator(Component): - def __init__(self, name, node1, node2, S = 0): + def __init__(self, name, node1, node2, node3="dump", S = 0): Component.__init__(self, name) self._requested_node_names.append(node1) self._requested_node_names.append(node2) + self._requested_node_names.append(node3) self.__S = Param("S",self,SIfloat(S)) @@ -582,11 +583,13 @@ class isolator(Component): if len(values) == 4: return isolator(values[0], values[2], values[3], values[1]) + elif len(values) == 5: + return isolator(values[0], values[2], values[3], values[4], values[1]) else: raise pkex.BasePyKatException("Isolator Finesse code format incorrect '{0}'".format(text)) def getFinesseText(self): - rtn = ['isol {0} {1} {2} {3}'.format(self.name, self.S.value, self.nodes[0].name, self.nodes[1].name)] + 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)] for p in self._params: rtn.extend(p.getFinesseText()) diff --git a/pykat/detectors.py b/pykat/detectors.py index 3d785067a7f8db7ab7755d328af5256ded39516e..670348742ff8c88340a5f05a109a1720ce48ad60 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -28,17 +28,19 @@ class Detector(object) : self._mask = {} self.__scale = None - if node[-1]=='*': - self._alternate_beam = True - node=node[:-1] + if node != None: + if node[-1]=='*': + self._alternate_beam = True + node=node[:-1] - self.__requested_node = node + self.__requested_node = node def _register_param(self, param): self._params.append(param) def _on_kat_add(self, kat): - self.__node = kat.nodes.createNode(self.__requested_node) + if self.__requested_node != None: + self.__node = kat.nodes.createNode(self.__requested_node) @staticmethod def parseFinesseText(text): @@ -321,7 +323,7 @@ class pd(Detector): if senstype == None: senstype = "" - + rtn.append("pd{0}{1} {2}{3} {4}{5}".format(senstype, self.num_demods, self.name, fphi_str, self.node.name, alt_str)) if self.scale != None: @@ -330,135 +332,135 @@ class pd(Detector): if self.pdtype != None: rtn.append("pdtype {0} {1}".format(self.name, self.pdtype)) - for p in self._params: - rtn.extend(p.getFinesseText()) + for p in self._params: + rtn.extend(p.getFinesseText()) return rtn - -class photodiode(Detector): + +def qnoised(pd): + + def __init__(self, name, num_demods, node_name, alternate_beam=False, pdtype=None, **kwargs): + pd.__init__(self, name, num_demods, node_name, alternate_beam=False, **kwargs) + + self.__homangle = AttrParam("homangle", self, None) + + @property + def homangle(self): return self.__homangle + @homangle.setter + def homangle(self, value): self.__homangle.value = value + + @pd.pdtype.setter + def pdtype(self, value): raise pkex.BasePyKatException("Setting pdtype is not possible with qnoised detectors") + + @pd.senstype.setter + def senstype(self,value): raise pkex.BasePyKatException("qnoised detector has no sensitvity type") + + + @staticmethod + def parseFinesseText(text): + values = text.split() - class __F(list): - def __init__(self, values=None): - if values==None: - values = [] - list.__init__(self,[SIfloat(value) for value in values]) + if len(values) <= 3: + raise pkex.BasePyKatException("Photodiode code format incorrect '{0}' (2)".format(text)) - class __Phi(list): - def __convertValue(self, value): - if value=="max": - return value - else: - return SIfloat(value) - - def __init__(self, values=None): - if values==None: - values = [] - list.__init__(self,[self.__convertValue(value) for value in values]) - - def __getitem__(self, key): # probably not needed - if list.__getitem__(self,key)=="max": - return list.__getitem__(self,key) - else: - return float(list.__getitem__(self,key)) + demods = values[2] - @property - def f(self): return self.__f - - @property - def phi(self): return self.__phi - - @property - def pdtype(self): return self.__pdtype - @pdtype.setter - def pdtype(self, value): self.__pdtype = value - - def __init__(self, name, node, senstype="", num_demods=0, demods=[], pdtype=None): - Detector.__init__(self, name, node) + if len(values) <= 4 and demods > 0: + raise pkex.BasePyKatException("Photodiode code format incorrect '{0}' (2)".format(text)) + elif len(values) > 4 and demods == 0: + raise pkex.BasePyKatException("Photodiode code format incorrect '{0}' (3)".format(text)) + + num_f_phs = len(values) - 4 + expected_f_phs = demods * 2 + + if not (num_f_phs == expected_f_phs or num_f_phs == expected_f_phs-1): + raise pkex.BasePyKatException("Photodiode code format incorrect '{0}' (4)".format(text)) + + f = values[3:len(values)-1:2] + phs = values[4:len(values)-1:2] + + dict = {} - if num_demods>2: - raise NotImplementedError("pd with more than two demodulations not implemented yet") + for i in range(len(f)): + dict['f{0}'.format(i+1)] = f[i] + for i in range(len(phs)): + dict['phi{0}'.format(i+1)] = phs[i] - self.num_demods = num_demods - self.senstype = senstype - self.__pdtype = pdtype + node = values[-1] + alt_beam = node[-1] == '*' + + if alt_beam: + node = node[0:-1] + + return qnoised(values[1], demods, node, alternate_beam=alt_beam, **dict) + + def getFinesseText(self) : + rtn = [] + + if self.enabled: + alt_str = "" + fphi_str = "" + + if self.alternate_beam: + alt_str = "*" + + for n in range(1, 1+self.num_demods): + fphi_str += " " + str(self.__getattribute__("f"+str(n))) + phi_val = self.__getattribute__("phi"+str(n)) + + if phi_val != None: + fphi_str += " " + str(phi_val) + + senstype = self.senstype + + if senstype == None: + senstype = "" + + rtn.append("qnoised {0} {1} {2} {3}{4}".format(self.name, self.num_demods, fphi_str, self.node.name, alt_str)) + if self.scale != None: + rtn.append("scale {1} {0}".format(self.name, self.scale)) + + for p in self._params: + rtn.extend(p.getFinesseText()) + + return rtn + +def xd(Detector): - # every second element into f (starting at 1) - self.__f = self.__F(demods[::2]) + def __init__(self, name, node_name, component, motion): + Detector.__init__(name, None) - # Every second element into phi (starting at 2) - self.__phi = self.__Phi(demods[1::2]) + self.__motion = motion + self.__component = component + @property + def motion(self): return self.__motion + + @property + def component(self): return self.__component + @staticmethod def parseFinesseText(text): values = text.split() - if values[0][0:2] != "pd": - raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text)) - if len(values[0])==2: - __num_demods=0 - __senstype="" - elif len(values[0])==3 or len(values[0])==4: - if values[0][2]=="S": - __senstype="S" - elif values[0][2]=="N": - __senstype="N" - else: - try: - __num_demods=int(values[0][2]) - __senstype="" - except ValueError: - raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text)) - if len(values[0])==4: - try: - __num_demods=int(values[0][3]) - except ValueError: - raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text)) - else: - raise exceptions.FinesseParse("'{0}' not a valid photodiode command".format(text)) - - if __num_demods<0 or __num_demods>5: - raise exceptions.FinesseParse("'{0}' number of demodulations must be >0 and <5".format(text)) - - values.pop(0) # remove initial value - - if len(values) == 2 * __num_demods + 1 or len(values) == 2 * __num_demods + 2: - return photodiode(values[0], values[-1], __senstype, __num_demods, values[1:len(values)-1]) - else: - raise exceptions.FinesseParse("Photodiode code format incorrect '{0}'".format(text)) - - #return photodiode("name", "node", demods) - #raise NotImplementedError("This function is not implemented") - + if len(values) != 4: + raise pkex.BasePyKatException("Motion detector command format incorrect '{0}' (2)".format(text)) + + return xd(values[1], values[2], values[3]) + def getFinesseText(self) : + rtn = [] + if self.enabled: - rtn = [] - __f_phi=range(len(self.f)+len(self.phi)) - __f_phi[::2]=self.f - __f_phi[1::2]=self.phi - __f_phi_str = " ".join(map(str, __f_phi)) - - if self._alternate_beam: - rtn.append("pd{0}{1} {2} {3} {4}".format(self.senstype, self.num_demods, self.name, __f_phi_str, self.node.name)) - else: - rtn.append("pd{0}{1} {2} {3} {4}*".format(self.senstype, self.num_demods, self.name, __f_phi_str, self.node.name)) + rtn.append("xd {0} {1} {2}".format(self.name, self.component, self.motion)) - if self.scale != None and self.scale !='': + if self.scale != None: rtn.append("scale {1} {0}".format(self.name, self.scale)) - - if self.pdtype != None and self.pdtype != '': - rtn.append("pdtype {0} {1}".format(self.name, self.pdtype)) - - if self.noplot: - rtn.append("noplot {0}".format(self.name)) + + for p in self._params: + rtn.extend(p.getFinesseText()) - return rtn - else: - return None + return rtn - def getQGraphicsItem(self): - if self._svgItem == None: - self._svgItem = ComponentQGraphicsItem(":/resources/photodiode_red.svg",self,[(-5,11,self.node)]) - - return self._svgItem - + \ No newline at end of file diff --git a/pykat/finesse.py b/pykat/finesse.py index f920cda09055aec82abc959d87089b05d47a08f2..bd5079859213d0eb4bf62aab03979f0804387240 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -33,6 +33,7 @@ import pickle import pykat import warnings import re +import collections from collections import namedtuple @@ -53,7 +54,6 @@ NO_GUI = False NO_BLOCK = "NO_BLOCK" pykat_web = "www.gwoptics.org/pykat" - class katRun(object): def __init__(self): self.runDateTime = datetime.datetime.now() @@ -258,6 +258,7 @@ class kat(object): self.pykatgui = None self.__signals = Signals() self.constants = {} + self.vacuum = [] # initialise default block self.__currentTag= NO_BLOCK @@ -857,6 +858,25 @@ class kat(object): out.append(txt + "\n") + if self.vacuum != None: + + if isinstance(self.vacuum, collections.Container): + objs = [] + + if len(self.vacuum) > 0: + for a in self.vacuum: + if hasattr(a, 'name'): + objs.append(a.name) + else: + objs.append(str(a)) + + out.append("vacuum {0}\n".format(" ".join(objs))) + + elif isinstance(self.vacuum, str): + out.append("vacuum {0}\n".format(self.vacuum)) + else: + pkex.BasePyKatException("Couldn't understand vacuum input list") + if self.scale != None and self.scale !='': out.append("scale {0}\n".format(self.scale)) if self.phase != None: out.append("phase {0}\n".format(self.phase)) if self.maxtem != None: