def registerComponentNodes(self, comp, node_names, change_callback):
        """
        For a given component we create some nodes or get existing ones and 
        attach them to this component. Also specify a callback function that
        is called whenever the nodes attached to this component are changed
        , e.g. connected, disconnected, name change, etc.
        """
        if not isinstance(comp, Component):
            raise pkex.BasePyKatException(
                "comp argument is not of type Component")

        if comp.id in self.__componentNodes:
            raise pkex.BasePyKatException(
                "Component has already been registered")

        list = []

        for name in node_names:
            n = self.createNode(name)
            self.__connectNodeToComp(n, comp, do_callback=False)
            list.append(n)

        self.__componentNodes[comp.id] = tuple(list)
        self.__componentCallback[comp.id] = change_callback

        change_callback()
Example #2
0
    def __init__(self, wavelength=1064e-9, nr=1, *args, **kwargs):
        if self.__class__ == gauss_param or self.__class__ == beam_param:
            warnings.warn("Name changed. Use BeamParam instead of gauss_param or beam_param.")

        self.__q = None
        self.__lambda = SIfloat(wavelength)
        self.__nr = SIfloat(nr)

        if len(args) == 1:
            self.__q = complex(args[0])

        elif len(kwargs) == 1:
            if "q" in kwargs:
                self.__q = complex(kwargs["q"])
            else:
                raise pkex.BasePyKatException("Must specify: z and w0 or z and zr or rc and w or q, to define the beam parameter")

        elif len(kwargs) == 2:

            if "w0" in kwargs and "z" in kwargs:
                q = SIfloat(kwargs["z"]) + 1j * math.pi*SIfloat(kwargs["w0"])**2/(self.__lambda/self.__nr)
            elif "z" in kwargs and "zr" in kwargs:
                q = SIfloat(kwargs["z"]) + 1j * SIfloat(kwargs["zr"])
            elif "rc" in kwargs and "w" in kwargs:
                one_q = 1 / SIfloat(kwargs["rc"]) - 1j * SIfloat(wavelength) / (math.pi * SIfloat(nr) * SIfloat(kwargs["w"])**2)
                q = 1/one_q
            else:
                raise pkex.BasePyKatException("Must specify: z and w0 or z and zr or rc and w or q, to define the beam parameter")

            self.__q = q
        else:
            raise pkex.BasePyKatException("Incorrect usage for gauss_param constructor")
    def __connectNodeToComp(self, node, comp, do_callback=True):
        """
        This is an internal function used to create connections between nodes
        """
        if node.id in self.__nodeComponents:
            comps = self.__nodeComponents[node.id]
        else:
            comps = (None, ) * 2

        if len(comps) >= 2 and comps[0] != None and comps[1] != None:
            raise pkex.BasePyKatException(
                "Node '{0}' is already connected to 2 components ({1}, {2})".
                format(node.name, comps[0], comps[1]))

        l = list(comps)

        if l[0] is None:
            l[0] = comp
        elif l[1] is None:
            l[1] = comp
        else:
            raise pkex.BasePyKatException("Connected to two coponents already")

        self.__nodeComponents[node.id] = tuple(l)

        if do_callback: self.__componentCallback[comp.id]()
