Exemple #1
0
    def _on_at_parking_sequence_position(
            self, parking_sequence_update: ParkingSequenceUpdate):
        """
        If reached a sequence position then move sequence set point on to next position

        Only move if sequence reported agrees with sequence this manager set and haven't already reached the end of the
        sequence.

        Args:
            parking_sequence_update: update indicating that a parking sequence has ended
        """
        if parking_sequence_update.parking_sequence == self.parking_index and self._parking_sequence_started:
            if self.get_is_in_beam():
                # axes are unparking
                if self.parking_index == 0:
                    self._move_axis_to(None)
                elif self.parking_index is not None:
                    self._move_axis_to(self.parking_index - 1)
                else:
                    self._parking_sequence_started = False
            else:
                # axes are parking
                if self.parking_index is None:
                    STATUS_MANAGER.update_error_log(
                        "Parking sequence error - the parking index is None but we are "
                        "parking the axis, this should not be possible")
                    STATUS_MANAGER.update_active_problems(
                        ProblemInfo(
                            "Next park sequence triggered but manager is in beam (report error)",
                            "InBeamManager", AlarmSeverity.MINOR_ALARM))
                if self.parking_index + 1 < self._maximum_sequence_count:
                    self._move_axis_to(self.parking_index + 1)
                else:
                    self._parking_sequence_started = False
    def restore_pre_move_velocity(self):
        """
        Restore the cached axis velocity.

        Restore the cached axis velocity from the value stored on the server and update the restored cache status.
        """
        if self._velocity_restored:
            STATUS_MANAGER.update_error_log(
                "Velocity for {pv_name} has not been restored from cache. The cache has already been "
                "restored previously. Hint: Are you moving the axis outside of the reflectometry server?"
                .format(pv_name=self.name))
        else:
            if self._velocity_to_restore is None:
                STATUS_MANAGER.update_error_log(
                    "Cannot restore velocity: velocity cache is None for {pv_name}"
                    .format(pv_name=self.name))
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Unable to restore axis velocity", self.name,
                                Severity.MINOR_ALARM))
            else:
                logger.debug(
                    "Restoring velocity cache of {value} for {pv_name}".format(
                        value=self._velocity_to_restore, pv_name=self.name))
                self._write_pv(self._velo_pv, self._velocity_to_restore)
            self._velocity_restored = True
            velocity_bool_autosave.write_parameter(
                self.name + "_velocity_restored", self._velocity_restored)
    def _init_velocity_cache(self):
        """
        Initialise the velocity cache for the current axis.

        Initialise the velocity cache and its restored status. If no cache exists then load the last velocity value
        from the auto-save file.
        """
        autosave_value = velocity_float_autosave.read_parameter(
            self.name, None)
        if autosave_value is not None:
            logger.debug(
                "Restoring {pv_name} velocity_cache with auto-save value {value}"
                .format(pv_name=self.name, value=autosave_value))
            self._velocity_to_restore = autosave_value
        else:
            logger.error(
                "Error: Unable to initialise velocity cache from auto-save for {}."
                .format(self.name))

        if autosave_value is not None:
            autosave_value = velocity_bool_autosave.read_parameter(
                self.name + "_velocity_restored", None)
            if autosave_value is not None:
                logger.debug(
                    "Restoring {pv_name} velocity_restored with auto-save value {value}"
                    .format(pv_name=self.name, value=autosave_value))
                self._velocity_restored = autosave_value
            else:
                STATUS_MANAGER.update_error_log(
                    "Error: Unable to initialise velocity_restored flag from auto-save for {}."
                    .format(self.name))
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo(
                        "Unable to read autosaved velocity_restored flag",
                        self.name, Severity.MINOR_ALARM))
    def _add_all_parameter_pvs(self):
        """
        Add PVs for each beamline parameter in the reflectometry configuration to the server's PV database.
        """
        param_info = {}
        for group in BeamlineParameterGroup:
            param_info[group] = []
        align_info = []
        for parameter in self._beamline.parameters.values():
            try:
                param_info_record = self._add_parameter_pvs(parameter)
                if param_info_record is not None:
                    for group in parameter.group_names:
                        param_info[group].append(param_info_record)
                    if parameter.define_current_value_as is not None:
                        align_info_record = {
                            "name": param_info_record["name"],
                            "prepended_alias": param_info_record["prepended_alias"],
                            "type": "align",
                            "description": ""
                        }
                        align_info.append(align_info_record)

            except Exception as err:
                STATUS_MANAGER.update_error_log("Error adding PV for parameter {}: {}".format(parameter.name, err), err)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Error adding parameter PV", parameter.name, Severity.MAJOR_ALARM))

        for param_group in BeamlineParameterGroup:
            self._add_pv_with_fields(PARAM_INFO_LOOKUP[param_group], None, STANDARD_2048_CHAR_WF_FIELDS,
                                     BeamlineParameterGroup.description(param_group), None,
                                     value=compress_and_hex(json.dumps(param_info[param_group])))

        self._add_pv_with_fields(ALIGN_INFO, None, STANDARD_2048_CHAR_WF_FIELDS, "All alignment pvs information",
                                 None, value=compress_and_hex(json.dumps(align_info)))
