Version 2.0.0 (03/11/16): This version of Mp does not yet support Python 3.x. The 'linux' build target now automatically figures out which version of Python is in use, so that this information can be used in the Mp makefiles. In most cases, this means that it should not be necessary to modify 'mp/libMp/Makehead.linux'. The 'win32' build target now automatically figures out which version of Python is installed by reading this from the Windows registry using the 'mx_config' program from MX. In most cases, this means that it should not be necessary to modify the 'mp/libMp/Makehead.win32' file. Added MpNum.ImageFrame class. This class allows one to exchange image data with NumPy arrays and is more efficient at processing the binary image data. Added support for Mp being invoked from the MX 'python' extension module. If Mp is running standalone, it creates it own MX record list. If Mp has been loaded by a C executable that already has its own internal MX database, then Mp attaches to that database rather than creating its own in-memory database. Mp now stores C-based MX database and callback pointers in PyCapsule objects (or PyCObject on older Pythons). A number of small Mp changes to match changes and new features in MX. Version 1.5.4 (05/10/11): New class added: Mp.MCAI - This supports reading out MX multichannel analog input devices. It has one method called read(). New methods added: Mp.AreaDetector get_exposure_mode() set_exposure_mode() These get and set the area detector exposure mode which currently can be Mp.MXT_AD_STILL_MODE, Mp.MXT_AD_DARK_MODE, or Mp.MXT_AD_EXPOSE_MODE. Mp.DigitalInput clear() - Clears any latched value in the digital input. Modified methods: Mp.AreaDetector set_duration_mode() replaces set_bulb_mode() New values added: Mp.MXT_IMAGE_FILE_PNM - NetPBM PNM format images. Mp.MXT_IMAGE_FILE_RAW - Raw images without a header. Mp.MXT_SQ_DURATION replaces Mp.MXT_SQ_BULB Mp.MXT_AD_STILL_MODE Mp.MXT_AD_DARK_MODE Mp.MXT_AD_EXPOSE_MODE These are exposure types for area detectors. Added the MP_BUILD_PYC makefile macro and the libMp/mp_build_pyc.bat script for Windows. With this change, Mp will build successfully on Windows from a Cygwin bash shell, __IF__ and only if all of the DLLs linked to libMx are in the path. If this is not the case, then the build of the *.pyc files will fail with a DLL load failure. Added true 'make depend' support for win32. Added a new example program 'examples/mpscript/mp_ad_take_image' that demonstrates acquiring and saving an image from an area detector. Version 1.5.2 (03/30/10): New methods added: Mp.AreaDetector Added status bit definitions for use by the get_status() and get_extended_status() methods. Mp.ImageFrame get_file_format_type_from_name() - This returns the file format type for an image rather than the in-memory format. Mp.Motor Added status bit definitions for use by the get_status() and get_extended_status() methods. Mp.Net connected() - This reports whether or not a given MX network field is connected to the remote server. Mp.c_wait_for_debugger() - This method waits for a C debugger such as GDB to attach to the process. Modified methods: Mp.ImageFrame Renamed get_format_type_from_name() to get_image_format_type_from_name(). 'mpshell' now uses the 'readline' module (if present) on Posix systems. Version 1.5.1 (10/04/09): New methods added: Mp.RecordList get_all_records() - This method returns a Python list of Mp.Record objects that corresponds to all of the records in the MX C database. Mp.Motor multiple_motors_move_absolute_with_flags() - This method starts motion for several motors using the supplied 'motion_flags' value. The previously existing method multiple_motors_move_absolute() is now implemented using this new method with 'motion_flags' set to 0. Mp.c_breakpoint() - This method invokes the mx_breakpoint() function of MX. Mp.change_filename_prefix() - This method can translate between two filename prefixes if the file can be accessed in more than one way. Modified methods: Mp.RecordList get_multiple_records() get_multiple_record_names() - The get_multiple_records() method now returns a list of record objects rather than a list of record names. You can get the old behavior using the new Mp.RecordList.get_multiple_record_names() method. In addition, the reverse_order argument has been removed since you can reverse the order of the list using the Python list.reverse() method. Version 1.5.0 (11/12/08): New classes added: Mp.Callback - This class encapsulates references to MX callbacks so that they can be passed to other Mp methods and functions. New methods added: Mp.RecordList connect_to_mx_server() - This method connects to the MX server at the specified hostname and port number and then returns an Mp server object. wait_for_messages() - This method waits for messages from any connected server until the specified timeout expires. Mp.Record resynchronize() - Invokes the mx_resynchronize_record() function on the MX record corresponding to the Mp.Record object. Mp.AreaDetector get_detector_readout_time() - Reports the total time required to read out the detector. This time may be for a single frame or for an entire sequence depending on the sequence type. get_total_sequence_time() - Reports the estimated time for the currently loaded sequence to run. get_total_num_frames() - Reports the total number of image frames received since the MX process was started. transfer_frame() - Modified to add an image_frame argument. Mp.DigitalInput pulse() - Generates an output pulse on a digital output for the specified duration. Mp.Server wait_for_message_id() - Waits until the arrival of a message using the supplied MX message ID or until the timeout expires. wait_for_messages_from_server() - Waits for messages from a particular MX server until the timeout expires. Mp.Net get_with_callback() - Designed to start an Mp get operation and then invoke a callback function when the operation completes. WARNING: For now this function is synchronous. get_attribute() - Returns the value of the specified network field attribute. set_attribute() - Sets the specified network field attribute to the specified value. get_attribute_number() - Returns the attribute number corresponding to the specified attribute name. add_callback() - Requests the MX server to set up an MX callback of the specified type, with the specified callback function and arguments. The method returns an Mp.Callback object. get_local_value() - This method returns the current value of the local copy of an Mp.Net object _without_ requesting an update of the value from the remote server. Added new 'mp_monitor' script. This script monitors a user supplied list of MX network fields for value changed callbacks. Added a new example script to demonstrate the use of value changed callbacks: mp/examples/mpscript/mp_move_callback - This script starts a motor move to the requested position and uses a value changed callback to notify the script that the move is complete. Added new 'mpenv' script. This script creates an environment in which the Mp module can run and then executes a user-supplied script. It does not actually load Mp itself or an MX database. Deleted the old Mp.CCD class which has been replaced by the Mp.AreaDetector class. Deleted the image_type attribute from the Mp.ImageFrame class. Version 1.4.0 (01/15/07): Three new classes have been added to MP to support the corresponding additions to MX: Mp.AreaDetector - This class provides support to MP scripts for MX-controlled area detectors. Mp.ImageFrame - This class provides a way of manipulating MX_IMAGE_FRAME structures from Python. Mp.Net - This class provides a way for MP scripts to perform low level I/O with an MX server via the Mp.Net.get() and Mp.Net.put() methods. At present, no MP class for MX video inputs has been created. This will be added as time permits. A new module called MpNum has been added. This module provides a single class called MpNum.Net which inherits from the Mp.Net class. The difference is that MpNum.Net reads and writes NumPy arrays, while the base class Mp.Net uses Python lists and tuples. The expectation is that MpNum.Net will normally be much faster than Mp.Net, but this expectation has not yet been tested with benchmarks. It is possible to configure the MP makefiles so that they do not attempt to compile MpNum.py on machines that do not have the 'numpy' Python module. However, even if the 'numpy' module is not available, the failure to compile MpNum.py will not cause the makefile to abort. Some test programs for the MpNum.Net class have been placed in the new subdirectory mp/net. The main program is called 'mpnet' while the other two programs 'mpget' and 'mpput' are symbolic links to 'mpnet'. 'mpget' and 'mpput' are intended to be similar to the 'mxget' and 'mxput' scripts from the MxTclNet package and may well replace them someday. One issue that remains to be resolved is whether or not 'mpget' should display the array returned in NumPy style format or alternately in a flattened format such as is currently used by 'mxget'. A couple of new functions have been added to the Mp.py module: Mp.start_c_debugger() - This function invokes the function called mx_start_debugger() in the underlying libMx library. Mp.start_py_debugger() - This function starts the 'pydb' Python debugger. In some cases it is useful to actually start both debuggers, so that 'pydb' debugs the Python part of the code, while DDD or GDB debugs the C part of the code. As far as I know, the order in which you start the two debuggers does not matter. It is now possible to compile a special version of MP that is compatible with the debugging version of Python. If you use the debugging version of Python, it becomes possible to trace into the part of Python written in C, which is occasionally useful. The procedure for using this feature is to recompile MP with the definition -DPy_DEBUG added to CFLAGS and then start your Python script with an Python interpreter binary that has the debugging support built in. For the Debian Etch distribution, this requires installing the 'python-dbg' package which provides a debugging interpreter that is also called 'python-dbg'. New Mp.Record.open_hardware() and Mp.Record.close_hardware() methods have been added so that your Python script can invoke the underlying functions in libMx. The fact that they were absent was merely an oversight. Version 1.3.0 (08/08/06): Added support for the scanlog_info, set_scanlog_enable, and get_scanlog_enable functions. These allow progress messages in MX scans to be turned on or off independently of other informational messages. Version 1.2.0 (03/17/06): Minor tweaks to accomodate changes in the MX API for MX 1.2.0. Version 1.1.1 (01/11/06): Added support for the new MX PTZ device class for Pan/Tilt/Zoom camera base controllers. Added support for the new info_entry_dialog routines that prompt users for text input from core MX software routines. Currently only used by the MX routine that prompts for a Blu-Ice username and password. MP now uses the new mx_initialize_runtime() function to setup the correct runtime environment for MX. Replaced calls to strcpy(), strncpy(), sprintf(), and vsprintf() with calls to strlcpy(), snprintf() and vsnprintf(). Makefile updates for newer operating system versions and for minor changes to the build system. Version 1.1.0 (07/13/05): The Mp.Variable class methods write and send_variable no longer require single object arguments passed to them to be converted to a 1-element tuple by the calling script. In addition, if the methods read and receive_variable are about to return a 1-element tuple to the caller, they unpack the tuple and directly return the object inside to the caller. This means that a method call like d = d_spacing_variable.read() now returns a value like 3.13555 rather than the previous behavior of returning (3.13555,). MP now defines its own set of Python exceptions that are returned when MX returns an error code. There is a 1-to-1 mapping between MX errors and MP exceptions. For example: MXE_ILLEGAL_ARGUMENT --> Mp.Illegal_Argument_Error MXE_NOT_READY --> Mp.Not_Ready_Error Added new methods to the Mp.MCA class called get_soft_roi_integrals, get_energy_scale, set_energy_scale, get_energy_offset, set energy_offset, get_energy_axis. Except for the first one, all of these methods were added to support displaying MCA spectra with an X axis in units of energy rather than channel number. Added new methods to the Mp.Motor class called get_status and get_extended_status which directly call the underlying MX functions mx_motor_get_status() and mx_motor_get_extended_status(). Added support for scan pause request handlers. These handlers allow the user to pause a scan in progress and then optionally resume the scan. Version 1.0.2 (08/27/04): Added two new device classes called Mp.USB and Mp.USBDevice. While an Mp.USB object does have a directly corresponding MX_RECORD, an Mp.USBDevice object does not. You obtain an Mp.USBDevice object from an Mp.USB object by a method like the following, where libusb is the usb record: usb = record_list.get_object( 'libusb' ) usbdev = usb.find_device_by_order( 0x6c2, 0x46, 0, 1, 0, 0, 0 ) You can find the arguments to find_device_by_order in the module file 'libMp/Mp.py'. This first implementation of an MX USB interface contains support for both control transfers and bulk transfers, although only the bulk transfers are really tested. There is currently no support for interrupt and isochronous transfers, since the Linux libusb package itself does not contain support for them. A new application program 'mpshell' based on 'mpscript' has been added. It provides a Python command interpreter similar to the one you get with the interactive 'python' command. The difference is that once you get to the command line of 'mpshell', MX is already setup with a running MX database loaded from the $MXDIR/etc/motor.dat file. 'mpshell' predefines two objects called 'record_list' and 'argv', where 'record_list' is the MX record list object for the running database and 'argv' is a tuple containing the command line arguments from sys.argv, but with the leading arguments 'python' and 'mpscript' stripped off. One example of using 'mpshell' looks like: === start of example === nyx:~$ mpshell (MX Python Interactive Console) >>> print record_list >>> print argv [] >>> theta = record_list.get_record( 'theta' ) >>> theta.get_position() 9.175650000000001 >>> theta.move_absolute( 20 ) >>> theta.get_position() 10.575650000000001 >>> theta.get_position() 13.17065 >>> theta.get_position() 15.290650000000001 >>> theta.get_position() 17.690650000000002 >>> theta.get_position() 19.854200000000002 >>> theta.get_position() 20.0 >>> ^D nyx:~$ === end of example === 'mpshell' is certainly not a replacement for 'motor', but it does expose a variety of interfaces to MX that are not directly available in 'motor'. Version 1.0.1 (05/26/04): Added new methods for the Mp.AnalogInput class called get_dark_current and set_dark_current. See the MX changelog for more information. Added a new method for the Mp.Timer class called get_last_measurement_time. This method can be used for computing dark current corrections directly in Python code. Version 1.0.0 (04/26/04): Added two new device classes called Mp.SampleChanger and Mp.MODBUS. The Mp.SampleChanger class is intended for use with robotic sample changers such as are used at many new crystallography beamlines. The Mp.MODBUS class is an interface to the new MODBUS fieldbus protocol in MX. Added get_signal_state and set_signal_state methods to the Mp.RS232 class. These methods allow the program to read and change the state of individual RS-232 pins. The Mp.VME class methods for multiword data transfer have been modified to include a new argument for the address increment. If the address increment is 0, then each read or write is done using the same VME bus address. If the address increment is _not_ zero, then the VME bus address is incremented by that value between each VME read or write. The Mp.CCD class now has a new method called start_for_preset_time. The Mp.Variable class now permits the passing of strings as arguments as requested by Jim Fait. Version 0.66.1 (08/24/03): The MX architecture 'freebsd' has been renamed to 'bsd' to reflect the fact that it builds equally well on FreeBSD, NetBSD, and OpenBSD. Version 0.66.0 (08/15/03): Added two new device classes Mp.PulseGenerator and Mp.CCD. The Mp.PulseGenerator class is a Python interface to the already existing MX pulse generator support, while the Mp.CCD class is an interface to the new MX support for remote control of CCD detectors. Added several new methods to the Mp.Motor class, namely, set_acceleration_time, get_gain, set_gain, and send_control_command. The get_gain and set_gain methods allow Python scripts to read and modify motor servo loop parameters such as proportional gain, integral gain, derivative gain, and so forth. send_control_command is for operations like enabling a motor axis, resetting controller faults, and reenabling closed loop control when the controller has gone open loop. Added a new method shutdown_hardware to the Mp.RecordList class that was requested by Terry Griffin of Axian, Inc. This method invokes the libMx routine mx_shutdown_hardware() routine and is used to cleanly shutdown connections to data acquisition controllers when an MP script is preparing to exit. Version 0.65.0 (04/01/03): The MP makefiles have renamed the old ARCH and INSTALL_DIR variables to MX_ARCH and MX_INSTALL_DIR. A new Mp.SCA class has been added as an interface to the new SCA (single channel analyzer) drivers that have been added to the base MX package. A new method for Mp.RecordList objects called set_program_name has been added that allows MP client scripts to identify themselves to remote MX servers. Although this feature is optional, MP scripts are encouraged to make use of this feature, since it makes the MX server's list of clients more useful. The write() and send_variable() methods of the Mp.Variable class have been modified to verify that the supplied value argument is a Python tuple. The MP examples directory has been reorganized. The old 'mpscript' examples are now in an 'mpscript' subdirectory. New subdirectories include 'simple' and 'tkinter_ex'. The examples in the 'simple' directories show ways of invoking MP that are simpler, although somewhat less portable, than the method used by the 'mpscript' examples. 'tkinter_ex' contains a set of example classes used by Jim Fait of SER-CAT to build MP-based Tkinter GUIs for automatic tune feedback and other tasks. MP has added support for QNX and FreeBSD. All references to 'acceleration_parameters' in MP have been changed to 'raw_acceleration_parameters' to match the corresponding changes in MX. Version 0.62.0 (12/03/02): A new build target 'irix-gcc' has been added to support building MP under SGI Irix with GCC. See the changelogs for MX or MxTcl for the reasons. 'mpscript' has been modified to see if the environment variable MXDATABASE exists. If the variable MXDATABASE exists, then 'mpscript' loads its MX database from that file instead of the default file '/opt/mx/etc/motor.dat'. Steve Weigand of DND-CAT discovered some bugs in the creation of MP amplifier objects which prevented them from working correctly. These bugs have been fixed. Version 0.60.0 (08/13/02): New functions have been added for controlling where output messages are sent and for controlling where user input is received from. These functions are: Mp.info, Mp.set_info_output_function Mp.warning, Mp.set_warning_output_function Mp.debug, Mp.set_debug_output_function Mp.set_error_output_function Mp.info_dialog, Mp.set_info_dialog_output_function Mp.getch, Mp.kbhit Mp.user_requested_interrupt, Mp.set_user_interrupt_function These functions are primarily used to permit things like sending output to a GUI window, receiving user interrupts from a GUI button, and so forth. However, they are also useful in other circumstances like using MP under the Apache mod_python module. The old MpTk module was previously responsible for doing some of the tasks mentioned above. Since these functions have now been folded into the base Mp module, the MpTk module has been deleted. The MpScan module for loading and saving scans has now finally been completed and tested. A new 'get_previous_record' method has been added to MP records. In addition, 'get_multiple_records' now has an extra argument to specify the order in which the records should be returned. This is done to support returning a list of records in reverse order. 'mxgui' uses this to report its list of scans in reverse order in the scan selection dialog. New 'move_absolute_with_flags' and 'move_relative_with_flags' methods have been added to the motor class. This allows MP scripts to directly set the flags field in the underlying C functions. The 'is_at_home_switch' method for motors has been renamed to 'home_search_succeeded'. A new 'read_raw' method for scalers has been added. This is to allow clients to read a scaler without dark current subtraction being performed. The old 'read_dark_current_subtracted_value' method for scalers has been removed since the 'read' method itself now does this. Version 0.56.1 (04/04/02): MP has now been tested on MacOS X using the Fink version of Python 2.2. Fink (fink.sourceforge.net) is a project that has ported a large number of Unix applications to MacOS X including a rootless XFree86 server that can share the screen with Aqua. Fink manages them using a modified version of the Debian dpkg and apt-get package system. At this point, both Fink and native Aqua versions of Python should work with MP. The code that parses MX string variables was not correctly initializing the value of the max_string_token_length variable. This has been fixed. Version 0.56.0 (03/04/02): This is the initial release of the Python interface to MX called MP. MP provides an object oriented interface to the MX beamline control system. The currently implemented base object classes are: Mp.RecordList, Mp.Record The following higher level classes are derived from the base Mp.Record class: Mp.CAMAC, Mp.GPIB, Mp.Portio, Mp.RS232, Mp.VME Mp.Amplifier, Mp.AnalogInput, Mp.AnalogOutput, Mp.Autoscale, Mp.DigitalInput, Mp.DigitalOutput, Mp.Encoder, Mp.MCA, Mp.MCE, Mp.MCS, Mp.Motor, Mp.Relay, Mp.Scaler, Mp.Table, Mp.Timer Mp.Scan Mp.Variable Since _real_ documentation has not yet been written, you can examine the file 'libMp/Mp.py' to see what class methods and functions are currently available for the objects. All of the standard MX functionality is available for moving motors, reading counters, running scans, and so forth. The subdirectory 'examples' contains several examples of MP scripts written using the 'mpscript' utility. The mpscript utility is intended as a front end to the Mp module to make it easier to write simple scripts to control MX. Mpscript is invoked by a Unix shell or DOS prompt command of the form mpscript user_script argument1 argument2 argument3 ... Mpscript handles all of the MX and MP initialization and then invokes a 'main' procedure with the supplied arguments that is expected to be provided by the supplied 'user_script'. Here is a complete working example: -------------------------- cut here ----------------------- #! /usr/bin/env mpscript # # This script reports the position of the requested motor. # def main( record_list, argv ): if ( len(argv) != 1 ): print "" print "Usage: mp_get_position motorname" print "" sys.exit(0); motor = record_list.get_record( argv[0] ) position = motor.get_position() units = motor.get_field("units") print "Motor '%s' position = %g %s" % (argv[0], position, units) -------------------------- cut here ----------------------- Alternate examples may be found in the examples package found at http://www.imca.aps.anl.gov/mx/src/examples.tar.gz. The examples package shows examples in C, Tcl, and Python of performing a step scan either via directly commanded motor moves or via an MX scan record. The alternate examples example1.py and example2.py there demonstrate setting up the Mp module directly and do not go through the 'mpscript' package.