Example #4
0
def convertToFloat(value):

    try:
        # first just try and convert the value
        return float(value)

    except ValueError as ex:
        # Catch any casting exeception
        value = value.strip()

        # only the last value can be an SI scaling letter
        last = value[-1]

        if last in __suffix:
            # remove last character and append the SI scaling
            value = value[0:-1] + __suffix[last]
        else:
            raise pkex.BasePyKatException(
                "Could not convert SI scaling in '{0}' to a float".format(
                    value))

        try:
            return float(value)
        except ValueError as ex:
            raise pkex.BasePyKatException(
                "Unable to convert '{0}' into a float".format(value))
    def __init__(self,
                 name,
                 owner,
                 value,
                 canFsig=False,
                 fsig_name=None,
                 fsig_name_options=[],
                 isPutable=True,
                 isPutter=True,
                 isTunable=True,
                 var_name=None,
                 register=True):
        self._unfreeze()
        self._name = name
        self._registered = register
        self._owner = weakref.ref(owner)
        self._isPutter = isPutter
        self._isTunable = isTunable
        self._canFsig = False
        self._isConst = False
        self._constName = None

        if self._registered:
            self._owner()._register_param(self)

        if canFsig:
            self._canFsig = True

            if not pykat.isContainer(fsig_name_options):
                raise pkex.BasePyKatException(
                    "fsig name options should be a list of names")

            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

            self.__fsig_name_options = list(fsig_name_options)

            if fsig_name not in self.__fsig_name_options:
                self.__fsig_name_options.append(fsig_name)

        if isPutter:
            if var_name is None:
                var_name = "var_{0}_{1}".format(owner.name, name)

        putter.__init__(self, var_name, owner, isPutter)

        putable.__init__(self, owner.name, name, isPutable)

        self.value = value

        self._freeze()
    def parseFinesseText(text):
        values = text.split()

        if values[0] != "x2axis" and values[0] != "x2axis*":
            raise pkex.BasePyKatException("'{0}' not a valid Finesse xaxis command".format(text))

        axis_type = values[0]

        values.pop(0) # remove initial value

        if len(values) != 6:
            raise pkex.BasePyKatException("xaxis Finesse code format incorrect '{0}'".format(text))

        return x2axis(values[2], [values[3], values[4]], values[1], values[5], comp=values[0],axis_type=axis_type)
 def parseFinesseText(text, kat):
     
     values = text.split()
     if not values[0].startswith("gauss") or (len(values) != 6 and len(values) != 8):
         raise pkex.BasePyKatException("'{0}' not a valid Finesse gauss command".format(text))        
     
     name = values[1]
     component = values[2]
     node = values[3]
     
     # setting the name of the gauss parameter is slightly convoluted
     # as we don't explicitly store gauss paramters as an object, they
     # are simply just complex numbers stored at each node. To fix this
     # the name is stored in the NodeGaussSetter object for each component
     
     if component in kat.components:
         c = kat.components[component]
         if hasattr(c, node):
             ns = getattr(c, node)
             ns.gauss_name = name
         else:
             raise pkex.BasePyKatException("Component '{0}' is not attached to node {1}".format(component, node))        
     else:
         raise pkex.BasePyKatException("Component '{0}' was not found".format(component))        
     
     if not values[0].endswith("*"):
         if len(values) == 6:
             gp = BeamParam(kat.lambda0, w0=values[-2], z=values[-1])
         elif len(values) == 8:
             gpx = BeamParam(kat.lambda0, w0=values[-4], z=values[-3])
             gpy = BeamParam(kat.lambda0, w0=values[-2], z=values[-1])
     elif values[0].endswith("*"):
         if len(values) == 6:
             gp = BeamParam(kat.lambda0, z=values[-2], zr=values[-1])
         elif len(values) == 8:
             gpx = BeamParam(kat.lambda0, z=values[-4], zr=values[-3])
             gpy = BeamParam(kat.lambda0, z=values[-2], zr=values[-1])
     elif values[0].endswith("**"):
         if len(values) == 6:
             gp = BeamParam(kat.lambda0, w=values[-2], rc=values[-1])
         elif len(values) == 8:
             gpx = BeamParam(kat.lambda0, w=values[-4], rc=values[-3])
             gpy = BeamParam(kat.lambda0, w=values[-2], rc=values[-1])
     else:
         raise pkex.BasePyKatException("Unexpected ending to gauss command '{0}'".format(text))
         
     if len(values) == 6:
         kat.nodes[node].setGauss(kat.components[component], gp)
     else:
         kat.nodes[node].setGauss(kat.components[component], gpx, gpy)
 def value(self):
     if self._owner().removed:
         raise pkex.BasePyKatException(
             "{0} has been removed from the simulation".format(
                 self._owner().name))
     else:
         if self._isConst:
             if self._constName[1:] not in self.owner._kat.constants:
                 raise pkex.BasePyKatException(
                     "Parameter {}.{} could not find a Finesse constant called `{}`"
                     .format(self.owner.name, self.name, self._constName))
             return self.owner._kat.constants[self._constName[1:]].value
         else:
             return self._value
    def __init__(self, name, nodes=None, max_nodes=1):

        self._unfreeze()

        self.__name = name
        self._svgItem = None
        self._kat = None
        self.noplot = False
        self.enabled = True
        self.tag = None
        self._params = []
        self._mask = {}
        self.__scale = []
        self.__removed = False
        self.noplot = False

        self._alternate_beam = []
        self._nodes = []
        self._requested_nodes = []

        if nodes != None:
            if isinstance(nodes, (list, tuple)):

                if len(nodes) > max_nodes:
                    raise pkex.BasePyKatException(
                        "Tried to set too many nodes, %s, maximum number is %i."
                        % (str(nodes), max_nodes))

                for n in nodes:
                    if n[-1] == '*':
                        self._alternate_beam.append(True)
                        n = n[:-1]
                    else:
                        self._alternate_beam.append(False)

                    self._requested_nodes.append(n)
            elif isinstance(nodes, six.string_types):
                # if we don't have a collection
                if nodes[-1] == '*':
                    self._alternate_beam.append(True)
                    nodes = nodes[:-1]
                else:
                    self._alternate_beam.append(False)

                self._requested_nodes.append(nodes)
            else:
                raise pkex.BasePyKatException(
                    "Nodes should be a list or tuple of node names or a singular node name as a string."
                )
    def parseFinesseText(text):
        values = text.split()

        if len(values) <= 3:
            raise pkex.BasePyKatException(
                "qshot code format incorrect '{0}' (2)".format(text))

        demods = int(values[2])

        if len(values) <= 4 and demods > 0:
            raise pkex.BasePyKatException(
                "qshot code format incorrect '{0}' (2)".format(text))
        elif len(values) > 4 and demods == 0:
            raise pkex.BasePyKatException(
                "qshot 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(
                "qshot code format incorrect '{0}' (4)".format(text))

        f = values[3:len(values) - 1:2]
        phs = values[4:len(values) - 1:2]

        dict = pd._parse_fphi(f, phs)

        node = values[-1]
        alt_beam = node[-1] == '*'

        if alt_beam:
            node = node[0:-1]

        if values[0].endswith('S'):
            sens = 'S'
        elif values[0].endswith('N'):
            sens = 'N'
        else:
            sens = None

        return qshot(values[1],
                     demods,
                     node,
                     senstype=sens,
                     alternate_beam=alt_beam,
                     **dict)
