23.3. Sample Handling¶
23.3.1. Overview¶
The Sample Handling process is a continually running process that controls the movement of plates through the beamline via two robots and the load-lock. The process is encapsulated into states and actions.
A plate’s state is read from ISPyB and other sources *. The action to be executed on a plate is decided based upon its current state. Once an action has completed the plate’s new state is written to ISPyB. Plates are individually identified using barcodes.
The concept of an action is plate movement from one location to another. The valid locations are:
IN_STORAGE- plate is in a Formulatrix (Hotel)IN_LOCALSTORAGE- plate is in beamline Local Storage (a series of storage slots inside the Endstation Enclosure)ON_GONIO- plate is on the Goniometer
In addition a plate being moved is considered In Transit (every action has
an associated In Transit status) - IN_TRANSIT_...
Thus the four sample handling actions are:
Retrieve a plate from a Formulatrix to Local Storage
Load a plate from Local Storage onto the Goniometer
Unload a plate from the Goniometer to Local Storage
Return a plate from Local Storage to a Formulatrix
Only one of these actions can be executed at any one time. The goal is to minimise the time no plate is on the Goniometer ready to be shot.
Plate states and actions allowed to move between them are shown below.

Each plate is either shot or not shot, this state is stored in ISPyB as its own field. A plate’s shot state is set by the Data Collection Process, allowing unloads.
* Data sources for a plate's state are:
ISPyB for plate locations and status.
Orange Triangle (a remote Python app) for the next-plate to retrieve from storage.
Configuration files for allowed Local Storage slots.
23.3.2. Action Determination¶
The Sample Handling process has a set of sensors that retrieve information
regarding the location of plates and available Local Storage slots. Plate
locations are stored in ISPyB, retrieved and updated via the
VMXi LIMS Agent
(Laboratory Information Management System Agent).
The allowed storage slots are set by beamline staff and stored as JSON in
i02-2-config/etc/sample_handling/local_storage.json.
The information from the sensors is passed to an action selector
(sample_handling.actions.selection) which returns a list of potential
sample-handling actions, in priority order. The first of these actions is
selected for execution by the handling process.
The sensor objects (defined in sample_handling.sense) are:
SenseLoadNext- asks the Orange Triangle what the next plate to retrieve from a Formulatrix isSenseSlots- reads the allowed Local Storage storage slots from the specified JSON fileSenseLocalStorage- request which plates (if any) are in Local Storage from ISPyBSenseGonio- requests which plate (if any) is on the GoniometerSenseTransit- requests which plates (if any) are currently in transit between fixed locations.
Additional sensor objects may be implemented in the future should the sample handling process need to become more sophisticated.
The prioritisations for sample handling actions, and their required conditions are (highest to lowest):
Unload a shot plate from the Goniometer (requires a completed plate on the Goniometer, i.e. all selected crystals in all plate wells have been imaged)
Load an unshot plate from Local Storage onto the Goniometer (requires no plate on Goniometer and an uncompleted plate in Local Storage) - plates are prioritised based on when they were placed into local storage (FIFO order)
Retrieve the next-plate from a Formulatrix (requires a next-plate from Orange Triangle service and an empty Local Storage slot of the correct type (20 versus 4 degrees Celsius))
Return a shot plate to a Formulatrix (requires a completed plate in Local Storage).
No action is considered if a plate is left In Transit - this is expected to be a superfluous check during normal operation, but is left as a precaution (to encourage proper manual recovery after failures, etc).
23.3.3. Action Objects¶
Actions encapsulate the work required to move a plate from one location to another, including requests to the internal and external robot, preparation of the endstation, final verification of hardware state, and updates to ISPyB.
The high-level interface is given by the
Action
Java interface but a Jython base class
(gda-mx.git/configurations/i02-2-config/scripts/sample_handling/actions/actions.py)
is used to provide the base behaviour as described below.
class VmxiAction(Action):
def update_pre_action_state(self):
"""
Set the Plate's status to relevant "IN_TRANSIT" state in ISPyB.
Called by the Sample Handling Processor.
"""
def update_post_action_state(self):
"""
Set the Plate's status to its final location in ISPyB.
Called by the Sample Handling Processor.
"""
def execute(self):
"""
Wraps run_action, handling exceptions and manages the action status appropriately.
Called by the Sample Handling Processor.
"""
def run_action(self):
"""
Run the action, triggering hardware moves.
Successful return indicates the action ran to completion, otherwise
an exception should be raised.
"""
def stop(self):
"""
Ask the action to stop (may not be honoured, best effort only,
particularly where the robot is concerned).
May be called by the Sample Handling Processor.
"""
def getStatus(self):
"""
Return an ActionStatus for the current state.
"""
def getName(self):
"""
Return the name given to the action.
"""
def getRunTime(self):
"""
Return the execution time for the action.
"""
The parameters for the action (e.g. plate barcode, Hotel to use, storage slot to use, etc), are passed to the action’s constructor.
23.3.4. Action Status¶
getStatus (see above) returns an
ActionStatus
enum , which has the following values:
PENDING- action has not yet startedRUNNING- action has started runningCOMPLETE- action ran successfullyERROR- action entered an error state and could not safely recoverFAILED- action failed safelySTOPPED- action stopped after receiving a stop request (assumed to be unsafe)
Actions are responsible for handling their own status, including the
transition from PENDING to RUNNING.
Action states COMPLETE, STOPPED, ERROR and FAILED are termination states and
no transitions can occur from these states. An action must only set its
status to COMPLETE if the movement of the plate was successful and further
actions can be safely taken.
NOTE: The semantics of the FAILED condition are not currently well
defined and therefore its use is not properly supported.
The VmxiAction base class handles all status updates appropriately, assuming
a correct implementation of run_action.
23.3.5. Interrupts¶
It is possible to request the Sample Handling process to stop. This will
result in the stop method being called on any currently running action.
It is not required that this request is honoured, and in the case of robot
motions, may not be possible (e.g. without leaving the robot in a
difficult to recover state). If a stop can be facilitated, some cleanup may
still be required, so action execution may resume for a short while after
the stop request has been made.
It can be noted that Sample Handling Actions are very similar to Data Collection Tasks; there are differences, but the trend is the same.
23.3.6. The Sample Handling control loop¶
An outline of the sample handling process control loop is given below:
while True:
if running_action:
if running_action.completed:
update_ispyb()
continue
elif running_action.errored:
raise
else:
continue
else:
state = sense_state()
action = decide_action(state)
if action:
start_action_async(action)
running_action = action
The screenshots below show the Sample Handling Montior displying plate processing progressing.

