Class ScannableMotionWithScannableFieldsBase

All Implemented Interfaces:
INeXusInfoWriteable, Device, Scannable, ContinuouslyScannableViaController, ScannableMotion, Configurable, Findable, gda.observable.IObservable
Direct Known Subclasses:
DummyConstantVelocityRasterScannable, DummyScannableFieldScannableMotion, HklScannable, PIE725ConstantVelocityRasterScannable

public class ScannableMotionWithScannableFieldsBase extends ScannableMotionBase implements ContinuouslyScannableViaController
Extend as ScannableMotionBase. Provides a ScannableMotionBase.completeInstantiation() method which adds a dictionary of ScannableFields to an instance. Each ScannableField allows one of the instances fields to be interacted with like it itself is a scannable. Fields are accessible from Jython as attributes, or using the getFieldScannable(String).

When moving a ScannableField (via either a pos or scan command), the ScnnableField calls the parent to perform the actual task. The ScannableField's asynchronousMoveto command will call the parent with a list of None values except for the field it represents which will be passed the desired position value.

The asynchronousMoveTo method in class that inherits from this base class then must handle these Nones. In some cases the method may actually be able to move the underlying system associated with one field individually from others. However by default it substitute's the None values with the actual current position of parent's scannables associated fields.

TODO: THIS IS NOT YET IMPLEMENTED ScannableMotionBaseWithMemory() extends this class and provides a solution useful for some scenarios: it keeps track of the last position moved to, and replaces the Nones in an asynchronousMoveTo request with these values. There are a number of dangers associated with this which are addressed in that class's documentation, but it provides a way to move one axis within a group of non-orthogonal axis while keeping the others still.

  • Constructor Details

    • ScannableMotionWithScannableFieldsBase

      public ScannableMotionWithScannableFieldsBase()
  • Method Details

    • setPositionAtScanStart

      public void setPositionAtScanStart(Object[] positionAtScanStart)
    • isUsePositionAtScanStartWhenCompletingPartialMoves

      public boolean isUsePositionAtScanStartWhenCompletingPartialMoves()
    • setUsePositionAtScanStartWhenCompletingPartialMoves

      public void setUsePositionAtScanStartWhenCompletingPartialMoves(boolean usePositionAtScanStartWhenCompletingPartialMoves)
    • isAutoCompletePartialMoveToTargets

      public boolean isAutoCompletePartialMoveToTargets()
    • setAutoCompletePartialMoveToTargets

      public void setAutoCompletePartialMoveToTargets(boolean autoCompletePartialMoveToTargets)
    • setInputNames

      public void setInputNames(String[] names)
      Sets input names and creates scannable for each field;
      Specified by:
      setInputNames in interface Scannable
      Overrides:
      setInputNames in class ScannableBase
      Parameters:
      names -
    • setExtraNames

      public void setExtraNames(String[] names)
      Sets extra names and creates scannable for each field;
      Specified by:
      setExtraNames in interface Scannable
      Overrides:
      setExtraNames in class ScannableBase
      Parameters:
      names -
    • atScanStart

      public void atScanStart() throws DeviceException
      Description copied from class: ScannableBase
      Called for every Scannable at the start of a group of nested scans (or a single scan if that is the case) Default behaviour is to do nothing. Inheriting classes have the option to implement this if their specific behaviour requires it.
      Specified by:
      atScanStart in interface Scannable
      Overrides:
      atScanStart in class ScannableBase
      Throws:
      DeviceException
      See Also:
    • atCommandFailure

      public void atCommandFailure() throws DeviceException
      Description copied from class: ScannableBase
      Hook to be used by Scan and pos commands to inform the Scannable that an exception, such as a DeviceExcpetion, has occurred. However not called when the command is aborted using an InterruptionException. If a Scan is aborted then only Scannable.stop() will be called by the Scan or pos command.

      Useful for telling Scannables which hold state during a scan for example, to reset themselves. Used for example by CoordinatedMotionScannables. This hook should be used not in the same way as the stop hook. Default behaviour is to do nothing. Inheriting classes have the option to implement this if their specific behaviour requires it.

      Specified by:
      atCommandFailure in interface Scannable
      Overrides:
      atCommandFailure in class ScannableBase
      Throws:
      DeviceException
      See Also:
    • atScanEnd

      public void atScanEnd() throws DeviceException
      Description copied from class: ScannableBase
      Called for every Scannable at the end of a group of nested scans (or a single scan if that is the case).

      Note that this is only called if the Scan finishes normally, or has been requested to finish early. This will not be called if the scan finishes due to an exception of any kind. See Scannable.atCommandFailure() Default behaviour is to do nothing. Inheriting classes have the option to implement this if their specific behaviour requires it.

      Specified by:
      atScanEnd in interface Scannable
      Overrides:
      atScanEnd in class ScannableBase
      Throws:
      DeviceException
      See Also:
    • getPositionAtScanStart

      public Object[] getPositionAtScanStart()
      Returns the position sampled at the start of the scan, or null if operating in a scan.
      Returns:
      position if in scan or null
    • asynchronousMoveFieldTo

      public void asynchronousMoveFieldTo(int index, Object position) throws DeviceException
      Calls asynchronousMovoTo on the DottedAccessScannable. Fills all fields but index with nulls. May be overridden to improve performance.
      Parameters:
      index -
      position -
      Throws:
      DeviceException
    • asynchronousMoveTo

      public void asynchronousMoveTo(Object externalPosition) throws DeviceException
      Description copied from class: ScannableBase
      Trigger a move/operation and return immediately. Implementations of this method should be non-blocking to allow concurrent motion; the isBusy method will be used to determine when the move has completed. Converts the external (user) position to an internal position and passes this to rawAsynchronousMoveTo.
      Specified by:
      asynchronousMoveTo in interface Scannable
      Overrides:
      asynchronousMoveTo in class ScannableMotionBase
      Parameters:
      externalPosition - Position to move to should have an element for each input field.
      Throws:
      DeviceException
    • completePartialMoveTarget

      protected Object[] completePartialMoveTarget(Object[] externalTarget) throws DeviceException
      Throws:
      DeviceException
    • createScannableForEachField

      protected void createScannableForEachField()
      Populates scannableFields and scannableFieldByName.
    • __getattr__

      Returns the ScannableField with the given name. As ScannableMotionBase does not extend PyObject, it is an 'old style' class and the more appropriate __getattribute__ method won't get called. The problem with __getattr__ is that defined methods (such as Scannable.a()) will block it. Then again, maybe this is not a problem!
      Parameters:
      name -
    • getFieldScannable

      Returns the ScannableField with the given name.
      Parameters:
      name -
      Returns:
      the Scannablefield, or null if it could not be found.
    • getFieldPosition

      public Object getFieldPosition(int index) throws DeviceException
      Override this if there is a more efficient way for your Scannable to get the value of a field than than by calling getPosition and picking out the ith object.
      Parameters:
      index -
      Returns:
      position of ith field
      Throws:
      DeviceException
    • addChildToMove

      public void addChildToMove(gda.device.scannable.scannablegroup.ICoordinatedChildScannable element)
    • isTargeting

      public boolean isTargeting()
    • setChildTarget

      public void setChildTarget(gda.device.scannable.scannablegroup.ICoordinatedChildScannable element, Object position) throws DeviceException
      Throws:
      DeviceException
    • setMembers

      public void setMembers(List<gda.device.scannable.scannablegroup.ICoordinatedChildScannable> members)
    • setOperatingContinuously

      public void setOperatingContinuously(boolean b)
      Description copied from interface: ContinuouslyScannableViaController
      Enable or disable control through the configured ContinuousMoveController
      Specified by:
      setOperatingContinuously in interface ContinuouslyScannableViaController
      Parameters:
      b -
    • isOperatingContinously

      public boolean isOperatingContinously()
      Description copied from interface: ContinuouslyScannableViaController
      Indicates whether the Scannable has deferred control to the he configured ContinuousMoveController
      Specified by:
      isOperatingContinously in interface ContinuouslyScannableViaController
      Returns:
      true if control is defered
    • getContinuousMoveController

      public ContinuousMoveController getContinuousMoveController()
      Specified by:
      getContinuousMoveController in interface ContinuouslyScannableViaController
    • setContinuousMoveController

      public void setContinuousMoveController(ContinuousMoveController controller)
      Specified by:
      setContinuousMoveController in interface ContinuouslyScannableViaController
    • isBusy

      public boolean isBusy() throws DeviceException
      Description copied from class: ScannableMotionBase
      Check if the Scannable is moving/operating.. Calls onto rawIsBusy for historical reasons, although there is currently no need for this.
      Specified by:
      isBusy in interface Scannable
      Overrides:
      isBusy in class ScannableMotionBase
      Returns:
      true - if operation carried out by moveTo has not completed yet
      Throws:
      DeviceException
      See Also:
    • waitWhileBusy

      public void waitWhileBusy() throws DeviceException, InterruptedException
      Description copied from class: ScannableBase
      Returns when operation carried out by moveTo has completed If this is to be overriden, isBusy must also be valid. Although the pos and scan command currently use this method to determine if the Scannable is busy, this must not be relied upon.
      Specified by:
      waitWhileBusy in interface Scannable
      Overrides:
      waitWhileBusy in class ScannableBase
      Throws:
      DeviceException
      InterruptedException
    • stop

      public void stop() throws DeviceException
      Description copied from class: ScannableBase
      Stop the current move/operation. Default behaviour is to do nothing. Inheriting classes have the option to implement this if their specific behaviour requires it.
      Specified by:
      stop in interface Scannable
      Overrides:
      stop in class ScannableBase
      Throws:
      DeviceException
      See Also:
    • getPositionWhileMovingContinuousely

      public Object getPositionWhileMovingContinuousely(gda.device.scannable.scannablegroup.ICoordinatedScannableGroupChildScannable childScannable) throws DeviceException
      Throws:
      DeviceException