示例#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 _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))
示例#3
0
    def param_write(self, pv_name, value):
        """
        Write a parameter value from epics to the beamline.
        Args:
            pv_name: pv name
            value: value to set

        Returns:
            True if value was accepted by the system; False otherwise

        """
        value_accepted = True
        param_name, param_sort = self._pv_manager.get_param_name_and_sort_from_pv(
            pv_name)
        param = self._beamline.parameter(param_name)
        if param_sort == PvSort.ACTION and not param.is_disabled:
            param.move = 1
        elif param_sort == PvSort.SP and not param.is_disabled:
            param.sp = convert_from_epics_pv_value(
                param.parameter_type, value, self._pv_manager.PVDB[pv_name])
        elif param_sort == PvSort.SET_AND_NO_ACTION:
            param.sp_no_move = convert_from_epics_pv_value(
                param.parameter_type, value, self._pv_manager.PVDB[pv_name])
        elif param_sort == PvSort.DEFINE_POS_AS:
            param.define_current_value_as.new_value = convert_from_epics_pv_value(
                param.parameter_type, value, self._pv_manager.PVDB[pv_name])
        else:
            STATUS_MANAGER.update_error_log(
                "Error: PV {} is read only".format(pv_name))
            value_accepted = False
        return value_accepted
    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)))
示例#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]
示例#6
0
    def _initialise_mode(self, modes):
        """
        Tries to read and apply the last active mode from autosave file. Defaults to first mode in list if unsuccessful.

        Args:
            modes(list[BeamlineMode]): A list of all the modes in this configuration.
        """
        mode_name = mode_autosave.read_parameter(MODE_KEY, default=None)
        initial_mode = None
        try:
            initial_mode = self._modes[mode_name]

        except KeyError:
            STATUS_MANAGER.update_error_log(
                "Mode {} not found in configuration. Setting default.".format(
                    mode_name))
            if len(modes) > 0:
                initial_mode = modes[0]
            else:
                STATUS_MANAGER.update_error_log(
                    "No modes have been configured.")

        if initial_mode is not None:
            self._active_mode = initial_mode
            self.trigger_listeners(ActiveModeUpdate(self._active_mode))
示例#7
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 _block_until_pv_available(self):
     """
     Blocks the process until the PV this driver is pointing at is available.
     """
     while not self._ca.pv_exists(self._rbv_pv):
         STATUS_MANAGER.update_error_log(
             "{} does not exist. Check the PV is correct and the IOC is running. Retrying in {} s."
             .format(self._rbv_pv, RETRY_INTERVAL))
         time.sleep(RETRY_INTERVAL)
示例#10
0
 def active_mode(self):
     """
     Returns: the name of the current modes; None for no active mode
     """
     try:
         return self._active_mode.name
     except AttributeError:
         STATUS_MANAGER.update_error_log(
             "Error: No active beamline mode found.")
         return None
示例#11
0
 def move(self, _):
     """
     Move to all the beamline parameters in the mode or that have changed
     Args:
         _: dummy can be anything
     """
     STATUS_MANAGER.clear_all()
     if self.reinit_mode_on_move:
         self._init_params_from_mode()
     self._move_for_all_beamline_parameters()
示例#12
0
 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)
示例#13
0
    def _validate(self, beamline_parameters, modes, drivers):
        errors = []

        beamline_parameters_names = [
            beamline_parameter.name
            for beamline_parameter in beamline_parameters
        ]
        for name in beamline_parameters_names:
            if beamline_parameters_names.count(name) > 1:
                errors.append(
                    "Beamline parameters must be uniquely named. Duplicate '{}'"
                    .format(name))

        mode_names = [mode.name for mode in modes]
        for mode in mode_names:
            if mode_names.count(mode) > 1:
                errors.append(
                    "Mode must be uniquely named. Duplicate '{}'".format(mode))

        # Validate the order of long_axis and position
        axis_params = [
            param for param in beamline_parameters
            if isinstance(param, AxisParameter)
        ]
        axes_per_comp = defaultdict(list)
        [
            axes_per_comp[param.component.name].append(param.axis)
            for param in axis_params
        ]
        errors.extend(
            check_long_axis_before_position(axes_per_comp, "parameter"))

        axes_per_comp = defaultdict(list)
        [
            axes_per_comp[driver.component.name].append(driver.component_axis)
            for driver in drivers
        ]
        errors.extend(check_long_axis_before_position(axes_per_comp, "driver"))

        for mode in modes:
            errors.extend(mode.validate(self._beamline_parameters.keys()))

        for parameter in self._beamline_parameters.values():
            errors.extend(parameter.validate(self._drivers))

        if len(errors) > 0:
            STATUS_MANAGER.update_error_log(
                "Beamline configuration is invalid:\n    {}".format(
                    "\n    ".join(errors)))
            raise BeamlineConfigurationInvalidException(
                "Beamline configuration invalid: {}".format(";".join(errors)))
示例#14
0
 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))
示例#15
0
    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))
示例#16
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:
         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))
示例#17
0
    def _read_pv(self, pv):
        """
        Read the value from a given PV.

        Args:
            pv (String): The pv to read
        """
        value = self._ca.caget(pv)
        if value is not None:
            return value
        else:
            STATUS_MANAGER.update_error_log(
                "Could not connect to PV {}.".format(pv))
            raise UnableToConnectToPVException(
                pv, "Check configuration is correct and IOC is running.")