Exemple #5
0
    def correction(self, setpoint):
        """
        Correction as interpolated from the grid data provided
        Args:
            setpoint: setpoint to use to calculate correction
        Returns: the correction calculated using the grid data.
        """
        self.set_point_value_as_parameter.sp_rbv = setpoint
        evaluation_point = [
            param.sp_rbv for param in self._beamline_parameters
        ]
        if None in evaluation_point:
            non_initialised_params = [
                param.name for param in self._beamline_parameters
                if param.sp_rbv is None
            ]
            STATUS_MANAGER.update_error_log(
                "Engineering correction, '{}', evaluated for non-autosaved value, {}"
                .format(self.description, non_initialised_params))
            STATUS_MANAGER.update_active_problems(
                ProblemInfo(
                    "Engineering correction evaluated for non-autosaved value",
                    self.description, Severity.MINOR_ALARM))

            interpolated_value = [0.0]
        else:
            interpolated_value = griddata(self._grid_data_provider.points,
                                          self._grid_data_provider.corrections,
                                          evaluation_point, 'linear',
                                          self._default_correction)
        return interpolated_value[0]
Exemple #6
0
def optional_is_set(optional_id, macros):
    """
    Check whether an optional macro for use in the configuration is set or not.

    Args:
        optional_id (String): The ID of the optional macro
        macros (dict): The macro values passed into the reflectometry server

    Returns: True if macro with given ID is set to True, otherwise False
    """
    try:
        macro_name = "OPTIONAL_{}".format(optional_id)
        macro_value = macros[macro_name]
        if macro_value.lower() == "true":
            return True
        elif macro_value.lower() == "false":
            return False
        else:
            STATUS_MANAGER.update_error_log(
                ("Invalid value for IOC macro {}: {} (Expected: True/False)".format(macro_name, macro_value)))
            STATUS_MANAGER.update_active_problems(
                ProblemInfo("Invalid IOC macro value", macro_name, Severity.MINOR_ALARM))
            return False
    except KeyError:
        return False
 def _log_autosave_type_error(self):
     """
     Logs an error that the autosave value this parameter was trying to read was of the wrong type.
     """
     STATUS_MANAGER.update_error_log(
         "Could not read autosave value for parameter {}: unexpected type.".format(self.name))
     STATUS_MANAGER.update_active_problems(ProblemInfo("Parameter autosave value has unexpected type", self.name,
                                           Severity.MINOR_ALARM))
 def _check_and_move_component(self):
     """
     Checks whether this parameter is initialised and moves the underlying component to its setpoint if so.
     """
     if self._set_point_rbv is not None:
         self._move_component()
     else:
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("No parameter initialization value found", self.name, Severity.MAJOR_ALARM))
         raise ParameterNotInitializedException(self.name)
    def velocity(self, value):
        """
        Writes a value to the underlying velocity PV's VAL field.

        Args:
            value (float): The value to set
        """
        STATUS_MANAGER.update_error_log(
            "Error: An attempt was made to write a velocity to a Jaws Axis. We do not "
            "support this as we do not expect jaws to be synchronised.")
        STATUS_MANAGER.update_active_problems(
            ProblemInfo(
                "Drivers for Jaws axes should not be synchronised. Check configuration",
                self.name, Severity.MINOR_ALARM))
 def _set_motor_moving_pv(self, value):
     """
     Set/clear the motor is moving pv to indicate we are calculating the readback value
     Args:
         value: value to set it to. 1 is moving, 0 not moving
     """
     try:
         ChannelAccess.caput(MOTOR_MOVING_PV, value, safe_not_quick=False)
     except Exception as e:
         STATUS_MANAGER.update_error_log(
             "Failed to set motor moving pv: {}".format(e), e)
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("Failed to update motor moving pv", "pv_wrapper",
                         Severity.MAJOR_ALARM))
 def define_position_as(self, new_position):
     """
     Set the current position in the underlying hardware as the new position without moving anything
     Args:
         new_position: position to move to
     """
     try:
         with motor_in_set_mode(self._prefixed_pv):
             self._write_pv_with_retry(self._sp_pv, new_position)
     except ValueError as ex:
         STATUS_MANAGER.update_error_log(
             "Can not define zero: {}".format(ex), ex)
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("Failed to redefine position", self.name,
                         Severity.MINOR_ALARM))
