Advanced Photon Source
Argonne National Laboratory
Contents:
1. Introduction
1.1. A Simple One
Dimensional Scan
1.2. Multidimensional
Scans
1.3. Interaction with clients
1.3.1 Starting a scan
1.3.2 Stopping a scan
1.3.3 Pausing a scan
1.3.4 Displaying scan data
1.3.5 Handshaking with data-storage clients
1.3.6 Handshaking with CA clients that implement positioners or detectors
1.4. Completion of positioner and
detector-trigger operations
2. sscan-Record Fields
2.1. Control Fields
2.2. Positioner Fields
2.2.1 Linear Mode
2.2.2. Table Mode
2.3. Detector-Trigger Fields
2.4. Delay Fields
2.5. Client Handshaking Fields
2.6. Detector Fields
2.7. Execution Fields
2.8. Status/Progress Fields
2.10. Miscellaneous Fields
A single sscan record supports a one dimensional scan. Several sscan records can be linked together to perform a multi-dimensional scan. Each sscan record can control up to four positioners, trigger up to four detectors, and acquire data from up to 74 process variables (70 detector values of type float and four positioner readbacks of type double).
Typically, the sscan record moves motors and acquires scaler data at each motor position, but obviously it can also be used for other purposes. Any writable EPICS PV (process variable) can be scanned through a set of values while data are recorded from any other PVs. For example, one of the positioner PVs could be used to vary the gain or dwell time of a detector during a scan. Therefore, throughout this document the term positioner should be taken to mean "any PV to which you can write a number". Similarly, the term detector trigger typically refers to a PV that will cause data acquisition to begin when it is written to, but it could be taken to mean "any PV to which you can write a number". Finally, the term detector refers to any readable numeric PV.
The sscan record normally acquires sets of scalar data values and assembles them into arrays, but it can also acquire arrays directly from array-valued PVs. The end results can only be one-dimensional arrays, however; a single sscan record cannot acquire multi-dimensional data.
All of the process variable names used to identify positioners, detectors, and detector triggers are specified using reassignable links. This allows a scan to be configured on the fly. Currently, these links are implemented with the recDynLink library, which is distributed along with the scan module.
Let's run through that again, this time more generally, with more detail, and including more of the available options.
Detector-signal values can be accumulated from scan to scan, so you can sweep over a set of positions, building up statistical precision and averaging over any positioning errors or variable external conditions. (See ACQM.)
To initiate the scan, the scan2 record is commanded to begin (scan2.EXSC is set to 1). scan2 sends its positioners to their starting points, and waits for their callbacks. Then scan2 writes to its detector trigger(s), (one of) which in this case causes scan1 to begin its own scan. The scan1 record will now go through its entire programmed scan, acquiring data from its detectors at each point.
When scan1 is finished, and its data have been written (or at least secured), its completion callback causes scan2 to continue in its scan procedure -- reading detector values, moving positioners to new positions, and causing scan1 to execute again.
This approach to configuring multidimensional scans is very flexible and permits scans of any dimension. Note that scan1 can be executed independently of scan2, so a complex multidimensional scan can be built and tested one dimension at a time. (In principle, it's possible to run several inner-loop scans in parallel from a single outer-loop scan, but in practice, the capability is of limited use, because there is no coordination between the inner-loop scans, and no data-storage client exists that would correctly understand the acquired data.)
An outer sscan record involved in a multidimensional scan doesn't know or care that the "detector" it's triggering is actually another sscan record, which is going to do an entire inner scan; the outer sscan record simply triggers what it regards as a detector, and waits for that detector to complete. Nor do the inner sscan records know that they are parts of something larger than themselves. The only piece of code that has to know a multidimensional scan is occurring is the client that stores the data. This client must collect all of the data from each inner scan before those data are overwritten by the next execution of that inner scan, because sscan records hold only one-dimensional arrays of data.
Clearly, this calls for some handshaking between the client and the sscan records involved in a multidimensional scan. The next section describes the handshake mechanisms implemented by the sscan record.
Clients of the sscan record include the software that starts, stops, or pauses a scan; software that displays data acquired by a scan; software that writes scan data to disk; and software that participates in the a scan by implementing positioner or detector operation. A single client may do any or all of these things, of course, but it seems best to discuss them separately.
If the sscan record cannot start a new scan, the client will receive an error indication, and the command will be ignored. The sscan record will set its SMSG field to a string describing the reason why it cannot start a new scan. Possible reasons include the following:
In all of these cases, the start command is ignored, and the scan will not automatically start when the condition that prevented it from starting is removed. A new start command must be issued.
When a sscan record is told to stop while it has outstanding callbacks, it sets its SMSG field to the string "Abort: waiting for callback". When the callback arrives, SMSG will change to "Scan aborted by operator", and the BUSY field will be set to 0.
When a sscan record is told to stop while it is waiting for service by the data-storage client, "saveData", it sets its SMSG field to the string "Killing scan (kill=n/3)", where n is 1, 2, or 3.. When saveData has serviced the sscan record, SMSG will change to "Scan aborted by operator", and the BUSY field will be set to 0. If saveData does not service the sscan record, writing 0 to EXSC a total of three times will cause the scan to complete with the message "Abandoning unsaved scan data".
If the sscan record is waiting for both outstanding callbacks and the data-storage client, the messages it writes to SMSG may overwrite each other, and not clearly indicate what is happening. The user's course of action, however, is always the same:
When a scan is aborted, and more than one write to EXSC was required, the next scan may inherit the problem. If the problem was an outstanding callback, and that callback still has not come in by the next time the sscan record is told to start, the scan will not be permitted to write to the PV whose callback is still outstanding. This may indicate that a PV is imperfectly implemented, and cannot be scanned; or that some error prevented the operation from completing; or that the sscan record missed the completion message; or simply that the operation is taking a long time to finish. If the operation cannot be manually stopped, the only recourse is to erase the PV name and rewrite it. This closes and reopens the channel-access connection to that PV, and frequently will resolve the immediate problem.
Pausing a multidimensional scan should work in the same way as pausing a single sscan record, but there have been reports that the process fails sometimes for multidimensional scans, leaving the scan active but not resuming when PAUS is rescinded. The issue is being studied.
The sscan record maintains two sets of array PV's for scan data: data from a completed scan are posted as PnRA and DnnDA (e.g., P1RA, D01DA); data from a scan in progress are posted as PnCA and DnnCA. During a scan, arrays are posted only if the user requests this by setting the array-posting period, ATIME, to a value greater than or equal to 0.1 (seconds). After a scan has completed, all data arrays are posted, marked with the mask DBE_LOG, and the completed-scan postings (PnRA and DnnDA) remain available to clients until the next scan completes.
Because the sscan record implements double-buffered data arrays, and because of the way in which posting is accomplished in EPICS, the posting of scan-in-progress data arrays results unavoidably in useless reposting of completed-scan data arrays. If this presents a problem for a data-display or data-storage client, there are two ways to avoid the problem: 1) Tell the sscan record not to post arrays during scans by leaving the array-post period, ATIME, at its default value of zero; 2) modify the client so that it monitors only postings flagged with the DBE_LOG mask.A more efficient, but more difficult, way for a client to get data from a scan in progress is to monitor the scalar current-value PVs, such as R1CV, D01CV, etc., and collect their values into arrays.
Positioners actually have two fields that might be suitable for display while a scan is in progress: the positioner's desired value (PnDV) and the readback's current value (RnCV). (If there is no readback PV, the posted readback value will be a copy of the desired value.)
Not all data points of a scan are guaranteed to be posted as scalar values, because the sscan record throttles it's posting, so that it doesn't exceed 20 data points per second. This throttling is intended to limit the network activity caused by a scan, and it's necessary because displaying scan data is not more important that acquiring it, and because the sscan record also uses the network to acquire data.
The task of accumulating posted scalar values into data arrays is complicated by the standard EPICS behavior of declining to post a field whose value has not changed since the last time the field was posted. If a client were simply to append each new posting to the data arrays it is accumulating, it would not be including those repeated values. The following algorithm will accumulate data correctly:
1) The new way, using the AWAIT and AAWAIT fields:
The data-storage client waits for DATA==1, which indicates that the scan is over and the sscan record has finished posting all array fields; writes 1 to the AWAIT field to prevent the sscan record from overwriting array fields before the client has read them; and writes 0 to AWAIT when it is finished reading. One advantage of this handshake is that it allows the sscan record to proceed with the next scan (the sscan record's data arrays are double buffered) until it's time to post data. In this way, the data-storage client can be writing one set of scan data while the sscan record is acquiring the next set.
For very fast scans, or a very slow data-storage client, there might not be sufficient time, between the posting of one data set and the acquisition of the next, for the client to write 1 to AWAIT (array wait) field. In this case, you can cause the sscan record automatically to set AWAIT==1, whenever it posts data, by setting the AAWAIT (auto array wait) field to 1. (It's OK if the client also sets AWAIT==1.) saveData, the data-storage client included in the synApps sscan module, sets AAWAIT for each of the sscan records it monitors.
NOTE: Because saveData sets AAWAIT for the sscan records it monitors, a scan cannot execute to completion until saveData has written the previous scan's data to disk (or has tried and failed a preset number of times to do this). The sscan module currently does not provide a mechanism by which the end user can turn data storage off and on. Data storage is turned on at boot time, for each sscan record, by telling saveData to monitor that sscan record. The only way to turn data storage off is to edit the startup file and reboot.
Only one data-storage client can use AWAIT. If you have more than one data-storage client, you must arrange for them to pool their use of the AWAIT field, so that it gets reset to zero only when all have finished. (It's OK if AWAIT gets set to one more than once. Only the first AWAIT==1 write has any effect.)
Note that this AWAIT handshake protects scan data no matter how the sscan record gets executed, unlike the old method described next.
2) The old way, using the WAIT, WCNT, and AWCT fields:
Before the AWAIT field was introduced, the only means of handshaking was an extension of the mechanism by which the sscan record waits for detector triggers to signal completion. In this extension, the sscan record waits until all detector triggers have signalled completion, and the field WAIT is equal to zero. This extension's intended purpose is to support detectors that can't signal completion with a callback, but that can write to a PV -- for example, a detector that's implemented as a channel-access client -- and it can still be used for that purpose, while a data-storage client is using it to protect data acquired from an inner-loop scan.
Here's how the handshake works in a data-storage application: The data-storage client notices that an inner sscan record has started a scan (typically, it monitors the DATA field, which is set to zero at the beginning of a scan), and writes a 1 to the outer sscan record's WAIT field. This prevents the outer sscan record from continuing until the client has read the inner scan's data. The client waits for DATA==1, which indicates that new data are available. When the client has finished reading the inner scan's data, it writes a 0 to the outer sscan record's WAIT field, allowing the scan to continue.
If there are several clients that want the scan to WAIT for them, they can all write to the WAIT field. Each 1 increments the scan's wait-count field, WCNT; each 0 decrements it. When WCNT reaches zero, the scan continues.
In fast scans, there might not be time for a client to notice that an inner scan has started and write that 1 to the outer scan's WAIT field before the inner scan completes and is triggered again. In this case, the outer scan can be made automatically to write a 1 to it's own WAIT field whenever it triggers detectors. It will do this if its AutoWaitCounT (AWCT) field is set to 1. In this case, the client must NOT write another 1 to the outer scan's WAIT field (that would increment the wait count to 2), but must only write 0 to the WAIT field to indicate that it is ready for the scan to continue.
If there are N clients, the autoWaitCount can be set to N, and the scan will continue only after N 0's have been written to the WAIT field.
The advantage of the autoWaitCount==0 method is that scans can be performed whether or not a client is available to write to the WAIT field. The disadvantage is that the is not reliable for very fast scans.
Note that this form of handshaking doesn't do a very thorough job of data protection, because it does not directly prevent a sscan record from overwriting its own arrays; it only prevents an outer-loop sscan record from telling an inner-loop record to start a new scan line. If the sscan record is executed by some other agent, the WAIT handshake doesn't protect data at all.
There are two mechanisms the client can use to signal completion that will work with the sscan record:
This is the method the sscan record expects everything it drives to use for signalling completion, and it is the method the sscan record itself uses to signal completion. Clients can't signal completion directly using putNotify, because their execution is not managed by EPICS. But they can do it indirectly, by writing to a busy record.
A busy record is a custom EPICS record, supplied as part of the synApps package, that looks and operates almost exactly like the binary-output ("bo") record, except that it executes its forward link, FLNK, only when its VAL field has the value zero. As it happens, EPICS' putNotify completion mechanism is implemented as part of the processing of forward links, so the fact that the busy record allows a CA client to control the execution of its forward link means that the client can control the timing of a putNotify callback.
Here's how it works in practice:
Very simple, but it does require that a dedicated record be loaded in some IOC. Here's a database that loads a busy record:
record(busy, "xxx:CCD_Busy") { }Many of the databases in synApps contain busy records for this purpose, particularly those that act as front ends for State Notation Language (SNL) code. Though motivated by the needs of the sscan record, this completion-signalling capability can be used by any CA client participating in any EPICS application.
This handshake is intended for CA clients implementing detectors. Here's how it works:
Several clients can use the WAIT field, each write of 1 increments a wait count WCNT; each write of 0 decrements WCNT; the sscan record stops waiting when WCNT is decremented to zero. The sscan record doesn't care, by the way, who writes what to WAIT; it simply waits until the number of WAIT==0 writes equals the number of WAIT==1 writes.
But what if clients are a little slow to react, and the sscan record checks its wait-count WCNT before the clients have had time to write 1's to it? If this is a problem, you can cause the sscan record to set WCNT at the appropriate time, by setting <scanrecord>.AWCT to the number of slow clients. (But now those slow clients must NOT write 1 to WAIT.)
As was mentioned previously, all of the process variable names used to identify positioners, detectors, and detector triggers are specified using reassignable links. These links are implemented differently than standard EPICS links. Reassignable links are channel-access links implemented with the recDynLink library (originally written by Marty Kraimer and Ned Arnold; modified to use callbacks and currently maintained by Tim Mooney). These links perform writes with the channel-access function, ca_put_callback(), and expect the callback function to be called only after all processing caused by the write operation is complete. For simple positioners and detectors, this is never a problem. Individual records using either synchronous or asynchronous completion strategies (as these terms are defined in the EPICS Application Developer's Guide) always satisfy the completion-callback criterion. Special records (motor, scaler, mca, and sscan record) which do not use either synchronous or asynchronous strategies have been engineered to satisfy the completion-callback criterion simply by having them refrain from calling recGblFwdLink() (i.e., from firing their Forward Links) until the operation they started has finished.
If a positioner or detector is implemented with a collection of linked records all of which individually satisfy the completion-callback criterion, the whole series of records will also satisfy the criterion if all links in the processing chain started by the sscan record's write have the attribute PP, and all of the records that process are scan-passive (i.e., their SCAN fields are set to "Passive"). Databases that do not satisfy this criterion can still satisfy the completion-callback criterion very simply: at least one record in the database must refrain from firing its Forward Link until the operation is finished, and that record must be either be the record written to, or it must be linked with attribute PP to the record. The busy record was implemented for this purpose. Using the busy record, any sort of processing, even processing that involves an external, non-EPICS processor can easily satisfy the completion-callback criterion.
Database developers should note that a PP link from a record in one
crate to a record in another crate will silently be converted to a CA
link, which will not satisfy the completion-callback criterion. In this case,
there are two options: the busy-record solution, detailed above, and the
use of a buffer record that can do a ca_put_callback() to make the
inter-crate link. Currently, I'm aware of six record types that can do a
ca_put_callback(): the sscan, swait, and sseq
records; an ai record with soft asynchronous device support; and the
sCalcout and aCalcout records. (The sscan, swait,
sseq, sCalcout, and aCalcout records are distributed with
synApps. swait, sCalcout, and aCalcout are variants of
the calcout record; sseq is a variant of the seq record.)
In this documentation, many of the sscan-record fields will be listed in tables containing the following informational headings:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
NPTS | Number of Points | LONG | Yes | 100 | Yes | Yes | Yes | No |
MPTS | Maximum Number of Points | LONG | Yes | 100 | Yes | No | No | No |
PASM | Positioner After-Scan Mode | Menu ("STAY", "START POS", "PRIOR POS", "PEAK POS", "VALLEY POS", "+EDGE POS", "-EDGE POS", CNTR OF MASS) | Yes | "STAY" (0) | Yes | No | No | No |
PASM allows the user to control where positioners are left after a scan is finished. Here are the possibilities: |
||||||||
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
REFD | Reference detector for After-Scan mode | SHORT | Yes | 1 | Yes | Yes | No | No |
BSPV | Before-Scan Process Variable link | STRING [40] | Yes | Null | Yes | Yes | No | No |
BSNV | BSPV Name Valid | LONG | No | 0 | Yes | No | Yes | No |
BSCD | Before-Scan Command Data | FLOAT | Yes | 1 | Yes | Yes | No | No |
BSWAIT | Wait for completion? | MENU ("YES", "NO") | Yes | "YES" (0) | Yes | Yes | Yes | No |
BSPV, BSNV, BSCD, and BSWAIT allow the user to specify a PV to be written to before every scan starts. (If the sscan record is part of a multidimensional scan, each participating sscan record has its own set of before-scan parameters, so you can cause an action to occur before the whole scan starts, and before each nested loop starts.) |
||||||||
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
ASPV | After-Scan Process Variable link | STRING [40] | Yes | Null | Yes | Yes | No | No |
ASNV | ASPV Name Valid | LONG | No | 0 | Yes | No | Yes | No |
ASCD | After-Scan Command Data | FLOAT | Yes | 1 | Yes | Yes | No | No |
ASWAIT | Wait for completion? | MENU ("YES", "NO") | Yes | "YES" (0) | Yes | Yes | Yes | No |
ASPV, ASNV, ASCD, and ASWAIT allow the user to specify a PV to be written to after every scan is finished. (If the sscan record is part of a multidimensional scan, each participating sscan record has its own set of after-scan parameters, so you can cause an action to occur after the whole scan is done, and after each nested loop is done.) |
||||||||
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
A1PV | Array-read trigger 1 PV Name | STRING [40] | Yes | Null | Yes | Yes | No | No |
A1NV | A1PV Name Valid | LONG | No | 0 | Yes | No | Yes | No |
A1CD | A1 Cmnd | FLOAT | Yes | 1 | Yes | Yes | No | No |
A1PV, A1NV, and A1CD allow the user to specify a PV to be written to before the sscan record tries to read array-valued data. (It may be necessary, for example, to cause data to be read from hardware into a set of EPICS PVs, or to execute some calculation on the data, before the sscan record acquires it. The sscan record will wait for processing triggered by this write to complete before reading arrays. |
||||||||
ATIME | Array post time period | FLOAT | Yes | 0.0 | Yes | Yes | No | No |
COPYTO | Copy Last Array Point Thru This Element Number | LONG | Yes | 0.0 | Yes | Yes | No | No |
These fields control the posting of array data during a scan. ATIME is the minimal time period in seconds between array postings during a scan. If ATIME is greater than 0.1 (seconds), and if more than this time has elapsed since the last array posting of this scan's data, then the current-data arrays will be posted after the next data point has been acquired. |
There are three modes for determining the desired value for the positioner. The desired mode is specified in the P1SM-P4SM fields: Linear, Table, and On-The-Fly. If a positioner is specified as Linear, its desired value is determined by using parameters such as start position, step increment, number of points, and end position (which are explained below). If a positioner is specified as Table, its next position is found in an array that has been loaded into the record prior to initiating a scan. If the positioner is specified as On-The-Fly, the sscan record sends it to the start position at the beginning of a scan, waits for it to get there, acquires one data point, sends the positioner to the end position, and begins acquiring the remaining data points while the positioner presumably is travelling to the end position.
Currently, the sscan record does not wait for an On-The-Fly positioner to arrive at the end point. Ideally, the sscan record should finish the data-acquisition portion of a scan but not enter the post-scan phase (sending positioners to after-scan positions, and executing the after-scan link) until the positioner has declared itself done. But currently this is not what is done.
For each positioner, the user may specify a process variable in the R1PV -R4PV fields that corresponds to the actual (or measured) position of the motor. If this readback field is configured, the sscan record will confirm after each movement that the actual position is within a specified delta to the desired position. The delta is specified in the R1DL -R4DL fields. If the delta is exceeded, the scan will abort and the record will go into an alarm state. A text field within the record (SMSG) will inform the operator of the error condition.
The positioner-readback field normally contains the name of a PV from which readback values are read, but it may also contain the static text "TIME", or "time". In this case, the sscan record sets the scalar readback field RnCV to the time in seconds since the beginning of the scan, and fills the readback array PnRA with those values.
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
PnPV | Positioner n Process Variable ame | STRING [40] | Yes | Null | Yes | Yes | No | No |
PnNV | PnPV Name Valid | LONG | No | 0 | Yes | Yes | Yes | No |
PnSM | Positioner n Step Mode | Menu ("LINEAR", "TABLE", "FLY") | Yes | "LINEAR" (0) | Yes | Yes | No | No |
PnAR | Positioner n Absolute/Relative Mode | Menu ("ABSOLUTE", "RELATIVE") | Yes | "ABSOLUTE" (0) | Yes | Yes | No | No |
PnDV | Pos. n Desired Value | DOUBLE | No | 0 | Yes | No | Yes | No |
PnLV | Pos. n Last Value | DOUBLE | No | 0 | Yes | No | No | No |
PnDV | Pos. n Desired Value | DOUBLE | No | 0 | Yes | No | Yes | No |
PnLV | Pos. n Last Value | DOUBLE | No | 0 | Yes | No | No | No |
PnEU | Positioner n Eng. Units | STRING [16] | Yes | 16 | Yes | Yes | No | No |
PnHR | Pos. n High Range | DOUBLE | Yes | 0 | Yes | Yes | No | No |
PnLR | Pos. n Low Range | DOUBLE | Yes | 0 | Yes | Yes | No | No |
PnPR | Pos. n Precision | SHORT | Yes | 0 | Yes | Yes | No | No |
PnPA | Pn Step Array | DOUBLE[] | No | 0 | Yes | Yes | No | No |
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
RnPV | Readback n Process Variable | STRING [40] | Yes | Null | Yes | Yes | No | No |
RnNV | Readback /n Name Valid | LONG | No | 0 | Yes | Yes | Yes | No |
RnDL | Readback n Delta | DOUBLE | Yes | 0 | Yes | Yes | No | No |
RnCV | Readback n Current Value | DOUBLE | No | 0 | Yes | No | Yes | No |
RnLV | Readback n Last Value | DOUBLE | No | 0 | Yes | No | No | No |
RnCV | Readback n Current Value | DOUBLE | No | 0 | Yes | No | Yes | No |
RnLV | Readback n Last Value | DOUBLE | No | 0 | Yes | No | No | No |
PnRA | Pn Readback Array | DOUBLE[] | No | 0 | Yes | No | Yes | No |
PnCA | Pn Current Readback Array | DOUBLE[] | No | 0 | Yes | No | Yes | No |
Clients that display scan data will most likely be interested in only one of the two positioner-array fields: PnCA or PnRA. These array fields are backed by the same double-buffered arrays, so they cannot be posted separately.
PnCA will yield data from the scan that currently is executing. This array can be read at any time during the scan, and it may be posted with the mask, DBE_VALUE, while the scan is in progress. (ATIME controls this.) When the scan completes, PnCA will be posted with the mask, DBE_VALUE|DBE_LOG.
PnRA will yield data from the most recently completed scan. This array's data will remain available while the next scan's data are being acquired, and will become unavailable when that scan completes. Clients interested only in completed-scan data should use this field. Clients that monitor this field should always specify the mask, DBE_LOG, in their ca_add_event() or ca_create_subscription() call. If this field is monitored with the mask, DBE_VALUE, the client may receive multiple postings of the same data.
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
PnSP | Positioner n Starting Point | DOUBLE | Yes | 0 | Yes | Yes | Yes | No |
PnEP | Positioner n Ending Point | DOUBLE | Yes | 0 | Yes | Yes | Yes | No |
PnCP | Positioner n Center Point | DOUBLE | Yes | 0 | Yes | Yes | Yes | No |
PnWD | Positioner n Width | DOUBLE | Yes | 0 | Yes | Yes | Yes | No |
PnSI | Positioner n Step Increment | DOUBLE | Yes | 0 | Yes | Yes | Yes | No |
Some of these fields can be redundant. For instance, the positioner width (P1WD -P4WD) is simply the distance from the starting position to the ending position (PnEP - PnSP). The record calculates redundant parameters for the same set, if the parameters are left undefined. However, the user can still configure the redundant parameters anyway.
There is no unique prescription for removing inconsistencies among redundant parameters, and no hard-coded set of preferences among parameters is likely to please everyone. Therefore, the sscan record allows the user to "freeze" parameters with flags so that they will not be changed by the record's internal attempts to ensure consistency among the parameter set. Frozen parameters can be changed by the user and by any other client, but not by the record. It is the user's responsibility to ensure that frozen parameters do not prevent freely specifying unfrozen parameters. For example, if both PnSI and NPTS are frozen, changes to PnWD will be rejected. Similarly, if both PnSP and PnCP are frozen, changes to PnEP and PnWD will have no effect. By default, PnSP , PnSI , and NPTS are frozen. When the record cannot adjust the parameters to be consistent, a flag is raised in the alert field (ALRT) and a message reported in the state message field (SMSG).
The freeze flag override field (FFO) has two choices: Use F-Flags and Override. Override causes the current settings of all the freeze flags to be saved and monitors to be called for those that have changed. Use F-Flags causes the flags saved with the Override command to be restored if any have changed. Changing the choice of this field at run-time causes the special record support routines to perform these actions. So if Override is chosen at run-time, then all current settings are saved, and can be restored at a later time by changing the FFO field to Use F-Flags.
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
FPTS | Freeze Flag for NPTS | Menu ("NO", "FREEZE") | Yes | "FREEZE" (1) | Yes | Yes | No | No |
FFO | Freeze Flag Override | Menu ("USE F-FLAGS", "OVERRIDE") | Yes | "USE F-FLAGS" (0) | Yes | Yes | No | No |
PnFS | Positioner n Freeze Flag for PnSP | Menu ("NO", "FREEZE") | Yes | "NO" (0) | Yes | Yes | No | No |
PnFE | Positioner n Freeze Flag for PnEP | Menu ("NO", "FREEZE") | Yes | "NO" (0) | Yes | Yes | No | No |
PnFI | Positioner n Freeze Flag for PnSI | Menu ("NO", "FREEZE") | Yes | "NO" (0) | Yes | Yes | No | No |
PnFC | Positioner n Freeze Flag for PnCP | Menu ("NO", "FREEZE") | Yes | "NO" (0) | Yes | Yes | No | No |
PnFW | Positioner n Freeze Flag for PnWD | Menu ("NO", "FREEZE") | Yes | "NO" (0) | Yes | Yes | No | No |
Although this approach may seem to present the user with an overwhelming number of choices when it comes to linear scans, it should be noted that by default the user only has to configure NPTS, and the starting position (PnSP) and the step increment (PnSI) fields for each positioner in order to fully define the scan of a positioner. The operator interface (usually MEDM or another CA client) need only present the user with these fields. However, by changing the freeze flags from the defaults and presenting the user with different fields to fill in, the scan can be defined in a completely flexible way. The result is that a simple scan can be defined easily, but advanced users are not limited in flexibility.
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
PnPA | Positioner n Position Array | DOUBLE array | No | Null | Yes | Yes | Yes | No |
For n in [1..4]:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
TnPV | Detector Trigger n Process Variable | STRING [40] | Yes | Null | Yes | Yes | No | No |
TnNV | Trigger n Name Valid | LONG | No | 0 | Yes | Yes | Yes | No |
TnCD | Trigger n Command Data | FLOAT | Yes | 1 | Yes | Yes | No | No |
If no positioners are defined, then PDLY is ignored. If no detector triggers are defined, then DDLY is ignored. PDLY does not apply to after-scan positioner motions.
1) A data-storage client can put a hold on a sscan record whose data it is writing by writing to the AWAIT field. This hold doesn't prevent the record from executing, or even from acquiring new data, but it does prevent the record from switching data buffers.
2) In a multidimensional scan, a data-storage client can put a hold on scan2 while it is writing data from scan1, by writing to the WAIT field. This relatively inefficient handshake is still used by some data-storage clients.
3) A data-acquisition client that doesn't declare completion via EPICS' putNotify mechanism can declare completion using WAIT.
A client may not be able to write quickly enough to WAIT to ensure that the scan holds before data acquisition. In this case, the client can cause the sscan record to write automatically to WCNT whenever detectors are triggered, by incrementing the value of the AWCT field. The client must remember to decrement AWCT before exiting, otherwise scans will hang waiting for a nonexistent client.
A client may not be able to write quickly enough to AWAIT to ensure that the scan holds before switching buffers. In this case, the sscan record can be made to write automatically to AWAIT whenever data are posted, by setting the AAWAIT field to 1.
Field | Summary | Type | DCT | Initial | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
WAIT | Wait for client | SHORT | No | 0 | Yes | Yes | No | No |
WCNT | Wait count | SHORT | No | 0 | Yes | No | Yes | No |
AWCT | Auto Wait | SHORT | No | 0 | Yes | Yes | No | No |
WTNG | Waiting | SHORT | No | 0 | Yes | No | Yes | No |
AWAIT | Waiting for data-storage client | SHORT | No | 0 | Yes | Yes | Yes | Yes |
AAWAIT | AutoWait for data-storage client | MENU ("NO","YES") | Yes | 0 | Yes | Yes | No | No |
Although positioner readbacks, R1-R4, are normally used to confirm the position at which data actually were acquired (as opposed to the position to which the sscan record told a positioner to go), they can be used to record any data. These four variables are the only place to record double-precision scan data. Note that these readbacks are not full-fledged detectors, because the sscan record currently cannot read into them from a array-valued PV's, as it can for actual detectors.
The scan results will most frequently be read as position arrays (P1RA-P4RA) and detector arrays (D01DA-D70DA).
A one-dimensional scan is complete when the BUSY field goes back to zero (during the scan its value is 1). A client program monitoring the scan can read the position and data arrays when the DATA field is set to 1. (The client could have a monitor set on the data-array fields so the record will post them when the scan is finished.)
For two-dimensional scans, the client should read the arrays from the scan1 record after the completion of each inner scan and associate these data with the current outer-scan information. (Let's call the inner scan 'x', and the outer scan 'y'.) This will allow the client to display data after each x scan. The sscan record will buffer the data for only one x scan, so the client must read the arrays before the next x scan is completed. If the scan is too fast for this, see section 1.3.4 - Handshaking with data-storage clients
During slow scans, the application program may want to display scan progress point-by-point. The sscan record posts monitors on fields that it updates each point, but it doesn't post point-by-point monitors faster than 20 times per second. If a scan is proceeding at a rate less than 20 points per second, every point will be posted. If a scan is proceeding at 100 steps per second, scalar values will be posted approximately every 5th point. In either case, the array data will contain every point at the completion of the scan.
Special Acquisition Parameters:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
version 5.16 and earlier: | ||||||||
ACQM | Acquisition Mode | Menu ("NORMAL", "ACCUMULATE", "ADD TO PREV", "GET ARRAYS") | Yes | "NORMAL" (0) | Yes | Yes | No | No |
version 5.17 and later: | ||||||||
ACQM | Acquisition Mode | Menu ("NORMAL", "ACCUMULATE", "ADD TO PREV") | Yes | "NORMAL" (0) | Yes | Yes | No | No |
ACQT | Acquisition Type | Menu ("SCALAR", "1D ARRAY") | Yes | "SCALAR" (0) | Yes | Yes | No | No |
Data and related PV's:
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
For nn in [01..70] (e.g., "D01PV", "D02PV", ... "D70PV") : | ||||||||
DnnPV | data nn Process Variable name | STRING [40] | Yes | Null | Yes | Yes | No | No |
DnnNV | data nn Name Valid | LONG | No | 0 | Yes | Yes | Yes | No |
DnnDA | Detector nn End-Of-Scan Data Array | FLOAT[ ] | No | Null | Yes | No | Yes | No |
DnnCA | Detector nn Current-Data Array | FLOAT[ ] | No | Null | Yes | No | Yes | No |
DnnEU | Detector nn Eng. Units | STRING [16] | Yes | 16 | Yes | Yes | No | No |
DnnHR | Det. nn High Range | DOUBLE | Yes | 0 | Yes | Yes | No | No |
DnnLR | Det. nn Low Range | DOUBLE | Yes | 0 | Yes | Yes | No | No |
DnnPR | Det. nn Precision | SHORT | Yes | 0 | Yes | Yes | No | No |
DnnCV | Detector nn Current Value | FLOAT | No | 0 | Yes | No | Yes | No |
DnnLV | Detector nn Last Value | FLOAT | No | 0 | Yes | No | No | No |
A scan is started when a client writes 1 to the EXSC field.
Prior to beginning an actual scan, the record can be commanded to check the scan parameters to ensure that all positioner requests are within reasonable limits. This is done by writing 1 to the CMND field. The record will do a "dry run" by calculating every positioner value (or looking it up in the table) and comparing it with the high range and low range values (P1HR-P4HR and P1LR-P4LR) associated with that positioner's Process Variable. (Drive limits are an attribute of most process variables). If any step would exceed the drive limits, the operator is notified via the SMSG field.
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
EXSC | Execute Scan Flag | SHORT | No | 0 | Yes | Yes | Yes | No |
CMND | Command Field | ENUM | No | 0 | Yes | Yes | Yes | No |
The command (CMND) field supports eight commands, as follows:
CMND | Command |
---|---|
0 | Clear the State Message field (SMSG) |
1 | Execute a "dry run", checking the desired position against the range limits for each positioner |
2 | Check to see if limits would be violated if the currently programmed scan were actually performed |
3 | Clear all PVs, freeze flags, modes, switches, etc. |
4 | Clear all positioner-name PVs, freeze flags, modes, and switches. |
5 | Clear positioner-name PVs. |
6 | Clear all positioner-name and readback-name PVs, freeze flags, modes, and switches. |
7 | Clear positioner-name and readback-name PVs. |
The Current Point (CPT) field contains the current point of an active scan.
The BUSY field indicates whether (1) or not (0) a scan is in progress.
The DATA field indicates the state of the data arrays. DATA is set to 0 at the beginning of a scan, and is set to 1 after the data arrays have been posted. Note that data arrays are not posted during a scan, but only at the end.
The VAL field is used only as a progress indicator. It is posted after all point-by-point PVs (e.g., R1CV, D01CV) have been posted. (So, if a PV you're interested in hasn't been posted by the time you get the VAL-field monitor, that PVs value hasn't changed since the last time it was posted.)
The State Message (SMSG) field holds a message sent by the record that alerts the operator to an error condition. It can be cleared by writing a 0 to the Command (CMND) field.
The Alert (ALRT) field is a flag which indicates if an error condition currently exists. 1 means YES; 0, NO. The cause of the condition will be displayed in the SMSG field.
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
CPT | Current Point | LONG | No | 0 | Yes | No | Yes | No |
BUSY | Scan-is-busy Flag | SHORT | No | 0 | Yes | No | Yes | No |
DATA | Data-are-ready flag | SHORT | No | 0 | Yes | No | Yes | No |
VAL | Value Field | DOUBLE | No | 0 | Yes | Yes | No | No |
SMSG | State Message | STRING [40] | No | Null | Yes | Yes | Yes | No |
ALRT | Alert Field | UCHAR | No | 0 | Yes | No | Yes | No |
The scan-phase (FAZE) field indicates in which phase of a scan the record currently is. The possible phases are as follows:
phase | message | meaning |
---|---|---|
0 | IDLE | Nothing is going on. |
1 | INIT_SCAN | A scan is starting |
2 | DO:BEFORE_SCAN | The next thing to do is trigger the before-scan link. |
3 | WAIT:BEFORE_SCAN | The before-scan link has been triggered. We're waiting for its callback to come in. |
4 | MOVE_MOTORS | The next thing to do is to write to positioners. |
5 | WAIT:MOTORS | We've told motors to move. Now we're waiting for their callbacks to come in. |
6 | TRIG_DETECTORS | The next thing to do is to trigger detectors. |
7 | WAIT:DETECTORS | We've triggered detectors. Now we're waiting for their callbacks to come in. |
8 | START_FLY | This is an on-the-fly scan |
9 | RETRACE_MOVE | The next thing to do it send positioners to their post-scan positions. |
10 | WAIT:RETRACE | We've told positioners to go to their post-scan positions. Now we're waiting for their callbacks to come in. |
11 | DO:AFTER_SCAN | The next thing to do is trigger the after-scan link. |
12 | WAIT:AFTER_SCAN | The after-scan link has been triggered. We're waiting for its callback to come in. |
13 | SCAN_DONE | The scan is finished. |
14 | WAIT:SAVE_DATA | The scan is waiting for AWAIT -> 0 so it can switch data buffers. |
15 | SCAN_PENDING | A scan has been commanded, but has not yet started |
The remaining menu choices can't be displayed as strings by CA clients, but should be displayed as numbers. | ||
16 | TRIG_ARRAY_READ | The scan is about to trigger array reads (A1PV) |
17 | WAIT:ARRAY_READ | The scan is waiting for a callback from the array-read PV |
18 | PREVIEW | We're doing a preview of the scan. |
The data-state (DSTATE) field indicates in what state is the processing of data arrays. The possible states are as follows:
state | message | meaning |
---|---|---|
0 | UNPACKED | Data arrays are either idle or being
filled. If a client should read an array now, it would get last scan's data. |
1 | TRIG_ARRAY_READ | The next thing to do is trigger the
array-read PV, A1PV. If a client should read an array now, it would get last scan's data. |
2 | ARRAY_READ_WAIT | A1PV has been triggered, and
the callback is still outstanding. If a client should read an array now, it would get last scan's data. |
2 | ARRAY_GET_CALLBACK_WAIT | recDynLinkGetCallback() has been issued for array-valued PVs, and one or more callbacks are still outstanding. |
3 | RECORD_ARRAY_DATA | It's time to read array data. If any array-valued PVs exist, the data state will change to ARRAY_GET_CALLBACK_WAIT while waiting for the callbacks. |
3 | SAVE_DATA_WAIT | Arrays are filled, but cannot be
posted yet because the data-storage client is not finished writing last scan's
data. If a client should read an array now, it would get last scan's data. |
4 | PACKED | Arrays are filled, and buffers have been
switched, but they haven't yet been posted. If a client should read an array now, it would get last scan's data. |
5 | POSTED | Data arrays have been posted. Now the data-storage client can read this scan's array data. |
Field | Summary | Type | DCT | Initial/Default | Read | Modify | Posted | PP |
---|---|---|---|---|---|---|---|---|
NAME | Record Name | STRING [29] | Yes | 0 | Yes | No | No | No |
DESC | Description | STRING [29] | Yes | Null | Yes | Yes | No | No |
PCPT | Previous Current Point | LONG | No | 0 | Yes | No | No | No |
PXSC | Previous Execute Scan | UCHAR | No | 0 | Yes | No | No | No |
TOLP | Time of Last Posting | ULONG | No | 0 | Yes | No | No | No |
TLAP | Time of Last Array Posting | ULONG | No | 0 | Yes | No | No | No |
VERS | Code Version | FLOAT | No | 1.0 | Yes | No | No | No |
XSC | Internal copy of EXSC | SHORT | No | 0 | Yes | No | Yes | No |
Private fields | ||||||||
RPVT | Record Private | NOACCESS | No | Null | No | No | No | No |
PnDB | Pos. n dbAddr | NOACCESS | No | Null | No | No | No | No |
RnDB | Readback n dbAddr | NOACCESS | No | Null | No | No | No | No |
DnnDB | Detector nn dbAddr | NOACCESS | No | Null | No | No | No | No |
|