malcolm.modules.pmac.parts

class malcolm.modules.pmac.parts.BeamSelectorPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'), selector_axis: Anno(name='ASelectorAxis', typ=<class 'str'>, description='Name of the selector axis scannable'), imaging_angle: Anno(name='ATomoAngle', typ=<class 'float'>, description='Angle of for the tomography detector position'), diffraction_angle: Anno(name='ADiffAngle', typ=<class 'float'>, description='Angle of the diffraction detector position'), imaging_detector: Anno(name='ATomoDetector', typ=<class 'str'>, description='Name of the tomography detector (should match DetectorChildPart)'), diffraction_detector: Anno(name='ADiffDetector', typ=<class 'str'>, description='Name of the diffraction detector (should match DetectorChildPart)'), move_time: Anno(name='AMoveTime', typ=<class 'float'>, description='Minimum move time between the two positions in seconds'), initial_visibility: Anno(name='AInitialVisibility', typ=<class 'bool'>, description='Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block') = False)[source]

This part is for the K11 beam selector scan.

It moves a motor between two positions, holding at each position for the exposure time of a particular detector before moving.

Parameters
  • name (str) – The name of the Part within the Controller

  • mri (str) – Malcolm resource id of child object

  • selector_axis (str) – Name of the selector axis scannable

  • imaging_angle (float) – Angle of for the tomography detector position

  • diffraction_angle (float) – Angle of the diffraction detector position

  • imaging_detector (str) – Name of the tomography detector (should match DetectorChildPart)

  • diffraction_detector (str) – Name of the diffraction detector (should match DetectorChildPart)

  • move_time (float) – Minimum move time between the two positions in seconds

  • initial_visibility (bool) – Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block

on_validate(generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), detectors: Anno(name='ADetectorTable', typ=<class 'malcolm.modules.scanning.util.DetectorTable'>, description='The detectors that should be active and their exposures')) Optional[Union[Anno(name='AParameterTweakInfos', typ=<class 'malcolm.modules.scanning.infos.ParameterTweakInfo'>, description='Parameters that need to be changed to make them compatible'), Sequence[malcolm.modules.scanning.infos.ParameterTweakInfo], malcolm.modules.scanning.infos.ParameterTweakInfo]][source]
Parameters
  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • part_info – The Infos returned from other Parts

  • detectors (DetectorTable) – The detectors that should be active and their exposures

Returns

Parameters that need to be changed to make them compatible

Return type

ParameterTweakInfo

on_configure(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), completed_steps: Anno(name='ACompletedSteps', typ=<class 'int'>, description='Number of steps already completed'), steps_to_do: Anno(name='AStepsToDo', typ=<class 'int'>, description='Number of steps we should configure for'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), detectors: Anno(name='ADetectorTable', typ=<class 'malcolm.modules.scanning.util.DetectorTable'>, description='The detectors that should be active and their exposures'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved')) None[source]
Parameters
  • context (Context) – Context that should be used to perform operations on child blocks

  • completed_steps (int) – Number of steps already completed

  • steps_to_do (int) – Number of steps we should configure for

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • detectors (DetectorTable) – The detectors that should be active and their exposures

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

class malcolm.modules.pmac.parts.CSPart(mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'), cs: Anno(name='ACS', typ=<class 'int'>, description='Co-ordinate system number'))[source]
Parameters
  • mri (str) – Malcolm resource id of child object

  • cs (int) – Co-ordinate system number

report_status(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) Optional[Union[Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts'), Sequence[malcolm.core.info.Info], malcolm.core.info.Info]][source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

Returns

Infos about current Part status to be passed to other parts

Return type

Info

on_init(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

move(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), a: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, b: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, c: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, u: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, v: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, w: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, x: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, y: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, z: Optional[Anno(name='ADemandPosition', typ=<class 'float'>, description='Motor position to move to in EGUs')] = None, moveTime: Anno(name='AMoveTime', typ=<class 'float'>, description='Time to take to perform move in seconds') = 0) None[source]

Move the given CS axes using a deferred co-ordinated move

Parameters
  • context (Context) – Context that should be used to perform operations on child blocks

  • a (float) – Motor position to move to in EGUs

  • b (float) – Motor position to move to in EGUs

  • c (float) – Motor position to move to in EGUs

  • u (float) – Motor position to move to in EGUs

  • v (float) – Motor position to move to in EGUs

  • w (float) – Motor position to move to in EGUs

  • x (float) – Motor position to move to in EGUs

  • y (float) – Motor position to move to in EGUs

  • z (float) – Motor position to move to in EGUs

  • moveTime (float) – Time to take to perform move in seconds

class malcolm.modules.pmac.parts.CSSourcePortsPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), rbv: Anno(name='ARbv', typ=<class 'str'>, description='Override for rbv'), group: Optional[Anno(name='AGroup', typ=<class 'str'>, description='If given, which GUI group should we attach to')] = None)[source]

Defines a string Attribute for the CS Port name, and 10 Source Ports for the axes A-Z and I for the axis assignments

Parameters
  • name (str) – The name of the Part within the Controller

  • rbv (str) – Override for rbv

  • group (str) – If given, which GUI group should we attach to

class malcolm.modules.pmac.parts.CompoundMotorSinkPortsPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), rbv: Anno(name='ARbv', typ=<class 'str'>, description='Override for rbv'), group: Optional[Anno(name='AGroup', typ=<class 'str'>, description='If given, which GUI group should we attach to')] = None)[source]