Exemple #12
0
    def read(self, reason):
        """
        Processes an incoming caget request.

        Args:
            reason (str): The PV that is being read.

        Returns: The value associated to this PV
        """
        try:
            if self._initialised:
                if self._pv_manager.is_param(reason):
                    return self.getParam(reason)

                elif self._pv_manager.is_beamline_mode(reason):
                    return self._beamline_mode_value(self._beamline.active_mode)

                elif is_pv_name_this_field(BEAMLINE_MOVE, reason):
                    return self._beamline.move

                elif is_pv_name_this_field(REAPPLY_MODE_INITS, reason):
                    return self._beamline.reinit_mode_on_move

                elif is_pv_name_this_field(SERVER_STATUS, reason):
                    beamline_status_enums = self._pv_manager.PVDB[SERVER_STATUS]["enums"]
                    new_value = beamline_status_enums.index(STATUS_MANAGER.status.display_string)
                    #  Set the value so that the error condition is set
                    self.setParam(reason, new_value)
                    return new_value

                elif is_pv_name_this_field(SERVER_MESSAGE, reason):
                    return STATUS_MANAGER.message
                elif is_pv_name_this_field(SERVER_ERROR_LOG, reason):
                    return STATUS_MANAGER.error_log
                elif is_pv_name_this_field(SAMPLE_LENGTH, reason):
                    return self._footprint_manager.get_sample_length()
                elif self._pv_manager.is_alarm_status(reason):
                    return self.getParamDB(self._pv_manager.strip_fields_from_pv(reason)).alarm
                elif self._pv_manager.is_alarm_severity(reason):
                    return self.getParamDB(self._pv_manager.strip_fields_from_pv(reason)).severity
        except Exception as e:
            STATUS_MANAGER.update_error_log("Exception when reading parameter {}".format(reason), e)
            STATUS_MANAGER.update_active_problems(
                ProblemInfo("PV Value read caused exception.", reason, Severity.MAJOR_ALARM))
            return

        return self.getParam(reason)
def _create_beamline_in_error(error_message):
    """
    Args:
        error_message: error message to set for beamline
    Returns: a blank beamline with an error status set

    """
    error_mode = BeamlineMode("No modes", [])
    beamline = Beamline([], [], [], [error_mode])
    try:
        STATUS_MANAGER.update_active_problems(
            ProblemInfo(
                "Error reading configuration: {}".format(error_message),
                "Configuration", Severity.MAJOR_ALARM))
    except Exception as e:
        print(e)
    return beamline
