McIDAS Programmer's Manual
Version 2006
[Search Manual] [Table of Contents] [ Go to Previous] [ Go to Next]
The McIDAS-X library provides a group of functions for performing system-related tasks such as:
This section provides descriptions and examples of the functions that you can use in your applications to perform these tasks.
For additional information about the functions described in this section, see the online man pages provided with the McIDAS-X software. |
A McIDAS-X string table is a collection of names and associated strings. String tables serve two purposes:
Users can run the commands TU, TL, TE, TD and REPEAT to manage string tables and simplify command entry. For information about these commands, see the McIDAS-X Learning Guide and the McIDAS User's Guide. |
As a programmer, you will find string tables useful because they can serve as a scratch pad for applications to communicate with each other. One application writes information into a character string and saves it in the table where it is available to all subsequent applications, until either the string is changed or the string table is replaced with another.
Use the three functions below to read from or write to a string table.
Fortran function | Description |
---|---|
forms a character string from a sequence of character tokens and writes it to the string table |
Although no separate operation exists to delete a string name from the string table, you can delete a string name using lbput with an argument string consisting of one or more blank characters.
Note that lbputc takes an input array of tokens and concatenates them. The resulting string is then associated with the string name only if it is less than 160 characters long. The lbput function will associate only a single string with the string name, subject to the same 160-character limit.
You must observe the following limitations when developing applications that access string tables.
String tables provide convenient, global storage for passing information in and out of applications without using the command line, text display or file I/O. Although the technique for implementing a string table is easy, using string tables for passing information between commands is not always desirable. If the applications using string tables do not provide a facility for reinitializing the strings used, unpredictable results may occur during subsequent use of the applications.
Storing or sharing information using the string table functions can make applications more convenient for users if used sparingly and documented clearly. It can just as easily lead to confusion, since a string name can't be protected for an application's exclusive use. Other applications or the user (via the string table editor TE) can modify or delete the string, causing the application relying on that string to behave unpredictably. To minimize the risk of name collisions in the string table, choose an unlikely name for the stored string.
Use the McIDAS-X disk file system if your application needs to save more than a few pieces of information that will be used by other applications at a later time. Use a text file, whenever practical, as it simplifies the editing and viewing of the file and makes debugging your application easier.
The code segments below demonstrate the McIDAS-X string table API. Sample user-level input, via the TE and ECHO commands, is also provided to show how string table entries can be written to and read from both the command line and within an application.
The lbget function extracts the contents of a string from within an application and places it in a character variable. If the string table value is longer than the character variable receiving it, the value stored in the character variable is truncated. For example, a user enters the following command from the McIDAS-X Text and Command Window.
The code segment below reads the contents of the string HITTER.
The lbput function stores the contents of a character string in the current McIDAS-X string table associated with a specified string name, as shown in the code fragment below.
If a user subsequently runs the following command from the McIDAS-X Text and Command Window:
The output displayed on the text screen will appear as shown below.
The Greatest Centerfielder of all time was Willie Mays |
The lbputc function allows a user to enter a group of character tokens into one string. The code fragment below demonstrates this function.
If a user subsequently runs the following command from the McIDAS-X Text and Command Window:
The output displayed on the text screen will appear as shown below.
Hank Aaron and Babe Ruth are the two greatest sluggers of all time |
McIDAS-X applications run in an environment consisting of both static and dynamic parts.
User Common contains the dynamic state of the session. All processes, including applications, can read and modify User Common. You will use it in applications to alter the display and make the applications interact with each other in predictable ways.
For information about the itrmch function, which provides details about the static part of the display, see the section in this chapter titled Display characteristics. For a detailed listing of the contents of User Common, see the file uc.doc in the McIDAS-X source directory. |
User Common is divided into positive and negative regions. You must understand the differences between the two and use the appropriate region so that your applications will behave predictably. Note that each session running on a workstation has its own private copy of User Common.
Negative User Common is initialized when the process chain starts. All subsequent processes inherit negative User Common and any changes made to it by processes in the chain.
Batch files, McBASI scripts, and commands separated from each other by a semicolon on a single command line all initiate a chain. Because each process chain has its own copy, Negative User Common cannot be changed from outside the process chain and changes to it are not visible except to the owning process chain, including the display.
The following sequence of commands illustrates why both positive (instantaneous) and negative (process-dependent) User Common are necessary and how applications use them to achieve predictable interactive behavior. If the user enters the three commands below:
The first command sets the current frame to 2; the second command requests that the latest GOES-EAST 4 km IR image, centered on Madison, Wisconsin, be displayed on the current frame. Now suppose the user wants to view a graphic already displayed on frame 4, and enters the third command before IMGDISP begins displaying the image. The display immediately switches to frame 4.
What happens to the IMGDISP command trying to display to the current frame? Is the current frame the frame the user intended (frame 2) or the frame presently displayed (frame 4)? The ambiguity is resolved with positive and negative User Common.
When SF 2 changes the appropriate word in User Common, in this case word 51, to 2, the display immediately reflects it. When IMGDISP starts, the display state, including the current frame number 2, is copied into negative User Common. IMGDISP can then examine the appropriate User Common word, in this case -1, to get the frame number that was current when it started. This value is always 2; whereas the true current frame (word 51) changes from 2 to 4 when SF 4 runs.
The User Common functions are described in the table below.
C function | Fortran function | Description |
---|---|---|
The most common error in using these functions is specifying the wrong User Common index value; the second most common error is transposing a new value with the User Common index value in puc and Mcpuc.
The m0glue.h include file has many of the User Common indexes enumerated using #define statements.
Several APIs are provided in addition to the basic Mcluc and Mcpuc functions. They are described in the table below.
User Common functions are often used to verify that an item, such as a frame, etc., is within a valid range. The example below, from the MAP command, illustrates the use of one of these functions.
The MAP command fragments below define what the highest numbered image frame is and compares that number to the desired frame to be used in the command.
Note that mcgetimageframenumber, not mcgetimageframenumberi, determines the current frame. This ensures that the current frame is the one displayed at the time MAP is started, not the frame displayed at the time the above code fragment actually runs.
The sample code below performs these three tasks:
Note the use of luc and puc since no other APIs are currently available.
When developing an applications program, check to see if a McIDAS-X command performs a needed task. If so, you should start that command from your application rather than duplicating the logic inside your program. If fixes are made to the command, your program will automatically contain the updated information. If keywords are removed from a command, it's your responsibility to make the necessary changes in your calling application.
McIDAS-X commands can run synchronously or asynchronously, with or without extended format.
You can start any McIDAS-X command from an application using the functions defined in the table below.
C function | Fortran function | Description |
---|---|---|
Use the keyin, mckeyin and Mckeyin functions to start commands asynchronously. For example, the McIDAS-X time scheduler, sked, starts user commands asynchronously. If the scheduler started a long-running command synchronously, other scheduled commands couldn't start until that command finished.
Use the skeyin, mcskeyin and Mcskeyin functions to start commands synchronously. Using these functions, the application stops and will not continue until the specified command is done. For example, a user can run the ERASE command to erase a frame and then run the IMGDISP command to display an image on that frame. If these applications aren't run synchronously, some of the image load could occur before the ERASE command finishes, erasing part of the image.
The mckeyin and mcskeyin functions expect a single command in McIDAS-X format. The asynchronous version, mckeyin, returns the status of the command if one was started, or an error code if it wasn't started. The synchronous version, mcskeyin, returns the exit status of the started command. The status code returned from mcskeyin is set by calling the function Mccodeset, which is described in the next section titled Error handling.
Below is a code fragment from an application that uses Mcskeyin. The first call attempts to position the cursor at a certain latitude and longitude. If this call returns a successful status, a second call is made to report the position in all the relevant coordinate systems.
It is not uncommon to have data reports with missing values. The McIDAS-X system uses specific values that flag parameters as missing. Integer values for code written in C use the macro MCMISSING4 defined in mcidas.h. Integer values for code written in FORTRAN use the value HEX80 stored in hex80.inc.
The McIDAS-X library provides a group of functions for assigning and verifying floating-point missing value codes. The functions are described in the table below.
Most functions use their return value to inform the calling program of their success or the nature of their failure. So it is with McIDAS-X commands, though in a more general way. When run from the command line, error messages generated by the edest or Mcprintf function are sufficient. These functions are described in the Text messages section earlier in this chapter.
McIDAS-X also allows scripts or McIDAS-X applications to run other applications, and depending upon the results, modify subsequent actions. For example, if you run a command to get data and then want to run a transformation on it, you can abandon the second command if the first one fails to acquire data.
This table describes the functions that an application should use to set an error code.
C function | Fortran function | Description |
---|---|---|
Some older McIDAS-X applications are not yet modified to use this status facility, so a zero, or successful status may sometimes be returned erroneously. Although Fortran programs that call mcabort return a status of 1, the process that started the command won't know if mcabort was called, or just return or exit. All new McIDAS-X applications are coded to call Mccodeset if they encounter a problem when running. Thus, when writing an application:
Do: | Don't: |
---|---|
call edest, call mccodeset, and return a status in a function return code |
Currently, SSEC uses the return codes below for McIDAS-X applications.
Value | Definition |
---|---|
For example, use a return code of 1 to tell users they entered a command with a syntax error. Use a return code of 2 to indicate the user's request is valid, but the data requested is not available yet.
The code fragment below is from a command that uses the mccodeset function.
The mcsleep function suspends an action or application for a specified number of milliseconds. It is most often used for polling, or repetitively checking to see if something has changed.
The term sleep means that an application tells the operating system that it doesn't want to be considered ready to be dispatched for a period of time. The system does not guarantee that the application will be dispatched again exactly when its sleep interval is over because that depends on system load. However, it does guarantee that the application will not wake up again until at least that period of time expires.
For example, the sked application checks the scheduler file every thirty seconds to see if any of its entries should be run. The Mcmoubtn function sleeps for 10 milliseconds if it is trying to detect a change in the cursor position. Even though these intervals are very different, their purpose is the same: to allow other processing to continue without slowing down the system by checking something more often than necessary.
The choice of a time interval is a matter of experimentation since you can't know how fast or busy the system will be. Don't test an application only on very fast machines if it will also be run on slow ones. Factors, such as whether file systems or servers are local, can also affect how long a unit of work takes, which in turn affects your choice of a time interval.
Below is a code fragment showing how long-running processes use the mcsleep function to perform polling. Notice that they always check the system shutdown User Common word (word 194) using the McIsMcIDASRunning function after waking up so they won't continue running when they're no longer needed.
c-- go to sleep for 10 seconds call mcsleep(10000) c-- verify that mcidas is still running if mcismcidasrunning ( ).eq.0) then return endif . . . |
An application sometimes needs exclusive use of a resource, such as one or more words in shared memory or one or more bytes in a file. The lock and unlock functions, shown in the table below, control the exclusive use of a resource, guaranteeing that once the program starts to run, nothing will interfere until it's finished.
C function | Fortran function | Description |
---|---|---|
For example, assume two programs want to update a record in a file of 100-byte records. The first program wants to change the third byte of the first record; the second program wants to change the fourth byte of that record.
If both programs read the record, change their respective byte, and write the record back out, one of the changes will be lost because both programs read the unmodified record before making their changes.
Using the lock function will prevent this from happening. If each program locks before it reads the record and unlocks after it writes the record, one process will wait for the other to complete before it begins.
Consider the following recommendations when locking and unlocking a resource.
The sample code below is from the file DDESERVF. The lock function is called by the function that updates the file; the unlock function is called after the file is closed so another process can access the lock.
[Search Manual] [Table of Contents] [ Go to Previous] [ Go to Next]