Beispiel #1
0
    def set_feedback_record(self, index, field, value):
        """Set a value to the feedback in records.

        possible element fields are:
            ['x_fofb_disabled', 'x_sofb_disabled', 'y_fofb_disabled',
             'y_sofb_disabled', 'h_fofb_disabled', 'h_sofb_disabled',
             'v_fofb_disabled', 'v_sofb_disabled', 'error_sum', 'enabled',
             'state', 'offset']
        possible lattice fields are:
            ['beam_current', 'feedback_status', 'bpm_id', 'emittance_status']

        Args:
            index (int): The index of the element on which to set the value;
                          starting from 1, 0 is used to set on the lattice.
            field (string): The field to set the value to.
            value (number): The value to be set.

        Raises:
            pytac.exceptions.FieldException: If the lattice or element does
                                              not have the specified field.
        """
        try:
            self._feedback_records[(index, field)].set(value)
        except KeyError:
            if index == 0:
                raise FieldException(
                    "Lattice {0} does not have field {1}.".format(
                        self.lattice, field))
            else:
                raise FieldException(
                    "Element {0} does not have field {1}.".format(
                        self.lattice[index], field))
Beispiel #2
0
    def set_value(self, field, value, throw=None):
        """Set the value for a field. The field and value go onto the queue of
        changes on the ATSimulator to be passed to make_change when the queue
        is emptied.

        Args:
            field (str): The requested field.
            value (float): The value to be set.
            throw (bool, optional): Throw is not needed and is only here to
                                     conform with the structure of the
                                     DataSource base class.

        Raises:
            HandleException: if the specified field cannot be set to.
            FieldException: if the specified field does not exist.
        """
        if field in self._fields:
            if field in self._set_field_funcs.keys():
                self._atsim.up_to_date.Reset()
                self._atsim.queue_set(self._make_change, field, value)
            else:
                raise HandleException("Field {0} cannot be set on element data"
                                      " source {1}.".format(field, self))
        else:
            raise FieldException("No field {0} on AT element {1}.".format(
                field, self._at_element))
Beispiel #3
0
    def get_emittance(self, field=None):
        """Return the emittance for the AT lattice for the specified plane.

        .. Note:: The emittance at the entrance of the AT lattice as it is
           constant throughout the lattice, and so which element's emittance
           is returned is arbitrary.

        Args:
            field (str): The desired field (x or y) of emittance, if None
                          return both emittance dimensions.

        Returns:
            float: The x or y emittance for the AT lattice.

        Raises:
            FieldException: if the specified field is not valid for emittance.
        """
        if field is None:
            return self._lattice_data.emittance[0]["emitXY"]
        elif field == "x":
            return self._lattice_data.emittance[0]["emitXY"][0]
        elif field == "y":
            return self._lattice_data.emittance[0]["emitXY"][1]
        else:
            raise FieldException(
                "Field {0} is not a valid emittance plane.".format(field))
Beispiel #4
0
    def get_orbit(self, field=None):
        """Return the closed orbit at each element in the AT lattice for the
        specified plane.

        Args:
            field (str): The desired field (x, px, y, or py) of closed orbit,
                          if None return whole orbit vector.

        Returns:
            numpy.array: The x, x phase, y or y phase for the AT lattice as an
            array of floats the length of the AT lattice.

        Raises:
            FieldException: if the specified field is not valid for orbit.
        """
        closed_orbit = self._lattice_data.twiss["closed_orbit"]
        if field is None:
            return closed_orbit[:-1]
        elif field == "x":
            return closed_orbit[:-1, 0]
        elif field == "px":
            return closed_orbit[:-1, 1]
        elif field == "y":
            return closed_orbit[:-1, 2]
        elif field == "py":
            return closed_orbit[:-1, 3]
        else:
            raise FieldException(
                "Field {0} is not a valid closed orbit plane.".format(field))
