Class ScannableNexusWrapper<N extends NXobject>

All Implemented Interfaces:
INexusDevice<N>, IActivatable, IBoundable<Object>, ILevel, INameable, IScanAttributeContainer, IScannable<Object>, ITimeoutable, ITolerable<Object>, IPositionListenable
Direct Known Subclasses:
JythonScannableNexusWrapper

public class ScannableNexusWrapper<N extends NXobject> extends AbstractScannable<Object> implements INexusDevice<N>
An instance of this class wraps a Scannable and adapts to both IScannable and INexusDevice. This allows a scannable to be used in a new scanning (a.k.a. solstice scanning) scan and write to the nexus file. The nexus writing delegated to an instanceof AbstractScannableNexusDevice. Note that an instance of this class is used only in new scanning.
  • Constructor Details

    • ScannableNexusWrapper

      public ScannableNexusWrapper()
      Used from spring
  • Method Details

    • setScannable

      public void setScannable(Scannable scannable)
      Used from spring to connect the wrapper to a particular GDA8 scannable.
      Parameters:
      scannable - the GDA8 scannable to wrap
      Throws:
      IllegalStateException - if the scannable is already set
    • getScannable

      public Scannable getScannable()
    • canReadPosition

      public boolean canReadPosition()
    • getNexusProvider

      public NexusObjectProvider<N> getNexusProvider(NexusScanInfo info) throws NexusException
      Description copied from interface: INexusDevice
      Returns the object provider required for writing correct NeXus files.

      In this method you should prepare the LazyDatasets the device will fill during the scan. You can also write out static device metadata, which will not change during the scan.

      Use the methods on NexusNodeFactory to create a NeXus object which matches the device e.g. a NXdetector. final NXdetector detector = NexusNodeFactory.createNXdetector();

      On the detector object you can create LazyDatasets and keep references which you can later use during the scan to write data. e.g. imageData = detector.initializeLazyDataset(NXdetector.NX_DATA, info.getRank() + 2, Double.class); You should also set chunking on the LazyDatasets you create e.g. imageData.setChunking(info.createChunk(detectorXSize, detectorYSize));.

      In this method you can also write static metadata such as the detector exposure e.g. detector.setField("exposure_time", model.getExposure());. Or static datasets such as the image axis data detector.setDataset("image_x_axis", DatasetFactory.createLinearSpace(DoubleDataset.class, minX, maxX, xPoints)); For fields that are defined in the NXDL base class definition for the returned nexus object, a setXXX or setXXXScalar method may be used as appropriate, e.g. detector.setLocalName(DatasetFactory.createFromObject("my detector")); or detector.setLocalNameScalar("my detector");

      If this device is a 'metadata scannable', then the device should write its data at this point directly into the returned nexus object. This can be done with the NXobject.setField(String, Object) method, or the setXXXScalar methods for fields defined in the appropriate NXDL base class definition.

      The default implementation of this method throws UnsupportedOperationException. One of either this method or INexusDevice.getNexusProviders(NexusScanInfo) must be overridden to create and return the nexus object(s) for this INexusDevice.

      Specified by:
      getNexusProvider in interface INexusDevice<N extends NXobject>
      Parameters:
      info - information about the scan which can be useful when creating datasets e.g. info.getRank()
      Returns:
      The NXobject created using the nodeFactory to represent this device
      Throws:
      NexusException - if the nexus object could not be created for any reason
    • getNexusProviders

      public List<NexusObjectProvider<N>> getNexusProviders(NexusScanInfo info) throws NexusException
      Description copied from interface: INexusDevice
      Returns the object providers required for writing correct NeXus files. Implement this method if your device needs to create multiple nexus objects. These can implement NexusObjectProvider

      The default implementation of this method calls INexusDevice.getNexusProvider(NexusScanInfo) and returns a List whose sole element is the NexusObjectProvider returned from that method. One of either this method or INexusDevice.getNexusProviders(NexusScanInfo) must be overridden to create and return the nexus object(s) for this INexusDevice.

      Specified by:
      getNexusProviders in interface INexusDevice<N extends NXobject>
      Parameters:
      info - information about the scan which can be useful when creating datasets e.g. info.getRank()
      Returns:
      The NXobject created using the nodeFactory to represent this device
      Throws:
      NexusException - if the nexus object could not be created for any reason
    • getCustomNexusModification

      public CustomNexusEntryModification getCustomNexusModification()
      Description copied from interface: INexusDevice
      Returns an object that performs a custom modification to an NXentry.

      NOTE: Use this method with caution as it can be used to break the central design concept of the new Nexus writing framework, namely that the nexus framework itself knows where to put the nexus groups for devices and build any required NXdata groups. It is currently used by the new Nexus framework to partially support legacy GDA8 spring configurations, in particular the 'locationmap'.

      The nexus framework will call this method after

      invalid reference
      #createNexusObject(NexusNodeFactory, NexusScanInfo)
      , so this method create links to nodes created in that method if appropriate.

      The easiest way to implement this method is to make this object itself also implement CustomNexusEntryModification. This method can then be overridden to simply return this.

      Specified by:
      getCustomNexusModification in interface INexusDevice<N extends NXobject>
      Returns:
      a CustomNexusEntryModification that makes a custom modification, or null if this device should not make custom modifications
    • setLevel

      public void setLevel(int level)
      Description copied from interface: ILevel
      Used for ordering the operations of Scannables during scans
      Specified by:
      setLevel in interface ILevel
      Overrides:
      setLevel in class AbstractScannable<Object>
      Parameters:
      level -
    • getLevel

      public int getLevel()
      Description copied from interface: ILevel
      get the operation level of this scannable.
      Specified by:
      getLevel in interface ILevel
      Overrides:
      getLevel in class AbstractScannable<Object>
      Returns:
      int - the level
    • getName

      public String getName()
      Description copied from interface: INameable
      Name of the scannable
      Specified by:
      getName in interface INameable
      Specified by:
      getName in interface INexusDevice<N extends NXobject>
      Overrides:
      getName in class AbstractNameable
      Returns:
    • setName

      public void setName(String name)
      Description copied from interface: INameable
      Set the name of the device.
      Specified by:
      setName in interface INameable
      Overrides:
      setName in class AbstractNameable
      Parameters:
      name -
    • getPosition

      public Object getPosition() throws ScanningException
      Description copied from interface: IBoundable
      The position is the value which should be: 1. Greater than or equal to the lower 2. Less than or equal to the upper. 3. One of the permitted values, if they are not null.
      Specified by:
      getPosition in interface IBoundable<N extends NXobject>
      Returns:
      Throws:
      ScanningException - if the position cannot be read for any reason
    • setPosition

      public Object setPosition(Object value) throws ScanningException
      Description copied from interface: IScannable
      Moves to the position required, blocking until it is complete. Similar to moveTo(...) in GDA8 Same as calling setPosition(value, null);
      Specified by:
      setPosition in interface IScannable<N extends NXobject>
      Parameters:
      value -
      Returns:
      the new position attained by the device, if known. (Saves additional call to getPosition()) If not know the demand value is returned. NOTE if null is returned the system will call getPosition() again.
      Throws:
      ScanningException
    • setPosition

      public Object setPosition(Object value, IPosition scanPosition) throws ScanningException
      Description copied from interface: IScannable
      Moves to the position required, blocking until it is complete. Similar to moveTo(...) in GDA8
      Specified by:
      setPosition in interface IScannable<N extends NXobject>
      Parameters:
      value - that this scalar should take.
      scanPosition - if within in a scan or null if not within a scan.
      Returns:
      the new position attained by the device, if known. (Saves additional call to getPosition()) If not know the demand value is returned. NOTE if null is returned the system will call getPosition() again.
      Throws:
      ScanningException
    • getUnit

      public String getUnit()
      Description copied from interface: IScannable
      The unit is the unit in which the setPosition and getPosition values are in.
      Specified by:
      getUnit in interface IScannable<N extends NXobject>
      Returns:
      String representation of unit which setPosition and getPosition are using.
    • getMaximum

      public Object getMaximum()
      Description copied from interface: IBoundable
      The upper limit in the same unit as the position.
      Specified by:
      getMaximum in interface IBoundable<N extends NXobject>
      Overrides:
      getMaximum in class AbstractScannable<Object>
      Returns:
      null if there is no upper limit. In this case it will be the upper limit of the type T.
    • getMinimum

      public Object getMinimum()
      Description copied from interface: IBoundable
      The lower limit in the same unit as the position.
      Specified by:
      getMinimum in interface IBoundable<N extends NXobject>
      Overrides:
      getMinimum in class AbstractScannable<Object>
      Returns:
      null if there is no upper limit. In this case it will be the upper limit of the type T.
    • getPermittedValues

      public String[] getPermittedValues() throws Exception
      Description copied from interface: IBoundable
      Returns a list of the permitted values for this object, or null if the values are not restricted to a set of permitted values
      Specified by:
      getPermittedValues in interface IBoundable<N extends NXobject>
      Returns:
      list of permitted values, or null
      Throws:
      Exception
    • scanFinally

      public void scanFinally()
    • addPositionListener

      public void addPositionListener(IPositionListener listener)
      Description copied from interface: IPositionListenable
      Use to be notified as levels / positions are reached. Not usually necessary as setPosition is blocking until the position is reached but useful for other objects which need to change when new positions are reached.
      Specified by:
      addPositionListener in interface IPositionListenable
      Overrides:
      addPositionListener in class AbstractScannable<Object>
      Parameters:
      listener -
    • removePositionListener

      public void removePositionListener(IPositionListener listener)
      Description copied from interface: IPositionListenable
      Use to be notified as levels / positions are reached.
      Specified by:
      removePositionListener in interface IPositionListenable
      Overrides:
      removePositionListener in class AbstractScannable<Object>
      Parameters:
      listener -
    • update

      public void update(Object source, Object arg)
    • toString

      public String toString()
      Overrides:
      toString in class AbstractNameableTimeoutable
    • abort

      public void abort() throws ScanningException
      Description copied from interface: IScannable
      Call to terminate a movement before it is complete, for example when ScannablePositioner#abort is called due to an exception with another IScannable's movement
      Specified by:
      abort in interface IScannable<N extends NXobject>
      Throws:
      ScanningException