Example #11
0
    def remove_IMC_HAM2(self, removeIMC, removeHAM2):
        """
        For use with files that have the IMC and HAM2 blocks.
        
        Removes the IMC and HAM2 blocks if not required in the model. Reconnects
        spaces between the laser and HAM2 and PRC. Assumes spaces exists
        with name and node:
            sHAM2in and node nIMCout
            sPRCin  and node nHAM2out
        
        
        This function alters the kat object directly.
        """

        if removeHAM2 and not removeIMC:
            raise pkex.BasePyKatException(
                "Must remove IMC if removing HAM2 block")

        if removeIMC:
            self.kat.removeBlock("IMC")
            self.kat.cavIMC.remove()
            self.kat.nodes.replaceNode(self.kat.sHAM2in, 'nIMCout',
                                       'nLaserOut')

        if removeHAM2:
            L = self.kat.sFI_IM3.L + self.kat.sIM3_IM4.L + self.kat.sPRCin.L
            self.kat.removeBlock("HAM2")
            self.kat.parse("""
            s sPRCin 0 nLaserOut nFI1
            dbs FI nFI1 nFI2 nFI3 nREFL
            s sFI_PRM {} nFI3 nPRM1
            """.format(L),
                           addToBlock='PRC')
 def parseFinesseText(line, kat):
     v = line.split()
     
     if len(v) != 3:
         raise pkex.BasePyKatException("'{0}' not a valid Finesse variable command".format(line))
     
     return variable(v[1], SIfloat(v[2]))