Exemple #14
0
    def _get_component_sp_and_is_to_from_parking(
            self, for_correction=False) -> Tuple[Optional[float], bool]:
        """
        Args:
            for_correction (bool): Setpoint is for engineering correction

        Returns:
            position that the set point axis is set to or None if it should not move because it is in a parking
                sequence with a None in it
            whether the movement is from or to a park position
        """
        if not self.component.beam_path_set_point.axis[self.component_axis].is_in_beam \
                and self._out_of_beam_lookup is None:
            STATUS_MANAGER.update_error_log(
                "An axis for component {} is set to out of beam but there is no out of beam position defined "
                "for the driver for the associated motor axis {}".format(
                    self.component.name, self._motor_axis.name))
            STATUS_MANAGER.update_active_problems(
                ProblemInfo("No out of beam position defined for motor_axis",
                            self.name, Severity.MINOR_ALARM))

        parking_index = self.component.beam_path_set_point.in_beam_manager.parking_index
        if parking_index is None or self._out_of_beam_lookup is None:
            displacement = self.component.beam_path_set_point.axis[
                self.component_axis].get_displacement()
            is_to_from_park = not self.component.beam_path_rbv.axis[
                self.component_axis].is_in_beam
        else:
            is_to_from_park = True
            beam_interception = self.component.beam_path_set_point.calculate_beam_interception(
            )

            out_of_beam_position = self._out_of_beam_lookup.get_position_for_intercept(
                beam_interception)

            if out_of_beam_position.is_offset:
                displacement = self.component.beam_path_set_point.axis[self.component_axis].\
                    get_displacement_for(out_of_beam_position.get_sequence_position(parking_index))
            else:
                displacement = out_of_beam_position.get_sequence_position(
                    parking_index)
            if displacement is None and for_correction:
                displacement = out_of_beam_position.get_final_position()
        return displacement, is_to_from_park
 def _run_custom_function(self, new_sp, original_sp):
     """
     Run the users custom function attached to this parameter
     Args:
         new_sp: the setpoint that has just been set
         original_sp: the value of the setpoint before the move was called
     """
     logger.debug(f"Running custom function on parameter {self.name} ...")
     try:
         message = self._custom_function(new_sp, original_sp)
         logger.debug(f"... Finished running custom function on parameter {self.name} it returned: {message}")
         if message is not None:
             STATUS_MANAGER.update_error_log(f"Custom function on parameter {self.name} returned: {message}")
             STATUS_MANAGER.update_active_problems(
                 ProblemInfo(f"Custom function returned: {message}", self.name, Severity.NO_ALARM))
     except Exception as ex:
         STATUS_MANAGER.update_error_log(f"Custom function on parameter {self.name} failed with {ex}")
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("Custom function on parameter failed.", self.name, Severity.MAJOR_ALARM))
    def _initialise_sp_from_motor(self, _):
        """
        Get the setpoint value for this parameter based on the motor setpoint position.
        """
        if not self.component.beam_path_set_point.in_beam_manager.get_is_in_beam():
            autosave_val = self.component.beam_path_set_point.axis[self.axis].autosaved_value
            if autosave_val is not None:
                init_sp = autosave_val
            else:
                # If the axis is out of the beam and there is not autosave the displacement should be set to 0
                init_sp = 0.0
                STATUS_MANAGER.update_error_log("Parameter {} is parkable so should have an autosave value but "
                                                "doesn't. Has been set to 0 check its value".format(self.name))
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Parameter has no autosave value", self.name, Severity.MAJOR_ALARM))
            self.component.beam_path_set_point.axis[self.axis].set_relative_to_beam(init_sp)
        else:
            init_sp = self.component.beam_path_set_point.axis[self.axis].get_relative_to_beam()

        self._set_initial_sp(init_sp)
Exemple #17
0
 def _move_drivers(self):
     """
     Issue move for all drivers at the speed of the slowest axis and set appropriate status for failure/success.
     """
     try:
         self._perform_move_for_all_drivers(self._get_max_move_duration())
     except ZeroDivisionError as e:
         STATUS_MANAGER.update_error_log(
             "Failed to perform beamline move: {}".format(e), e)
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("Failed to move driver", "beamline",
                         Severity.MAJOR_ALARM))
         return
     except (ValueError, UnableToConnectToPVException) as e:
         STATUS_MANAGER.update_error_log(
             "Unable to connect to PV: {}".format(str(e)))
         STATUS_MANAGER.update_active_problems(
             ProblemInfo("Unable to connect to PV", "beamline",
                         Severity.MAJOR_ALARM))
         return
