MX A Portable Data Acquisition and Control Toolkit
MX: A Portable Data Acquisition and Control Toolkit William M. Lavender Biological, Chemical, and Physical Sciences Department Illinois Institute of Technology Chicago, Illinois 60616 http: //www. imca. aps. anl. gov/mx/ lavender@icarus. csrri. iit. edu
What is MX? " " " MX is a portable beamline control system. It includes a pair of servers, mxserver and mxupdate, to manage the hardware. Both Tcl/Tk GUI applications and command line based applications are currently supported. Device drivers and core functionality are encapsulated in the lib. Mx library. Lib. Mx is written in ANSI C to maximize its ability to be used from other languages and applications.
What is MX? (cont. ) " " Both servers and clients use the same lib. Mx library and can use the same device drivers. Client-server operation is not required. This simplifies the debugging of device drivers. MX has its own TCP/IP protocol, but most of MX is independent of the protocol used. Clients can use foreign protocols exclusively, or a mix of MX and foreign protocols.
Current Users of MX · MRCAT, APS Sector 10 -ID materials science · IMCA-CAT, APS Sector 17 -ID and 17 -BM macromolecular crystallography · Bio. CAT, APS Sector 18 -ID biophysical science · SER-CAT, APS Sector 22 -ID and 22 -BM macromolecular crystallography · GCPCC Beamline, CAMD macromolecular crystallography
Why I Wrote MX " " Beamline control software packages have tended to be environment specific and non-portable. Many are centered around a particular interface method, e. g. CAMAC or VME. EPICS seemed to be a less than ideal choice, since it requires a rather high level of expertise to setup, maintain, and develop for. Users sometimes bring in their own equipment that they want to interface to the beamline.
MX Control System Goals " Encapsulate the core functionality in libraries like lib. Mx. " Make client-server functionality available. " " " Require that lib. Mx know very little about the application programs invoking it. Localize the knowledge lib. Mx has of device hardware to driver functions with well defined interfaces. Minimize the effort required to implement new device drivers by putting as much functionality as is possible into generic code.
MX Control System Goals (cont. ) " Emphasize operating system independence. " Require only ANSI C and BSD sockets or Winsock. " " Be able to interoperate with pre-existing beamline control systems. Try to minimize built-in assumptions about the structure of future data acquisition APIs. Do not depend on the presence of software that may not be freely distributed. Make the source code freely available.
MX Platforms " Linux 2. 0 and 2. 2 - " SGI Irix 6. 3 and 6. 5 - SGI C compiler " Solaris 2. 5 and 2. 6 - SPARCompiler C or GCC " HP/UX 10. 20 " Sun. OS 4. 1. 4 " Mac. OS X " Windows 95, 98, NT 4 - " MSDOS 6. 2 - HP/UX C compiler - - GCC SPARCompiler C GCC - Visual C++ 4, 5, or 6 DJGPP 2. 0. 2 and Watt 32
MX Internal Architecture " " " The fundamental object is the MX record. Application programs maintain their set of MX records in a doubly linked list called the MX database. Each motor, scaler, serial port, or other device on a beamline is represented as an individual MX records are also used to store variables, server connections, and even scan parameters. Application programs control the beamline by invoking the defined functions or methods for each device type.
MX Records " " " MX records are defined by the typedef MX_RECORD in the header file lib. Mx/mx_rec. h. MX is not fully object oriented since it only has a fairly restricted form of inheritance. MX record types are organized in a fixed hierarchy of superclasses, and types. Each MX record type has an associated MX driver which implements the methods of this record type. Methods are implemented via function tables defined in the MX_DRIVER structure.
The MX_RECORD Structure typedef struct mx_record_type { long mx_superclass; /* MXR_LIST_HEAD, MXR_INTERFACE, etc. */ long mx_class; /* MXI_CAMAC, MXC_MOTOR, etc. */ long mx_type; /* MXT_MTR_E 500, MXT_MTR_PANTHER, etc. */ char name[MXU_RECORD_NAME_LENGTH+1]; char label[MXU_LABEL_LENGTH+1]; void *acl; char acl_description[MXU_ACL_DESCRIPTION_LENGTH+1]; signed long handle; int precision; int resynchronize; long flags; struct mx_record_type *list_head; struct mx_record_type *previous_record; struct mx_record_type *next_record; void *record_superclass_struct; /* Ptr to MX_SCAN, MX_VARIABLE, etc. */ void *record_class_struct; /* Ptr to MX_CAMAC, MX_MOTOR, etc. */ void *record_type_struct; /* Ptr to MX_DSP 6001, MX_E 500, etc. */ void *record_function_list; /* Ptr to MX_RECORD_FUNCTION_LIST */ void *superclass_specific_function_list; void *class_specific_function_list; long num_record_fields; MX_RECORD_FIELD *record_field_array; struct mx_record_type *allocated_by; long num_groups; struct mx_record_type **group_array; long num_parent_records; struct mx_record_type **parent_record_array; long num_child_records; struct mx_record_type **child_record_array; MX_CLOCK_TICK event_interval; MX_CLOCK_TICK next_event_time; void *event_queue; /* Ptr to MXSRV_QUEUED_EVENT */ void *application_ptr; } MX_RECORD;
An MX record list
MX Device Types MX Interface Types Amplifier Analog Input Analog Output Digital Input Digital Output Encoder Motor Multichannel Analyzer Multichannel Encoder Multichannel Scaler Relay Scaler Table Timer CAMAC Generic GPIB Port I/O RS-232 MX Server Types TCP/IP MX Variable Types Calc EPICS Inline MX
MX Scan Types MX has a selection of scan types optimized for different kinds of experiments. � Linear Scan � Input Scan � Motor Scan � Slit Scan � q-2 q Scan � List Scan � Quick Scan � Joerger Quick Scan � MCS Quick Scan � XAFS Scan (multiple energy and k regions)
MX Motor Drivers Am 9513 -based controller APS undulator (EPICS) Bruker D 8 (prerelease) Compumotor 6000/6 K DAC motor Delta Tau PMAC (EPICS) DSP E 500 EPICS motor record IMS Panther HI/HE Joerger SMC-24 Lake. Shore 330 temp. ctrl. Mc. Lennan PM-304 MX network motor National Inst. Value. Motion Newport MM-3000 Newport MM-4000/4005 OMS VME-58 (Linux) PI E-662 piezo controller Pontech STP-100 Radix Databox motor SCIPE network motor Soft motor Velmex VP 9000 XIA HSC-1 slit controller
MX Pseudomotor Drivers Delta (position difference) Elapsed time Linear function Monochromator Q = 4 p sinq/l Sector 18 -ID mono Slit center or width Table pseudomotor - (x, y, z, roll, pitch, yaw) q-2 q pseudomotor Translation pseudomotor X-ray energy X-ray wavelength X-ray wavenumber XAFS wavenumber (k)
MX Monochromator Pseudomotor The MX monochromator pseudomotor couples the motion of several groups of dependent motors and devices such that they track changes in the monochromator angle, q. Supported dependency types · Monochromator q (of course) · Polynomial function of monochromator q · Polynomial function of monochromator energy · APS undulator energy · Fixed exit crystal separation · Fixed exit crystal translation · Diffractometer table height · Diffractometer q
ADC Table Pseudomotor · Supports linear x, y, and z translation of the rotation center. · Supports pure roll, pitch, and yaw motions about the rotation center. · Uses a small angle approximation for rotations.
MX Application Programs MX currently supports writing application programs in C and Tcl/Tk. Support is planned for Python, C++, and Labview. Command line programs motor - a general data acquisition and control program for MX. mxget & mxput - shell commands for talking to an MX server. goniostat - used by Mar. CCD to control the X-ray energy. Tcl/Tk GUI programs imcagui - a protein crystallography GUI capable of setting up and performing MAD experiments. optimize - an end-user GUI for performing simple optimizations of the X-ray intensity. mxgui - a general data acquisition and control GUI intended for beamline staff users. mxcontrol - an MX server control and log display GUI.
Selecting an Absorption Edge
MXGUI - A Beamline Staff GUI
MXGUI - Setting up a motor scan
MXGUI - Setting up an XAFS scan
MX Network Protocol " " MX is bundled with a network protocol and a pair of servers that implement it. – mxserver - manages hardware and handles communication with clients. – mxupdate - handles automatic save and restore of database parameters. The protocol is designed to be simple to implement and easy to extend. Most of MX does not depend on this protocol and clients are not required to use it. This protocol is included so that MX can be a standalone system.
MX Network Protocol (cont. ) " " " MX protocol is an RPC style protocol. Asynchronous callback support is planned but is not fully implemented yet. MX protocol messages have a binary header with an ASCII body. Uses record field names to identify the object of the message. For example, ``theta. position''. Currently 3 types of messages are implemented: get_array_ascii, put_array_ascii, get_field_type. Other types are planned. The protocol is intended to have a simple core, but be extensible by negotiation at runtime.
Future Plans for MX Protocol " Use numeric handles rather that passing record field names. " Finish implementation of asynchronous callbacks. " Explore passing data using binary XDR format. " " Add support for automatic resource discovery and browsing of servers. Improve support for security and add ACLs.
MX is Transport Independent " " The driver API does not distinguish between remotely and locally controlled devices. Applications can switch between drivers and protocols just by changing a config file. Servers can be clients and clients can be servers. Clients can simultaneously use several different network protocols.
APS Sector 17 -ID Control System
MX Simulated Devices " " " The driver API does not distinguish between real devices and simulated devices. Almost every MX driver type has a simulated driver available. Very useful for offline development and testing of new software. " Potentially useful for user training. " Can use simulated devices alongside real devices.
MX Programming API MX has an extensive API. All of it cannot be shown here, so we show only motor related functions. mx_motor_get_position() mx_motor_is_busy() mx_motor_positive_limit_hit() mx_motor_negative_limit_hit() mx_motor_move_absolute() mx_motor_array_move_absolute() mx_wait_for_motor_stop() mx_wait_for_motor_array_stop() mx_motor_soft_abort() mx_motor_immediate_abort() mx_motor_set_position() mx_motor_find_home_position() mx_motor_is_at_home_switch() mx_motor_get_speed() mx_motor_save_speed() mx_motor_restore_speed() mx_motor_set_speed_between_positions() mx_motor_get_acceleration_type() mx_motor_get_acceleration_parameters() mx_motor_set_acceleration_parameters() mx_motor_get_acceleration_time() mx_motor_get_acceleration_distance() mx_motor_compute_pseudomotor_position_ from_real_position() mx_motor_compute_real_position_from_ pseudomotor_position() mx_motor_compute_extended_scan_range() mx_motor_constant_velocity_move() mx_motor_get_parameter() mx_motor_set_parameter()
Cu K-edge scan in C using MX #include <stdio. h> #include "mx_rec. h" #include "mx_motor. h" #include "mx_scalr. h" #include "mx_timer. h" #define DATABASE_FILENAME "example. dat" int main() { MX_RECORD *record_list, *energy_motor_record; MX_RECORD *i_zero_record, *i_trans_record, *timer_record; double start, step_size, measurement_time, energy; int i, num_steps, busy; long i_zero_value, i_trans_value; mx_setup_database( &record_list, DATABASE_FILENAME ); energy_motor_record = mx_get_record( record_list, "energy" ); i_zero_record = mx_get_record( record_list, "Io" ); i_trans_record = mx_get_record( record_list, "It" ); timer_record = mx_get_record( record_list, "timer 1" ); start = 8950; step_size = 1. 0; num_steps = 101; measurement_time = 1. 0; for ( i = 0; i < num_steps; i++ ) { mx_scaler_clear( i_zero_record ); mx_scaler_clear( i_trans_record ); energy = start + step_size * (double) i; mx_motor_move_absolute( energy_motor_record, energy, 0 ); mx_timer_start( timer_record, measurement_time ); busy = TRUE; while ( busy ) { mx_msleep(10); /* Wait for 10 milliseconds */ mx_timer_is_busy( timer_record, &busy ); } mx_scaler_read( i_zero_record, &i_zero_value ); mx_scaler_read( i_trans_record, &i_trans_value ); printf( "%10. 3 f %10 lun", energy, i_zero_value, i_trans_value ); } exit(0); }
Cu K-edge scan in Tcl using MX #! /opt/mx/bin/mxtclsh set mxdir "/opt/mx" ; set database_filename "example. dat" source [ file join $mxdir "lib" "mx. tcl" ] package require Mx : : Mx: : init set record_list [ Mx: : setup_database $database_filename ] set energy_motor_record [ $record_list get_record "energy" ] set i_zero_record [ $record_list get_record "Io" ] set i_trans_record [ $record_list get_record "It" ] set timer_record [ $record_list get_record "timer 1" ] set start 8950 ; set step_size 1. 0 ; set num_steps 101 set measurement_time 1. 0 for { set i 0 } { $i < $num_steps } { incr i } { $i_zero_record clear $i_trans_record clear set energy [ expr ( $start + $step_size * $i ) ] $energy_motor_record move_absolute $energy set busy 1 while { $busy } { after 10 set busy [ $energy_motor_record is_busy ] } $timer_record start $measurement_time set busy 1 while { $busy } { after 10 set busy [ $timer_record is_busy ] } set i_zero_value [ $i_zero_record read ] set i_trans_value [ $i_trans_record read ] puts [ format "%10. 3 f %10 lu" $energy $i_zero_value $i_trans_value ] }
MX Driver Header File /* ===== Mc. Lennan PM 304 motor data structures ===== */ typedef struct { MX_RECORD *rs 232_record; int axis_number; int axis_encoder_number; } MX_PM 304; MX_API mx_status_type mxd_pm 304_initialize_type( long type ); MX_API mx_status_type mxd_pm 304_create_record_structures( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_finish_record_initialization(MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_delete_record( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_print_motor_structure( FILE *file, MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_read_parms_from_hardware( MX_RECORD *record); MX_API mx_status_type mxd_pm 304_write_parms_to_hardware( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_open( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_close( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_resynchronize( MX_RECORD *record ); MX_API mx_status_type mxd_pm 304_motor_is_busy( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_move_absolute( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_get_position( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_soft_abort( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_immediate_abort( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_positive_limit_hit( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_negative_limit_hit( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_find_home_position( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_constant_velocity_move( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_get_parameter( MX_MOTOR *motor ); MX_API mx_status_type mxd_pm 304_set_parameter( MX_MOTOR *motor ); extern MX_RECORD_FUNCTION_LIST mxd_pm 304_record_function_list; extern MX_MOTOR_FUNCTION_LIST mxd_pm 304_motor_function_list;
MX Driver Header File (cont. ) /* Define some extra functions for the use of this driver. */ MX_API mx_status_type mxd_pm 304_command( MX_PM 304 *pm 304, char *command, char *response, int response_buffer_length, int debug_flag ); MX_API mx_status_type mxd_pm 304_getline( MX_PM 304 *pm 304, char *buffer, int buffer_length, int debug_flag ); MX_API mx_status_type mxd_pm 304_putline( MX_PM 304 *pm 304, char *buffer, int debug_flag ); MX_API mx_status_type mxd_pm 304_getc( MX_PM 304 *pm 304, char *c, int debug_flag ); MX_API mx_status_type mxd_pm 304_getc_nowait( MX_PM 304 *pm 304, char *c, int debug_flag ); MX_API mx_status_type mxd_pm 304_putc( MX_PM 304 *pm 304, char c, int debug_flag ); extern long mxd_pm 304_num_record_fields; extern MX_RECORD_FIELD_DEFAULTS *mxd_pm 304_rfield_def_ptr; #define MXD_PM 304_STANDARD_FIELDS {-1, "rs 232_record", MXFT_RECORD, NULL, 0, {0}, MXF_REC_TYPE_STRUCT, offsetof(MX_PM 304, rs 232_record), {0}, NULL, (MXFF_IN_DESCRIPTION | MXFF_IN_SUMMARY)}, {-1, "axis_number", MXFT_INT, NULL, 0, {0}, MXF_REC_TYPE_STRUCT, offsetof(MX_PM 304, axis_number), {0}, NULL, (MXFF_IN_DESCRIPTION | MXFF_IN_SUMMARY)}, {-1, "axis_encoder_number", MXFT_INT, NULL, 0, {0}, MXF_REC_TYPE_STRUCT, offsetof(MX_PM 304, axis_encoder_number), {0}, NULL, (MXFF_IN_DESCRIPTION | MXFF_IN_SUMMARY)}
An Example MX Driver Function MX_EXPORT mx_status_type mxd_pm 304_move_absolute( MX_MOTOR *motor ) { const char fname[] = "mxd_pm 304_move_absolute()"; MX_PM 304 *pm 304; char command[20]; char response[20]; long motor_steps; mx_status_type status; status = mxd_pm 304_get_pointers( motor, &pm 304, fname ); if ( status. code != MXE_SUCCESS ) return status; motor_steps = motor->raw_destination. stepper; /* Format the move command send it. */ sprintf( command, "ma%ld", motor_steps ); status = mxd_pm 304_command( pm 304, command, response, sizeof response, PM 304_DEBUG ); if ( status. code != MXE_SUCCESS ) return status; /* Did we get an "OK" response? */ if ( strcmp( response, "OK" ) != 0 ) { return mx_error( MXE_DEVICE_IO_ERROR, fname, "Did not get 'OK' response from controller. Instead got '%s'", response ); } return MX_SUCCESSFUL_RESULT; }
Future Plans " Server-side improvements – Improve mxserver's ability to cope with broken or missing hardware. – Add callback support to mxserver. – Performance and concurrency improvements. – Create servers to export MX services to other control systems (EPICS, CORBA, etc. ) – GUI database configuration tool. – GUI server control tool.
Future Plans (cont. ) " " Client-side improvements – Development of more application specific GUIs. – Export MX APIs to more languages: (Python, C++, Labview, etc. ) – Add client-side part of callback support. General improvements – Port MX to new platforms: (QNX, VMS, etc. ) – Collaborate with SER-CAT to develop MX systems based on Delta Tau PMAC controllers. – Add new data file formats such as HDF/Ne. Xus. – Addition of new drivers.
Summary " " " MX is now in use at 6 APS beamlines, 1 CAMD beamline, and in X-ray labs at IIT. Several beamlines at APS, ALS, NSLS, and CLS have expressed interest. Runs on a variety of hardware platforms. Designed to interoperate with other control systems and user interfaces. We are interested in collaborating with other groups on the further development and application of MX.
Acknowledgements A. Howard J. Chrzas L. Keefe C. Segre B. Bunker N. Leyarovska H. Tostmann J. Terry J. Kropf G. Bunker R. Fischetti J. Fait G. Rosenbaum J. Quintana E. Westbrook M. White IMCA-CAT, IIT MRCAT, Notre Dame MRCAT, IIT MRCAT, Univ. of Florida MRCAT, IIT MRCAT, Argonne Natl. Lab. Bio. CAT, IIT SER-CAT, Univ. of Georgia DND-CAT, Northwestern ALS Beamline 4. 2. 2, MBC GCPCC beamline at CAMD, Univ. of Texas Medical Branch
- Slides: 42