Beispiel #5
0
    def get_dispersion(self, field=None):
        """Return the dispersion at every element in the AT lattice for the
        specified plane.

        Args:
            field (str): The desired field (x, px, y, or py) of dispersion, if
                          None return whole dispersion vector.

        Returns:
            numpy.array: The eta x, eta prime x, eta y or eta prime y for the
            AT lattice as an array of floats the length of the AT lattice.

        Raises:
            FieldException: if the specified field is not valid for dispersion.
        """
        dispersion = self._lattice_data.twiss["dispersion"]
        if field is None:
            return dispersion[:-1]
        elif field == "x":
            return dispersion[:-1, 0]
        elif field == "px":
            return dispersion[:-1, 1]
        elif field == "y":
            return dispersion[:-1, 2]
        elif field == "py":
            return dispersion[:-1, 3]
        else:
            raise FieldException(
                "Field {0} is not a valid dispersion plane.".format(field))
Beispiel #6
0
    def get_pv_name(self, field, handle):
        """Get PV name for the specified field and handle.

        Args:
            field (str): The requested field.
            handle (str): pytac.RB or pytac.SP.

        Returns:
            str: The readback or setpoint PV for the specified field.

        Raises:
            DataSourceException: if there is no data source for this field.
            FieldException: if the specified field doesn't exist.
        """
        try:
            return (self._data_source_manager.get_data_source(
                pytac.LIVE).get_device(field).get_pv_name(handle))
        except DataSourceException as e:
            raise DataSourceException(f"{self}: {e}")
        except AttributeError:
            raise DataSourceException(
                f"Cannot get PV for field {field} on element "
                f"{self}, as the device does not have associated PVs.")
        except FieldException as e:
            raise FieldException(f"{self}: {e}")
Beispiel #7
0
    def get_tune(self, field=None):
        """Return the tune for the AT lattice for the specified plane.

        .. Note:: A special consideration is made so only the fractional digits
           of the tune are returned.

        Args:
            field (str): The desired field (x or y) of tune, if None return
                          both tune dimensions.

        Returns:
            float: The x or y tune for the AT lattice.

        Raises:
            FieldException: if the specified field is not valid for tune.
        """
        tunes = self._lattice_data.tunes
        if field is None:
            return numpy.array(tunes) % 1
        elif field == "x":
            return tunes[0] % 1
        elif field == "y":
            return tunes[1] % 1
        else:
            raise FieldException(
                "Field {0} is not a valid tune plane.".format(field))
Beispiel #8
0
    def set_value(
        self,
        field,
        value,
        units=pytac.DEFAULT,
        data_source=pytac.DEFAULT,
        throw=True,
    ):
        """Set the value for a field.

        This value can be set on the machine or the simulation.

        Args:
            field (str): The requested field.
            value (float): The value to set.
            units (str): pytac.ENG or pytac.PHYS.
            data_source (str): pytac.LIVE or pytac.SIM.
            throw (bool): On failure: if True, raise ControlSystemException: if
                           False, log a warning.

        Raises:
            DataSourceException: if arguments are incorrect.
            FieldException: if the element does not have the specified field.
        """
        try:
            self._data_source_manager.set_value(field, value, units,
                                                data_source, throw)
        except DataSourceException as e:
            raise DataSourceException(f"{self}: {e}")
        except FieldException as e:
            raise FieldException(f"{self}: {e}")
Beispiel #9
0
    def add_field(self, field):
        """Add a field to this data source. This is normally done
        automatically when adding a device, however since the simulated data
        sources do not use devices this method is needed.

        Args:
            field (str): The name of a supported field that is not already on
                          this data_source.

        Raises:
            FieldException: if the specified field is already present or if it
                             is not supported.
        """
        if field in self._fields:
            raise FieldException("Field {0} already present on element data "
                                 "source {1}.".format(field, self))
        elif field not in self._get_field_funcs.keys():
            raise FieldException("Unsupported field {0}.".format(field))
        else:
            self._fields.append(field)