Exemple #18
0
    def write(self, reason, value):
        """
        Process an incoming channel_access request.
        :param reason: The PV that is being written to.
        :param value: The value being written to the PV
        """
        value_accepted = True
        try:
            if self._pv_manager.is_param(reason):
                value_accepted = self._driver_help.param_write(reason, value)
            elif is_pv_name_this_field(BEAMLINE_MOVE, reason):
                self._beamline.move = 1
            elif is_pv_name_this_field(REAPPLY_MODE_INITS, reason):
                self._beamline.reinit_mode_on_move = value
            elif self._pv_manager.is_beamline_mode(reason):
                try:
                    beamline_mode_enums = self._pv_manager.PVDB[BEAMLINE_MODE]["enums"]
                    new_mode_name = beamline_mode_enums[value]
                    self._beamline.active_mode = new_mode_name
                except ValueError:
                    STATUS_MANAGER.update_error_log("Invalid value entered for mode. (Possible modes: {})".format(
                        ",".join(self._beamline.mode_names)))
                    value_accepted = False
            elif is_pv_name_this_field(SAMPLE_LENGTH, reason):
                self._footprint_manager.set_sample_length(value)
            else:
                STATUS_MANAGER.update_error_log("Error: PV is read only")
                value_accepted = False

            if value_accepted:
                pv_name = "{}{}".format(REFLECTOMETRY_PREFIX, reason)
                self.put_log.write_pv_put(pv_name, value, self.getParam(reason))
                self._update_param_both_pv_and_pv_val(reason, value)
                self.update_monitors()
        except Exception as e:
            STATUS_MANAGER.update_error_log("PV Value {} for PV {} rejected by server: {}".format(value, reason, e), e)
            STATUS_MANAGER.update_active_problems(ProblemInfo("PV Value rejected by server.", reason,
                                                              Severity.MINOR_ALARM))
            value_accepted = False
        return value_accepted
Exemple #19
0
    def _move_for_all_beamline_parameters(self):
        """
        Updates the beamline parameters to the latest set point value; reapplies if they are in the mode. Then moves to
        latest positions.
        """
        logger.info("BEAMLINE MOVE TRIGGERED")
        parameters = self._beamline_parameters.values()
        parameters_in_mode = self._active_mode.get_parameters_in_mode(
            parameters, None)

        for beamline_parameter in parameters:
            if beamline_parameter in parameters_in_mode or beamline_parameter.sp_changed:
                try:
                    beamline_parameter.move_to_sp_no_callback()
                except ParameterNotInitializedException:
                    STATUS_MANAGER.update_active_problems(
                        ProblemInfo(
                            "Parameter not initialized. Is the configuration correct?",
                            beamline_parameter.name, Severity.MAJOR_ALARM))
                    return

        self._move_drivers()
    def _add_constants_pvs(self):
        """
        Add pvs for the beamline constants
        """

        beamline_constant_info = []

        for beamline_constant in self._beamline.beamline_constants:
            try:
                const_alias = create_pv_name(beamline_constant.name, list(self.PVDB.keys()), CONST_PREFIX,
                                             limit=20, allow_colon=True)
                prepended_alias = "{}:{}".format(CONST_PREFIX, const_alias)

                if isinstance(beamline_constant.value, bool):
                    value = 1 if bool(beamline_constant.value) else 0
                    fields = PARAM_FIELDS_BINARY
                elif isinstance(beamline_constant.value, str):
                    value = beamline_constant.value
                    fields = STANDARD_2048_CHAR_WF_FIELDS
                else:
                    value = float(beamline_constant.value)
                    fields = STANDARD_FLOAT_PV_FIELDS

                self._add_pv_with_fields(prepended_alias, None, fields, beamline_constant.description, None,
                                         interest="MEDIUM", value=value)
                logger.info("Adding Constant {} with value {}".format(beamline_constant.name, beamline_constant.value))
                beamline_constant_info.append(
                    {"name": beamline_constant.name,
                     "prepended_alias": prepended_alias,
                     "type": "float_value",
                     "description": beamline_constant.description})
            except Exception as err:
                STATUS_MANAGER.update_error_log("Error adding constant {}: {}".format(beamline_constant.name, err), err)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Error adding PV for beamline constant", beamline_constant.name, Severity.MAJOR_ALARM))

        self._add_pv_with_fields(BEAMLINE_CONSTANT_INFO, None, STANDARD_2048_CHAR_WF_FIELDS, "All value parameters",
                                 None, value=compress_and_hex(json.dumps(beamline_constant_info)))