Defines a string Attribute representing the CS this compound motor is permanently assigned to by reading its motor record OUT link

Parameters
  • name (str) – The name of the Part within the Controller

  • rbv (str) – Override for rbv

  • group (str) – If given, which GUI group should we attach to

class malcolm.modules.pmac.parts.MotorPreMovePart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'), demand: Anno(name='ADemand', typ=<class 'float'>, description='The demand value to move the axis to'), initial_visibility: Anno(name='AInitialVisibility', typ=<class 'bool'>, description='Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block') = False)[source]
Parameters
  • name (str) – The name of the Part within the Controller

  • mri (str) – Malcolm resource id of child object

  • demand (float) – The demand value to move the axis to

  • initial_visibility (bool) – Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block

on_configure(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.pmac.parts.PmacChildPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'), initial_visibility: Anno(name='AInitialVisibility', typ=<class 'bool'>, description='Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block') = False)[source]
Parameters
  • name (str) – The name of the Part within the Controller

  • mri (str) – Malcolm resource id of child object

  • initial_visibility (bool) – Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block

on_reset(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

on_validate(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts')) Optional[Union[Anno(name='AParameterTweakInfos', typ=<class 'malcolm.modules.scanning.infos.ParameterTweakInfo'>, description='Parameters that need to be changed to make them compatible'), Sequence[malcolm.modules.scanning.infos.ParameterTweakInfo], malcolm.modules.scanning.infos.ParameterTweakInfo]][source]
Parameters
  • context (Context) – Context that should be used to perform operations on child blocks

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

  • part_info – The Infos returned from other Parts

Returns

Parameters that need to be changed to make them compatible

Return type

ParameterTweakInfo

calculate_generator_duration(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), motion_axes: List[str]) Optional[float][source]

Calculate a generator duration based on the generator and axes we are moving

calculate_duration_from_first_two_points(axis_mapping: Dict[str, malcolm.modules.pmac.infos.MotorInfo], first_point: scanpointgenerator.core.point.Point, second_point: scanpointgenerator.core.point.Point) float[source]

Guess a duration by using the distance between two points and the max velocities

get_cs_port(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), motion_axes: List[str]) str[source]

Work out the cs_port and motion_axes we should be using

on_configure(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), completed_steps: Anno(name='ACompletedSteps', typ=<class 'int'>, description='Number of steps already completed'), steps_to_do: Anno(name='AStepsToDo', typ=<class 'int'>, description='Number of steps we should configure for'), part_info: Anno(name='APartInfo', typ=(<class 'str'>, annotypes._array.Array[malcolm.core.info.Info]), description='The Infos returned from other Parts'), generator: Anno(name='AGenerator', typ=<class 'scanpointgenerator.core.compoundgenerator.CompoundGenerator'>, description='Generator instance providing specification for scan'), axesToMove: Anno(name='AAxesToMove', typ=<class 'str'>, description='List of axes in inner dimension of generator that should be moved')) None[source]
Parameters
  • context (Context) – Context that should be used to perform operations on child blocks

  • completed_steps (int) – Number of steps already completed

  • steps_to_do (int) – Number of steps we should configure for

  • part_info – The Infos returned from other Parts

  • generator (CompoundGenerator) – Generator instance providing specification for scan

  • axesToMove (str) – List of axes in inner dimension of generator that should be moved

