At present, this manual is incomplete and is a work in progress.
General description of records go here.
All motor records in MX support a common set of operations that are described in this chapter. We describe first the set of record fields found in the record description string in an MX database file for a motor.
Motor records are divided into two subclasses, namely, stepper and analog motors. The two classes are distinguished by the format of the numbers used to communicate with the underlying controller. Motor controllers for which positions, speeds, etc. are specified in integer units (steps or encoder ticks) are called stepper motors by MX motor support. Motor controllers for which positions, speeds, etc. are specified in floating point units are called analog motors by MX motor support.
The following fields must be included in the record description for a record in an MX database file. They must appear in the order presented below.
Field Name | Field Type | Number of Dimensions | Sizes | Description |
name | string | 1 | 16 | The name of the record |
mx_superclass | recordtype | 0 | 0 | The string “device” |
mx_class | recordtype | 0 | 0 | The string “motor” |
mx_type | recordtype | 0 | 0 | The name of the motor driver for this motor. |
label | string | 1 | 40 | A verbose description of the record. |
acl_description | string | 1 | 40 | Placeholder for an access control list (not yet implemented). |
raw_position | long for stepper, double for analog | 0 | 0 | The motor position in raw units. Generally this value will be overwritten by the position read from the motor controller. |
raw_backlash_correction | long for stepper, double for analog | 0 | 0 | The MX backlash correction in raw units. |
raw_negative_limit | long for stepper, double for analog | 0 | 0 | The software negative limit in raw units. |
raw_positive_limit | long for stepper, double for analog | 0 | 0 | The software positive limit in raw units. |
raw_deadband | long for stepper, double for analog | 0 | 0 | The motion deadband in raw units. A requested move is not performed unless the difference between the requested and the current positions is bigger than the deadband distance. |
raw_minimum_speed_limit | long for stepper, double for analog | 0 | 0 | The slowest raw speed that can be requested for this motor. Negative values have special meanings. -1 means there are no restrictions on the requested raw speed. -2 means that the speed cannot be changed. |
raw_maximum_speed_limit | long for stepper, double for analog | 0 | 0 | The fastest raw speed that can be requested for this motor. Negative values have the same meaning as for “raw_minimum_speed_limit”. |
scale | double | 0 | 0 | The “scale” field is used together with the “offset” field to compute positions in user units using the formula: user_units = scale * raw_units + offset. |
offset | double | 0 | 0 | See the description of the “scale” field. |
units | string | 1 | 16 | User units for the motor, such as um, or deg. |
theta device motor disabled_motor "" "" 0 0 -20000000 20000000 0 -1 -1 5e-05 0 deg
|
The disabled motor record was chosen for this example since it has no type-specific fields.
MX currently supports a wide variety of motor controllers.
This set of drivers supports both the Compumotor 6000 and 6K series of controllers from the Compumotor division of Parker Hannifin. Several different MX drivers are associated with this type of controller. They are:
So far these drivers have been tested with both the 6K and Zeta 6104 controllers.
Not yet written.
Go to the MX Motor Driver Support page for the common motor record description fields. For the compumotor driver, the following driver specific fields are present:
Field Name | Field Type | Number of Dimensions | Sizes | Description |
See Common motor field definitions
| ||||
compumotor_interface_record | record | 0 | 0 | The name of the Compumotor generic interface for this motor. |
controller_number | int | 0 | 0 | The controller number for this particular motor. |
axis_number | int | 0 | 0 | The axis number for this particular motor in the specified controller. |
flags | hex | 0 | 0 | Setting particular bits in the flags variable can modify the behavior of the driver. The individual bit values are specified below. |
Warning: The port number seems to have changed for more recent 6K controllers. Using a packet sniffer while the vendor supplied code for Windows is running should be able to determine the correct port number.
At present, Zeta 6104s occasionally stop communicating with the MX driver. The exact circumstances under which this occurs is not entirely clear. However, since most of our Compumotor usage is migrating towards the 6K series, the need to fix this issue may become less important.
The PMAC series of motor controllers is manufactured by Delta Tau Data Systems of Chatsworth, CA. PMAC motor controllers are definitely the most powerful motor controllers supported by MX. However, they are also the most complicated to setup and program of all the controllers supported by MX, so they may not be the best choice for simple applications.
The MX PMAC drivers are designed to be easily adaptable to any model of PMAC motor controller. However, so far the drivers have been mostly used with the Turbo PMAC series of controllers. The drivers listed below currently all operate via PMAC ASCII communication interfaces of various types.
MX has a large number of drivers for interacting with PMAC motor controllers:
pmac | Interface driver for controlling one or more PMAC motor controllers connected to an ASCII serial interface. |
pmac_motor | Motor driver for controlling a single motor of a PMAC controller. |
pmac_cs_axis | Motor driver for controlling a coordinate system axis belonging to a PMAC motor controller. |
pmac_mce | Multichannel encoder (MCE) driver for reading out any motor belonging to a given PMAC motor controller. |
pmac_ainput | Analog input driver for reading a floating point value from a PMAC variable. |
pmac_aoutput | Analog output driver for writing a floating point value to a PMAC variable. |
pmac_dinput | Digital input driver for reading an integer value from a PMAC variable. |
pmac_doutput | Digital output driver for writing an integer value to a PMAC variable. |
pmac_long | Variable driver for reading and writing signed integer values to and from a PMAC variable. |
pmac_ulong | Variable driver for reading and writing unsigned integer values to and from a PMAC variable. |
pmac_double | Variable driver for reading and writing floating point values to and from a PMAC variable. |
pmac1 interface generic pmac "" "" rs232 pmac1_rs232 1
|
Field Name | Field Type | Number of Dimensions | Sizes | Description |
See Common record field definitions
| ||||
port_type_name | string | 1 | 80 | A string such as rs232 that describes the type of PMAC interface this is. See below for more information. |
port_args | string | 1 | 80 | This contains port type specific information such as the name of an RS-232 port record. See below for more information. |
num_cards | int | 0 | 0 | The number of individual PMAC controllers attached to this interface. In most cases this will be 1. However, for a controller attached to a multidrop connection such as RS-485, this will be the number of controllers attached to the multidrop. |
PMAC ASCII command interfaces are accessible via a variety of different mechanisms such as RS-422, Ethernet, USB, VME, etc. Since the information needed to describe the interface can vary widely from interface type to interface type, the information needed to the interface is specified in a string called port_args. The currently defined port types are:
port_type_name | port_args |
rs232 | The name of the MX RS-232/422/485 record that this PMAC interface is attached to, such as pmac1_rs232 in the example above. |
epics_ect | This port type uses the string command and response interfaces provided with the EPICS PMAC software written by Tom Coleman of the Argonne National Laboratory ECT group. This port type uses EPICS process variable names that are constructed by appending “StrCmd” or “StrRsp” to the names. Thus, if the port args were “S18ID”, then the EPICS process variables used by this interface would be S18IDStrCmd.VAL and S18IDStrRsp.VAL. |
Note: There is an alternate set of MX EPICS drivers called pmac_tc_motor and pmac_bio_motor that is described elsewhere in this manual. | |
Note: It is anticipated that ethernet and maybe usb port types will be added at some point in the future.
An example pmac_motor record looks like
theta device motor pmac_motor "" "" 0 0 -10000000 10000000 0 -1 -1 0.05 0 um pmac1 0 4
|
Field Name | Field Type | Number of Dimensions | Sizes | Description |
See Common motor field definitions
| ||||
pmac_record | record | 0 | 0 | Name of the PMAC interface record that controls this motor. |
card_number | int | 0 | 0 | Card number of the PMAC card that controls this motor. For PMACs that are not in a multi-drop configuration, the card number will normally be 0. |
motor_number | int | 0 | 0 | The PMAC axis number for this specific motor. |
Warning: This driver has not yet been tested on a real beamline.
Pmac_cs_axis motor records require that some preliminary setup be done in the PMAC before they may be used. There are three primary steps in this process:
An example pmac_cs_axis record looks like
det_distance motor pmac_cs_axis "" "" 0 0 200 1000 0 -1 -1 1 0 mm pmac1 0 2 Z 3 Q50 Q51 Q52 Q53 Q54
|
Field Name | Field Type | Number of Dimensions | Sizes | Description |
See Common motor field definitions
| ||||
pmac_record | record | 0 | 0 | Name of the PMAC interface record that controls this axis. |
card_number | int | 0 | 0 | Card number of the PMAC card that controls this axis. For PMACs that are not in a multi-drop configuration, the card number will normally be 0. |
axis_name | char | 0 | 0 | The name of the coordinate system axis used by this motor. The possible names are X, Y, Z, ???, A, B, and C. |
move_program_number | int | 0 | 0 | The number of the motion program that is used to move this axis as part of the coordinate system. |
position_variable | string | 1 | 8 | Name of the PMAC variable that the MX driver uses to read the current position of the axis from. |
destination_variable | string | 1 | 8 | The MX driver writes the new axis destination to this PMAC variable before starting the motion program to perform the move. |
feedrate_variable | string | 1 | 8 | The MX driver sets the axis speed by writing to the specified PMAC feedrate variable. |
acceleration_time_variable | string | 1 | 8 | The MX driver sets the axis acceleration time by writing to this variable. |
s_curve_acceleration_time_variable | string | 1 | 8 | The MX driver sets the axis S-curve acceleration time by writing to this variable. |
Note: If all you want is basic control of the individual motors belonging to a PMAC controller, then it is not necessary to create MX pmac_cs_axis motor records or coordinate systems in the PMAC. You can get basic control of the motors with just the pmac_motor records, with much less setup required. You only need pmac_cs_axis records if you want to make use of the special abilities of PMAC coordinate systems.
This is an MX motor driver for the Joerger SMC24 CAMAC stepping motor controller, which is still available as of August 2003, from Joerger Enterprises, Inc.
Warning: As far as I know, this driver has not been tested in a long time. However, if broken, I expect that it would take less than a day to get the MX driver working again.
The Joerger SMC24 controller does not have an internal register to record its current position, so it needs the assistance of an external device to keep track of the motor’s absolute position. Traditionally, a Kinetic Systems 3640 CAMAC up/down counter is used as the external device, but any device capable of acting as an encoder-like device may be used as long as there is an MX encoder driver for it.
Also, traditionally the Kinetic Systems 3640 up/down counter was modified in the field to connect pairs of 16-bit up/down counters to form 32-bit up/down counters. However, if this has not been done, the driver can also emulate in software a 32-bit step counter using a 16-bit hardware encoder by setting the bit in the ”flags” variable called MXF_SMC24_USE_32BIT_SOFTWARE_COUNTER (0x1) .
The MX driver for the PM304 requires that responses from the controller include an address prefix. By default, the PM304 has this feature turned off. You may turn it on by sending the string
1AD |
Note: For the MM4000, this driver assumes that the value of the field “Terminator” under “General Setup” for the controller is set to CR/LF.
There are several other ITC503 control commands, but only the ones likely to be used in routine operation are supported.
The permitted board numbers are from 1 to 255.
The permitted values for digital I/O pins are:
0 | - | Disable the pin. |
3, 5, 6, 8 | - | The pin is active closed. |
-3, -5, -6, -8 | - | The pin is active open. |
Pins 5 and 6 are normally used for limit switches while either pin 3 or pin 8 is used for the home switch. This is because pins 5 and 6 already have pullup resistors.
The output of the RP command is 0 = closed and 1 = open.
By default, the HSC-1 Huber Slit Controllers are delivered with default values that do not allow the slit blades to be moved to anywhere the blades can physically reach. The default values for parameters 1 and 2 are:
Parameter | Name | Default Value | Default in um |
1 | Outer Motion Limit | 4400 | 11000 um |
2 | Origin Position | 400 | 1000 um |
The MX drivers for the HSC-1 assume that these two parameters have been redefined to have the following values:
Parameter | Name | Default Value | Default in um |
1 | Outer Motion Limit | 10400 | 26000 um |
2 | Origin Position | 5200 | 13000 um |
The reprogramming must be done using a terminal program like Kermit or Minicom. Suppose you have an HSC-1
controller with a serial number of XIAHSC-B-0001. Then the appropriate commands to send to the HSC-1 would
be:
!XIAHSC-B-0001 W 1 10400
!XIAHSC-B-0001 W 2 5200 |
XIA motor name | negative limit (raw units) | positive limit (raw units) | scale | offset |
A | -65535 | 65535 | 2.5 | -13000 |
B | -65535 | 65535 | 2.5 | -13000 |
C | -65535 | 65535 | 2.5 | 0 |
S | 0 | 131071 | 2.5 | -26000 |
Then, you will be able to move the A, B, and C motors from -13000 um to +13000 um and the S motor from 0 um to 26000 um.
Please note that the HSC-1 motor positions can only be set to the value 0. A “set motor ... position” command to any other value than zero will fail. The “set motor ... position 0” command itself will cause the HSC-1 to execute an “Immediate Calibration” or “0 I” command. Also note that the slit size motor S cannot be moved to a negative value, so if S is at zero and there is a visible gap between the blades, then you will have to manually close the slit by hand.
Here is an example database for two HSC-1 controllers attached to the same serial port:
hsc1_rs232 interface rs232 tty "" "" 9600 8 N 1 N 0xd0a 0xd /dev/ttyS0 hsc1_1 interface generic hsc1 "" "" hsc1_rs232 2 XIAHSC-B-0067 XIAHSC-B-0069 hsc67a device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 -13000 um hsc1_1 0 A hsc67b device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 -13000 um hsc1_1 0 B hsc67c device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 0 um hsc1_1 0 C hsc67s device motor hsc1_motor "" "" 0 0 0 131071 0 -1 -1 2.5 -26000 um hsc1_1 0 S hsc69a device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 -13000 um hsc1_1 1 A hsc69b device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 -13000 um hsc1_1 1 B hsc69c device motor hsc1_motor "" "" 0 0 -65535 65535 0 -1 -1 2.5 0 um hsc1_1 1 C hsc69s device motor hsc1_motor "" "" 0 0 0 131071 0 -1 -1 2.5 -26000 um hsc1_1 1 S |
Pseudomotor support goes here.
This is an MX motor driver for the pseudomotors used by Gerd Rosenbaum’s A-frame CCD detector mount. The geometry of this detector mount is shown in the following figure:
The pseudomotors available are:
There are three constants that describe the system:
The pseudomotors depend on the positions of three real motors. These are:
Confused? I am planning to write a short document that describes the definitions of these parameters in more detail and derives the formulas describing them. If you are reading this text and I have not yet written that document, then pester me until I do write it.
Warning: The detector horizonal angle is expressed internally in radians. If you want to display the angle in degrees, use the scale field of the angle pseudomotor to do the conversion.
The monochromator pseudomotor is implemented using a large collection of MX records. These records can be categorized into several groups:
where the value of N above is set by the value of the num_dependencies field in the monochromator record.
The MX Motor Driver Support page describes the common motor record description fields. For the monochromator driver, the following driver specific fields are present:
Field Name | Field Type | Number of Dimensions | Sizes | Description |
See Common motor field definitions
| ||||
num_dependencies | long | 0 | 0 | The number of dependencies for this monochromator pseudomotor. |
list_array | record | 1 | num_dependencies | The list of depencency list records. |
Example:
theta device motor monochromator "" "" 0 0 -10 270 0 -1 -1 1 0 deg 4 theta_list momega_list id_ev_list normal_list
|
The monochromator record is a pseudomotor record which contains a list of the dependencies used by the pseudomotor. In general, one of the dependencies will be a primary dependency which describes the primary axis used by the monochromator pseudomotor (usually theta). The rest of the dependencies will be secondary dependencies that describe motors that are to be moved to positions that depend on the position of the primary dependency motor. There should only be one primary dependency.
In the example above, the dependencies specified are:
This example does not include all of the available dependency types which are described in more detail below. In addition, the primary dependency does not have to be the first record listed, but it is customary to do so.
An example dependency list record looks like
momega_list variable inline record "" "" 1 4 momega_enabled momega_type momega_params momega_records
|
The individual elements of the array are described in more detail below.
An example dependency enable record looks like
momega_enabled variable net_variable net_int "" "" localhost momega_enabled.value 1 1 0
|
An example dependency parameters record looks like
momega_params variable net_variable net_double "" "" localhost momega_params.value 1 4 0 0 0 0
|
An example dependency record list looks like
momega_records variable inline record "" "" 1 1 momega
|
An example dependency type record looks like
momega_type variable inline int "" "" 1 1 2
|
At present, nine different dependency types are available. Dependency types 0 and 1 are primary dependency types, while types 2 through 8 are secondary dependency types.
The theta dependency is used to control the position of the primary theta axis. This dependency is normally the primary dependency for the monochromator pseudomotor. If this dependency does not exist or is disabled, the real theta axis will not be moved at all.
An example set of records for the theta dependency looks like
theta_list variable inline record "" "" 1 4 theta_enabled theta_type dummy_params theta_records
theta_type variable inline int "" "" 1 1 0 theta_enabled variable inline int "" "" 1 1 1 theta_records variable inline record "" "" 1 1 theta_real dummy_params variable inline double "" "" 1 1 0 |
Normally, there is no reason for the users to disable this dependency, so it is standard to hard code it to 1 as in the example above.
The energy dependency is a primary dependency that computes the monochromator theta angle from a monochromator energy provided by a foreign beamline control system. Use of this dependency is not recommended, unless the underlying beamline control software/hardware does not provide a direct way of querying and controlling the theta angle. Use of this dependency is incompatible with the type 0 theta dependency specified above. Do not specify both of them in the same MX database.
If you are looking for a way to control a dependent motor as a polynomial function of energy, you should be using the type 8 energy polynomial dependency described below.
An example set of records for the energy dependency looks like
energy_list variable inline record "" "" 1 4 energy_enabled energy_type dummy_params energy_records
energy_type variable inline int "" "" 1 1 1 energy_enabled variable net_variable net_int "" "" 1 1 1 energy_records variable inline record "" "" 1 2 energy d_spacing dummy_params variable inline double "" "" 1 1 0 |
d_spacing variable net_variable net_double "" "" localhost d_spacing.value 1 1 3.1355
|
The monochromator theta angle is computed using the standard Bragg equation
theta = asin( 12398.5 / ( 2.0 * d_spacing * energy ) )
Normally, there is no reason for the users to disable this dependency, so it is standard to hard code it to 1 as in the example above.
This dependency type is a secondary dependency that allows a dependent motor to be moved to positions that are a polynomial function of the theta position of the monochromator. The computed position will be of the form
dependent_position = c0 + c1 * theta + c2 * (theta**2) + c3 * (theta**3) + ...
Beamline staff may configure this polynomial to have as few or as many terms in it as they want by changing the number of elements in the parameters array below. For example, a parameters array record with only two array elements will describe a dependent position that has a linear dependence on theta, while a parameters array record with four array elements describes a cubic dependence on theta. It is generally not useful to use a polynomial of higher order than cubic, although there is no limit in the record as to how high the order may be.
An example set of records for the polynomial dependency looks like
momega_list variable inline record "" "" 1 4 momega_enabled momega_type momega_params momega_records
momega_type variable inline int "" "" 1 1 2 momega_enabled variable net_variable net_int "" "" localhost momega_enabled.value 1 1 0 momega_records variable inline record "" "" 1 1 momega momega_params variable net_variable net_double "" "" localhost momega_params.value 1 4 0 0 0 0 |
momega = 0.32 + 0.41 * theta - 0.02 * (theta**2) + 0.015 * (theta**3)
Typically, the values of these coefficients will be determined by measuring the location of the peak X-ray intensity as a function of the dependent motor position for several values of theta Then a curve will be fitted to the measurements.
This dependency type is a secondary dependency that changes the energy of the undulator peak such that the maximum of the undulator spectrum is at the same energy as the monochromator.
For a given monochromator theta position in degrees, the undulator energy is computed as follows:
mono_energy = 12398.5 / ( 2.0 * d_spacing * sin( theta ) )
undulator_energy = ( mono_energy + gap_offset ) / gap_harmonic
Please note that if the undulator controls provided by your storage ring also have a way of setting the gap harmonic in addition to the method provided by MX, then you should only set one of them to the harmonic number and set the other to 1. For example, at the APS, if you set both EPICS’s variable for the gap harmonic to 3 and MX’s variable for the gap harmonic to 3, you would actually end up with the ninth harmonic.
An example set of records for the insertion device energy dependency looks like
id_ev_list variable inline record "" "" 1 4 id_ev_enabled id_ev_type id_ev_params id_ev_records
id_ev_type variable inline int "" "" 1 1 3 id_ev_enabled variable net_variable net_int "" "" localhost id_ev_enabled.value 1 1 0 id_ev_records variable inline record "" "" 1 2 id_ev d_spacing id_ev_params variable net_variable net_double "" "" localhost id_ev_params.value 1 2 1 100 |
This dependency type is a secondary dependency that changes the perpendicular spacing between the first and second monochromator crystals so that the X-ray beam exiting the monochromator stays at a constant height.
An example set of records for the Bragg normal dependency looks like
normal_list variable inline record "" "" 1 4 normal_enabled normal_type dummy_params normal_records
normal_type variable inline int "" "" 1 1 4 normal_enabled variable net_variable net_int "" "" localhost normal_enabled.value 1 1 0 normal_records variable inline record "" "" 1 2 normal beam_offset dummy_params variable inline double "" "" 1 1 0 |
beam_offset variable net_variable net_double "" "" localhost beam_offset.value 1 1 -35000
|
bragg_normal = beam_offset / ( 2.0 * cos( theta ) )
If a positive move of the normal motor at theta = 0 is in the opposite direction from the desired beam offset, then the value of the beam offset must be set to a negative number. For example, this is true of the MX installations at APS sectors 10 and 17 where beam_offset = -35000 um.
This dependency type is a secondary dependency that translates the second crystal parallel to its surface. This dependency should normally be used in combination with the Bragg normal dependency listed above. It is used to ensure that the X-ray beam does not fall off the end of the second crystal.
An example set of records for the Bragg parallel dependency looks like
parallel_list variable inline record "" "" 1 4 parallel_enabled parallel_type dummy_params parallel_records
parallel_type variable inline int "" "" 1 1 5 parallel_enabled variable net_variable net_int "" "" localhost parallel_enabled.value 1 1 0 parallel_records variable inline record "" "" 1 2 parallel beam_offset dummy_params variable inline double "" "" 1 1 0 |
beam_offset variable net_variable net_double "" "" localhost beam_offset.value 1 1 -35000
|
The Bragg parallel position is computed from the beam offset and the monochromator theta angle via the equation
bragg_parallel = beam_offset / ( 2.0 * sin( theta ) )
If a given monochromator does not support fixed exit beam operation, an alternate way to ensure that the X-ray beam hits the desired target is to put the experiment on a table that can be vertically translated to track the beam.
An example set of records for the experiment table height dependency looks like
theight_list variable inline record "" "" 1 4 theight_enabled theight_type dummy_params theight_records
theight_type variable inline int "" "" 1 1 6 theight_enabled variable net_variable net_int "" "" localhost theight_enabled.value 1 1 0 theight_records variable inline record "" "" 1 3 theight toffset crystal_sep dummy_params variable inline double "" "" 1 1 0 |
toffset variable net_variable net_double "" "" localhost toffset.value 1 1 0
crystal_sep variable net_variable net_double "" "" localhost crystal_sep.value 1 1 5000 |
The experiment table height position is computed via the equation
table_height = table_offset + 2.0 * crystal_separation * cos( theta )
The diffractometer theta dependency is used to control the Bragg angle of a diffractometer or goniostat in the experimental hutch so that it is set to the correct angle to diffract the X-ray beam coming from the monochromator. This dependency assumes that, in general, the crystal on the diffractometer will have a different d spacing than that of the monochromator crystal.
If the diffractometer angle is called htheta and the diffractometer d spacing is called hd_spacing, the diffractometer angle is computed by the equation
sin(htheta) = d_spacing * sin(theta) / hd_spacing
The raw value of htheta is adjusted using a linear equation of the form
htheta_adjusted = diffractometer_scale * htheta + diffractometer_offset
An example set of records for the diffractometer theta dependency looks like
htheta_list variable inline record "" "" 1 4 htheta_enabled htheta_type htheta_params htheta_records
htheta_type variable inline int "" "" 1 1 7 htheta_enabled variable net_variable net_int "" "" localhost htheta_enabled.value 1 1 0 htheta_records variable inline record "" "" 1 3 htheta d_spacing hd_spacing htheta_params variable net_variable net_double "" "" localhost htheta_params.value 1 2 0 0 |
The energy polynomial dependency is similar to the type 2 polynomial dependency described above, except the dependent motor position is a polynomial function of the monochromator X-ray energy. Thus, the dependent position will have the form
dependent_position = c0 + c1 * energy + c2 * (energy**2) + c3 * (energy**3) + ...
This dependency assumes that the energy is expressed in eV.
An example set of records for the energy polynomial dependency looks like
focus_list variable inline record "" "" 1 4 focus_enabled focus_type focus_params focus_records
focus_type variable inline int "" "" 1 1 8 focus_enabled variable net_variable net_int "" "" localhost focus_enabled.value 1 1 0 focus_records variable inline record "" "" 1 2 focus d_spacing focus_params variable net_variable net_double "" "" localhost focus_params.value 1 4 0 0 0 0 |
The option selector dependency is used together with a “position_select” calculation record to switch an external value between multiple settings depending on the current value of the monochromator theta position. The “position_select” variable has an integer value from 1 to N. For example, this could be used to automatically switch between mirror stripes at certain X-ray energies.
The number N is the number of theta ranges.
An example set of records for the option selector dependency looks like
stripe_list variable inline record "" "" 1 4 stripe_enabled stripe_type dummy_params stripe_records
stripe_type variable inline int "" "" 1 1 9 stripe_enabled variable inline int "" "" 1 1 1 stripe_records variable inline record "" "" 1 2 stripe_select stripe_params stripe_params variable inline double "" "" 2 4 2 0 5 4.5 8.5 8 11 10.5 15 stripe_select variable calc position_select "" "" stripe 4 300 600 900 1200 1 1 -1 stripe device motor soft_motor "" "" 0 0 -1000000000 1000000000 0 -1 -1 0.01 0 um 100000 0 50000 |
The example above is for an X-ray mirror whose transverse position is determined by a motor record called stripe. There are 4 allowed positions for stripe, namely, 300, 600, 900, and 1200. The allowed theta ranges corresponding to the allowed positions are 0 to 5 degrees, 4.5 to 8.5 degrees, 8 to 11 degrees, and 10.5 to 15 degrees. The stripe position to be selected is determined by comparing the current position of theta to the parameter ranges in the variable stripe_params. According to stripe_params, the stripe motor is allowed to be at 300 if theta is between 0 and 5, or it is allowed to be at 600 if theta is between 4.5 and 8.5, and so forth. If theta moves outside the allowed range of positions for the current selection, the option selector will switch to the next selection.
Notice that the allowed ranges for theta overlap. This is to provide a deadband for switches between option selector ranges. As an example, suppose theta is currently at 7 degrees. This means that theta is within the second option selector range of 4.5 to 8.5 degrees and that the stripe motor should currently be at 600. However, if theta is moved to 9 degrees, this is outside the current option selector range, so stripe will be moved to the next allowed position of 900. However, the lower end of the new range, namely, 8 degrees, is below the upper end of the original range, namely, 8.5 degrees. This means that theta must be moved below 8 degrees before the stripe position will be moved back to the previous value of 600.
Note that if theta is below 0 degrees, the stripe motor will be sent to 300, while if theta is above 15 degrees, the stripe motor will be moved to 1200.
Some of the dependencies are user configurable via the parameters record while others are configured via additional records added to the record list.
This is an MX pseudomotor driver for the momentum transfer parameter q, which is defined as
Warning: above must not be set to the angle of the analyzer arm. Instead, it must be set to half of that angle which is the nominal Bragg angle.
slit_type field - This integer field select the type of slit pseudomotor that this record represents. There are four possible values for the slit_type field, which come in two groups of two, namely, the SAME case and the OPPOSITE case. The allowed values are:
The SAME cases above are for slit blade pairs that move in the same physical direction when they are both commanded to perform moves of the same sign. The OPPOSITE cases are for slit blade pairs that move in the opposite direction from each other when they are both commanded to perform moves of the same sign.
As an example, for a top and bottom slit blade pair, if a positive move of each causes both blades to go up, you use the SAME case. On the other hand, if a positive move of each causes the top slit blade to go up and the bottom slit blade to go down, you use the OPPOSITE case.
This is an MX motor driver to move a tangent arm or sine arm pseudomotor.
IMPORTANT: The moving motor position and the arm length must both be specified using the same user units, while the angle offset must be specified in radians. Thus, if the moving motor position is specified in micrometers, then the arm length must be specified in micrometers as well.
If you want to specify the angle offset in degrees rather than in radians, the simplest way is to create a ’translation_mtr’ record containing only the raw angle offset motor. Then, set a scale factor in the translation motor record that converts from radians to degrees.
A tangent arm consists of two arms that are connected at a pivot point as follows:
* B * * * | * | * | * | m * | * | * \ theta | *-----------------------+------ ^ a A | | pivot point |
A linear motor is attached to the fixed arm at point A and then moves a push rod that pushes the moving arm at point B. In this geometry, the position of the moving motor, m, is related to the angle theta by the relationship
A sine arm is similar except that the linear motion is now perpendicular to the moving arm:
* * * B * * * \ * \ * \ m * \ * \ theta \ *-----------------------+------ ^ a A | | pivot point |
This changes the equation to the form
Note: The ’tangent_arm’ and ’sine_arm’ drivers share the same code and distinguished in the driver code by their different driver types, namely, MXT_MTR_TANGENT_ARM and MXT_MTR_SINE_ARM.
This MX pseudomotor driver controls another MX motor in units of XAFS electron wavenumber.
The XAFS electron wavenumber k is computed using the equation:
The following is an example database for the IIT BCPS setup for Am9513 boards:
ports interface portio linux_portio "" "" /dev/portio am9513 interface generic am9513 "" "" ports 0x284 0x1b0 i8255 interface generic i8255 "" "" ports 0x280 # # Motor 1 uses Am9513 counters 1 & 2 to generate the motor step pulses while # 8255 output bit 2 of port C is used to generate the direction signal. # motor1 device motor am9513_motor "" "" 0 0 -1000000 1000000 0 -1 -1 0.005 0 um 2 am9513:1 am9513:2 portc 2 5000000 1000 0 portc device digital_output i8255_out "" "" 0 i8255 C # # Scaler 1 is a 32 bit scaler created using Am9513 counters 4 & 5. The # counter is gated by the gate input for its low order counter (GATE4), # while external pulses to be counted are fed to the source input for # its low order counter (SRC4). # scaler1 device scaler am9513_scaler "" "" 0 0 0 2 am9513:4 am9513:5 0x4 0x4 # # Timer 1 is a 16 bit timer created using Am9513 counter 3. It is using # a 5 MHz clock signal. # timer1 device timer am9513_timer "" "" 1 am9513:3 5000000 |
Warning: The am9513 interface driver has only been fully implemented and tested for Am9513-based systems using 8-bit bus access.
At present, MX Am9513 timers can only use one 16-bit counter. Also note that the timer driver relies on the output for the timer’s counter being connected to its own gate input. That is, OUT(n) must be connected to GATE(n) for the timer to work. Of course, OUT(n) is also connected to the GATE inputs of the scalers that this timer is gating.
The MX EPICS scaler support optionally can make use of globally visible dark current values. This is done by loading an additional EPICS database file in “st.cmd” that can be found in the MX base distribution in the file mx/driver_info/epics_scaler/Jscaler_dark.db. This EPICS database implements two additional records per EPICS scaler channel. For example, for scaler channel 2 the records are
where $(P) and $(S) are defined to have the same values as in the standard Jscaler.db database. The database is loaded into the EPICS VME crate by adding a line to the ’st.cmd’ startup script that looks like
dbLoadRecords("iocBoot/ioc1/Jscaler_dark.db","P=s10id:,S=scaler1,C=0", top) |
Please note that this database contains a definition for the scaler record $(P) and $(S) itself and thus is not immediately compatible with the standard Jscaler.db database. This is due to the fact that EPICS does not supply any way for an add-on database to add forward links to existing records. If you wish to combine Jscaler.db and Jscaler_dark.db, the simplest way is to merely move the FLNK field whose value is “$(P)$(S)_cts1.PROC” in Jscaler.db to the LNK4 field of Fanout record “$(P)$(S)_fan0” defined in Jscaler_dark.db.
Hopefully, something equivalent to the dark current fields in Jscaler_dark.db will be added to some future version of Jscaler.db.
The MX timer fanout driver is used to control multiple MX timers in software as if they were one timer.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
This driver does NOT attempt to ensure that all of the timers start at exactly the same time. This means that devices gated by different timers may not be gated on for exactly the same timer interval, although the lengths of time they are gated on for should be the same. The result is that you may get SYSTEMATIC ERRORS if you do not use this driver intelligently. It is up to you to decide whether or not this makes a difference to the experiment you are performing. The best solution is to make sure that all of your measuring devices are gated by the same hardware timer, but if that is not possible, then this driver may be useful as a stopgap.
Caveat emptor.
The MX EPICS MCS support optionally can make use of globally visible dark current values. This is done by loading an additional EPICS analog output record per MCS channel which is used to store the dark current value. This is most easily described by giving an example.
Suppose you have a set of MCS records loaded in the EPICS “st.cmd” script that look like
dbLoadRecords("mcaApp/Db/mca.db","P=s10id:,M=mcs1,CARD=0,SIGNAL=0,DTYPE=Struck STR7201 MCS,NCHAN=2000", share) dbLoadRecords("mcaApp/Db/mca.db","P=s10id:,M=mcs2,CARD=0,SIGNAL=1,DTYPE=Struck STR7201 MCS,NCHAN=2000", share) dbLoadRecords("mcaApp/Db/mca.db","P=s10id:,M=mcs3,CARD=0,SIGNAL=2,DTYPE=Struck STR7201 MCS,NCHAN=2000", share) dbLoadRecords("mcaApp/Db/mca.db","P=s10id:,M=mcs4,CARD=0,SIGNAL=3,DTYPE=Struck STR7201 MCS,NCHAN=2000", share) |
Then, all that you need to add to support dark currents for these channels is to add something like the following lines to “st.cmd”.
dbLoadRecords("iocBoot/ioc1/mcs_dark.db","P=s10id:,M=mcs1", top) dbLoadRecords("iocBoot/ioc1/mcs_dark.db","P=s10id:,M=mcs2", top) dbLoadRecords("iocBoot/ioc1/mcs_dark.db","P=s10id:,M=mcs3", top) dbLoadRecords("iocBoot/ioc1/mcs_dark.db","P=s10id:,M=mcs4", top) |
The mcs_dark.db database file is extremely simple. The entire contents of the file is:
grecord(ao,"$(P)$(M)_Dark") { field(PREC,"3") } |
A copy of this file may be found in the MX base source distribution in the file mx/driver_info/epics_mcs/mcs_dark.db.
The ADC table is designed to support a standard crystallography goniostat. At present, it is the support for an ADSC Quantum 105 detector system. The geometry of the table is shown by the figure below:
The MX table support for ADC tables uses two different kinds of records, namely, an ADC specific table record described here and the generic table motor record described in the motor section.
Field Name | Field Type | Number of Dimensions | Sizes | Description |
name | string | 1 | 16 | The name of the record |
mx_superclass | recordtype | 0 | 0 | The string “device” |
mx_class | recordtype | 0 | 0 | The string “table” |
mx_type | recordtype | 0 | 0 | The string “adc_table” |
label | string | 1 | 40 | A verbose description of the record. |
acl_description | string | 1 | 40 | Placeholder for an access control list (not yet implemented). |
motor_record_array | record | 1 | 6 | The names of the raw motor records used by this table record listed in the order X1, Y1, Y2, Z1, Z2, and Z3. |
m1 | double | 0 | 0 | Distance from the table zero point to the Z1 pivot point. |
m2 | double | 0 | 0 | Distance from the table zero point to the Z2 pivot point. |
m3 | double | 0 | 0 | Distance from the table zero point to the Z3 pivot point. |
rx | double | 0 | 0 | X component of the distance from the table zero point to the rotation center. |
ry | double | 0 | 0 | Y component of the distance from the table zero point to the rotation center. |
rz | double | 0 | 0 | Z component of the distance from the table zero point to the rotation center. |
An example database for this table type would look like:
adsc_table device table adc_table "" "" x1 y1 y2 z1 z2 z3 0.4 0.6 0.75 0.25 0.25 0.5
x1 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um y1 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um y2 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um z1 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um z2 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um z3 device motor soft_motor "" "" 0 0 -20000000 20000000 0 -1 -1 0.001 0 um tx device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 um adsc_table 1 ty device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 um adsc_table 2 tz device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 um adsc_table 3 troll device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 urad adsc_table 4 tpitch device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 urad adsc_table 5 tyaw device motor table_motor "" "" 0 0 -20000000 20000000 0 -1 -1 1 0 urad adsc_table 6 |
In this example, the adsc_table record is the actual table record itself. It is configured to use soft motors x1, y1, y2, z1, z2, and z3 as the raw motors. The table parameters for the example are set to m1 = 0.4, m2 = 0.6, m3 = 0.75, rx = 0.25, ry = 0.25, and rz = 0.5.
MX scaler driver to control MX gain tracking scalers. Gain tracking scalers are pseudoscalers that rescale their reported number of counts to go up and down when an associated amplifier changes its gain.
For example, suppose that the real scaler was reading 1745 counts, the amplifier was set to 108 gain and the gain tracking scale factor was 1010. Then, the gain tracking scaler would report a value of 174500 counts. If the amplifier gain was changed to 109 , then the gain tracking scaler would report a value of 17450 counts.
Gain tracking scalers are intended to be used in combination with autoscaling scalers, so that when the autoscaling scaler changes the gain of the amplifier, the values reported by gain tracking scalers will change to match.
Warning: This MX driver was originally developed for the Linux 2.0.x device driver provided by the Linux Lab Project, but that project seems to have stalled. Fortunately, the code seems to have been picked up by the Linux GPIB Package Homepage (http://linux-gpib.sourceforge.net/) which supports Linux 2.4.x. However, this MX driver has not yet been tested with the new Linux 2.4.x version of the device driver.
The Linux Lab Project GPIB driver does not provide an equivalent to the ibdev() function that finds a GPIB device by address. That makes the Linux Lab Project driver the only one that does not provide such an interface, so it is easier just to provide one for it. This is handled by adding to /etc/gpib.conf the contents of the file mx/driver_info/llp_gpib/gpib.conf_addon from the MX base source distribution, so that there is a way to find a given GPIB device by its primary address. The contents of the file gpib.conf_addon is shown in the following figure:
|
This MX driver is an interface to the DriverLINX port I/O driver for Windows NT/98/95 written by Scientific Software Tools, Inc. The DriverLINX package may be downloaded from http://www.sstnet.com/dnload/dnload.htm. This driver is primarily intended for use under Windows NT, since the ’dos_portio’ driver already handles Windows 98/95, but it should work on all three operating systems.
Warning: These drivers have not yet been tested with Windows 2000 or Windows XP.
There are several device drivers that were never finished for some reason or other. The source code is still maintained in the MX driver library just in case the opportunity arises to finish the work.