示例#18
0
    def _strip_source_pv(self, pv):
        """
        Extracts the direction key from a given pv.

        Params:
            pv (String): The source pv

        Returns: The direction key embedded within the pv
        """
        for key in self._directions:
            if key in pv:
                return key
        STATUS_MANAGER.update_error_log(
            "Wrapper for {} received event from unexpected source: {}".format(
                self.name, pv))
示例#19
0
    def get_from_parameter(self, parameter, pv_fields):
        """
        Get the value of the correct sort from a parameter
        Args:
            parameter(ReflectometryServer.parameters.BeamlineParameter): the parameter to get the value from
            pv_fields: values that the pv can take if

        Returns: the value of the parameter of the correct sort and their alarms
        """
        severity = AlarmSeverity.No
        status = AlarmStatus.No
        if self == PvSort.SP:
            value, severity, status = _convert_to_epics_pv_value(
                parameter.parameter_type, parameter.sp, AlarmSeverity.No,
                AlarmStatus.No, pv_fields)
        elif self == PvSort.SP_RBV:
            value, severity, status = _convert_to_epics_pv_value(
                parameter.parameter_type, parameter.sp_rbv, AlarmSeverity.No,
                AlarmStatus.No, pv_fields)
        elif self == PvSort.RBV:
            value, severity, status = _convert_to_epics_pv_value(
                parameter.parameter_type, parameter.rbv,
                parameter.alarm_severity, parameter.alarm_status, pv_fields)
        elif self == PvSort.SET_AND_NO_ACTION:
            value, severity, status = _convert_to_epics_pv_value(
                parameter.parameter_type, parameter.sp_no_move,
                AlarmSeverity.No, AlarmStatus.No, pv_fields)
        elif self == PvSort.CHANGED:
            value = parameter.sp_changed
        elif self == PvSort.ACTION:
            value = parameter.move
        elif self == PvSort.CHANGING:
            value = parameter.is_changing
        elif self == PvSort.RBV_AT_SP:
            value = parameter.rbv_at_sp
        elif self == PvSort.DEFINE_POS_AS:
            if parameter.define_current_value_as is None:
                value, severity, status = float(
                    "NaN"), AlarmSeverity.Invalid, AlarmStatus.UDF
            else:
                value = parameter.define_current_value_as.new_value
        else:
            value, severity, status = float(
                "NaN"), AlarmSeverity.Invalid, AlarmStatus.UDF
            STATUS_MANAGER.update_error_log(
                "PVSort not understood {}".format(PvSort))

        return value, severity, status
示例#20
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
示例#22
0
    def _monitor_pv(self, pv, call_back_function):
        """
        Adds a monitor function to a given PV.

        Args:
            pv (String): The pv to monitor
            call_back_function: The function to execute on a pv value change
        """
        while True:
            if self._ca.pv_exists(pv):
                self._ca.add_monitor(pv, call_back_function)
                logger.debug("Monitoring {} for changes.".format(pv))
                break
            else:
                STATUS_MANAGER.update_error_log(
                    "Error adding monitor to {}: PV does not exist. Check the PV is correct and the IOC is running. "
                    "Retrying in {} s.".format(pv, RETRY_INTERVAL))
                time.sleep(RETRY_INTERVAL)
示例#23
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
示例#24
0
def _convert_to_epics_pv_value(parameter_type: BeamlineParameterType,
                               value: Union[float, int, str, bool],
                               alarm_severity: AlarmSeverity,
                               alarm_status: AlarmStatus, pv_fields: Dict):
    """
    Convert from parameter value to the epic pv value
    Args:
        parameter_type: parameters type
        value: value to convert
        alarm_severity: alarm severity
        alarm_status: alarm status
        pv_fields: pv fields for the pv, e.g. used for options on en enum field

    Returns: epics value and alarms

    """
    if alarm_status is None:
        status = alarm_status
    else:
        status = min(MAX_ALARM_ID, alarm_status)
    severity = alarm_severity
    if parameter_type == BeamlineParameterType.IN_OUT:
        if value:
            pv_value = OUT_IN_ENUM_TEXT.index("IN")
        else:
            pv_value = OUT_IN_ENUM_TEXT.index("OUT")
    elif parameter_type == BeamlineParameterType.ENUM:
        try:
            pv_value = pv_fields.get("enums", None).index(value)
        except ValueError:
            pv_value = -1
            status = AlarmStatus.State
            severity = AlarmSeverity.Invalid
            STATUS_MANAGER.update_error_log(
                "Value set of parameter which is not in pv options {}".format(
                    value))
    else:
        if value is None:
            pv_value = float("NaN")
        else:
            pv_value = value
    return pv_value, severity, status
示例#25
0
    def _move_for_single_beamline_parameters(self, request: RequestMoveEvent):
        """
        Moves starts from a single beamline parameter and move is to parameters sp read backs. If the
        request source is not in the mode then don't update any other parameters. Move to latest position.

        Args:
            request: request to move a single parameter; if source is None start from the beginning,
                otherwise start from source
        """
        STATUS_MANAGER.clear_all()
        logger.info("PARAMETER MOVE TRIGGERED (source: {})".format(
            request.source.name))
        if self._active_mode.has_beamline_parameter(request.source):
            parameters = self._beamline_parameters.values()
            parameters_in_mode = self._active_mode.get_parameters_in_mode(
                parameters, request.source)

            for beamline_parameter in parameters_in_mode:
                beamline_parameter.move_to_sp_rbv_no_callback()
        self._move_drivers()
示例#26
0
    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)
示例#27
0
    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)
示例#28
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()
示例#29
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))
示例#30
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)