Beispiel #10
0
    def __init__(self, at_element, index, atsim, fields=None):
        """
        .. Note:: This data source, currently, cannot understand the simulated
           equivalent of shared devices on the live machine, or multiple
           devices that address the same field/attribute for that matter.

        Args:
            at_element (at.elements.Element): The AT element corresponding to
                                               the Pytac element which this
                                               data source is attached to.
            index (int): The element's index in the ring, starting from 1.
            atsim (ATSimulator): An instance of an ATSimulator object.
            fields (list, optional): The fields found on this element.

        Raises:
            ValueError: if an unsupported field is passed, i.e. a field not in
                         _field_funcs.keys().

        **Methods:**
        """
        self.units = pytac.PHYS
        self._at_element = at_element
        self._index = index
        self._atsim = atsim
        self._get_field_funcs = {
            "x_kick": partial(self._get_KickAngle, 0),
            "y_kick": partial(self._get_KickAngle, 1),
            "x": partial(self._get_ClosedOrbit, "x"),
            "y": partial(self._get_ClosedOrbit, "y"),
            "a1": partial(self._get_PolynomA, 1),
            "b1": partial(self._get_PolynomB, 1),
            "b2": partial(self._get_PolynomB, 2),
            "b0": self._get_BendingAngle,
            "f": self._get_Frequency,
        }
        self._set_field_funcs = {
            "x_kick": partial(self._set_KickAngle, 0),
            "y_kick": partial(self._set_KickAngle, 1),
            "a1": partial(self._set_PolynomA, 1),
            "b1": partial(self._set_PolynomB, 1),
            "b2": partial(self._set_PolynomB, 2),
            "b0": self._set_BendingAngle,
            "f": self._set_Frequency,
        }
        fields = set() if fields is None else set(fields)
        # We assume that every set field has a corresponding get field.
        supported_fields = set(self._get_field_funcs.keys())
        if not all(f in supported_fields for f in fields):
            raise FieldException(
                "Unsupported field(s) {0}.".format(fields - supported_fields))
        else:
            self._fields = list(fields)
Beispiel #11
0
    def get_value(self, field, handle=None, throw=True):
        """Get the value for a field on the Pytac lattice.

        Args:
            field (str): The requested field.
            handle (str, optional): Handle is not needed and is only here to
                                     conform with the structure of the
                                     DataSource base class.
            throw (bool, optional): If the check for completion of outstanding
                                     calculations times out, then:
                                     if True, raise a ControlSystemException;
                                     if False, log a warning and return the
                                     potentially out of date data anyway.

        Returns:
            float: The value of the specified field on this data source.

        Raises:
            FieldException: if the specified field does not exist.
            ControlSystemException: if the calculation completion check fails,
                                     and throw is True.
        """
        # Wait for any outstanding calculations to conclude, to ensure they are
        # complete before a value is returned; if the wait times out then raise
        # an error message or log a warning according to the value of throw.
        if not self._atsim.wait_for_calculations():
            error_msg = ("Check for completion of outstanding "
                         "calculations timed out.")
            if throw:
                raise ControlSystemException(error_msg)
            else:
                logging.warning("Potentially out of date data returned. " +
                                error_msg)
        if field in list(self._field_funcs.keys()):
            # The orbit x_phase and y_phase, and the eta prime_x and prime_y
            # fields are represented by 'px' or 'py' in the ATSimulator data
            # handling functions.
            if (field.startswith('phase')) or (field.find('prime') != -1):
                return self._field_funcs[field]('p' + field[-1])
            elif field.endswith('x'):
                return self._field_funcs[field]('x')
            elif field.endswith('y'):
                return self._field_funcs[field]('y')
            else:
                return self._field_funcs[field]()
        else:
            raise FieldException("Lattice data source {0} does not have field "
                                 "{1}".format(self, field))
Beispiel #12
0
    def get_device(self, field):
        """Get device from the data_source.

        Args:
            field (str): field of the requested device.
        Returns:
            Device: The device of the specified field.

        Raises:
            FieldException: if the specified field doesn't exist on this data
                             source.
        """
        try:
            return self._devices[field]
        except KeyError:
            raise FieldException(f"No field {field} on data source {self}.")