Exemple #21
0
    def on_define_position(self, define_position: DefineValueAsEvent):
        """
        When a define position happens on the rbv control parameters take it and apply it to the motor axes after
        transforming the parameters by getting their readback values and setting the newly set parameter.
        Args:
            define_position: the position defined for the axis
        """
        rbv_axis = self.beam_path_rbv.axis
        height, pivot_angle, seesaw = self._calculate_motor_rbvs(rbv_axis)

        change_axis = define_position.change_axis
        if change_axis == self._position_axis:
            height = define_position.new_position

        elif change_axis == self._angle_axis:
            pivot_angle = define_position.new_position

        elif change_axis == ChangeAxis.SEESAW:
            seesaw = define_position.new_position

        else:
            STATUS_MANAGER.update_error_log(
                "Define on bench using axis {} is not allowed".format(
                    change_axis))
            STATUS_MANAGER.update_active_problems(
                ProblemInfo("Invalid bench update axis", self.name,
                            Severity.MINOR_ALARM))

        front_jack_height, rear_jack_height, horizontal_position = \
            self._calculate_motor_positions(height, pivot_angle, seesaw)

        rbv_axis[ChangeAxis.JACK_FRONT].define_axis_position_as(
            front_jack_height)
        rbv_axis[ChangeAxis.JACK_REAR].define_axis_position_as(
            rear_jack_height)
        if change_axis is not self._position_axis:
            rbv_axis[ChangeAxis.SLIDE].define_axis_position_as(
                horizontal_position)
Exemple #22
0
    def correction(self, setpoint):
        """
        Correction as calculated by the provided user function.
        Args:
            setpoint: setpoint to use to calculate correction
        Returns: the correction calculated using the users function.
        """
        try:
            return self._user_correction_function(
                setpoint,
                *[param.sp_rbv for param in self._beamline_parameters])
        except Exception as ex:
            if setpoint is None or None in [
                    param.sp_rbv for param in self._beamline_parameters
            ]:
                non_initialised_params = [
                    param.name for param in self._beamline_parameters
                    if param.sp_rbv is None
                ]
                STATUS_MANAGER.update_error_log(
                    "Engineering correction, '{}', raised exception '{}' is this because you have not coped with "
                    "non-autosaved value, {}".format(self.description, ex,
                                                     non_initialised_params),
                    ex)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo(
                        "Invalid engineering correction (uses non autosaved value?)",
                        self.description, Severity.MINOR_ALARM))

            else:
                STATUS_MANAGER.update_error_log(
                    "Engineering correction, '{}', raised exception '{}' ".
                    format(self.description, ex), ex)
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Engineering correction throws exception",
                                self.description, Severity.MINOR_ALARM))

        return 0
    def define_position_as(self, new_position):
        """
        Set the current position in the underlying hardware as the new position without moving anything
        Args:
            new_position: position to move to
        """
        try:
            mtr1, mtr2 = self._pv_names_for_directions("MTR")
            logger.info(
                "Defining position for axis {name} to {corrected_value}. "
                "From sp {sp} and rbv {rbv}.".format(
                    name=self.name,
                    corrected_value=new_position,
                    sp=self.sp,
                    rbv=self.rbv))
            for motor in self._pv_names_for_directions("MTR"):
                rbv = self._read_pv("{}.RBV".format(motor))
                sp = self._read_pv("{}".format(motor))
                logger.info(
                    "    Motor {name} initially at rbv {rbv} sp {sp}".format(
                        name=motor, rbv=rbv, sp=sp))

            with motor_in_set_mode(mtr1), motor_in_set_mode(mtr2):
                # Ensure the position has been redefined before leaving the "Set" context, otherwise the motor moves
                self._write_pv_with_retry(self._sp_pv, new_position)

            for motor in self._pv_names_for_directions("MTR"):
                rbv = self._read_pv("{}.RBV".format(motor))
                sp = self._read_pv("{}".format(motor))
                logger.info(
                    "    Motor {name} moved to rbv {rbv} sp {sp}".format(
                        name=motor, rbv=rbv, sp=sp))
        except ValueError as ex:
            STATUS_MANAGER.update_error_log(
                "Can not define zero: {}".format(ex), ex)
            STATUS_MANAGER.update_active_problems(
                ProblemInfo("Failed to redefine position", self.name,
                            Severity.MAJOR_ALARM))
 def _initialise_sp_from_motor(self, _):
     # Optional parameters should always be autosaved and should not be initialised from the motor there is no code
     # to perform this operation so this is a major error if triggered.
     STATUS_MANAGER.update_error_log("Optional parameter, {}, was asked up init from motor".format(self.name))
     STATUS_MANAGER.update_active_problems(ProblemInfo("Optional Parameter updating from motor", self.name,
                                                       Severity.MAJOR_ALARM))