Example #13
0
 def __float__(self):
     if self._owner().removed:
         raise pkex.BasePyKatException(
             "{0} has been removed from the simulation".format(
                 self._owner().name))
     else:
         return float(self.value)
 def __getitem__(self, value):
     if str(value) in self.__nodes:
         return self.__nodes[str(value)]
     else:
         raise pkex.BasePyKatException(
             "The node '%s' could not be found in the network." %
             str(value))
    def parameter(self, value):

        if value is None or (value not in self.acceptedParameters):
            raise pkex.BasePyKatException('Parameter must be one of: %s' %
                                          (", ".join(self.acceptedParameters)))

        self.__param = value
    def remove_IMC_HAM2(self, removeIMC, removeHAM2):
        """
        For use with files that have the IMC and HAM2 blocks.
        
        Removes the IMC and HAM2 blocks if not required in the model. Reconnects
        spaces between the laser and HAM2 and PRC. Assumes spaces exists
        with name and node:
            sHAM2in and node nIMCout
            sPRCin  and node nHAM2out
        
        
        This function alters the kat object directly.
        """

        if removeHAM2 and not removeIMC:
            raise pkex.BasePyKatException(
                "Must remove IMC if removing HAM2 block")

        if removeIMC:
            self.kat.removeBlock("IMC")
            self.kat.cavIMC.remove()
            self.kat.nodes.replaceNode(self.kat.sHAM2in, 'nIMCout',
                                       'nLaserOut')

        if removeHAM2:
            self.kat.removeBlock("HAM2")
            self.kat.nodes.replaceNode(self.kat.sPRCin, 'nHAM2out',
                                       'nLaserOut')
    def num_demods(self, value):
        if value < 0 or value > 5:
            raise pkex.BasePyKatException(
                "Number of demodulations must be between 0 and 5")

        self.__num_demods = value
        self.__set_demod_attrs()
    def mode(self, value):
        if value != None and len(value) != 2:
            raise pkex.BasePyKatException(
                'Mode must be a container of length 2, first element the x mode and second the y mode'
            )

        self.__mode = value
    def __set_phi(self, num, value):
        value = SIfloat(value)

        if value is None and num != self.num_demods:
            # check if we are setting no phase that this is only on the last
            # demodulation phase.
            raise pkex.BasePyKatException(
                "Only last demodulation phase can be set to None")
        elif isinstance(value, six.string_types) and not isinstance(
                value, float) and value.lower() != "max":
            raise pkex.BasePyKatException(
                "Demodulation phase can only be set to a 'max' or a number (or None if the last demodulation phase)"
            )

        p = getattr(self, '_pd__phase' + num)
        p.value = value
    def parseAttributes(self, values):

        for key in values.keys():
            if key in ["homangle"]:
                self.__homangle.value = values[key]
            else:
                raise pkex.BasePyKatException(
                    "No attribute {0} for qnoised".format(key))
    def senstype(self, value):
        if value == "": value = None

        if value != "S" and value != "N" and value != None:
            raise pkex.BasePyKatException(
                "Photodiode sensitivity type can either be 'N', 'S' or None.")

        self.__senstype = value
    def scan_REFL_gouy_telescope_gouy_cmds(self,
                                           start,
                                           end,
                                           steps=20,
                                           xaxis=1,
                                           AB_gouy_diff=None,
                                           relative=False):
        """
        This will return commands to scan the REFL gouy telescope gouy phase of the A and B paths.
        """
        if "REFL_gouy_tele" not in self.kat.getBlocks():
            raise pkex.BasePyKatException(
                "\033[91mREFL Gouy phase telescope isn't in the kat object, see kat.IFO.add_REFL_gouy_telescope()\033[0m"
            )

        if xaxis not in [1, 2]:
            raise pkex.BasePyKatException("xaxis value must be 1 or 2")
        elif xaxis == 1:
            xaxis_cmd = "xaxis"
        elif xaxis == 2:
            xaxis_cmd = "x2axis"

        if AB_gouy_diff is None:
            AB_gouy_diff = self.kat.sWFS_REFL_B.gouy - self.kat.sWFS_REFL_A.gouy

        if relative:
            put = "put*"
        else:
            put = "put"

        cmds = ("var REFL_GOUY_SCAN 0\n"
                "{xaxis} REFL_GOUY_SCAN re lin {start} {end} {steps}\n"
                "{put} sWFS_REFL_A gx $x{axis}\n"
                "{put} sWFS_REFL_A gy $x{axis}\n"
                "func REFL_SCAN_B = $x{axis} + {AB_gouy_diff}\n"
                "{put} sWFS_REFL_B gx $REFL_SCAN_B\n"
                "{put} sWFS_REFL_B gy $REFL_SCAN_B\n").format(
                    xaxis=xaxis_cmd,
                    axis=xaxis,
                    start=start,
                    end=end,
                    steps=steps,
                    AB_gouy_diff=AB_gouy_diff,
                    put=put)

        return cmds
    def remove(self):
        if self.__removed:
            raise pkex.BasePyKatException(
                "{0} has already been marked as removed".format(self.name))
        else:
            self._kat.remove(self)

        self.__removed = True
    def parseFinesseText(text):
        values = text.split()
        demods = 0
        senstype = None

        if len(values[0]) == 4:
            senstype = values[0][2]
            demods = int(values[0][3])
        elif len(values[0]) == 3:
            demods = int(values[0][2])
        elif len(values[0]) != 2:
            raise pkex.BasePyKatException(
                "Photodiode code format incorrect '{0}' (1)".format(text))

        if len(values) <= 3 and demods > 0:
            raise pkex.BasePyKatException(
                "Photodiode code format incorrect '{0}' (2)".format(text))
        elif len(values) > 3 and demods == 0:
            raise pkex.BasePyKatException(
                "Photodiode code format incorrect '{0}' (3)".format(text))

        num_f_phs = len(values) - 3
        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[2:len(values) - 1:2]
        phs = values[3:len(values) - 1:2]

        dict = pd._parse_fphi(f, phs)

        node = values[-1]
        alt_beam = node[-1] == '*'

        if alt_beam:
            node = node[0:-1]

        return pd(values[1],
                  demods,
                  node,
                  senstype=senstype,
                  alternate_beam=alt_beam,
                  **dict)
    def _set_node(self, value, index):
        if self._kat is None:
            raise pkex.BasePyKatException(
                "This detector has not been added to a kat object yet")
        else:
            if value[-1] == '*':
                self._alternate_beam[index] = True
                value = value[:-1]
            else:
                self._alternate_beam[index] = False

            if value in self._kat.nodes:
                self._nodes[index] = self._kat.nodes[value]
            else:
                raise pkex.BasePyKatException(
                    "There is no node called " + value +
                    " in the kat object this detector is attached to.")
 def parseFinesseText(line, kat):
     v = line.split()
     
     if len(v) != 6:
         raise pkex.BasePyKatException("cav command format `{0}` is incorrect".format(line))
     
     if v[2] not in kat.components:
         raise pkex.BasePyKatException("cav command `{0}` refers to component `{1}` which does not exist".format(line, v[2]))
     
     if v[4] not in kat.components:
         raise pkex.BasePyKatException("cav command `{0}` refers to component `{1}` which does not exist".format(line, v[4]))
     
     if v[3] not in kat.nodes.getNodes():
         raise pkex.BasePyKatException("cav command `{0}` refers to node `{1}` which does not exist".format(line, v[3]))
     
     if v[5] not in kat.nodes.getNodes():
         raise pkex.BasePyKatException("cav command `{0}` refers to node `{1}` which does not exist".format(line, v[5]))
     
     c1 = getattr(kat, v[2])
     c2 = getattr(kat, v[4])
     
     n1 = getattr(kat.nodes, v[3])
     n2 = getattr(kat.nodes, v[5])
     
     if not hasattr(c1, n1.name):
         raise pkex.BasePyKatException("cav command `{0}`: node `{1}` is not attached to `{2}`".format(line, n1.name, c1.name))
     
     if not hasattr(c2, n2.name):
         raise pkex.BasePyKatException("cav command `{0}`: node `{1}` is not attached to `{2}`".format(line, n2.name, c2.name))
         
     return pykat.commands.cavity(v[1], c1, n1, c2, n2)
 def sensitivity(self, value):
     if value == 'S' or value == 'N':
         self.__sensitivity = value
     elif value is None or value == '':
         self.__sensitivity = ""
     else:
         raise pkex.BasePyKatException(
             "qhd (%s) sensitivity option '%s' is not available, use either 'S' or 'N'."
             % (self.name, value))
    def parseFinesseText(text):
        values = text.split()

        if len(values) == 4:
            return xd(values[1], values[2], values[3])
        else:
            raise pkex.BasePyKatException(
                'Motion detector code "{0}" is not a valid FINESSE command'.
                format(text))
    def parseFinesseText(text):
        values = text.split()

        if len(values) > 3:
            return gouy(str(values[1]), str(values[2]), values[3:])
        else:
            raise pkex.BasePyKatException(
                'Gouy detector code "{0}" is not a valid FINESSE command'.
                format(text))
    def put(self, var):
        if not isinstance(var, putter):
            raise pkex.BasePyKatException(
                "var was not something that can be `put` as a value")

        if self._putter != None:
            self._putter.put_count -= 1

        self._putter = var
        self._putter.put_count += 1