Beispiel #13
0
    def get_unitconv(self, field):
        """Get the unit conversion option for the specified field.

        Args:
            field (str): The field associated with this conversion.

        Returns:
            UnitConv: The object associated with the specified field.

        Raises:
            FieldException: if no unit conversion object is present.
        """
        try:
            return self._data_source_manager.get_unitconv(field)
        except FieldException as e:
            raise FieldException(f"{self}: {e}")
Beispiel #14
0
    def get_unitconv(self, field):
        """Get the unit conversion option for the specified field.

        Args:
            field (str): The field associated with this conversion.

        Returns:
            UnitConv: The object associated with the specified field.

        Raises:
            FieldException: if no unit conversion object is present.
        """
        try:
            return self._uc[field]
        except KeyError:
            raise FieldException(
                f"No unit conversion option for field {field} on manager {self}."
            )
Beispiel #15
0
    def get_value(self, field, handle=None, throw=True):
        """Get the value for a field.

        Args:
            field (str): The requested field.
            handle (str, optional): Handle is not needed and is only here to
                                     conform with the structure of the
                                     DataSource base class.
            throw (bool, optional): If the check for completion of outstanding
                                     calculations times out, then:
                                     if True, raise a ControlSystemException;
                                     if False, log a warning and return the
                                     potentially out of date data anyway.

        Returns:
            float: The value of the specified field on this data source.

        Raises:
            FieldException: if the specified field does not exist.
            ControlSystemException: if the calculation completion check fails,
                                     and throw is True.
        """
        # Wait for any outstanding calculations to conclude, to ensure they are
        # complete before a value is returned; if the wait times out then raise
        # an error message or log a warning according to the value of throw.
        if not self._atsim.wait_for_calculations():
            error_msg = ("Check for completion of outstanding "
                         "calculations timed out.")
            if throw:
                raise ControlSystemException(error_msg)
            else:
                logging.warning("Potentially out of date data returned. " +
                                error_msg)
        # Again we assume that every set field has a corresponding get field.
        if field in self._fields:
            return self._get_field_funcs[field]()
        else:
            raise FieldException("No field {0} on AT element {1}."
                                 .format(field, self._at_element))
Beispiel #16
0
    def get_chromaticity(self, field=None):
        """Return the chromaticity for the AT lattice for the specified plane.

        Args:
            field (str): The desired field (x or y) of chromaticity, if None
                          return both chromaticity dimensions.

        Returns:
            float: The x or y chromaticity for the AT lattice.

        Raises:
            FieldException: if the specified field is not valid for
                             chromaticity.
        """
        if field is None:
            return self._lindata[2]
        elif field == 'x':
            return self._lindata[2][0]
        elif field == 'y':
            return self._lindata[2][1]
        else:
            raise FieldException("Field {0} is not a valid chromaticity "
                                 "plane.".format(field))
Beispiel #17
0
    def get_value(
        self,
        field,
        handle=pytac.RB,
        units=pytac.DEFAULT,
        data_source=pytac.DEFAULT,
        throw=True,
    ):
        """Get the value for a field.

        Returns the value of a field on the element. This value is uniquely
        identified by a field and a handle. The returned value is either
        in engineering or physics units. The data_source flag returns either
        real or simulated values.

        Args:
            field (str): The requested field.
            handle (str): pytac.SP or pytac.RB.
            units (str): pytac.ENG or pytac.PHYS returned.
            data_source (str): pytac.LIVE or pytac.SIM.
            throw (bool): On failure: if True, raise ControlSystemException; if
                           False, return None and log a warning.

        Returns:
            float: The value of the requested field

        Raises:
            DataSourceException: if there is no data source on the given field.
            FieldException: if the element does not have the specified field.
        """
        try:
            return self._data_source_manager.get_value(field, handle, units,
                                                       data_source, throw)
        except DataSourceException as e:
            raise DataSourceException(f"{self}: {e}")
        except FieldException as e:
            raise FieldException(f"{self}: {e}")