Exemple #25
0
    def __init__(
            self,
            component: 'Component',
            component_axis: ChangeAxis,
            motor_axis: PVWrapper,
            out_of_beam_positions: Optional[List[OutOfBeamPosition]] = None,
            synchronised: bool = True,
            engineering_correction: Optional[EngineeringCorrection] = None,
            pv_wrapper_for_parameter: Optional[PVWrapperForParameter] = None):
        """
        Drive the IOC based on a component
        Args:
            component: Component for IOC driver
            motor_axis: The PV that this driver controls.
            out_of_beam_positions: Provides the out of beam status as configured for this pv_wrapper.
            synchronised: If True then axes will set their velocities so they arrive at the end point at the same
                time; if false they will move at their current speed.
            engineering_correction: the engineering correction to apply to the value from the component before it is
                sent to the pv. None for no correction
            pv_wrapper_for_parameter: change the pv wrapper based on the value of a parameter
        """
        self.component = component
        self.component_axis = component_axis
        self._default_motor_axis = motor_axis
        self._motor_axis = None
        self._set_motor_axis(motor_axis, False)
        self._pv_wrapper_for_parameter = pv_wrapper_for_parameter
        if pv_wrapper_for_parameter is not None:
            pv_wrapper_for_parameter.parameter.add_listener(
                ParameterSetpointReadbackUpdate, self._on_parameter_update)

        if out_of_beam_positions is None:
            self._out_of_beam_lookup = None
        else:
            try:
                self._out_of_beam_lookup = OutOfBeamLookup(
                    out_of_beam_positions)
                self.component.beam_path_rbv.axis[component_axis].park_sequence_count = \
                    self._out_of_beam_lookup.get_max_sequence_count()
                self.component.beam_path_set_point.axis[component_axis].park_sequence_count = \
                    self._out_of_beam_lookup.get_max_sequence_count()
                self.component.beam_path_set_point.axis[
                    component_axis].add_listener(
                        ParkingSequenceUpdate, self._move_to_parking_sequence)
            except ValueError as e:
                STATUS_MANAGER.update_error_log(str(e))
                STATUS_MANAGER.update_active_problems(
                    ProblemInfo("Invalid Out Of Beam Positions", self.name,
                                Severity.MINOR_ALARM))

        self._synchronised = synchronised
        if engineering_correction is None:
            self._engineering_correction = NoCorrection()
            self.has_engineering_correction = False
        else:
            self.has_engineering_correction = True
            self._engineering_correction = engineering_correction
            self._engineering_correction.add_listener(
                CorrectionUpdate, self._on_correction_update)
            self._engineering_correction.add_listener(
                CorrectionRecalculate, self._retrigger_motor_axis_updates)

        self._sp_cache = None
        self._rbv_cache = self._engineering_correction.from_axis(
            self._motor_axis.rbv, self._get_component_sp(True))

        self.component.beam_path_rbv.axis[component_axis].add_listener(
            DefineValueAsEvent, self._on_define_value_as)