on_run(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

on_abort(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

write_profile_points(child, cs_port=None)[source]

Build profile using given data

Parameters
  • child (Block) – Child block for running

  • cs_port (str) – CS Port if this is a build rather than append

add_sparse_point(points, point_num, points_are_joined, same_velocities)[source]

Add in points but skip those that are linear to create a sparse trajectory. Add the upper bound when the points are non-linear. Always add the upper bound for the last point in a row (not joined to the next point).

Joined| Same Vel|| Add Point | Add Upper 0 | 0 || Y | Y 0 | 1 || N | Y 1 | 0 || Y | Y 1 | 1 || N | N

NOTE: This function may be called millions of times during the configure phase and hence is highly optimized. In particular the use of variable ‘point’ looks like it may be referenced before assignment. The paths controlled by the matrix above show that it will be always be assigned or not used at all. Indexing into points[] is expensive so this is intentional.

class malcolm.modules.pmac.parts.PmacStatusPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'), initial_visibility: Optional[Anno(name='AInitialVisibility', typ=<class 'bool'>, description='Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block')] = None, stateful: Anno(name='AStateful', typ=<class 'bool'>, description='If the child is a StatefulController then this should be True') = True)[source]
Parameters
  • name (str) – The name of the Part within the Controller

  • mri (str) – Malcolm resource id of child object

  • initial_visibility (bool) – Whether the part is initially visible with no config loaded, None means only if child Source/Sink Ports connect to another Block

  • stateful (bool) – If the child is a StatefulController then this should be True

servo_frequency(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) -> Anno(name='AServoFrequency', typ=<class 'float'>, description='The Servo Frequency of the PMAC in Hz')[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

Returns

The Servo Frequency of the PMAC in Hz

Return type

float

report_status(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) Optional[Union[Anno(name='AInfos', typ=<class 'malcolm.core.info.Info'>, description='Infos about current Part status to be passed to other parts'), Sequence[malcolm.core.info.Info], malcolm.core.info.Info]][source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

Returns

Infos about current Part status to be passed to other parts

Return type

Info

class malcolm.modules.pmac.parts.PmacTrajectoryPart(name: Anno(name='APartName', typ=<class 'str'>, description='The name of the Part within the Controller'), mri: Anno(name='AMri', typ=<class 'str'>, description='Malcolm resource id of child object'))[source]
Parameters
  • name (str) – The name of the Part within the Controller

  • mri (str) – Malcolm resource id of child object

write_profile(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks'), timeArray: Anno(name='ATimeArray', typ=<class 'numpy.int32'>, description='The relative time points to scan in microseconds'), csPort: Optional[Anno(name='ACSPort', typ=<class 'str'>, description='The Asyn Port name of the Co-ordinate system port we want to scan')] = None, velocityMode: Optional[Anno(name='AVelocityMode', typ=<class 'numpy.int32'>, description='The velocity mode of each point')] = None, userPrograms: Optional[Anno(name='AUserPrograms', typ=<class 'numpy.int32'>, description='Which user program to run for each point')] = None, a: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, b: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, c: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, u: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, v: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, w: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, x: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, y: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None, z: Optional[Anno(name='ADemandTrajectory', typ=<class 'numpy.float64'>, description='The position the axis should be at for each point in the scan')] = None) None[source]
Parameters
  • context (Context) – Context that should be used to perform operations on child blocks

  • timeArray (int32) – The relative time points to scan in microseconds

  • csPort (str) – The Asyn Port name of the Co-ordinate system port we want to scan

  • velocityMode (int32) – The velocity mode of each point

  • userPrograms (int32) – Which user program to run for each point

  • a (float64) – The position the axis should be at for each point in the scan

  • b (float64) – The position the axis should be at for each point in the scan

  • c (float64) – The position the axis should be at for each point in the scan

  • u (float64) – The position the axis should be at for each point in the scan

  • v (float64) – The position the axis should be at for each point in the scan

  • w (float64) – The position the axis should be at for each point in the scan

  • x (float64) – The position the axis should be at for each point in the scan

  • y (float64) – The position the axis should be at for each point in the scan

  • z (float64) – The position the axis should be at for each point in the scan

execute_profile(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

abort_profile(context: Anno(name='AContext', typ=<class 'malcolm.core.context.Context'>, description='Context that should be used to perform operations on child blocks')) None[source]
Parameters

context (Context) – Context that should be used to perform operations on child blocks

class malcolm.modules.pmac.parts.RawMotorSinkPortsPart(pv_prefix: Anno(name='APvPrefix', typ=<class 'str'>, description='PV prefix for CSPort and CSAxis records'), group: Optional[Anno(name='AGroup', typ=<class 'str'>, description='If given, which GUI group should we attach to')] = None)[source]

Defines a string Attribute representing a asyn port that should be depicted as a Source Port on a Block

Parameters
  • pv_prefix (str) – PV prefix for CSPort and CSAxis records

  • group (str) – If given, which GUI group should we attach to