Building IDL Applications - Thermal Geophysics Research Group

Building IDL Applications - Thermal Geophysics Research Group
Building IDL
Applications
IDL Version 5.2
November, 1998 Edition
Copyright © Research Systems, Inc.
All Rights Reserved
IDL Version 4.0
October, 1995 Edition
Copyright © Research Systems, Inc.
Restricted Rights Notice
The IDL® software program and the accompanying procedures, functions, and
documentation described herein are sold under license agreement. Their use,
duplication, and disclosure are subject to the restrictions stated in the license
agreement.
Limitation of Warranty
Research Systems, Inc. makes no warranties, either express or implied, as to any
matter not expressly set forth in the license agreement, including without
limitation the condition of the software, merchantability, or fitness for any
particular purpose.
Research Systems, Inc. shall not be liable for any direct, consequential, or other
damages suffered by the Licensee or any others resulting from use of the IDL
software package or its documentation.
Most Current Documentation
Because changes may be made to IDL after documentation has gone to press,
please consult IDL’s hypertext online help system for the most current version of
this document.
Permission to Reproduce this Manual
Purchasers of IDL licenses are given limited permission to reproduce this manual
provided such copies are for their use only and are not sold or distributed to third
parties. All such copies must contain the title page and this notice page in their
entirety.
Acknowledgments
IDL® is a trademark of Research Systems Inc., registered in the United States
Patent and Trademark Office, for the computer program described herein. All
other brand or product names are trademarks of their respective holders.
Numerical Recipes™is a trademark of Numerical Recipes Software. Numerical
Recipes routines are used by permission.
GRG2™is a trademark of Windward Technologies, Inc. The GRG2 software for
nonlinear optimization is used by permission.
Portions of this software are copyrighted by INTERSOLV, Inc., 1991-1998.
IDL documentation is printed on recycled paper. Our paper has a minimum
20% post-consumer waste content and meets all EPA guidelines.
Contents
Chapter 1:
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
What is an IDL Application? .......................................................................................
About IDL ....................................................................................................................
IDL Documentation ....................................................................................................
Typographical Conventions ........................................................................................
Reporting Problems .....................................................................................................
1
2
3
5
5
Chapter 2:
Constants and Variables . . . . . . . . . . . . . . . . . . . . 11
Data Types ..................................................................................................................
Constants ....................................................................................................................
Type Conversion Functions ......................................................................................
Variables .....................................................................................................................
System Variables ........................................................................................................
i
12
14
19
21
22
ii
Contents
Chapter 3:
Expressions and Operators . . . . . . . . . . . . . . . . . . . 25
Operator Precedence .................................................................................................. 26
IDL Operators ............................................................................................................. 28
Type and Structure of Expressions ............................................................................ 37
Chapter 4:
Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Creating and Defining Structures .............................................................................. 42
Structure References ................................................................................................... 45
Using HELP with Structures ...................................................................................... 47
Parameter Passing with Structures ............................................................................ 47
Arrays of Structures .................................................................................................... 49
Structure Input/Output .............................................................................................. 51
Advanced Structure Usage ......................................................................................... 53
Automatic Structure Definition ................................................................................. 54
Relaxed Structure Assignment ................................................................................... 55
Chapter 5:
ArraySubscripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Array Subscript Syntax: [ ] vs. ( ) ............................................................................... 60
Subscript Examples ..................................................................................................... 61
Subscript Ranges ......................................................................................................... 64
Structure of Subarrays ................................................................................................ 65
Array Subscripts .......................................................................................................... 66
Combining Array Subscripts with Others ................................................................. 67
Storing Elements with Array Subscripts .................................................................... 68
Chapter 6:
Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
String Operations ....................................................................................................... 72
Non-string and Non-scalar Arguments .................................................................... 73
String Concatenation .................................................................................................. 74
Using STRING to Format Data ................................................................................. 74
Byte Arguments and Strings ....................................................................................... 75
Case Folding ................................................................................................................ 76
Whitespace .................................................................................................................. 77
Finding the Length of a String ................................................................................... 79
Substrings .................................................................................................................... 79
Contents
Building IDL Applications
Contents
iii
Chapter 7:
Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Components of Statements ....................................................................................... 84
The Assignment Statement ........................................................................................ 85
Blocks .......................................................................................................................... 90
CASE Statement ......................................................................................................... 92
Common Blocks ......................................................................................................... 93
FOR Statement ........................................................................................................... 96
Function Definition Statement ................................................................................. 99
GOTO Statement ..................................................................................................... 102
IF Statement ............................................................................................................. 102
Procedure Call Statement ........................................................................................ 104
Procedure Definition Statement ............................................................................. 106
REPEAT Statement .................................................................................................. 107
WHILE Statement .................................................................................................... 108
Chapter 8:
Defining Procedures and Functions . . . . . . . . . . 109
Procedure & Function Definitions ..........................................................................
Parameters ................................................................................................................
Using Keyword Parameters .....................................................................................
Keyword Inheritance ...............................................................................................
Entering Procedure Definitions ..............................................................................
Parameter Passing Mechanism ................................................................................
Calling Mechanism ..................................................................................................
110
110
113
114
118
120
121
Chapter 9:
Writing IDL Programs . . . . . . . . . . . . . . . . . . . . . 123
Informational Routines ...........................................................................................
Program Control Routines ......................................................................................
Expression Evaluation Order ..................................................................................
Avoid IF Statements .................................................................................................
Use Vector and Array Operations ...........................................................................
IDL System Functions & Procedures ......................................................................
Use Constants of the Correct Type .........................................................................
Eliminate Invariant Expressions .............................................................................
Virtual Memory .......................................................................................................
IDL Implementation ................................................................................................
Building IDL Applications
124
128
130
131
132
133
134
134
135
139
Contents
iv
Contents
Chapter 10:
Controlling Errors . . . . . . . . . . . . . . . . . . . . . . . . . 141
Default Error-Handling Mechanism ....................................................................... 142
Disappearing Variables ............................................................................................. 142
Controlling Errors Using CATCH ........................................................................... 143
Controlling Errors Using ON_ERROR ................................................................... 145
Controlling Input/Output Errors ............................................................................ 146
Error Signaling .......................................................................................................... 147
Obtaining Traceback Information ........................................................................... 148
Error Handling ......................................................................................................... 149
Math Errors ............................................................................................................... 151
Chapter 11:
Files and Input/Output . . . . . . . . . . . . . . . . . . . . . 155
File I/O Overview ...................................................................................................... 156
Unformatted Input/Output ..................................................................................... 158
Formatted Input/Output .......................................................................................... 158
Opening Files ............................................................................................................ 160
Closing Files .............................................................................................................. 161
Logical Unit Numbers (LUNs) ................................................................................ 162
Reading And Writing Very Large Files .................................................................... 164
Using Free Format Input/Output ............................................................................ 165
Using Explicitly Formatted Input/Output .............................................................. 169
Format Codes ............................................................................................................ 173
Using Unformatted Input/Output .......................................................................... 191
Portable Unformatted Input/Output ...................................................................... 197
Associated Input/Output ......................................................................................... 202
File Manipulation Operations ................................................................................. 206
UNIX-Specific Information ..................................................................................... 213
VMS-Specific Information ....................................................................................... 217
Windows-Specific Information ............................................................................... 226
Macintosh-Specific Information ............................................................................. 227
Scientific Data Formats ............................................................................................ 227
Standard Image File Formats ................................................................................... 227
Chapter 12:
Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Heap Variables .......................................................................................................... 230
Creating Heap Variables .......................................................................................... 231
Saving and Restoring Heap Variables ...................................................................... 232
Contents
Building IDL Applications
Contents
v
Pointer Heap Variables ............................................................................................
IDL Pointers .............................................................................................................
Operations on Pointers ............................................................................................
Dangling References ................................................................................................
Heap Variable “Leakage” .........................................................................................
Pointer Validity ........................................................................................................
Freeing Pointers .......................................................................................................
Pointer Examples .....................................................................................................
233
233
235
239
239
241
242
242
Chapter 13:
Object Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
IDL Object Overview ...............................................................................................
Class Structures ........................................................................................................
Inheritance ...............................................................................................................
Object Heap Variables .............................................................................................
Null Objects ..............................................................................................................
The Object Lifecycle .................................................................................................
Operations on Objects .............................................................................................
Information about Objects ......................................................................................
Method Routines .....................................................................................................
Method Overriding ..................................................................................................
Object Examples .......................................................................................................
250
251
253
254
255
255
258
259
261
263
265
Chapter 14:
Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
IDL Direct Graphics ................................................................................................. 268
IDL Object Graphics ................................................................................................ 268
Chapter 15:
Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Widget Types ............................................................................................................
Manipulating Widgets .............................................................................................
Examples of Widget Programming .........................................................................
The Widget Application Model ...............................................................................
Creating Widget Applications .................................................................................
Widget Example 1 ....................................................................................................
Widget Values ..........................................................................................................
Widget User Values ..................................................................................................
Widget Events ..........................................................................................................
Widget Example 2 ....................................................................................................
Building IDL Applications
273
277
278
278
281
283
284
286
287
292
Contents
vi
Contents
Using Draw Widgets ................................................................................................. 294
Creating Menus ........................................................................................................ 295
Controlling Widgets ................................................................................................. 300
Widget Example 3 ..................................................................................................... 302
Widget Sizing ............................................................................................................ 304
Event Processing And Callbacks .............................................................................. 309
Managing Widget Application State ........................................................................ 312
Compound Widgets ................................................................................................. 314
Tips on Creating Widget Applications .................................................................... 315
Compound Widget Example ................................................................................... 316
Chapter 16:
Building Cross-Platform Applications . . . . . . . . . . 327
Which Operating System is Running? ..................................................................... 328
File and Path Specifications ..................................................................................... 329
Environment Variables ............................................................................................ 331
Files and I/O .............................................................................................................. 331
Math Exceptions ....................................................................................................... 334
Operating System Access .......................................................................................... 334
Display Characteristics and Palettes ........................................................................ 335
Fonts .......................................................................................................................... 335
Printing ..................................................................................................................... 335
SAVE and RESTORE ................................................................................................ 336
Widgets ...................................................................................................................... 336
Using External Code ................................................................................................. 339
Licensing ................................................................................................................... 339
DataMiner Issues ...................................................................................................... 339
Index
Contents
Building IDL Applications
Chapter 1
Overview
This chapter includes information about IDL, the IDL documentation set, and
about contacting Research Systems regarding problems with IDL.
What is an IDL Application?
We use the term “IDL Application” very broadly; any program written in the IDL
language is, in our view, an IDL application. IDL Applications range from the
very simple (a MAIN program entered at the IDL command prompt, for
example) to the very complex (large programs with full-blown graphical user
interfaces, such as ENVI). Whether you are writing a small program to analyze a
single data set or a large-scale application for commercial distribution, it is useful
to understand the programming concepts used by the IDL language.
1
2
Chapter 1: Overview
Can I Distribute My Application?
You can freely distribute IDL source code for your IDL applications to colleagues
and others who use IDL. (If you intend to distribute your applications, it is a good
idea to avoid any code that depends on the qualities of a specific platform. See
“!VERSION” on page 45 of the IDL Reference Guide and “Creating Widget
Applications” on page 281 of Building IDL Applications for some hints on
writing platform-independent code.) Of course, IDL applications can only be
run from within the IDL environment, so anyone who wishes to run your IDL
application must have access to an IDL license.
If you would like to distribute your IDL application to people who do not have
access to an IDL license, you may wish to consider a runtime IDL licensing
agreement. Runtime IDL licenses allow you to distribute a special version of IDL
along with your application. Contact your distributor or Research Systems sales
representative for information about runtime licensing.
About IDL
IDL is a complete computing environment for the interactive analysis and
visualization of data. IDL integrates a powerful, array-oriented language with
numerous mathematical analysis and graphical display techniques.
Programming in IDL is a time-saving alternative to programming in FORTRAN
or C—using IDL, tasks which require days or weeks of programming with
traditional languages can be accomplished in hours. You can explore data
interactively using IDL commands and then create complete applications by
writing IDL programs.
Advantages of IDL include:
About IDL
•
IDL is a complete, structured language that can be used both interactively and to
create sophisticated functions, procedures, and applications.
•
Operators and functions work on entire arrays (without using loops), simplifying
interactive analysis and reducing programming time.
•
Immediate compilation and execution of IDL commands provides instant feedback and “hands-on” interaction.
•
Rapid 2D plotting, multi-dimensional plotting, volume visualization, image display, and animation allow you to observe the results of your computations
immediately.
•
Many numerical and statistical analysis routines—including Numerical Recipes
routines—are provided for analysis and simulation of data.
Building IDL Applications
Chapter 1: Overview
3
•
IDL’s flexible input/output facilities allow you to read any type of custom data
format. Support is also provided for common image standards (including BMP,
GIF, JPEG, and XWD) and scientific data formats (CDF, HDF, and NetCDF).
•
IDL widgets can be used to quickly create multi-platform graphical user interfaces
to your IDL programs.
•
IDL programs run the same across all supported platforms (Unix, VMS, Microsoft
Windows, and Macintosh systems) with little or no modification. This application
portability allows you to easily support a variety of computers.
•
Existing FORTRAN and C routines can be dynamically-linked into IDL to add
specialized functionality. Alternatively, C and FORTRAN programs can call IDL
routines as a subroutine library or display “engine”.
IDL Documentation
IDL’s Online Help system gives you access to the complete IDL documentation set
in electronic, hypertext-linked format. You can enter the Online Help system by
entering ? at the IDL command prompt or by selecting “Online Help” from the
Help menu of the IDL Development Environment user interface.
Research Systems provides a subset of the complete IDL documentation set in
printed form along with your copy of the IDL software. We do not ship the full
printed documentation set because some volumes cover specialized topics, which
are of limited interest to some of our customers. Shipping only the volumes of
greatest general interest in printed form allows us to provide the highest quality
documentation set possible while minimizing the impact of our documentation
on the environment. In addition to being available on-line, volumes not
automatically shipped with new or upgrade orders are available for purchase; use
the order sheet included with your shipment or consult your sales representative
or distributor for details.
The IDL documentation set consists of the following volumes:
Using IDL
Using IDL explains IDL from an interactive user’s point of view. It contains
information about the IDL environment, the structure of IDL, and how to use
IDL Direct Graphics to analyze your data.
Building IDL Applications
Building IDL Applications (this book) explains how to use the IDL language to
write programs — from simple procedures to large, complex applications. It
Building IDL Applications
IDL Documentation
4
Chapter 1: Overview
contains information on the structure of the IDL language, programming
techniques, IDL Direct Graphics, and IDL’s user-interface toolkit.
IDL Reference Guide
The Reference Guide is a two-volume set that contains detailed information about
all of IDL’s non-object oriented procedures, functions, system variables, and
commands. Information on IDL’s object-oriented features is contained in
Building IDL Applications; information on IDL Object Graphics is contained in
Object Graphics.
Object Graphics
Object Graphics contains a complete discussion of IDL Object Graphics. This
volume also contains the complete reference to IDL’s object class libraries.
Note Each of the above books includes a comprehensive index that covers all four
volumes.
Using Insight
Using Insight contains information on IDL Insight, the graphical interface to
IDL’s analysis capabilities. Insight allows you to import, analyze, and visualize
data without programming in the IDL language.
External Development Guide
The External Development Guide explains how to use IDL in concert with your
computer’s operating system or with programs written in other programming
languages.
Scientific Data Formats
Scientific Data Formats contains detailed information about IDL’s routines for
dealing with Common Data Format (CDF), Hierarchical Data Format (HDF),
Earth Observing System extensions to HDF (HDF-EOS), and Network Common
Data Format (NetCDF) files.
IDL DataMiner Guide
The DataMiner Guide contains information on using IDL to interact with
databases using the Open Database Connectivity (ODBC) interface.
Note The DataMiner option must be purchased separately.
IDL HandiGuide
The HandiGuide is a handy quick reference that contains calling-sequence
information on all IDL routines.
IDL Documentation
Building IDL Applications
Chapter 1: Overview
5
Typographical Conventions
The following typographical conventions are used throughout the IDL
documentation set:
•
UPPER CASE
IDL functions, procedures, and keywords are displayed in UPPER CASE type. For
example, the calling sequence for an IDL procedure looks like this:
CONTOUR, Z [, X, Y]
•
Mixed Case
IDL object class and method names are displayed in Mixed Case type. For
example, the calling sequence to create an object and call a method looks like this:
object = OBJ_NEW(’IDLgrPlot’)
object -> GetProperty, ALL=properties
•
Italic type
Arguments to IDL procedures and functions — data or variables you must
provide — are displayed in italic type. In the above example, Z, X, and Y are all
arguments.
•
Square brackets ( [ ] )
Square brackets used in calling sequences indicate that the enclosed arguments
are optional. Do not type the brackets. In the above CONTOUR example, X and
Y are optional arguments. Square brackets are also used to specify array elements.
•
Courier type
In examples or program listings, things that you must enter at the command line
or in a file are displayed in courier type. Results or data that IDL displays on
your computer screen are shown in courier bold type. An example might
direct you to enter the following at the IDL command prompt:
array = INDGEN(5)
PRINT, array
In this case, the results are shown like this:
0
1
2
3
4
Reporting Problems
We strive to make IDL as reliable and bug free as possible. However, no program
with the size and complexity of IDL is perfect, and bugs do surface. When you
encounter a problem with IDL, the manner in which you report it has a large
Building IDL Applications
Typographical Conventions
6
Chapter 1: Overview
bearing on how well and quickly we can fix it. This section is intended to help you
report problems in a way that will help us correct the problem rapidly.
Background Information
When a bug is reported and verified, we correct it in a later release. Sometimes, a
bug only occurs when running on a certain machine, operating system, or
graphics device. For these reasons, we need to know the following facts when you
report a bug:
•
Your IDL installation number.
•
The version of IDL you are running.
•
The type of machine it is running on.
•
The operating system version it is running under.
•
The type and version of your windowing system.
•
The graphics device, if the problem involves graphics.
The installation number is assigned by us when you purchase IDL. The IDL
version, site number, and type of machine are printed when IDL is started. For
example:
IDL. Version 4.0.1c (sunos sparc).
Copyright 1989-1996, Research Systems, Inc.
All rights reserved. Unauthorized reproduction prohibited.
Installation number: 177.
Licensed for use by: ACME Datawhack Corp.
is the startup announcement from IDL version 4.0.1c under SunOS on a
Sun Sparc workstation at installation number 177.
Under Unix, the version of the operating system can usually be found in the file
/etc/motd. It is also printed when the machine boots. In any event, your
system administrator should know.
Under VMS, the DCL statement:
write sys$output f$getsyi("version")
will give you the operating system version.
Under Windows 95 and Windows NT version 4, select “About” from the Help
menu in the Windows Explorer. Under Windows NT version 3.5, select “About”
from the Help menu in the File Manager.
On the Macintosh, select “About this Macintosh” from the apple menu.
Reporting Problems
Building IDL Applications
Chapter 1: Overview
7
Double Check
Before reporting a problem, you should always ask yourself “Is it really a bug?”
Sometimes, it is a simple matter of misinterpreting what is supposed to happen.
Double check with the manual or a local expert.
If you cannot determine what should happen in a given situation by consulting
the reference manual, the manual needs to be improved on that topic. Please let
us know if you feel that the manual was vague or unclear on a subject.
It is often obvious whether something is a bug or not. If IDL crashes, it is a
genuine bug. If however, it draws a plot differently than you would expect or
desire, it might be a bug, but it is certainly less obvious. Another question to ask
is whether the problem lies within IDL, or with the system running IDL. Is your
system properly configured with enough virtual memory and sufficient
operating system quotas? Does the system seem stable and is everything else
working normally?
Describing The Problem
When describing the problem, it is important to use precise language. Vague
terms like “crashes”, “blows up”, and “fails” are open to many interpretations.
Does it really crash IDL and leave you looking at an operating system prompt?
This would be our interpretation of “crash.” Perhaps, however, it just issues an
unexpected error message and gives another prompt. What is really meant by a
term like “fails?”
It is also important to separate concrete facts from conjecture about underlying
causes. For example, a statement such as “IDL dumps core when allocating
dynamic memory.” is not nearly as useful as one like “IDL dumps core when I
execute the following statements. I think it might be trying to get dynamic
memory”. The second version tells us exactly what happened. The opinion about
what was going on when the problem surfaced is also useful to us, but it helps to
have it clearly labeled as such.
Reproducibility
Intermittent bugs are by far the hardest kind to fix. In general, if we can’t make it
happen on our machine, we can’t fix it. It is therefore far more likely that we can
help you if you can tell us a sequence of IDL statements that cause the problem to
happen. Naturally, there are degrees of reproducibility. Situations where a certain
sequence of statements causes the bug 1 time in 3 tries are fairly likely to be
fixable. Situations where the bug happens once every few months and no one is
sure what triggered it are almost hopeless.
Building IDL Applications
Reporting Problems
8
Chapter 1: Overview
Simplify the Problem
When reporting a bug, it is important to give us the shortest possible series of IDL
statements that cause it. The longer and more intricate an example, the less likely
it is that we can help. Sometimes a single statement triggers the bug. Often
though, the problem surfaces when writing a larger system of inter-related
procedures and functions. Such a situation must be simplified before we can
tackle it. Take the following steps to simplify your problem:
•
Copy the procedure and function files that are involved to a scratch second copy.
Never modify your only copy!
•
Eliminate everything that is not involved in demonstrating the bug. Don’t do this
all at once. Instead, do it in a series of slow careful steps. Between each step, stop
and run IDL on the result to ensure that the bug still appears.
•
If a simplification causes the bug to disappear, restore the statements involved and
look for other things to eliminate.
•
If the problem does not involve file Input/Output, strive to eliminate all file I/O
statements. Use IDL routines to generate a dummy data set, rather than including
your own data. If your bug report does not involve I/O, it will be much easier for
us to reproduce. If you have to provide us with a copy of your data, things become
more complicated.
On the other hand, if the bug involves file Input/Output, attempt to determine if
the problem only happens with a certain file, or with any data. If you are running
under VMS, check the file organization using the DCL DIRECTORY/FULL
command, and include this information in your report.
The end result of such simplification should be a small number of IDL statements
that demonstrate the problem.
Bugs with Dynamic Loading
The CALL_EXTERNAL and LINKIMAGE system routines allow you to
dynamically load routines written in other languages into IDL. This is a very
powerful technique for extending IDL, but it is considerably more difficult than
simply writing IDL statements. At this level, the programmer is underneath the
user level shell of IDL and is not protected from small programming errors that
can corrupt data, give incorrect results, or even crash IDL. In such situations, the
burden of proving that a bug is within IDL and not the dynamically loaded code
is entirely the programmer’s.
Although it is certainly true that a bug in this situation can be within IDL, it is
very important that you exhaust all other possibilities before reporting a bug. If
Reporting Problems
Building IDL Applications
Chapter 1: Overview
9
you decide that you need to report a bug, the comments above on simplifying
things are even more important than usual. If you send us a small example that
tickles the bug, we can respond quickly with a correction or advice. Otherwise,
we may not even know where to begin.
Sending Data with Your Bug Report
If the statements required to reproduce the bug are more than a few lines or
require data files, we will need you to send them to us on magnetic media or via
e-mail. Call us for details.
Contact Us
To report a problem, contact us at the following addresses.
Mail
Research Systems, Inc.
4990 Pearl East Circle
Boulder, Colorado 80301
Telephone
(303) 786-9900 (Voice)
(303) 786-9909 (Fax)
(303) 413-3920 (IDL technical support direct line)
Electronic Mail
[email protected]
Building IDL Applications
Reporting Problems
10
Reporting Problems
Chapter 1: Overview
Building IDL Applications
Chapter 2
Constants and
Variables
The following topics are covered in this chapter:
Data Types ........................................... 12
Constants ............................................. 14
Type Conversion Functions ................... 19
Variables ............................................... 21
System Variables ................................... 22
11
12
Chapter 2: Constants and Variables
Constants and variables are building blocks with which operators and functions
produce results. A constant is a value that does not change during the execution
of a program. A variable is a location with a name that contains a scalar or array
value. During the execution of a program or an interactive terminal session,
numbers, strings, or arrays can be stored in variables and used in future
computations.
Data Types
The IDL language is dynamically typed. This means that an operation on a
variable can change that variable’s type. In general, when variables of different
types are combined in an expression, the result has the data type that yields the
highest precision.
For example, if an integer variable is added to a floating-point variable, the result
will be a floating-point variable.
Basic Data Types
In IDL there are twelve basic, atomic data types, each with its own form of
constant. The data type assigned to a variable is determined either by the syntax
used when creating the variable, or as a result of some operation that changes the
type of the variable.
IDL’s basic data types are discussed in more detail beginning with “Constants” on
page 14.
•
Byte: An 8-bit unsigned integer ranging in value from 0 to 255. Pixels in images
are commonly represented as byte data.
•
Integer: A 16-bit signed integer ranging from −32,768 to +32,767.
•
Unsigned Integer: A 16-bit unsigned integer ranging from 0 to 65535.
•
Long: A 32-bit signed integer ranging in value from approximately minus two
billion to plus two billion.
•
Unsigned Long: A 32-bit unsigned integer ranging in value from 0 to approximately four billion.
•
64-bit Long: A 64-bit signed integer ranging in value from –
9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.
•
64-bit Unsigned Long: A 64-bit unsigned integer ranging in value from 0 to
18,446,744,073,709,551,615.
Data Types
Building IDL Applications
Chapter 2: Constants and Variables
13
•
Floating-point: A 32-bit, single-precision, floating-point number in the range of
±1038, with approximately six or seven decimal places of significance.
•
Double-precision: A 64-bit, double-precision, floating-point number in the range
of ±10308 with approximately 14 decimal places of significance.
•
Complex: A real-imaginary pair of single-precision, floating-point numbers.
Complex numbers are useful for signal processing and frequency domain filtering.
•
Double-precision complex: A real-imaginary pair of double-precision, floatingpoint numbers.
Note In previous versions of IDL prior to version 4, the combination of a doubleprecision number and a complex number in an expression resulted in a singleprecision complex number because those versions of IDL lacked the DCOMPLEX double-precision complex data type. Starting with IDL version 4, this
combination results in a DCOMPLEX number.
•
String: A sequence of characters, from 0 to 32,767 characters in length, which is
interpreted as text.
Precision of Floating-Point Numbers
The precision of IDL’s floating-point numbers depends somewhat on the
platform involved and the compiler and specific compiler switches used to
compile the IDL executable. The values shown here are minimum values; in some
cases, IDL may deliver slightly more precision than we have indicated. If your
application uses numbers that are sensitive to floating-point truncation or
round-off errors, or values that cannot be represented exactly as floating-point
numbers, this is something you should consider.
For more information on floating-point mathematics, see “Accuracy & FloatingPoint Operations” on page 427 of Using IDL. For information on your machine’s
precision, see “MACHAR” on page 703 of the IDL Reference Guide.
Complex Data Types
•
Structures: Aggregations of data of various types. Structures are discussed in
chapter 4 of this volume.
•
Pointers: A reference to a dynamically-allocated heap variable. Pointers are discussed in chapter 12 of this volume.
•
Object References: A reference to a special heap variable that contains an IDL
object structure. Object references are discussed in chapter 13 of this volume.
Building IDL Applications
Data Types
14
Chapter 2: Constants and Variables
Constants
Integer Constants
Numeric constants of different types can be represented by a variety of forms.
The syntax used when creating integer constants is shown in Table 2-1, where n
represents one or more digits.
Radix
Decimal
Hexadecimal
Type
Form
Examples
Byte
nB
12B, 34B
Integer
n or nS
12,12S,425,425S
Unsigned Integer
nU or nUS
12U,12US
Long
nL
12L, 94L
Unsigned Long
nUL
12UL, 94UL
64-bit Long
nLL
12LL, 94LL
Unsigned 64-bit Long
nULL
12ULL, 94ULL
Byte
’n’XB
’2E’XB
Integer
’n’X
’0F’X
Unsigned Integer
’n’XU
’0F’XU
Long
’n'XL
’FF’XL
Unsigned Long
'n'XUL
’FF’XUL
64-bit Integer
’n’XLL
’FF’XLL
Unsigned 64-bit Integer
’n’XULL
'FF'XULL
Table 2-1: Integer Constants
Constants
Building IDL Applications
Chapter 2: Constants and Variables
15
Radix
Type
Form
Examples
Octal
Byte
"nB
"12B
Integer
"n
"12
’n’O
’377’O
"nU
"12U
’n’OU
’377’OU
"nL
"12L
’n’OL
’777777’OL
"nUL
"12UL
’n’OUL
'777777’OUL
"nLL
"12LL
’n’OLL
'777777'OLL
Unsigned 64-bit
"nULL
"12ULL
Long
’n’OULL
'777777'OULL
Unsigned Integer
Long
Unsigned Long
64-bit Long
Table 2-1: Integer Constants
Digits in hexadecimal constants include the letters A through F for the decimal
numbers 10 through 15. Octal constant use the same style as hexadecimal
constants, substituting an O for the X. Table 2-2 illustrates examples of both valid
and invalid IDL constants.Table 1
Absolute values of integer constants are given in Table 1. Integers specified
Type
Absolute Value Range
Byte
0 – 255
Integer
0 – 32767
Unsigned Integer
0 – 65535
0 – 231 - 1
Long
64-bit Long
0 – 232 - 1
0 – 263 - 1
Unsigned 64-bit Long
0 – 264 - 1
Unsigned Long
Table 1: Absolute Value Range Of Integer Constants
without one of the B, S, L, or LL specifiers are automatically promoted to an
Building IDL Applications
Constants
16
Chapter 2: Constants and Variables
integer type capable of holding them. For example, 40000 is promoted to
longword because it is too large to fit in an integer. Any numeric constant can be
preceded by a plus (+) or minus (-) sign.
Unacceptable
Reason
Acceptable
256B
Too large, limit is 255
255B
’123L
Missing apostrophe
’123’L
’03G’x
Invalid character
"129
’27’L
No radix
’27’OL
650XL
No apostrophes
’650’XL
"129
9 is an invalid octal digit
"124
Table 2-2: Examples of Integer Constants
Floating-Point and Double-Precision Constants
Floating-point and double-precision constants can be expressed in either
conventional or scientific notation. Any numeric constant that includes a decimal
point is a floating-point or double-precision constant.
The syntax of floating-point and double-precision constants is shown in the
following table. The notation “sx” represents the sign and magnitude of the
exponent, for example, E-2.
Form
Example
n.
102.
.n
.102
n.n
10.2
nEsx
10E5
n.Esx
10.E-3
.nEsx
.1E+12
n.nEsx
2.3E12
Table 2-3: Syntax of Floating-Point
Constants
Double-precision constants are entered in the same manner, replacing the E with
a D. For example, 1.0D0, 1D, and 1.D each represent a double-precision
numeral 1.
Constants
Building IDL Applications
Chapter 2: Constants and Variables
17
Complex Constants
Complex constants contain a real and an imaginary part, both of which are
single- or double-precision floating-point numbers. The imaginary part can be
omitted, in which case it is assumed to be zero. The form of a complex constant
is as follows:
COMPLEX(REAL_PART, IMAGINARY_PART)
or
COMPLEX(REAL_PART)
For example, COMPLEX(1,2) is a complex constant with a real part of one, and
an imaginary part of two. COMPLEX(1) is a complex constant with a real part of
one and a zero imaginary component. To extract the real part of a complex
expression, use the FLOAT function. The ABS function returns the magnitude of
a complex expression, and the IMAGINARY function returns the imaginary part.
String Constants
A string constant consists of zero or more characters enclosed by apostrophes (’)
or quotes ("). The value of the constant is simply the characters appearing
between the leading delimiter (’or “") and the next occurrence of the same
delimiter. A double apostrophe (’’) or quote ("") is considered to be the null
string; a string containing no characters. An apostrophe or quote can be
represented within a string by two apostrophes or quotes; e.g., ’Don’’t’
returns Don’t. This syntax often can be avoided by using a different delimiter;
e.g., "Don’t" instead of ’Don’’t’. The following table illustrates valid string
constants.
Expression
Resulting String
’Hi there’
Hi there
"Hi there"
Hi there
’’
Null String
"I’m happy"
I’m happy
’I"m happy’
I”m happy
’counter’
counter
’129’
129
Table 2-4: Examples of Valid String Constants
The following table illustrates invalid string constants. In the last entry of the
table, "129" is interpreted as an illegal octal constant. This is because a quote
Building IDL Applications
Constants
18
Chapter 2: Constants and Variables
character followed by a digit from 0 to 7 represents an octal numeric constant,
not a string, and the character 9 is an illegal octal digit.
String Value
Unacceptable
Reason
Hi there
’Hi there"
Mismatched delimiters
Null String
’
Missing delimiter
I’m happy
'I'm happy'
Apostrophe in string
counter
''counter''
Double apostrophe is null string
129
"129"
Illegal octal constant
Table 2-5: Examples of Invalid String Constants
Note While an IDL string variable can hold up to 64 Kbytes of information, the
buffer than handles input at the IDL command prompt is limited to 255
characters. If for some reason you need to create a string variable longer than
255 characters at the IDL command prompt, split the variable into multiple
sub-variables and combine them with the “+” operator:
var = var1+var2+var3
This limit only affects string constants created at the IDL command prompt.
Representing Non-Printable Characters
The ASCII characters with value less than 32 or greater than 126 do not have
printable representations. Such characters can be included in string constants by
specifying their ASCII value as a byte argument to the STRING function. The
following table gives examples of using octal or hexadecimal character notation.
Specified String
Actual Contents
Comment
STRING(27B)+'[;H'
+STRING(27B)+[2J’
’<Esc>[;H<Esc>[2J’
Erase ANSI terminal
STRING(7B)
Bell
Ring the bell
STRING(8B)
Backspace
Move cursor
left
Table 2-6: Specifying Non-Printable Characters
Note that ASCII characters may have different effects (or no effect) on platforms
that do not support ASCII terminal commands.
Constants
Building IDL Applications
Chapter 2: Constants and Variables
19
Type Conversion Functions
IDL allows you to convert data from one data type to another using a set of
conversion functions. These functions are useful when you need to force the
evaluation of an expression to a certain type, output data in a mode compatible
with other programs, etc. The conversion functions are shown in Table 2-7:
Function
Description
STRING
Convert to string
BYTE
Convert to byte
FIX
Convert to (6-bit integer
UINT
Convert to 16-bit unsigned integer
LONG
Convert to 32-bit integer
ULONG
Convert to 32-bit unsigned integer
LONG64
Convert to 64-bit integer
ULONG64
Convert to 64-bit unsigned integer
FLOAT
Convert to floating-point
DOUBLE
Convert to double-precision floating-point
COMPLEX
Convert to complex value
DCOMPLEX
Convert to double-precision complex value
Table 2-7: Type Conversion Functions
Conversion functions operate on data of any structure: scalars, vectors, or arrays,
and variables can be of any type.
Take Care When Converting Types
If the variable you are converting lies outside the range of the type you are
converting to, IDL will truncate the binary representation of the value without
informing you. For example:
A = 33000
Define A. Note that the value of A is
outside the range of integers, and is
automatically created as a longword
integer by IDL.
B = FIX(A)
B is silently truncated.
PRINT, B
IDL prints:
Building IDL Applications
Type Conversion Functions
20
Chapter 2: Constants and Variables
-32536
Applying FIX creates a short (16-bit) integer. If the value of the variable passed to
FIX lies outside the range of 16-bit integers, IDL will silently truncate the binary
value, returning only the 16 least-significant digits, with no indication that an
error has occurred.
With most floating-point operations, error conditions can be monitored using
the FINITE and CHECK_MATH functions. See Chapter 10, “Controlling
Errors”, for more information.
Converting Strings
When converting from a string argument, it is possible that the string does not
contain a valid number and no conversion is possible. The default action in such
cases is to print a warning message and return zero. The ON_IOERROR
procedure can be used to establish a statement to be jumped to in case of such
errors.
Conversion between strings and byte arrays (or vice versa) is something of a
special case. The result of the BYTE function applied to a string or string array is
a byte array containing the ASCII codes of the characters of the string.
Converting a byte array with the STRING function yields a string array or scalar
with one less dimension than the byte array.
Examples of Type Conversion
See Table 2-8 for examples of type conversions and their results.
Operation
Results
FLOAT(1)
1.0
FIX(1.3 + 1.7)
3
FIX(1.3) + FIX(1.7)
2
BYTE(1.2)
1
BYTE(-1)
255b (Bytes are modulo 256)
BYTE(’01ABC’)
[48b, 49b, 65b, 66b, 67b]
STRING([65B, 66B, 67B])
’ABC’
FLOAT(COMPLEX(1, 2))
1.0
COMPLEX([1, 2], [4, 5])
[COMPLEX(1,4),COMPLEX(2,5)]
Table 2-8: Uses of Type Conversion Functions
Type Conversion Functions
Building IDL Applications
Chapter 2: Constants and Variables
21
Variables
Variables are named repositories where information is stored. A variable can have
virtually any size and can contain a scalar, vector, multi-dimensional array,
structure, pointer, or object reference. Arrays can contain elements of any IDL
data. Variables can be used to store images, spectra, single quantities, names,
tables, etc.
Attributes of Variables
Every variable has a number of attributes that can change during the execution of
a program or terminal session. Variables have both a structure and a type as
described below.
Structure
A variable can contain a single value (a scalar) or a number of values of the same
type (an array) or data entities of potentially differing type and size (a structure).
Strings are considered as single values, and a string array contains a number of
variable-length strings.
In addition, a variable can associate an array structure with a file; these variables
are called associated variables. Referencing an associated variable causes data to
be read from, or written to, the file. Associated variables are described in
“ASSOC” on page 204 of the IDL Reference Guide.
Type
A variable can have one and only one of the following types: undefined, byte,
integer, unsigned integer, longword, unsigned longword, 64-bit integer, unsigned
64-bit integer, floating-point, double-precision floating-point, complex floatingpoint, double-precision complex floating-point, string, structure, pointer, or
object reference.
When a variable appears on the left-hand side of an assignment statement, its
attributes are copied from those of the expression on the right-hand side. For
example, the statement
ABC = DEF
redefines or initializes the variable ABC with the attributes and value of variable
DEF. Attributes previously assigned to the variable are destroyed. Initially, every
variable has the single attribute of undefined. Attempts to use the value of an
undefined variables result in an error.
Variable Names
IDL variables are named by identifiers. Each identifier must begin with a letter
and can contain from 1 to 128 characters. The second and subsequent characters
Building IDL Applications
Variables
22
Chapter 2: Constants and Variables
can be letters, digits, the underscore character, or the dollar sign. A variable name
cannot contain embedded spaces, because spaces are considered to be delimiters.
Characters after the first 128 are ignored. Names are case insensitive. Lowercase
letters are converted to uppercase; so the variable name abc is equivalent to the
name ABC.
Acceptable
Unacceptable
Reason
A
EOF
Conflicts with function name
A6
6A
Does not start with letter
INIT_STATE
_INIT
Does not start with letter
ABC$DEF
[email protected]
Illegal character
My_variable
ab cd
Embedded space
Table 2-9: Examples of Valid and Invalid Variable Names.
Caution A variable cannot have the same name as a function (either built-in or user
defined) or a reserved word (see the list below). Giving a variable such a name
results in a syntax error or in “hiding” the variable.
Table 2-10 lists all of the reserved words in IDL.
AND
BEGIN
CASE
COMMON
DO
ELSE
END
ENDCASE
ENDELSE
ENDFOR
ENDIF
ENDREP
ENDWHILE
EQ
FOR
FUNCTION
GE
GOTO
GT
IF
LE
LT
MOD
NE
NOT
OF
ON_IOERROR
OR
PRO
REPEAT
THEN
UNTIL
WHILE
XOR
Table 2-10: IDL Reserved Words
System Variables
System variables are a special class of predefined variables available to all program
units. Their names always begin with the exclamation mark character (!). System
System Variables
Building IDL Applications
Chapter 2: Constants and Variables
23
variables are used to set the options for plotting, to set various internal modes, to
return error status, etc.
System variables have a predefined type and structure that cannot be changed.
When an expression is stored into a system variable, it is converted to the variable
type, if necessary and possible. Certain system variables are read only, and their
values cannot be changed. The user can define new system variables with the
DEFSYSV procedure.
System variables are discussed in chapter 3 of the IDL Reference Guide.
Building IDL Applications
System Variables
24
System Variables
Chapter 2: Constants and Variables
Building IDL Applications
Chapter 3
Expressions and
Operators
The following topics are covered in this chapter:
Operator Precedence ............................ 26
IDL Operators ....................................... 28
Type and Structure of Expressions ......... 37
25
26
Chapter 3: Expressions and Operators
Variables and constants are combined into expressions using operators and
functions, and providing a result. Expressions can be combined with other
expressions, variables, and constants to yield more complex expressions. In IDL,
unlike FORTRAN or C, expressions can be scalar- or array-valued.
There are many types of operators in IDL. In addition to the usual operators—
addition, subtraction, multiplication, division, exponentiation, relations (EQ,
NE, GT, etc.), and Boolean arithmetic (AND, OR, NOT, and XOR)—operators
exist to find minima, maxima, select scalars and subarrays from arrays
(subscripting), and to concatenate scalars and arrays to form new arrays.
Functions, which are operators in themselves, perform operations that are
usually of a more complex nature than those denoted by simple operators.
Functions exist in IDL for data smoothing, shifting, transforming, evaluation of
transcendental functions, and other operations.
Expressions can be arguments to functions or procedures. For example, the
expression SIN(A*!PI) evaluates the variable A multiplied by the value of π,
then applies the trigonometric sine function. This result can be used as an
operand to form a more complex expression or as an argument to yet another
function (e.g., EXP(SIN(A*!PI)) evaluates esin πa).
Operator Precedence
IDL operators are divided into the levels of algebraic precedence found in
common arithmetic. Operators with higher precedence are evaluated before
those with lesser precedence, and operators of equal precedence are evaluated
from left to right. Operators are grouped into five classes of precedence as shown
in Table 3-1.
The effect of operators is based on precedence, not position. This concept is
shown by the following examples.
A = 4 + 5 * 2
A = 14 because the multiplication
operator has a higher precedence
than the addition operator.
Parentheses can be used to override the default evaluation.
A = (4 + 5) * 2
A = 18 because the expression inside the parentheses is evaluated
first.
A useful rule of thumb is, “when in doubt, parenthesize”. Some examples of
expressions are provided in Table 3-2.
Operator Precedence
Building IDL Applications
Chapter 3: Expressions and Operators
27
Priority
Operator
First (highest)
* (pointer dereference)
^ (exponentiation)
Second
* (multiplication)
# and ## (matrix multiplication)
/(division)
MOD (modulus)
Third
+ (addition)
- (subtraction and negation)
< (minimum)
> (maximum)
NOT (Boolean negation)
Fourth
EQ (equality)
NE (not equal)
LE (less than or equal)
LT (less than)
GE (greater than or equal)
GT (greater than)
Fifth
AND (Boolean AND)
OR (Boolean OR)
XOR (Boolean exclusive OR)
Sixth
? (conditional expression)
Table 3-1: Operator Precedence
Expression
Value
A+1
The sum of A and 1.
A<2+1
The smaller of A or two, plus one.
A<2*3
The smaller of A and six, since * has higher
precedence than <.
2 * SQRT(A)
Twice the square root of A.
A + ’Thursday’
The concatenation of the strings A and
“Thursday.” An error results if A is not a string
Table 3-2: Examples of Expressions
Building IDL Applications
Operator Precedence
28
Chapter 3: Expressions and Operators
IDL Operators
As described above, operators are used to combine terms and expressions. The set
of IDL operators is described below:
Parentheses
Parentheses are used to group expressions and to enclose function parameter
lists. Parentheses can be used to override the order of operator evaluation
described above. Examples:
SIN(ANG * PI/180.)
Parentheses enclose function argument lists.
(A + 5)/B
Parentheses specify order of operator evaluation.
The right parenthesis must always close the list begun by the left parenthesis.
Square Brackets
Square brackets are used to create arrays and to enclose array subscripts.
ARRAY = [1, 2, 3, 4, 5]
Use brackets when assigning elements to an array.
ARRAY[X, Y]
Brackets enclose subscripts.
Note In versions of IDL prior to version 5.0, parentheses were used to enclose array
subscripts. While using parentheses to enclose array subscripts will continue
to work as in previous version of IDL, we strongly suggest that you use
brackets in all new code. See “Array Subscript Syntax: [ ] vs. ( )” on page 60
for additional details.
Mathematical Operators
There are seven basic IDL mathematical operators, described below.
Assignment
The equal sign (=) is the assignment operator. The value of the expression on the
right hand side of the equal sign is stored in the variable, subscript element, or
range on the left side. See “The Assignment Statement” on page 85. For example:
A = 32
IDL Operators
Assigns the value 32 to A.
Building IDL Applications
Chapter 3: Expressions and Operators
29
Addition
The positive sign (+) is the addition operator. When applied to strings, the
addition operator concatenates the strings. Examples:
B = 3 + 6
Store the sum of 3 and 6 in B.
B = ’John’ + ’ ’ + ’Doe’
Store the string value of “John
Doe” in B.
Subtraction and Negation
The negative sign (-) is the subtraction operator. Also, the minus sign is used as
the unary negation operator. Examples:
C = 9 - 5
Store the value of 5 subtracted
from 9 in C.
C = -C
Change the sign of C.
Multiplication
The asterisk (*) is the multiplication operator. Example:
C = 2 * 5
Store the product of 2 and 5 in
variable C.
Division
The forward slash (/) is the division operator. Example:
D = 10.0/3.2
Store the result of 10.0 divided by
3.2 in variable D.
Exponentiation
The caret (^) is the exponentiation operator. A^B is equal to A raised to the B
power.
•
If A is a real number and B is of integer type, repeated multiplication is applied.
•
If A is real and B is real (non-integer), the formula AB = eBlnA is evaluated.
•
If A is complex and B is real, the formula AB = (reiθ)B = rB (cosBθ + isinBθ) (where
r is the real part of A and iθ is the imaginary part) is evaluated.
•
If B is complex, the formula AB = eB ln A is evaluated. If A is also complex, the
natural logarithm is computed to be ln (A) = ln(reiθ) = ln (r) + iθ (where r is the
real part of A and iθ is the imaginary part).
•
A0 is defined as 1.
Building IDL Applications
IDL Operators
30
Chapter 3: Expressions and Operators
Modulo
The keyword MOD is the modulo operator. I MOD J is equal to the remainder
when I is divided by J. The magnitude of the result is less than that of J, and its
sign agrees with that of I.
Example:
A = 9 MOD 5
Assign the value of 9 modulo 5 (4)
to A.
A =(ANGLE + B) MOD (2 * !PI)
Compute angle modulo 2p.
Minimum and Maximum Operators
The IDL minimum and maximum operators return the smaller or larger of their
operands, as described below. Note that negated values must be enclosed in
parentheses in order for IDL to interpret them correctly.
The Minimum Operator
The “less than” sign (<) is the IDL minimum operator. The value of “A < B” is
equal to the smaller of A or B. Examples:
A = 5 < 3
Set A equal to 3.
A = 5 < (-6)
Set A equal to -6.
A = 5 < -6
Syntax Error. IDL attempts to perform a subtraction operation if the
“-6” is not enclosed in parentheses.
ARR = ARR < 100
Set all points in array ARR that
are larger than 100 to 100.
X = X0 < X1 < X2
Set X to the smallest of the three
operands.
The Maximum Operator
The “greater than” sign (>) is the IDL maximum operator. “A > B” is equal to the
larger of A or B. Examples:
IDL Operators
C = ALOG(D > 1E - 6)
‘>’ is used to avoid taking the log
of zero or negative numbers.
PLOT, ARR > 0
Plot positive points only. Negative
points are plotted as zero.
Building IDL Applications
Chapter 3: Expressions and Operators
31
Matrix Multiplication
IDL has two operators used to multiply arrays and matrices.
The # Operator
The # operator computes array elements by multiplying the columns of the first
array by the rows of the second array. The second array must have the same
number of columns as the first array has rows. The resulting array has the same
number of columns as the first array and the same number of rows as the second
array.
The ## Operator
The ## operator does what is commonly referred to as matrix multiplication. It
computes array elements by multiplying the rows of the first array by the columns
of the second array. The second array must have the same number of rows as the
first array has columns. The resulting array has the same number of rows as the
first array and the same number of columns as the second array.
For an example illustrating the difference between the two, see “Multiplying
Arrays” on page 430 of Using IDL.
Array Concatenation
The square brackets are used as array concatenation operators. Operands
enclosed in square brackets and separated by commas are concatenated to form
larger arrays. The expression [A,B] is an array formed by concatenating A and
B, which can be scalars or arrays, along the first dimension.
Similarly, [A,B,C] concatenates A, B, and C. The second and third dimensions
can be concatenated by nesting the bracket levels; [[1,2],[3,4]] is a 2element by 2-element array with the first row containing 1 and 2 and the second
row containing 3 and 4. Operands must have compatible dimensions; all
dimensions must be equal except the dimension that is to be concatenated, e.g.,
[2,INTARR(2,2)] are incompatible. Examples:
C = [-1, 1, -1]
Define C as three-point vector.
C = [C, 12]
Add 12 to the end of C.
C = [12, C]
Insert 12 at the beginning of C.
PLOT, [ARR1, ARR2]
Plot ARR2 appended to ARR1.
KER = [[1,2,1], [2,4,2], [1,2,1]]
Define a 3x3 matrix.
Note The maximum number of operands that can appear within brackets varies
across IDL implementations but is always at least 25. If you must create an
array of more than 25 elements using the concatenation operator, use multiple
Building IDL Applications
IDL Operators
32
Chapter 3: Expressions and Operators
statements. For example, to create an array with 70-constant elements, use
the following statements:
A = [k0, k1, ..., k24]
A = [A, k25, k26, ..., k49]
A = [A, k50, k51, ..., k69]
This method is relatively inefficient and should be performed only once if
possible.
Boolean Operators
There are four Boolean operators in IDL. Boolean operators return either “true”
or “false” as described previously. Note that the Boolean operators do not work
with string and complex arguments.
AND
AND is a Boolean operator that returns “true” whenever both of its operands are
true; otherwise, the result is “false.” Any nonzero value is considered true. For
integer, longword, and byte operands, a bitwise AND operation is performed. For
operations on other types, the result is equal to the second operand if the first
operand is not equal to zero or the null string; otherwise, the result is zero or the
null string.
NOT
The NOT operator is the Boolean inverse and is a unary operator (it has only one
operand). In other words, “NOT true” is equal to “false” and “NOT false” is equal
to “true.” NOT complements each bit for integer operands.
Note Signed integers are expressed using the “2s complement” representation. This
means that to arrive at the decimal representation of a negative binary number
(a string of binary digits with a one as the most significant bit), you must take
the complement of each bit, add one, convert to decimal, and prepend a
negative sign. This means that NOT 0 equals -1, NOT 1 equals -2, etc.
For floating-point operands, the result is 1.0 if the operand is zero; otherwise, the
result is zero. The NOT operator is not valid for string or complex operands.
OR
OR is the Boolean inclusive operator. For integer or byte operands, a bitwise
inclusive OR is performed. For example, 3 OR 5 equals 7. For floating-point
operands, the OR operator returns the first operand if it is non-zero, or the 2nd
operand otherwise.
IDL Operators
Building IDL Applications
Chapter 3: Expressions and Operators
33
XOR
XOR is the Boolean “exclusive or” function. XOR is only valid for byte, integer,
and longword operands. A bit in the result is set to 1 if the corresponding bits in
the operands are different; if they are equal, it is set to zero.
Table 3-3 summarizes the action of the boolean operators:
Operator(op)
T op T
AND
T
F
F
OR
T
T
F
XOR
F
T
F
op T
op F
F
T
NOT
T op F
F op F
Table 3-3: Action of Boolean Operators
When applied to bytes, integers, and longword operands, the Boolean functions
operate on each binary bit. For example:
Decimal
Binary
3 AND 5 =
1
0011 AND 0101 = 0001
3
OR 5 =
7
0011
3 XOR 5 =
6
0011 XOR 0101 = 0110
NOT 5 = -6
NOT 0101 = 1010
OR 0101 = 0111
Table 3-4: Action of Boolean Operators on Integers
Results of relational expressions can be combined into more complex expressions
using the Boolean operators. Some examples of relational and Boolean
expressions are as follows:
(A LE 50) AND (A GE 25)
True if A is between 25 and 50. If
A is an array, then the result is an
array of zeros and ones.
(A GT 50) OR (A LT 25)
True if A is less than 25 or greater
than 50. This is the inverse of the
first.
Building IDL Applications
IDL Operators
34
Chapter 3: Expressions and Operators
ARR AND ’FF’X
Adds (using the logical AND operator) the hexadecimal constant FF
(255 in decimal) to the array ARR.
This masks the lower 8-bits and
zeros the upper bits.
Relational Operators
The IDL relational operators can be used to test the relationship between two
arguments. The six relational operators are described in the following table:
Operator
Purpose
EQ
Equal to
NE
Not equal to
LE
Less than or equal to
LT
Less than
GE
Greater than or equal to
GT
Greater than
Table 3-5: Relational Operators
Relational operators apply a relation to two operands and return a logical value
of true or false. The resulting logical value can be used as the predicate in IF,
WHILE or REPEAT statements can be combined using Boolean operators with
other logical values to make more complex expressions. For example: 1 EQ 1 is
true, and 1 GT 3 is false.
The rules for evaluating relational expressions with operands of mixed modes are
the same as those given above for arithmetic expressions. For example, in the
relational expression (2 EQ 2.0), the integer 2 is converted to floating point
and compared to the floating point 2.0. The result of this expression is true, as
represented by a byte 1.
Individual relational operators are described at the end of this chapter—see
“Relational Operators” on page 34.
Definition of True
In IDL, the value “true” is represented by the following:
•
IDL Operators
Any odd, nonzero value for byte, integer, and longword data types
Building IDL Applications
Chapter 3: Expressions and Operators
35
•
Any nonzero value for single, double-precision, and the real part of a complex
number (the imaginary part is ignored)
•
Any non-null string
Conversely, false is represented as anything that is not true—zero or even-valued
integers; zero-valued, floating-point quantities; and the null string.
The relational operators return a value of 1 for true and 0 for false. The type of
the result is always byte.
Using Relational Operators with Arrays
Relational operators can be applied to arrays, and the resulting array of ones and
zeroes can be used as an operand. For example, the expression, ARR * (ARR LE
100) is an array equal to ARR except that all points greater than 100 have been
reduced to zero. The expression (ARR LE 100) is an array that contains a 1
where the corresponding element of ARR is less than or equal to 100, and zero
otherwise.
PRINT,TOTAL(ARR GT 0)
prints the number of positive elements in the array ARR.
The six relational operators are described below:
EQ
EQ is the relational “equal to” operator. This operator returns true if its operands
are equal; otherwise, it returns false. This operator always returns a byte value of
1 for true and a byte value of 0 for false.
GE
GE is the “greater than or equal to” relational operator. The GE operator returns
true if the operand on the left is greater than or equal to the one on the right. One
use of relational operators is to mask arrays as shown in the following statement:
A = ARRAY * (ARRAY GE 100)
This command sets A equal to ARRAY whenever the corresponding element of
ARRAY is greater than or equal to 100. If the element is less than 100, the
corresponding element of A is set to zero.
Strings are compared using the ASCII collating sequence: " " is less than "0" is
less than "9" is less than "A" is less than "Z" is less than "a" which is less than
"z".
Building IDL Applications
IDL Operators
36
Chapter 3: Expressions and Operators
GT
GT is the “greater than” relational operator. This operator returns true if the
operand on the left is greater than the operand on the right. For example,
6 GT 5 returns true.
LE
LE is the “less-than or equal-to” relational operator. This operator returns true if
the operand on the left is less than or equal to the operand on the right. For
example, 4 LE 4 returns true.
LT
LT is the “less-than” relational operator. This operator returns true if the operand
on the left is less than the operand on the right. For example, 3 LT 4 returns
true.
NE
NE is the “not-equal-to” relational operator. This operator returns true whenever
the operands are different. For example "sun" NE "fun" returns true.
Conditional Expression
?:
The conditional expression—written with the ternary operator ?:—has the
lowest precedence of all the operators and is used wherever any other expression
is used. It provides an alternate way to write simple constructions of the
IF:THEN:ELSE combination. The following statement shows an example:
IF (a GT b) THEN z = a
ELSE z = b
z holds the greater value, a or b.
Note that if a=b, z holds b.
Using a conditional expression, this statement can be simplified:
z = (a GT b) ? a : b
Set z to the greater of a and b,
with z=b if a=b.
The general form of this expression follows:
expr1 ? expr2 : expr3
The expression expr1 is evaluated first. If expr1 is true, then the expression
expr2 is evaluated and set as the value of the conditional expression. If expr1 is
false, expr3 is evaluated and set as the value of the conditional expression. Either
expr2 or expr3 is evaluated, based on the result of expr1.
IDL Operators
Building IDL Applications
Chapter 3: Expressions and Operators
37
Note Since ?: has very low precedence—just above assignment—parentheses are
not necessary around the first expression expr1. Parentheses are advisable
anyway to distinguish the condition part of the expression.
For more information about the behavior of the ?: operator, see “Definition of
True and False” on page 103.
Type and Structure of Expressions
Every entity in IDL has an associated type and structure. The twelve atomic data
types in decreasing order of precedence are as follows:
•
Double-precision complex floating-point
•
Complex floating-point
•
Double-precision floating-point
•
Floating-point
•
Signed and unsigned 64-bit integer
•
Signed and unsigned longword (32-bit) integer
•
Signed and unsigned (16-bit) integer
•
Byte
•
String
The structure of an expression can be either a scalar or an array. The type and
structure of an expression depends on the type and structure of its operands.
Unlike many other languages, the type and structure of most expressions in IDL
cannot be determined until the expression is evaluated. Because of this, care must
be taken when writing programs. For example, a variable can be a scalar byte
variable at one point in a program while at a later point it can be set to a complex
array.
Expression Type
IDL attempts to evaluate expressions containing operands of different types in
the most accurate manner possible. The result of an operation becomes the same
type as the operand with the greatest precedence or potential precision. For
example, when adding a byte variable to a floating-point variable, the byte
variable is first converted to floating-point, then added to the floating-point
variable, yielding a floating-point result. When adding a double-precision
variable to a complex variable, the result is double precision complex because the
Building IDL Applications
Type and Structure of Expressions
38
Chapter 3: Expressions and Operators
double precision complex type has a higher position in the hierarchy of data
types.
Note Signed and unsigned integers of a given width have the same precedence. In
an expression involving a combination of such types, the result is given the
type of the leftmost operand.
When writing expressions with mixed types, care must be taken to obtain the
desired results. For example, assume the variable A is an integer variable with a
value of 5. The following expressions yield the indicated results:
A / 2 = 2
Integer division is performed. The
remainder is discarded.
A / 2. = 2.5
The value of A is first converted to
floating.
A / 2 + 1. = 3.
Integer division is done first because of operator precedence. Result is floating point.
A / 2. +1 = 3.5
Division is done in floating, thenthe 1 is converted to floating and
added.
A + 5U = 10
Signed and unsigned integer operands have the same precedence, so
the left-most operand determines
the type of the result as signed integer.
5U + 1 = 10U
As above, the left-most operand
determines the result type between
types with the same precedence
Note When other types are converted to complex type, the real part of the result is
obtained from the original value and the imaginary part is set to zero.
When a string type appears as an operand with a numeric data type, the string is
converted to the type of the numeric term. For example: ’123’ + 123.0 is
246.0, while ’123.333’ + 33 gives the result 156 because 123.333 is first
converted to integer type. In the same manner, ’ABC’ + 123 also causes a
conversion error.
Expression Structure
IDL expressions can contain operands with different structures, just as they can
contain operands with different types. Structure conversion is independent of
Type and Structure of Expressions
Building IDL Applications
Chapter 3: Expressions and Operators
39
type conversion. An expression will yield an array result if any of its operands is
an array, as shown in the following table:
Operands
Result
Scalar : Scalar
Scalar
Array : Array
Array
Scalar : Array
Array
Array : Scalar
Array
Table 3-6: Structure of Expressions
Functions exist to create arrays of the data types IDL supports: BYTARR,
INTARR, UINTARR, LONARR, ULONARR, LON64ARR, ULON64ARR,
FLTARR, DCOMPLEXARR, DBLARR, COMPLEXARR, OBJARR, PTRARR,
and STRARR. The dimensions of the desired array are the parameters to these
functions. The result of FLTARR(5) is a floating-point array with one
dimension, a vector, with five elements initialized to zero. FLTARR(50,100)
is a two-dimensional array, a matrix, with 50 columns and 100 rows.
The size of an array-valued expression is equal to the smaller of its array
operands. For example, adding a 50-point array to a 100-point array gives a 50point array; the last 50 points of the larger array are ignored. Array operations are
performed point-by-point, without regard to individual dimensions. An
operation involving a scalar and an array always yields an array of identical
dimensions. When two arrays of equal size (number of elements) but different
structure are operands, the result is of the same structure as the first operand. For
example:
FLTARR(4) + FLTARR(1, 4)
Yields fltarr(4).
In the above example, a row vector is added to a column vector and a row vector
is obtained because the operands are the same size. This causes the result to take
the structure of the first operand. Here are some examples of expressions
involving arrays:
ARR + 1
Building IDL Applications
An array in which each element is
equal to the same element in ARR
plus one. The result has the same
dimensions as ARR. If ARR is byte
or integer, the result is of integer
type; otherwise, the result is the
same type as ARR.
Type and Structure of Expressions
40
Chapter 3: Expressions and Operators
ARR1 + ARR2
An array obtained by summing
two arrays.
(ARR < 100) * 2
An array in which each element is
set to twice the smaller of either the
corresponding element of ARR or
100.
EXP(ARR/10.)
An array in which each element is
equal to the exponential of the
same element of ARR divided by
10.
ARR * 3./MAX(ARR)
An inefficient way of writing the
following line.
ARR * (3./MAX(ARR))
In the last example, each point in ARR is multiplied by three, then divided by the
largest element of ARR. The MAX function returns the largest element of its array
argument. This way of writing the statement requires that each element of ARR
be operated on twice. If (3./MAX(ARR)) is evaluated with one division and
the result then multiplied by each point in ARR, the process requires
approximately half the time.
Type and Structure of Expressions
Building IDL Applications
Chapter 4
Structures
The following topics are covered in this chapter:
Creating and Defining Structures ......... 42
Structure References ............................. 45
Using HELP with Structures ................... 47
Parameter Passing with Structures......... 47
Arrays of Structures ............................... 49
Structure Input/Output......................... 51
Advanced Structure Usage .................... 53
Automatic Structure Definition.............. 54
Relaxed Structure Assignment............... 55
41
42
Chapter 4: Structures
IDL supports structures and arrays of structures. A structure is a collection of
scalars, arrays, or other structures contained in a variable. Structures are useful
for representing data in a natural form, transferring data to and from other
programs, and containing a group of related items of various types. There are two
types of structures; they have similar features.
Named Structures
Each distinct type of named structure is defined by a unique structure name. The
first time a structure name is used, IDL creates and saves a definition of the
structure which cannot be changed. Each structure definition consists of the
structure’s name and a definition of each field that is a member of the structure.
Each instance of a named structure shares the same definition. Named structures
are used when their definitions will not be changed.
Anonymous Structures
If a structure definition contains no name, an anonymous structure is created. A
unique structure definition is created for each anonymous structure. Use
anonymous structures when the structure, type, and/or dimensions of its
components change during program execution.
Each field definition consists of a tag name and a tag definition that contains the
type and structure of the data contained in the field. A field is referred to by its
tag name. The tag definition is simply an expression or variable. The type,
structure, and value of the tag definition serve to define the field’s type, structure,
and value. As with structure definitions, a field definition is fixed and cannot be
changed. The contents of a field can be any type of data representable by IDL.
Fields can contain scalars, arrays of the seven basic data types, and even other
structures or arrays of structures.
Creating and Defining Structures
A named structure is created by executing a structure-definition expression,
which is an expression of the following form:
{Structure_Name, Tag_Name1 : Tag_Definition1, ..., Tag_Namen :
Tag_Definitionn}
Anonymous structures are created in the same way, but with the structure’s name
omitted.
{Tag_Name1 : Tag_Definition1 , ..., Tag_Namen : Tag_Definitionn}
Anonymous structures can also be created and combined using the
CREATE_STRUCT function.
Creating and Defining Structures
Building IDL Applications
Chapter 4: Structures
43
Tag names must be unique within a given structure, although the same tag name
can be used in more than one structure. Structure names and tag names follow
the rules of IDL identifiers: they must begin with a letter; following characters can
be letters, digits, or the underscore or dollar sign characters; and case is ignored.
As mentioned above, each tag definition is a constant, variable, or expression
whose structure defines the structure and initial value of the field. The result of
the structure definition expression is an instance of the structure, with each field
set equal to its tag definition.
A named structure that has already been defined can be referred to by simply
enclosing the structure’s name in braces, as shown below:
{Structure_Name }
The result of this expression is a structure of the designated name.
Note When a new instance of a structure is created from an existing named
structure, all of the fields in the newly-created structure are zeroed. This means
that fields containing numeric values will contain zeros, fields containing
string values will contain null strings, and fields containing pointers or objects
will contain null pointers or null objects. In other words, no matter what data
the original structure contained, the new structure will contain only a template for that type of data.
Also, when making a named structure that has already been defined, the tag
names need not be present:
{Structure_Name, expression1, ..., expressionn}
All of the expressions must agree in structure with the original tag definition.
Once defined, a given named structure type cannot be changed. If a structure
definition with tag names is executed and the structure already exists, each tag
name and the structure of each tag field must agree with the original definition.
Anonymous structures do not have this restriction because each instance has its
own definition.
Structure Inheritance
Structures can inherit tag names and definitions from other structures. To cause
one structure to inherit tags from another, use the INHERITS specifier. For
example, if we define a structure one as follows:
A = {one, data1a:0, data1b:0L }
we can define a second structure two that includes the tags from the one
structure with the following definition statement:
Building IDL Applications
Creating and Defining Structures
44
Chapter 4: Structures
B = { two, INHERITS one, data2:0.0 }
This is the same as defining the structure two with the statement:
B = { two, data1a:0, data1b:0L, data2:0.0 }
Note that the fields of the one structure are included in the two structure in the
position that the INHERITS specifier appears in the structure definition.
Remember that tag names must be unique. If you use structure inheritance, be
sure that the tag names in the inherited structure do not conflict with the tag
names in the inheriting structure.
Structures that are inherited must be defined before the inheriting structure can
be defined. If a structure inherits tags from another structure that is not yet
defined, IDL will search for a routine to define the inherited structure as outlined
in “Automatic Structure Definition” on page 54. If the inherited structure cannot
be defined, definition of the new structure fails.
While structure inheritance can be used with any structure, it is most useful when
dealing with object class structures. When the INHERITS specifier is used in a class
structure definition, it has the added effect of defining the inheriting object as a
subclass of the inherited class. For a discussion of object-oriented IDL
programming, see “Object Basics” on page 249.
Example of Creating a Structure
Assume that a star catalog is to be processed. Each entry for a star contains the
following information: star name, right ascension, declination, and an intensity
measured each month over the last 12 months. A structure for this information
is defined with the following IDL statement:
A = {star, name:’’, ra:0.0, dec:0.0, inten:FLTARR(12)}
This structure definition is the basis for all examples in this chapter. The
statement above defines a structure type named star, which contains four fields.
The tag names are name, ra, dec, and inten. The first field, with the tag name,
contains a scalar string as given by its tag definition. The following two fields each
contain floating-point scalars. The fourth field, inten, contains a 12-element,
floating-point array. Note that the type of the constants, 0.0, is floating point. If
the constants had been written as 0, the fields ra and dec would contain short
integers.
The same structure is created as an anonymous structure by the statement:
A = {name:’’, ra:0.0, dec:0.0, inten:FLTARR(12)}
or by using the CREATE_STRUCT function:
A = CREATE_STRUCT(’name’, ’’, ’ra’, 0.0, ’dec’, 0.0, $
Creating and Defining Structures
Building IDL Applications
Chapter 4: Structures
45
’inten’, FLTARR(12))
Structure References
The basic syntax of a reference to a field within a structure is as follows:
Variable_Name.Tag_Name
Variable_Name must be a variable that contains a structure. Tag_Name is the
name of the field and must exist in the structure. If the field referred to by the tag
name is itself a structure, the Tag_Name can optionally be followed by one or
more additional tag names, as shown by the following example:
var.tag1.tag2
This nesting of structure references can be continued up to 10 levels. Each tag
name, except possibly the last, must refer to a field that contains a structure.
Subscripted Structure References
A subscript specification can be appended to the variable or tag names if the
variable is an array of structures or if the field referred to by the tag contains an
array. Scalar fields within a structure can also be subscripted, provided the
subscript is zero.
Variable_Name.Tag_Name[Subscripts]
Variable_Name[Subscripts].Tag_Name...
Variable_Name[Subscripts].Tag_Name[Subscripts]
Each subscript is applied to the variable or tag name it immediately follows. The
syntax and meaning of the subscript specification is similar to simple array
subscripting in that it can contain a simple subscript, array of subscripts, or a
subscript range. If a variable or field containing an array is referenced without a
subscript specification, all elements of the item are affected. Similarly, when a
variable that contains an array of structures is referenced without a subscript but
with a tag name, the designated field in all array elements is affected. The
complete syntax of references to structures follows. (Optional items are enclosed
in curly brackets, {}.)
Structure_reference:= Variable_Name{[Subscripts]}.Tags
Tags:= {Tags.}Tag
Tag:= Tag_Name{[Subscripts]}
For example, all of the following are valid structure references:
A.B
Building IDL Applications
Structure References
46
Chapter 4: Structures
A.B[N, M]
A[12].B
A[3:5].B[*, N]
A[12].B.C[X, *]
The semantics of storing into a structure field using subscript ranges is slightly
different than that of simple arrays. This is because the structure of arrays in fields
are fixed. See “Storing Into Array Fields” on page 48.
Examples of Structure References
The name of the star contained in A is referenced as A.NAME. The entire
intensity array is referred to as A.INTEN, while the n-th element of A.INTEN is
A.INTEN[N]. The following are valid IDL statements using the STAR structure:
A = {star, name:’SIRIUS’, ra:30., dec:40., inten:INDGEN(12)}
Store a structure of type STAR into
variable A. Define the values of all
fields.
A.name = ’BETELGEUSE’
Set name field. Other fields remain
unchanged.
PRINT, A.name, A.ra, A.dec
Print name, right ascension, and
declination.
Q = A.inten[5]
Set Q to the value of the sixth element of A.inten . Q will be a
floating-point scalar.
A.ra = 23.21
Set ra field to 23.21.
A.inten = 0
Zero all 12 elements of intensity
field. Because the type and size of
A.inten are fixed by the structure definition, the semantics of
assignment statements is somewhat different than with normal
variables.
B = A.inten[3:6]
Store fourth through seventh elements of inten field in variable
B.
A.name = 12
The integer 12 is converted to
string and stored in the name field
because the field is defined as a
string.
Structure References
Building IDL Applications
Chapter 4: Structures
47
Copy A to B. The entire structure
is copied and B contains a STAR
structure.
B = A
Using HELP with Structures
Use the HELP,/STRUCTURE command to determine the type, structure, and
tag name of each field in a structure. In the example above, a structure was stored
into variable A. The statement,
HELP, /STRUCTURE, A
prints the following information:
** Structure STAR, 4 tags, length=40:
NAME
STRING
’SIRIUS’
RA
FLOAT
30.0000
DEC
FLOAT
40.0000
INTEN
INT
Array(12)
Using HELP with anonymous structures prints the structure’s name as a unique
number enclosed in angle brackets. Calling HELP with the STRUCTURE
keyword and no parameters prints a list of all defined, named structure types and
their tag names.
Parameter Passing with Structures
An entire structure is passed by reference by simply using the name of the variable
containing the structure as a parameter. Changes to the parameter within the
procedure are passed back to the calling procedure. Fields within a structure are
passed by value. For example, the following statement prints the value of the
structure field A.name:
PRINT, A.name
Any reference to a structure with a subscript or tag name is evaluated into an
expression, hence A.name is an expression and is passed by value. This works as
expected unless the called procedure returns information in the parameter. For
example, the call
READ, A.name
does not read into A.name but interprets its parameter as a prompt string. The
proper code to read into the field is as follows.
Building IDL Applications
Using HELP with Structures
48
Chapter 4: Structures
B = A.name
Copy type and attributes to variable.
READ, B
Read into a simple variable.
A.name = B
Store result into field.
Storing Into Array Fields
As mentioned previously, the semantics of storing into structure array fields is
slightly different than storing into simple arrays. The main difference is that with
structures, a subscript range must be used when storing an array into part of an
array field. With normal arrays, when storing an array inside part of another
array, use the subscript of the lower-left corner, not a range specification. Other
differences occur because the size and type of a field are fixed by the original
structure definition, and the normal IDL semantics of dynamic binding are not
applicable. The rules for storing into array fields are as follows:
VAR.ARRAY_TAG = Scalar_Expression
All elements of VAR.tag are set to Scalar_Expression. For example:
A.inten = 100
Sets all 12 elements of A.inten to
100.
VAR.TAG = Array_Expression
Each element of Array_Expression is copied into the array VAR.tag. If
Array_Expression contains more elements than the destination array does, an
error results. If it contains fewer elements than VAR.TAG, the unmatched
elements remain unchanged. For example:
A.inten = FINDGEN(12)
Sets A.inten to the 12 numbers
0, 1, 2,..., 11.
A.inten = [1, 2]
Sets A.inten[0] to 1 and
A.inten[1] to 2. The other elements remain unchanged.
VAR.TAG[Subscript] = Scalar_Expression
The value of the scalar expression is simply copied into the designated element of
the destination. If Subscript is an array of subscripts, the scalar expression is
copied into the designated elements. For example:
A.inten[5] = 100
Sets the sixth element of A.inten
to 100.
A.inten[[2, 4, 6]] = 100
Sets elements 2, 4, and 6 to 100.
Parameter Passing with Structures
Building IDL Applications
Chapter 4: Structures
49
VAR.TAG[Subscript] = Array_Expression
Unless VAR.tag is an array of structures, the subscript must be an array. Each
element of Array_Expression is copied into the element given by the
corresponding element subscript. For example:
A.inten[[2, 4, 6]] = [5, 7, 9]
Sets elements 2, 4, and 6 to the values 5, 7, and 9 respectively.
VAR.TAG[Subscript_Range] = Scalar_Expression
The value of the scalar expression is stored into each element specified by the
subscript range. For example:
A.inten[8:*] = 5
Sets elements 8, 9, 10, and 11 to the
value 5.
VAR.TAG[Subscript_Range] = Array_Expression
Each element of the array expression is stored into the element designated by the
subscript range. The number of elements in the array expression must agree with
the size of the subscript range. For example:
A.inten[3:6] = FINDGEN(4)
Sets elements 3, 4, 5, and 6 to the
numbers 0, 1, 2, and 3, respectively.
Arrays of Structures
An array of structures is simply an array in which each element is a structure of
the same type. The referencing and subscripting of these arrays (also called
structure arrays) follow the same rules as simple arrays.
Creating an Array of Structures
The easiest way to create an array of structures is to use the REPLICATE function.
The first parameter to REPLICATE is a reference to the structure of each element.
Using the example in “Using HELP with Structures” on page 47 (star catalog) and
assuming the STAR structure has been defined, an array containing 100 elements
of the structure is created with the following statement:
cat = REPLICATE({star}, 100)
Alternatively, since the variable A contains an instance of the structure STAR,
then
cat = REPLICATE(A, 100)
Or, to define the structure and an array of the structure in one step, use the
following statement:
Building IDL Applications
Arrays of Structures
50
Chapter 4: Structures
cat = REPLICATE({star, name:’’, ra:0.0, dec:0.0, $
inten:FLTARR(12)}, 100)
The concepts and combinations of subscripts, subscript arrays, subscript ranges,
fields, nested structures, etc., are quite general and lead to many possibilities, only
a small number of which can be explained here. In general, any structures that are
similar to the examples above are allowed.
Examples of Arrays of Structures
This example uses the above definition in which the variable CAT contains a star
catalog of STAR structures.
cat.name = ’EMPTY’
Set the name field of all 100 elements to “EMPTY.”
cat[I] = {star, ’BETELGEUSE’, 12.4, 54.2, FLTARR(12)}
Set the i-th element of cat to the
contents of the star structure.
cat.ra = INDGEN(100)
Store 0.0 into cat[0].ra, 1.0
into cat[1].ra, ..., 99.0 into
cat[99].ra
PRINT, cat.name + ’,’
Prints name field of all 100 elements of cat, separated by commas (the last field has a trailing
comma).
I = WHERE(cat.name EQ ’SIRIUS’)
Find index of star with name of
SIRIUS.
Q = cat.inten
Extract intensity field from each
entry. Q will be a 12 by 100 floating-point array.
PLOT, cat[5].inten
Plot intensity of sixth star in array
cat.
CONTOUR, cat[5:50].inten[2:8]
Make a contour plot of the (7,46)
floating-point array taken from
months (2:8) and stars (5:50).
cat = cat(SORT(cat.name))
Sort the array into ascending order
by names. Store the result back
into cat.
monthly = cat.inten # REPLICATE(1,100)
Determine the monthly total intensity of all stars in array.
Arrays of Structures
Building IDL Applications
Chapter 4: Structures
51
monthly is now a 12-element
array.
Structure Input/Output
Structures are read and written using the formatted and unformatted
input/output procedures READ, PRINT, READU, and WRITEU. Structures and
arrays of structures are transferred in much the same way as simple data types,
with each element of the structure transferred in order.
Formatted Input/Output with Structures
Writing a structure with PRINT or PRINTF and the default format outputs the
contents of each element using the default format for the appropriate data type.
The entire structure is enclosed in braces: “{}”. Each array begins a new line. For
example, printing the variable A, as defined in the first example in this chapter,
results in the following output.
{SIRIUS 30.0000 40.0000 0 1 2 3 4 5 6 7 8 9 10 11}
When reading a structure with READ or READF and the default format, white
space should separate each element. Reading string elements causes the
remainder of the input line to be stored in the string element, regardless of spaces,
etc. A format specification can be used with any of these procedures to override
the default formats. The length of string elements is determined by the format
specification (i.e, to read the next 10 characters into a string field, use an (A10)
format).
Unformatted Input/Output with Structures
Reading and writing unformatted data contained in structures is a
straightforward process of transferring each element, without interpretation or
modification, except in the case of strings. Each IDL data type, except strings, has
a fixed length expressed in bytes. This length (which is padded when using
ASSOC, but not padded when using READU/WRITEU) is also the number of
bytes read or written for each element.
All instances of structures contain an even number of bytes. On machines whose
native C compilers force short integers to begin on an even byte boundary, IDL
begins fields that are not of type byte on an even byte boundary. Thus, a “padding
byte” may appear (when using ASSOC for I/O) after a byte field to cause the
following non-byte-type field to begin on an even byte. A padding byte is never
added before a byte or byte array field. For example, the structure:
{example, t1:1b, t2:1}
Building IDL Applications
Structure Input/Output
52
Chapter 4: Structures
occupies four bytes on a machine where short integers must begin on an even
byte boundary. When using ASSOC, a padding byte is added after field t1 to
cause the integer field t2 to begin on an even-byte boundary.
Strings
Strings are exceptions to the above rules because the length of strings within
structures is not fixed. For example, one instance of the {star} structure can
contain a name field with a five-character name, while another instance of the
same structure can contain a 20-character name. When reading into a structure
field that contains a string, IDL reads the number of bytes given by the length of
the string. If the string field contains a 10-character string, 10 characters are read.
If the data read contains a null byte, the length of the string field is truncated, and
the null and following characters are discarded. When writing fields containing
strings with the unformatted procedure WRITEU, IDL writes each character of
the string and does not append a terminating null byte.
String Length Issues
When reading or writing structures containing strings with READU and
WRITEU, make each string in a given field the same length to be compatible with
C and to be able to read the data back into IDL. You must know how many
characters exist to read into a string element. One way around this problem is
using the STRING function with a format specification that sets the length of all
elements to some maximum number. For example, it is easy to set the length of
all name fields in the cat array to 20 characters by using the following statement.
cat.name = STRING(cat.name, FORMAT = ’(A20)’)
This statement will truncate names longer than 20 characters and will pad with
blanks those names shorter than 20 characters. The structure or structure array
then can be output in a format suitable to be read by C or FORTRAN programs.
For example, to read into the cat array from a file in which each name field
occupies 26 bytes, use the following statements.
cat = REPLICATE({star, STRING(’ ’, FORMAT = ’(A26)’), $
FLTARR(0., 0.12)}, 100)
READU, 1, cat
Structure Input/Output
Make a 100-element array of
{STAR} structures, storing a 26character string in each name
field.
Read the structure. As mentioned
above, 26 bytes will be read for
each name field. The presence of a
null byte in the file will truncate
Building IDL Applications
Chapter 4: Structures
53
the field to the correct number of
bytes.
Advanced Structure Usage
Facilities exist to process structures in a general way using tag numbers rather
than tag names. A tag can be referenced using its index, enclosed in parentheses,
as follows:
Variable_Name.(Tag_Index)... ... ...
The Tag_Index ranges from zero to the number of fields minus one.
Note The Tag_Index is an expression, the result of which is taken to be a tag
position. In order for the IDL parser to understand that this is the case, you
must enclose the Tag_Index in parentheses. This is not an array indexing
operation, so the use of square brackets ([]) is not allowed in this context.
Number of Structure Tags
The function N_TAGS(Structure) returns the number of fields in a structure. To
obtain the size, in bytes, of a structure call N_TAGS with the /LENGTH keyword.
Names of Structure Tags
The function TAG_NAMES(Structure) returns a string array containing the
names of each tag. To return the name of the structure itself, call TAG_NAMES
with the /STRUCTURE_NAME keyword.
Example
Using tag indices and the above-mentioned functions, we specify a procedure
that reads into a structure from the keyboard. The procedure prompts the user
with the type, structure, and tag name of each field within the structure.
PRO READ_STRUCTURE, S
A procedure to read into a structure, S, from the keyboard with
prompts.
NAMES = TAG_NAMES(S)
Get the names of the tags. Loop for
each field.
FOR I = 0, N_TAGS(S) - 1 DO BEGIN
A = S.(I)
Define variable A of same type and
structure as the i-th field.
HELP, S.(I)
Use HELP to print the attributes of
the field. Prompt user with tag
name of this field, and then read
Building IDL Applications
Advanced Structure Usage
54
Chapter 4: Structures
into variable A. S.(I) = A. Store
back into structure from A.
READ, ’Enter Value For Field ’, NAMES[I], ’: ’, A
S.(I) = A
ENDFOR
END
Note In the above procedure, the READ procedure reads into the variable A rather
than S.(I) because S.(I) is an expression, not a simple variable reference.
Expressions are passed by value; variables are passed by reference. The READ
procedure prompts the user with parameters passed by value and reads into
parameters passed by reference.
Automatic Structure Definition
In versions of IDL prior to version 5, references to an undefined named structure
would cause IDL to halt with an error. This behavior was changed in IDL version
5 to allow the automatic definition of named structures.
When IDL encounters a reference to an undefined named structure, it will
automatically search the directories specified in !PATH for a procedure named
Name__DEFINE, where Name is the actual name of the structure. If this
procedure is found, IDL will call it, giving it the opportunity to define the
structure. If the procedure does in fact define the named structure, IDL will
proceed with the desired operation.
Note There are two underscores in the name of the structure definition procedure.
For example, suppose that a structure named mystruct has not been defined,
and that no procedure named mystruct__define.pro exists in the
directories specified by !PATH. A call to the HELP procedure produces the
following output:
HELP, { mystruct }, /STRUCTURE
IDL prints:
% Attempt to call undefined procedure/function: ’MYSTRUCT__DEFINE’.
% Structure type not defined: MYSTRUCT.
% Execution halted at:
$MAIN$
Suppose now that we define a procedure named mystruct__define.pro as
follows, and place it in one of the directories specified by !PATH:
PRO mystruct__define
Automatic Structure Definition
Building IDL Applications
Chapter 4: Structures
55
tmp = { mystruct, a:1.0, b:’string’ }
END
With this structure definition routine available, the call to HELP produces the
following output:
HELP, { mystruct }, /STRUCTURE
IDL prints:
% Compiled module: MYSTRUCT__DEFINE.
** Structure MYSTRUCT, 2 tags, length=12:
A
FLOAT
0.00000
B
STRING
’’
Remember that the fields of a structure created by copying a named structure
definition are filled with zeroes or null strings. Any structure created in this
way—either via automatic structure definition or by explicitly creating a new
structure from an existing structure—must be initialized to contain values after
creation.
Relaxed Structure Assignment
The IDL “=” operator is unable to assign a structure value to a structure with a
different definition. For example, suppose we have an existing structure
definition SRC, as follows:
source = { SRC, A:FINDGEN(4), B:12 }
and we wish to create a second instance of the same structure, but with slightly
different data and a different field:
dest = { SRC, A:INDGEN(2), C:20 }
Attempting to execute these two statements at the IDL command prompt gives
the following results:
% Conflicting data structures: <INT
% Execution halted at:
Array[2]>,SRC.
$MAIN$
Versions of IDL beginning with IDL 5.1 include a mechanism to solve this
problem. The STRUCT_ASSIGN procedure performs “relaxed structure
assignment,” which is a field-by-field copy of a structure to another structure.
Fields are copied according to the following rules:
Building IDL Applications
Relaxed Structure Assignment
56
Chapter 4: Structures
1. Any fields found in the destination structure that are not found in the source
structure are “zeroed” (set to zero, the empty string, or a null pointer or object
reference depending on the type of field).
2. Any fields in the source structure that are not found in the destination structure
are quietly ignored.
3. Any fields that are found in both the source and destination structures are copied
one at a time. If necessary, type conversion is done to make their types agree. If a
field in the source structure has fewer data elements than the corresponding field
in the destination structure, then the “extra” elements in the field in the destination structure are zeroed. If a field in the source structure has more elements than
the corresponding field in the destination structure, the extra elements are quietly
ignored.
Using STRUCT_ASSIGN, we can make the assignment that failed using the =
operator:
source = { src, a:FINDGEN(4), b:12 }
dest = { dest, a:INDGEN(2), c:20 }
STRUCT_ASSIGN, source, dest, /VERBOSE
IDL prints:
% STRUCT_ASSIGN: SRC tag A is longer than destination.
The end will be clipped.
% STRUCT_ASSIGN: Destination lacks SRC tag B. Not copied.
If we check the variable dest, we see that it has the definition of the dest
structure and the data from the source structure:
HELP, dest, /STRUCTURE
IDL prints:
** Structure DEST, 2 tags, length=6:
A
INT
Array[2]
C
INT
0
Using Relaxed Structure Assignment
Why would you want to use Relaxed Structure Assignment? One case where this
type of structure definition is very useful is in restoring object structures into an
environment where the structure definition may have changed since the restored
objects were saved.
Relaxed Structure Assignment
Building IDL Applications
Chapter 4: Structures
57
Suppose you have created an application that saves data in structures. Your
application may use the IDL SAVE routine to save the data structures to disk files.
If you later change your application such that the definition of the data structures
changes, you would not be able to restore your saved data into your application’s
framework without relaxed structure assignment. The
RELAXED_STRUCTURE_ASSIGNMENT keyword to the RESTORE procedure
allows you to make relaxed assignments in such cases.
To see how this works, try the following exercise:
1. Start IDL, create a named structure, and use the SAVE procedure to save it to a file:
mystruct = { STR, A:10, B:20L, C:’a string’ }
SAVE, mystruct, FILE='test.dat'
2. Exit and restart IDL.
3. Create a new structure definition with the same name you used previously:
newstruct = { STR, A:20L, B:10.0, C:’a string’, D:ptr_new() }
4. Attempt to restore the variable mystruct from the test.dat file:
RESTORE, 'test.dat'
IDL prints:
% Wrong number of tags defined for structure: STR.
% RESTORE: Structure not restored due to conflict with
existing definition: STR.
5. Now use relaxed structure definition when restoring:
RESTORE, 'test.dat', /RELAXED_STRUCTURE_ASSIGNMENT
6. Check the contents of mystruct:
HELP, mystruct, /STRUCTURE
IDL prints:
** Structure STR, 4 tags, length=20:
A
LONG
B
FLOAT
C
STRING
’a string’
D
POINTER
<NullPointer>
Building IDL Applications
10
20.0000
Relaxed Structure Assignment
58
Chapter 4: Structures
The structure in the variable mystruct now uses the definition from the new
version of the STR structure, but contains the data from the old (restored)
structure. In cases where the data type of a field has changed, the data type of the
old data element has been converted to the new data type. Fields in the new
structure definition that do not correspond to fields in the old definition contain
“zero” values (zeroes for numeric fields, empty strings for string fields, null
pointer or references for pointer or reference fields).
Relaxed Structure Assignment
Building IDL Applications
Chapter 5
Array
Subscripts
The following topics are covered in this chapter:
Array Subscript Syntax: [ ] vs. ( ) .......... 60
Subscript Examples ............................... 61
Subscript Ranges................................... 65
Structure of Subarrays........................... 65
Array Subscripts .................................... 66
Combining Array Subscripts with Others . 67
Storing Elements with Array Subscripts . 68
59
60
Chapter 5: Array Subscripts
Subscripts provide a means of selecting one or more elements of an array for
retrieval or modification.
The values of the selected array elements are extracted when a subscripted
variable reference appears in an expression. New values are stored in selected
array elements, without disturbing the remaining elements, when a subscript
reference appears on the left side of an assignment statement. “The Assignment
Statement” on page 85 discusses the use of the different types of assignment
statements when storing into arrays.
The subscripts of an array element denote the address of the element within the
array. In the simple case of a one-dimensional array, an n-element vector,
elements are numbered starting at 0 with the first element, 1 for the second
element, and running to n − 1, the subscript of the last element.
Arrays with multiple dimensions are addressed by specifying a subscript
expression for each dimension. A two-dimensional array, a matrix with n
columns and m rows, is addressed with a subscript of the form [i, j], where 0Š ≤ i
< n and 0Š≤ j < m. The first subscript, i, is the column index; the second subscript,
j, is the row index. The syntax of a subscript reference is:
Variable_Name [Subscript_ List]
or
(Array_Expression)[Subscript_List]
The Subscript_List is simply a list of expressions, constants, or subscript ranges
containing the values of one or more subscripts. Subscript expressions are
separated by commas if there is more than one subscript. In addition, multiple
elements are selected with subscript expressions that contain either a contiguous
range of subscripts or an array of subscripts.
Array Subscript Syntax: [ ] vs. ( )
Versions of IDL prior to version 5.0 used parentheses to indicate array subscripts.
Function calls use parentheses in a visually identical way to specify argument lists.
As a result, the IDL compiler is not able to distinguish between arrays and
functions by looking at the statement syntax. For example, the IDL statement
value = fish(5)
could either set the variable value equal to the sixth element of an array named
fish, or set value equal to the result of passing the argument 5 to a function
called fish.
To determine if it is compiling an array subscript or a function call, IDL checks
its internal table of known functions. If it finds a function name that matches the
Array Subscript Syntax: [ ] vs. ( )
Building IDL Applications
Chapter 5: Array Subscripts
61
unknown element in the command (fish, in the above example), it calls that
function with the argument specified. If IDL does not find a function with the
correct name in its table of known functions, it assumes that the unknown
element is an array, and attempts to return the value of the designated element of
that array. This rule generally gives the desired result, but it can be fooled into the
wrong choice under certain circumstances, much to the surprise of the unwary
programmer.
For this reason, versions of IDL beginning with version 5.0 use square brackets
rather than parentheses for array subscripting. An array subscripted in this way
is unambiguously interpreted as an array under all circumstances. In IDL 5.0 and
later:
value = fish[5]
sets value to the sixth element of an array named fish.
Due to the large amount of existing IDL code written in the older syntax, as well
as the ingrained habits of thousands of IDL users, IDL continues to allow the old
syntax to be used, subject to the ambiguity mentioned above. That is, while
value = fish[5]
is unambiguous,
value = fish(5)
is still subject to the same ambiguity—and rules—that applied in IDL versions
prior to version 5.0
Since the older syntax has been used widely, you should not be surprised to see it
from time to time. However, square brackets are the preferred form, and should
be used for new code.
Subscript Examples
Subscripts can be used either to retrieve the value of one or more array elements
or to designate array elements to receive new values. The expression ARR[12]
denotes the value of the 13th element of ARR (because subscripts start at 0), while
the statement ARR[12] = 5 stores the number 5 in the 13th element of ARR
without changing the other elements.
Elements of multidimensional arrays are specified by using one subscript for each
dimension. In arrays and images, the first subscript denotes the column and the
second subscript is the row. For matrices, the first subscript denotes the row and
the second subscript is the column.
Building IDL Applications
Subscript Examples
62
Chapter 5: Array Subscripts
If A is a 2-element by 3-element array, the elements are stored in memory as
A[0,2]follows:
A0,0
A1,0
A0,1
A1,1
A0,2
A1,2
Lowest memory address
.
.
.
Highest memory address
Table 5-1: Storage of IDL Array Elements in Memory
The elements are ordered in memory as: A0,0, A1,0, A0,1, A1,1, A0,2, A1,2, etc. Thus,
IDL arrays are row major (i.e., stored by rows). This ordering is like FORTRAN.
It is the opposite of the way C and Pascal handle arrays. IDL uses row major
storage because it is oriented toward image processing while the other languages
stress matrix computation. For a more extensive discussion of row versus column
majority and how it relates to IDL mathematics routines, see “Arrays and
Matrices” on page 429 of Using IDL.
Images are usually displayed with row zero at the bottom of the screen, matching
the display’s coordinate system, although this order can be reversed by setting the
system variable !ORDER to a nonzero value. Arrays are printed with the first row
on top.
Elements of multidimensional arrays also can be specified using only one
subscript, in which case the array is treated as a vector with the same number of
points. In the above example, A[2] is the same element as A [0, 1], and A[5] is the
same element as A[1, 2].
If an attempt is made to reference a nonexistent element of an array using a scalar
subscript (a subscript that is negative or larger than the size of the dimension
minus 1), an error occurs and program execution stops.
Subscripts can be any type of vector or scalar expression. If a subscript expression
is not integer, a longword integer copy is made and used to evaluate the subscript.
“Extra” Dimensions
When creating arrays, IDL eliminates all size 1, or “degenerate”, trailing
dimensions. Thus, the statements
A = INTARR(10, 1)
HELP, A
Subscript Examples
Building IDL Applications
Chapter 5: Array Subscripts
63
print the following:
A
INT
= Array(10)
This removal of superfluous dimensions is usually convenient, but it can cause
problems when attempting to write fully general procedures and functions.
Therefore, IDL allows you to specify “extra” dimensions for an array as long as
the extra dimensions are all zero. For example, consider a vector defined as
follows:
ARR = INDGEN(10)
The following are all valid references to the sixth element of ARR:
X = ARR[5]
X = ARR[5, 0]
X = ARR[5, 0, 0, *, 0]
Thus, the automatic removal of degenerate trailing dimensions does not cause
problems for routines that attempt to access the resulting array.
Subscripting Scalars
Scalar quantities in IDL can be though of as arrays with dimensions of (1,0). They
can be subscripted with a zero reflecting the first and only position. Therefore,
A = 5
Assign the value of 5 to A.
PRINT, A[0]
Print the value of the first element
of A.
IDL prints:
5
A[0] = 6
Redefine the first element of A.
PRINT, A
IDL prints:
6
Note You cannot subscript a variable that has not yet been defined. Thus, if the
variable B has not been previously defined, the statement:
B[0] = 9
will fail with the error “variable is undefined.”
Building IDL Applications
Subscript Examples
64
Chapter 5: Array Subscripts
Subscript Ranges
Subscript ranges are used to select a subarray from an array by giving the starting
and ending subscripts of the subarray in each dimension. Subscript ranges can be
combined with scalar and array subscripts and with other subscript ranges. Any
rectangular portion of an array can be selected with subscript ranges. There are
four types of subscript ranges:
•
A range of subscripts, written [e0:e1], denoting all elements whose subscripts
range from the expression e0 through e1 (e0 must not be greater than e1). For
example, if the variable VEC is a 50-element vector, VEC[5:9] is a five-element
vector composed of VEC[5] through VEC[9].
•
All elements from a given element to the last element of the dimension, written
as [e:*]. Using the above example, VEC[10:*] is a 40-element vector made from
VEC[10] through VEC[49].
•
A simple subscript, [n]. When used with multidimensional arrays, simple subscripts specify only elements with subscripts equal to the given subscript in that
dimension.
•
All elements of a dimension, written [*]. This form is used with multidimensional
arrays to select all elements along the dimension. For example, if ARR is a 10column by 12-row array, ARR[*, 11] is the last row of ARR, composed of
elements [ARR[0,11], ARR[1,11], ..., ARR[9,11]], and is a 10-element
row vector. Similarly, ARR[0, *] is the first column of ARR, [ARR[0,0],
ARR[0,1],..., ARR[0,11]], and its dimensions are 1 column by 12 rows.
Multidimensional subarrays can be specified using any combination of the above
forms. For example, ARR[*, 0:4] is made from all columns of rows 0 to 4 of
ARR or a 10-column, 5-row matrix. The table below summarizes the possible
forms of subscript ranges:
Form
Meaning
e
A simple subscript expression
e 0:e 1
Subscript range from e 0 to e 1
e:*
All points from element e to end
*
All points in the dimension
Table 5-2: Subscript Ranges
Subscript Ranges
Building IDL Applications
Chapter 5: Array Subscripts
65
Structure of Subarrays
The dimensions of the extracted subarray are determined by the size in each
dimension of the subscript range expression. In general, the number of
dimensions is equal to the number of subscripts and subscript ranges. The size of
the n-th dimension is equal to one if a simple subscript was used to specify that
dimension in the subscript; otherwise, it is equal to the number of elements
selected by the corresponding range expression.
Degenerate dimensions (trailing dimensions whose size is equal to one) are
removed. This was illustrated in the previous example by the expression
ARR[*,11] which resulted in a row vector with a single dimension because the
last dimension of the result was one and was removed. On the other hand, the
expression ARR[0, *] became a column vector with dimensions of [1, 12]
showing that the structure of columns is preserved because the dimension with a
size of one does not appear at the end.
Using the examples of VEC, a 50-element vector, and A, a 10-column by 12-row
array, some typical subscript range expressions are as follows:
VEC[5:10]
Elements 5 through 10 of VEC, a
six-element vector.
VEC[I - 1:I + 1]
A three-element vector.
[VEC[I - 1], VEC[I], VEC[I + 1]]
The same vector.
VEC[4:*]
Elements of VEC from VEC(4) to
the end, a 46-element (50 - 4) vector.
A[3, *]
The fourth column of A, a 1 column by 12 row vector.
[A[3, 0], A[3, 1], ..., A[3, 11]]
A[*, 0]
The first row of A, a 10-element
row vector. Note, the last dimension was removed because it was
degenerate.
A[X - 1:X + 1, Y - 1:Y + 1]
The nine-point neighborhood surrounding A[X,Y], a 3 by 3 array.
A[3:5,*]
Three columns of A, a 3 by 12 subarray:
See “The Assignment Statement” on page 85 for a description of the process of
assigning values to subarrays.
Building IDL Applications
Structure of Subarrays
66
Chapter 5: Array Subscripts
Array Subscripts
Arrays can be used as subscripts to other arrays. Each element in the array used
as a subscript selects an element in the subscripted array. When used with
subscript ranges, more than one element may be selected for each subscript
element.
If no subscript ranges are present, the length and structure of the result is the
same as that of the subscript expression. The type of the result is the same as that
of the subscripted array. If only one subscript is present, all subscripts are
interpreted as if the subscripted array has one dimension.
In the simple case of only one subscript, in which the subscript is an array, the
process can be written as follows:

 V S i if

V ( S ) =  V 0 if

 V n – 1 if

0 ≤ Si < n
Si < 0
for 0 ≤ i < m
Si ≥ n
The vector V has n elements, and S has m elements. The result V(S) has the same
structure and number of elements as does the subscript vector S.
If an element of the subscript array is less than or equal to zero, the first element
of the subscripted variable is selected. If an element of the subscript is greater
than or equal to the last subscript in the subscripted variable (N, above), the last
element is selected.
Example
As an example, consider the commands:
A = [6, 5, 1, 8, 4, 3]
B = [0, 2, 4, 1]
C = A[B]
PRINT, C
that produce the following output:
6 1 4 5
The first element of C is 6 because that is the number in the 0 position of A. The
second is 1 because the value in B of 2 indicates the third position in A, and so on.
As another example, assume the variable A is a 10 by 10 array. The expression
A[INDGEN(10) * 11] yields a 10-element vector equal to the diagonal
Array Subscripts
Building IDL Applications
Chapter 5: Array Subscripts
67
elements of A. The subscripts of the diagonal elements, A[0,0], A[1,1],
..., A[9, 9] are equal to 0, 11, 22, 99, when singularly subscripted. The
elements of the vector INDGEN(10)*11 also are equal to 0, 11, 22, ..., 99.
Applying the vector as a subscript selects the diagonal elements.
The WHERE function, which returns a vector of subscripts, can be used to select
elements of an array using expressions similar to A[WHERE(A GT 0)] which
results in a vector composed only of the elements of A that are greater than 0.
Combining Array Subscripts with Others
Array subscripts can be combined with subscript ranges, simple scalar subscripts
and other array subscripts.
When IDL encounters a multidimensional subscript that contains one or more
subscript arrays, it builds an array of subscripts by processing each subscript from
left to right. The resulting array of subscripts is then applied to the variable that
is to be subscripted. As with other subscript operations, trailing degenerate
dimensions (those with a size of 1) are eliminated.
Subscript Ranges
When combining an array subscript with a subscript range, the result is an array
of subscripts constructed by combining each element of the subscript array with
each member of the subscript range. Combining an n-element array with an melement subscript range yields an nm-element subscript. Each dimension of the
result is equal to the number of elements in the corresponding subscript array or
range.
For example, the expression A[[1, 3, 5], 7:9] is a nine-element, 3 × 3
array composed of the following elements:
A 1, 7 A 3, 7 A 5, 7
A 1, 8 A 3, 8 A 5, 8
A 1, 9 A 3, 9 A 5, 9
Each element of the three-element subscript array (1, 3, 5) is combined with each
element of the three-element range (7, 8, 9).
Another example shows the common process of zeroing the edge elements of a
two-dimensional n × m array:
A[*, [0, M-1]] = 0
Zero the first and last rows.
A[[0, N - 1], *] = 0
Zero the first and last columns.
Building IDL Applications
Combining Array Subscripts with Others
68
Chapter 5: Array Subscripts
Other Subscript Arrays
When combining two subscript arrays, each element of the first array is
combined with the corresponding element of the other subscript array. The two
subscript arrays must have the same number of elements. The resulting subscript
array has the same number of elements as its constituents. For example, the
expression A[[1, 3], [5, 9]] yields the elements A[1,5] and A[3,9].
Scalars
Combining an n-element subscript range or n-element subscript array with a
scalar yields an n-element result. The value of the scalar is combined with each
element of the range or array. For example, the expression A[[1, 3, 5], 8]
yields the three-element vector composed of the elements A[1,8], A[3,8],
and A[5,8]. The second dimension of the result is 1 and is eliminated because it
is degenerate. The expression A[8, [1, 3, 5]] is the 1 × 3-column vector
A[8,1], A[8,3], and A[8,5], illustrating that leading dimensions are not
eliminated.
Storing Elements with Array Subscripts
One or more values can be stored in selected elements of an array by using an
array expression as a subscript for the array on the left side of an assignment
statement. Values are taken from the expression on the right side of the
assignment statement and stored in the elements whose subscripts are given by
the array subscript. The right-hand expression can be either a scalar or array.
The subscript array is converted to longword type before use if necessary.
Regardless of structure, this subscript array is interpreted as a vector. For details
and examples of storing with vector subscripts, see “Assignment Statement” on
85.
Examples
The statement:
A[[2, 4, 6]] = 0
zeroes elements A[2], A[4], and A[6], without changing other elements of A.
The statement:
A[[2, 4, 6]] = [4, 16, 36]
stores 4 in A[2], 16 in A[4], and 36 in A[6].
One way to create a square n × n identity matrix is as follows:
A = FLTARR(N, N)
Storing Elements with Array Subscripts
Building IDL Applications
Chapter 5: Array Subscripts
69
A[INDGEN(N) * (N + 1)] = 1.0
The expression INDGEN(N)*(N + 1) results in a vector containing the
subscripts of the diagonal elements [0, N+1, 2N+2, ..., (N-1)*(N+1)].
Yet another way is to use two array subscripts. The statements:
A = FLTARR(N, N)
A[INDGEN(N), INDGEN(N)] = 1.0
create the array subscripts [[0,0], [1,1], ..., [n-1, n-1]]. The
statement:
A[WHERE(A LT 0)] = -1
sets negative elements of A to -1.
The statements:
A = FLTARR(10, 10)
A[INDGEN(10) * 11] = 1
create a 10x10 identity matrix.
Building IDL Applications
Storing Elements with Array Subscripts
70
Storing Elements with Array Subscripts
Chapter 5: Array Subscripts
Building IDL Applications
Chapter 6
Strings
The following topics are covered in this chapter:
String Operations ................................. 72
Non-string and Non-scalar Arguments .. 73
String Concatenation ............................ 74
Using STRING to Format Data............... 74
Byte Arguments and Strings.................. 75
Case Folding ......................................... 76
Whitespace ........................................... 77
Finding the Length of a String .............. 79
Substrings............................................. 79
71
72
Chapter 6: Strings
An IDL string is a sequence of characters from 0 to 32,767 characters in length.
Strings have dynamic length (they grow or shrink to fit), and there is no need to
declare the maximum length of a string prior to using it. As with any data type,
string arrays can be created to hold more than a single string. In this case, the
length of each individual string in the array depends only on its own length and
is not affected by the lengths of the other string elements.
A Note About the Examples
In some of the examples in this chapter, it is assumed that a string array named
TREES exists. TREES contains the names of seven trees, one name per element,
and is created using the statement:
trees = [’Beech’, ’Birch’, ’Mahogany’, ’Maple’, ’Oak’, $
’Pine’, ’Walnut’]
Executing the statement,
PRINT, ’>’ + trees + ’< ’
results in the following output:
>Beech< >Birch< >Mahogany< >Maple< >Oak< >Pine< >Walnut<
String Operations
IDL supports several basic string operations, as described below.
Concatenation
The Addition operator, “+”, can be used to concatenate strings together.
Formatting Data
The STRING function is used to format data into a string. The READS procedure
can be used to read values from a string into IDL variables.
Case Folding
The STRLOWCASE function returns a copy of its string argument converted to
lowercase. Similarly, the STRUPCASE function converts its argument to
uppercase.
White Space Removal
The STRCOMPRESS and STRTRIM functions can be used to eliminate
unwanted white space (blanks or tabs) from their string arguments.
Length
The STRLEN function returns the length of its string argument.
String Operations
Building IDL Applications
Chapter 6: Strings
73
Substrings
The STRPOS, STRPUT, and STRMID routines locate, insert, and extract
substrings from their string arguments.
Non-string and Non-scalar Arguments
Most of the string processing routines described in this chapter expect at least one
argument that is the string on which they act.
If the argument is not of type string, IDL converts it to type string using the same
default formatting rules that are used by the PRINT/PRINTF or STRING
routines. The function then operates on the converted result. Thus, the IDL
statement,
PRINT, STRLEN(23)
returns the result
8
because the argument “23” is first converted to the string ’
happens to be a string of length 8.
23’ that
If the argument is an array instead of a scalar, the function returns an array result
with the same structure as the argument. Each element of the result corresponds
to an element of the argument. For example, the following statements:
A = STRUPCASE(trees)
Get an uppercase version of
TREES.
HELP, A
Show that the result is also an array.
PRINT, trees
Display the original.
PRINT, A
Display the result.
produce the following output:
A
STRING
= Array(7)
Beech Birch Mahogany Maple Oak Pine Walnut
BEECH BIRCH MAHOGANY MAPLE OAK PINE WALNUT
For more details on how individual routines handle their arguments, see the
individual descriptions in the IDL Reference Guide.
Building IDL Applications
Non-string and Non-scalar Arguments
74
Chapter 6: Strings
String Concatenation
The addition operator is used to concatenate strings. For example, the command:
A = ’This is’ + ’ a concatenation example.’
PRINT, A
results in the following output:
This is a concatenation example.
The following IDL statements build a scalar string containing a commaseparated list of the names found in the TREES string array:
names = trees + [REPLICATE(’,’, N_ELEMENTS(trees)-1), ’’]
Use REPLICATE to make an array with the correct number of
commas and add it to trees.
Show the resulting list.
PRINT, names
Running the above statements results in the following output:
Beech, Birch, Mahogany, Maple, Oak, Pine, Walnut
Using STRING to Format Data
The STRING function has the following form:
S = STRING(Expression1, ..., Expressionn)
It converts its parameters to characters, returning the result as a string expression.
It is identical in function to the PRINT procedure, except that its output is placed
into a string rather than being output to the terminal. As with PRINT, the
FORMAT keyword can be used to explicitly specify the desired format. See the
discussions of free format and explicitly formatted input/output (“Free Format
I/O” on page 159) for details of data formatting. The STRING function is
described fully in the IDL Reference Guide.
As a simple example, the following IDL statements:
A = STRING(FORMAT=’("The values are:", /, (I))’, INDGEN(5))
Produce a string array.
HELP, A
Show its structure.
FOR I = 0, 4 DO PRINT, A[I]
Print the result.
produce the following output:
A
STRING
String Concatenation
= Array(6)
Building IDL Applications
Chapter 6: Strings
75
The values are:
0
1
2
3
Reading Data from Strings
The READS procedure performs formatted input from a string variable and
writes the results into one or more output variables. This procedure differs from
the READ procedure only in that the input comes from memory instead of a file.
This routine is useful when you need to examine the format of a data file before
reading the information it contains. Each line of the file can be read into a string
using READF. Then the components of that line can be read into variables using
READS.
See the description of READS in the IDL Reference Guide for more details.
Byte Arguments and Strings
There is a close association between a string and a byte array—a string is simply
an array of bytes that is treated as a series of ASCII characters. Therefore, it is
convenient to be able to convert between them easily.
When STRING is called with a single argument of byte type and the FORMAT
keyword is not used, STRING does not work in its normal fashion. Instead of
formatting the byte data and placing it into a string, it returns a string containing
the byte values from the original argument. Thus, the result has one less
dimension than the original argument. A two-dimensional byte array becomes a
vector of strings, and a byte vector becomes a scalar string. However, a byte scalar
also becomes a string scalar. For example, the statement
PRINT, STRING([72B, 101B, 108B, 108B, 111B])
produces the output below:
Hello
This output results because the argument to STRING, as produced by the array
concatenation operator, is a byte vector. Its first element is 72B which is the ASCII
code for “H,” the second is 101B which is an ASCII “e,” and so forth. Set the
PRINT keyword can be used to disable this feature and cause STRING to treat
byte data in the usual way.
Building IDL Applications
Byte Arguments and Strings
76
Chapter 6: Strings
As discussed in Chapter 11, it is easier to read fixed-length string data from
binary files into byte variables instead of string variables. Therefore, it is
convenient to read the data into a byte array and use this special behavior of
STRING to convert the data into string form.
Another use for this feature is to build strings that contain nonprintable
characters in a way such that the character is not entered directly. This results in
programs that are easier to read and that also avoid file transfer difficulties (some
forms of file transfer have problems transferring nonprintable characters). Due
to the way in which strings are implemented in IDL, applying the STRING
function to a byte array containing a null (zero) value will result in the resulting
string being truncated at that position. Thus, the statement,
PRINT, STRING([65B, 66B, 0B, 67B])
produces the following output:
AB
This output is produced because the null byte in the third position of the byte
array argument terminates the string and hides the last character.
Note The BYTE function, when called with a single argument of type string,
performs the inverse operation to that described above, resulting in a byte
array containing the same byte values as its string argument. For additional
information about the BYTE function, see “Type Conversion Functions” on
page 19.
Case Folding
The STRLOWCASE and STRUPCASE functions are used to convert arguments
to lowercase or uppercase. They have the form:
S = STRLOWCASE(String)
S = STRUPCASE(String)
where String is the string to be converted to lowercase or uppercase.
The following IDL statements generate a table of the contents of TREES showing
each name in its actual case, lowercase and uppercase:
FOR I=0, 6 DO PRINT, trees[I], STRLOWCASE(trees[I]),$
STRUPCASE(trees[I]), FORMAT = ’(A, T15, A, T30, A)’
The resulting output from running this statement is as follows:
Beech
Case Folding
beech
BEECH
Building IDL Applications
Chapter 6: Strings
77
Birch
birch
BIRCH
Mahogany
mahogany
MAHOGANY
Maple
maple
MAPLE
Oak
oak
OAK
Pine
pine
PINE
Walnut
walnut
WALNUT
A common use for case folding occurs when writing IDL procedures that require
input from the user. By folding the case of the response, it is possible to handle
responses written in uppercase, lowercase, or mixed case. For example, the
following IDL statements can be used to ask “yes or no” style questions:
Create a string variable to hold the
response.
answer = ’’
READ, ’Answer yes or no:
’, answer Ask the question.
IF (STRUPCASE(answer) EQ ’YES’) THEN $
PRINT,’YES’ ELSE PRINT, ’NO’
Compare the response to the expected answer.
Whitespace
The STRCOMPRESS and STRTRIM functions are used to remove unwanted
white space (tabs and spaces) from a string. This can be useful when reading
string data from arbitrarily formatted strings.
Removing All Whitespace
The function STRCOMPRESS returns a copy of its string argument with all white
space replaced with a single space or completely removed. It has the form:
S = STRCOMPRESS(String)
where String is the string to be compressed.
The default action is to replace each section of white space with a single space.
Setting the REMOVE_ALL keyword causes white space to be completely
eliminated. For example,
A = ’
This
is
a poorly
spaced
sentence.
’
Create a string with undesirable
white space. Such a string might be
the result of reading user input
with a READ statement.
Building IDL Applications
Whitespace
78
Chapter 6: Strings
PRINT, ’>’, STRCOMPRESS(A), ’<’
Print the result of shrinking all
white space to a single blank.
PRINT ’>’, STRCOMPRESS(A, /REMOVE_ALL), ’<’
Print the result of removing all
white space.
results in the output:
> This is a poorly spaced sentence. <
>Thisisapoorlyspacedsentence.<
Removing Leading or Trailing Blanks
The function STRTRIM returns a copy of its string argument with leading and/or
trailing white space removed. It has the form:
S = STRTRIM(String[, Flag])
where String is the string to be trimmed and Flag is an integer that indicates the
specific trimming to be done. If Flag is 0 or is not present, trailing white space is
removed. If it is 1, leading white space is removed. Both trailing and leading white
space are removed if Flag is equal to 2. For example:
A = ’ This string has leading and trailing white space
’
Create a string with unwanted
leading and trailing blanks.
PRINT, ’>’, STRTRIM(A), ’<’
Remove trailing white space.
PRINT, ’>’, STRTRIM(A,1), ’<’
Remove leading white space.
PRINT, ’>’, STRTRIM(A,2), ’<’
Remove both.
Executing these statements produces the output below.
>
This string has leading and trailing white space<
>This string has leading and trailing white space
<
>This string has leading and trailing white space<
Removing All Types of Whitespace
When processing string data, STRCOMPRESS and STRTRIM can be combined
to remove leading and trailing white space and shrink any white space in the
middle down to single spaces.
A =
’Yet
another
poorly
spaced
sentence.
’
Create a string with undesirable
white space.
Whitespace
Building IDL Applications
Chapter 6: Strings
79
PRINT, ’>’ STRCOMPRESS(STRTRIM(A,2)),
’<’
Eliminate unwanted white space.
Executing these statements gives the result below:
>Yet another poorly spaced sentence.<
Finding the Length of a String
The STRLEN function is used to obtain the length of a string. It has the form:
L = STRLEN(String)
where String is the string for which the length is required. For example, the
following statement
PRINT, STRLEN(’This sentence has 31 characters’)
results in the output
31
while the following IDL statement prints the lengths of all the names contained
in the array TREES.
PRINT, STRLEN(trees)
The resulting output is as follows:
5
5
8
5
3
4
6
Substrings
IDL provides the STRPOS, STRPUT, and STRMID routines to locate, insert, and
extract substrings from their string arguments.
Searching for a Substring
The STRPOS function is used to search for the first occurrence of a substring. It
has the form
S = STRPOS(Object, Search_string[, Position])
where Object is the string to be searched, Search_string is the substring to search
for, and Position is the character position (starting with position 0) at which the
search is begun. If the optional argument Position is omitted, the search is started
at the first character (character position 0). The following IDL procedure counts
the number of times that the word “dog” appears in the string “dog cat duck
rabbit dog cat dog”:
Building IDL Applications
Finding the Length of a String
80
Chapter 6: Strings
PRO Animals
animals = ’dog cat duck rabbit dog cat dog’
The search string, “dog”, appears
three times.
I = 0
Start searching in character position 0.
cnt = 0
Number of occurrences found.
WHILE (I NE -1) DO BEGIN
Search for an occurrence.
I = STRPOS(animals, ’dog’, I)
If one is found, count it and advance to next character position.
IF (I NE -1) THEN BEGIN
cnt = cnt + 1
Update counter.
I = I + 1
Increment I so as not to count the
same instance of ‘dog’ twice.
ENDIF
Print the result.
ENDWHILE
PRINT, ’Found ’, cnt, " occurrences of ’dog’"
END
Running the above program produces the result below.
Found
3 occurrences of ’dog’
Inserting the Contents of One String into Another
The STRPUT procedure is used to insert the contents of one string into another.
It has the form,
STRPUT, Destination, Source[, Position]
where Destination is the string to be overwritten, Source is the string to be
inserted, and Position is the first character position within Destination at which
Source will be inserted. If the optional argument Position is omitted, the overwrite
is started at the first character (character position 0). The following IDL
statements use STRPOS and STRPUT to replace every occurrence of the word
“dog” with the word “CAT” in the string “dog cat duck rabbit dog cat dog”:
animals = ’dog cat duck rabbit dog cat dog’
The string to search, “dog”, appears three times.
WHILE (((I = STRPOS(animals, ’dog’))) NE -1) DO $
Substrings
Building IDL Applications
Chapter 6: Strings
81
STRPUT, animals, ’CAT’, I
While any occurrence of “dog” exists, replace it.
PRINT, animals
Show the resulting string.
Running the above statements produces the result below.
CAT cat duck rabbit CAT cat CAT
Extracting Substrings
The STRMID function is used for extracting substrings from a larger string. It has
the form:
STRMID(Expression, First_Character [, Length])
where Expression is the string from which the substring will be extracted,
First_Character is the starting position within Expression of the substring (the
first position is position 0), and Length is the length of the substring to extract. If
there are not Length characters following the position First_Character, the
substring will be truncated. If the Length argument is not supplied, STRMID
extracts all characters from the specified starting position to the end of the string.
The following IDL statements use STRMID to print a table matching the number
of each month with its three-letter abbreviation:
months = ’JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC’
String containing all the month
names.
FOR I = 1, 12 DO PRINT, I, ’
STRMID(months, (I - 1) * 3, 3)
’, $
Extract each name in turn. The
equation (I-1)*3 calculates the
position within MONTH for each
abbreviation
The result of executing these statements is as follows:
1
JAN
2
FEB
3
MAR
4
APR
5
MAY
6
JUN
7
JUL
8
AUG
Building IDL Applications
Substrings
82
Substrings
Chapter 6: Strings
9
SEP
10
OCT
11
NOV
12
DEC
Building IDL Applications
Chapter 7
Statements
The following topics are covered in this chapter:
Components of Statements ................. 84
The Assignment Statement ................... 85
Blocks ................................................... 90
CASE Statement.................................... 92
Common Blocks.................................... 93
FOR Statement ..................................... 96
Function Definition Statement .............. 99
GOTO Statement .............................. 102
IF Statement....................................... 102
Procedure Call Statement ................... 104
Procedure Definition Statement.......... 106
REPEAT Statement .............................. 107
WHILE Statement ............................... 108
83
84
Chapter 7: Statements
IDL programs, procedures, and functions are composed of one or more valid
statements. Most simple IDL statements can also be entered in the immediate
mode in response to the IDL> prompt. The thirteen types of IDL statements are
as follows:
•
Assignment
•
Block
•
Case
•
Common Block Definition
•
For
•
Forward Function Definition
•
Function Definition
•
Goto
•
If
•
Procedure Call
•
Procedure Definition
•
Repeat
•
While
Components of Statements
Statements in IDL can consist of any combination of three parts:
•
A label field
•
The statement proper
•
A comment field
Spaces and tabs can appear anywhere except in the middle of an identifier or
numeric constant.
Statement Labels
Labels are the destinations of GOTO statements as well as the ON_ERROR and
ON_IOERROR procedures. The label field, which must appear before the
statement or comment, is simply an identifier followed by a colon. A line can
Components of Statements
Building IDL Applications
Chapter 7: Statements
85
consist of only a label field. Label identifiers, as with variable names, consist of 1
to 15 alphanumeric characters and are case insensitive. The dollar sign ($) and
underscore (_) characters can appear after the first character. Some examples of
labels are as follows:
LABEL1:
LOOP_BACK: A = 12
I$QUIT: RETURN
;Comments are allowed.
Comments
The comment field, which is ignored by IDL, begins with a semicolon and
continues to the end of the line. Lines can consist of only a comment field or can
be entirely blank. It is good programming practice to fully annotate programs
with comments. There are no execution-time or space penalties for comments in
IDL.
The following IDL statement shows a simple assignment statement with a
comment field:
COUNT = 5
;Set variable COUNT to 5. This is the comment field.
The Assignment Statement
The assignment statement stores a value in a variable. There are four forms of the
assignment statement, as shown in Table 7-1.
Syntax
Subscript
Structure
Expression
Structure
Effect
Variable = Expression
None
All
Expression is stored in Variable
Variable[Subscripts] = Expression
Scalar
Scalar
Expression is stored in a single
element of Variable
Scalar
Array
Expression array is inserted in
Variable array
Array
Scalar
Expression scalar is stored in
designated elements of Variable
Array
Array
Elements of Expression are
stored in designated elements of
Variable
Variable[Range] = Expression
Building IDL Applications
Range
Scalar
Scalar is inserted into subarray
The Assignment Statement
86
Chapter 7: Statements
Syntax
Subscript
Structure
Expression
Structure
Effect
Variable[Range] = Expression
Range
Array
Illegal
Table 7-1: Types of Assignment Statements
In the second and fourth cases, an array can be used as a subscript. This stores the
values from the right side of the statement into elements of the variable
designated by the contents of the array subscript.
Note In versions of IDL prior to version 5.0, parentheses were used to enclose array
subscripts. While using parentheses to enclose array subscripts will continue
to work as in previous version of IDL, we strongly suggest that you use
brackets in all new code. See “Array Subscript Syntax: [ ] vs. ( )” on page 60
for additional details.
The Basic Assignment Statement
The first, and most basic, form of the assignment statement is as follows:
Variable = Expression
The old value of the variable, if any, is discarded, and the value of the expression
is stored in the variable. The expression on the right side can be of any type or
structure.
Examples
Some examples of the basic form of the assignment statement are as follows:
mmax = 100 * X + 2.987
Set mmax to value.
name = ’Mary ’
name becomes a scalar string
variable.
arr = FLTARR(100)
Make arr a 100-element, floating-point array.
arr = ARR[50:*]
Discard points 0 to 49 of arr. It is
now a 50-element array.
The Second Form of the Assignment Statement
The second type of assignment statement has the following form:
Variable[Subscripts] = Scalar_Expression
Here, a single element of the specified array is set to the value of the scalar
expression. The expression can be of any type and is converted, if necessary, to the
The Assignment Statement
Building IDL Applications
Chapter 7: Statements
87
type of the variable. The variable on the left side must be either an array or a file
variable. Some examples of assigning scalar expressions to subscripted variables
are shown below:
data[100] = 1.234999
Set element 100 of data to value.
name[index] = ’Joe ’
Store string in an array. name
must be a string array or an error
will result.
image[X, Y] = pixel
Set element [X, Y] of the 2-dimensional array image to the value
contained in pixel.
Using Array Subscripts with the Second Form of the Assignment Statement
The subscripted variable can have either a scalar or array subscript. If the
subscript expression is an array, the scalar value is stored in the elements of the
array whose subscripts are elements of the subscript array. For example, the
statement
data[[3, 5, 7, 9]] = 0
zeroes the four specified elements of data: data[3], data[5], data[7]
and data[9].
The subscript array is converted to longword type if necessary before use.
Elements of the subscript array that are negative, or greater than the highest
subscript of the subscripted array, are clipped to the target array boundaries.
Note that a common error is to use a negative scalar subscript (e.g., A[-1]).
Using this type of subscript causes an error. Negative array subscripts (e.g.,
A[[-1]]) do not cause errors.
The WHERE function can be used to select array elements to be changed. For
example, the statement:
data[WHERE(data LT 0)] = -1
sets all negative elements of data to -1 without changing the positive elements.
The result of the function, WHERE(data LT 0), is a vector composed of the
subscripts of the negative elements of data. Using this vector as a subscript
changes only the negative elements.
The Third Form of the Assignment Statement
The third type of assignment statement is similar to the second, except the
subscripts specify a range in which all elements are set to the scalar expression.
Variable[Subscript_Range] = Scalar_Expression
Building IDL Applications
The Assignment Statement
88
Chapter 7: Statements
A subscript range specifies a beginning and ending subscript. The beginning and
ending subscripts are separated by the colon character. An ending subscript equal
to the size of the dimension minus one can be written as *.
For example, arr[I:J] denotes those points in the vector arr with subscripts
between I and J inclusive. I must be less than or equal to J and greater than or
equal to zero. J denotes the points in arr from arr[I] to the last point and must
be less than the size of the dimension arr [I:*]. See “Array Subscripts” on page
59 for more details on subscript ranges.
Examples
Assuming the variable B is a 512 × 512-byte array, some examples are as follows:
array[*, I] = 1
Store 1 in every element of the i-th
row.
array[J, *] = 1
Store 1 in every element of the j-th
column.
array[200:220, *] = 0
Zero all the rows of columns 200
through 220 of array.
array[*] = 100
Store the value 100 in all the elements of array.
The Fourth Form of the Assignment Statement
The fourth type of assignment statement is of the following form:
Variable[Subscripts] = Array
Note that this form is syntactically identical to the second type of assignment
statement, but that the expression on the right-hand-side is an array instead of a
scalar. This form of the assignment statement is used to insert one array into
another.
The array expression on the right is inserted into the array appearing on the left
side of the equal sign starting at the point designated by the subscripts.
Examples
For example, to insert the contents of an array called A into array B, starting at
point B[13, 24], use the following statement:
B[13, 24] = A
If A is a 5-column by 6-row array, elements B[13:17, 24:29] are replaced by
the contents of array A.
In the next example, a subarray is moved from one position to another with the
statement:
The Assignment Statement
Building IDL Applications
Chapter 7: Statements
89
B[100, 200] = B[200:300, 300:400]
A subarray of B, specifically the columns 200 to 300 and rows 300 to 400, is moved
to columns 100 to 200 and rows 200 to 300, respectively.
Using Array Subscripts with the Fourth Form of the Assignment Statement
If the subscript expression applied to the variable is an array and an array appears
on the right side of the statement:
Variable[Array] = Array
then elements from the right side are stored in the elements designated by the
subscript vector. Only those elements of the subscripted variable whose
subscripts appear in the subscript vector are changed. For example, the statement
B[[ 2, 4, 6 ]] = [4, 16, 36]
is equivalent to the following series of assignment statements:
B[2] = 4
B[4] = 16
B[6] = 36
Subscript elements are interpreted as if the subscripted variable is a vector. For
example, if A is a 10 × n matrix, the element A[i, j] has the subscript i+10*j. The
subscript array is converted to longword type before use, if necessary.
As described previously for the second form of assignment statement, elements
of the subscript array that are negative or larger than the highest subscript are
clipped to the target array boundaries. Note that a common error is to use a
negative scalar subscript (e.g., A[-1]). Using this type of subscript causes an
error. Negative array subscripts (e.g., A[[-1]]) do not cause errors.
As another example, assume that the vector DATA contains data elements and
that a data drop-out is denoted by a negative value. In addition, assume that there
are never two or more adjacent drop-outs. The following statements replace all
drop-outs with the average of the two adjacent good points:
bad = WHERE(data LT 0)
Subscript vector of drop-outs.
data[bad] = (data[bad - 1] + data[bad + 1]) / 2
Replace drop-outs with average of
previous and next point.
In this example, the following actions are performed:
•
We use the LT (less than) operator to create an array, with the same dimensions
as data, that contains a 1 for every element of data that is less than zero and a
zero for every element of data that is zero or greater. We use this “drop-out array”
Building IDL Applications
The Assignment Statement
90
Chapter 7: Statements
as a parameter for the WHERE function, which generates a vector that contains
the one-dimensional subscripts of the elements of the drop-out array that are
nonzero. The resulting vector, stored in the variable bad, contains the subscripts
of the elements of data that are less than zero.
•
The expression data[bad - 1] is a vector that contains the subscripts of the
points immediately preceding the drop-outs; while similarly, the expression
data[bad + 1] is a vector containing the subscripts of the points immediately
after the drop-outs.
•
The average of these two vectors is stored in data[bad], the points that originally
contained drop-outs.
Associated Variables in Assignment Statements
A special case occurs when using an associated file variable in an assignment
statement. For additional information regarding the ASSOC function, see
“ASSOC” on page 204 of the IDL Reference Guide. When a file variable is
referenced, the last (and possibly only) subscript denotes the record number of
the array within the file. This last subscript must be a simple subscript. Other
subscripts and subscript ranges, except the last, have the same meaning as when
used with normal array variables.
An implicit extraction of an element or subarray in a data record can also be
performed. For example:
A = ASSOC(1, FLTARR(200))
Variable A associates the file open
on unit 1 with the records of 200element, floating-point vectors.
X = A[0:99, 2]
Then, X is set to the first 100 points
of record number 2, the third
record of the file.
A[23, 16] = 12
Set the 24th point of record 16 to
12.
A[10, 12] = A[10:*, 12]+1
Increment points 10 to 199 of
record 12. Points 0 to 9 of the
record remain unchanged.
Blocks
A block of statements is simply a group of statements that are treated as a single
statement. For example, a group of statements can be bracketed as follows:
BEGIN
Statement1
Blocks
Building IDL Applications
Chapter 7: Statements
91
...
Statementn
END
Blocks are necessary when more than one statement is the subject of a conditional
or repetitive statement, as in the FOR, WHILE, and IF statements. In general, the
format of a FOR statement with a block subject is as follows:
FOR Variable = Expression, Expression DO BEGIN
Statement1
Statement2
...
...
...
Statementn
ENDFOR
All the statements between the BEGIN and the END are the subject of the FOR
statement. The group of statements is executed as a single statement and is called
a compound statement. Blocks can be nested within other blocks.
Syntactically, a block of statements is composed of one or more statements of any
type, started by a BEGIN identifier and ended by an END identifier. IDL allows
the use of blocks wherever a single statement is allowed. As an example, the
process of reversing an array in place might be written as follows:
FOR I = 0,(N - 1)/2 DO BEGIN
T = arr[I]
arr[I] = arr[N - I - 1]
arr[N - I - 1] = T
ENDFOR
Note The code shown above is for illustration only. The IDL REVERSE function is
much more efficient.
The three statements between the BEGIN and ENDFOR are the subject of the
FOR statement, and each will be executed once during each iteration of the loop.
If the statements are not enclosed in a block, only the first statement (T =
arr[I]) is executed during each iteration, and the remaining two statements are
executed only once after the termination of the FOR statement.
Building IDL Applications
Blocks
92
Chapter 7: Statements
To ensure proper nesting of compound statements (one or more different
blocks), the “END” statement terminating the block can be followed by the block
type as shown in Table 7-2. The compiler checks the end of each block,
comparing it with the type of the enclosing statement. Any block can be
terminated by the generic END, although no type checking is performed.
END Statement
Use
ENDCASE
CASE statement
ENDELSE
IF statement, ELSE clause
ENDFOR
FOR statement
ENDIF
IF statement, THEN clause
ENDREP
REPEAT statement
ENDWHILE
WHILE statement
Table 7-2: Types of END Statements
Listings produced by the IDL compiler indent each block four spaces to the right
of the previous level to make the program structure easier to read. (See “.RUN”
on page 34 of the IDL Reference Guide for details on producing program listings
with the IDL compiler.)
CASE Statement
The CASE statement is used to select one, and only one, statement for execution,
depending upon the value of the expression following the word CASE. This
expression is called the case selector expression. The general form of the CASE
statement is as follows:
CASE Expression OF
Expression: Statement
...
Expression: Statement
ELSE: Statement
ENDCASE
Each statement that is part of a CASE statement is preceded by an expression that
is compared to the value of the selector expression. If a match is found, the
statement is executed and control resumes directly below the CASE statement.
CASE Statement
Building IDL Applications
Chapter 7: Statements
93
The ELSE clause of the CASE statement is optional. If included, it must be the last
clause in the case statement. The statement after the ELSE is executed only if none
of the preceding statement expressions match. If the ELSE is not included and
none of the values match, an error occurs and program execution stops.
Example
An example of the CASE statement follows:
CASE name OF
’Linda’: PRINT, ’sister’
If name is “Linda,” print “sister.”
’John’: PRINT, ’brother’
If name is “John,” print “brother.”
’Harry ’: PRINT, ’step-brother’ If name is “Harry,” print “step-
brother”.
ELSE: PRINT, ’Not a sibling.’
No matches, print “Not a sibling.”
ENDCASE
End of CASE statement.
Another example shows the CASE statement with the number 1 as the selector
expression of the CASE. One is equivalent to true and is matched against each of
the conditionals.
CASE 1 OF
(X GT 0) AND (X LE 50): Y = 12 * X + 5
(X GT 50) AND (X LE 100): Y = 13 * X + 4
(X LE 200): BEGIN
Y = 14 * X - 5
Z = X + Y
END
ELSE: PRINT, ’X has an illegal value.’
ENDCASE
In this CASE statement, only one clause is selected, and that clause is the first one
whose value is equal to the value of the case selector expression. Each clause is
tested in order, so it is most efficient to order the most frequently selected clauses
first.
Common Blocks
Common blocks are useful when there are variables that need to be accessed by
several IDL procedures or when the value of a variable within a procedure must
Building IDL Applications
Common Blocks
94
Chapter 7: Statements
be preserved across calls. Once a common block has been defined, any program
unit referencing that common block can access variables in the block as though
they were local variables. Variables in a common statement have a global scope
within procedures defining the same common block. Unlike local variables,
variables in common blocks are not destroyed when a procedure is exited.
There are two types of common block statements: definition statements and
reference statements.
Common Block Definition Statements
The common block definition statement creates a common block with the
designated name and places the variables whose names follow into that block.
Variables defined in a common block can be referenced by any program unit that
declares that common block. The general form of the COMMON block
definition statement is as follows:
COMMON Block_Name, Variable1, Variable2, ..., Variablen
The number of variables appearing in the common block definition statement
determines the size of the common block. The first program unit (main program,
function, or procedure) defining the common block sets the size of the common
block, which can never be expanded. Other program units can reference the
common block with any number of variables up to the number originally
specified. Different program units can give the variables different names, as
shown in the example below.
Common blocks share the same space for all procedures. In IDL, common block
variables are matched variable to variable, unlike FORTRAN, where storage
locations are matched. The third variable in a given IDL common block will
always be the same as the third variable in all declarations of the common block
regardless of the size, type, or structure of the preceding variables.
Note that common blocks must appear before any of the variables they define are
referenced in the procedure.
Variables in common blocks can be of any type and can be used in the same
manner as normal variables. Variables appearing as parameters cannot be used in
common blocks. There are no restrictions on the number of common blocks
used, although each common block uses dynamic memory.
Example The two procedures in the following example show how variables defined in
common blocks are shared.
PRO ADD, A
COMMON SHARE1, X, Y, Z, Q, R
A = X + Y + Z + Q + R
PRINT, X, Y, Z, Q, R, A
Common Blocks
Building IDL Applications
Chapter 7: Statements
95
RETURN
END
PRO SUB, T
COMMON SHARE1, A, B, C, D
T = A - B - C - D
PRINT, A, B, C, D, T
RETURN
END
The variables X, Y, Z, and Q in the procedure ADD are the same as the
variables A, B, C, and D, respectively, in procedure SUB. The variable R in
ADD is not used in SUB. If the procedure SUB were to be compiled before
the procedure ADD, an error would occur when the COMMON definition in
ADD was compiled. This is because SUB has already declared the size of the
common block, SHARE1, which cannot be extended.
Common Block Reference Statements
The common block reference statement duplicates the common block and
variable names from a previous definition. The common block need only be
defined in the first routine to be compiled that references the block.
Example The two procedures in the following example share the common block
SHARE2 and all its variables.
PRO MULT, M
COMMON SHARE2, E, F, G
M = E * F * G
PRINT, M, E, F, G
RETURN
END
PRO DIV, D
COMMON SHARE2
D = E / F
PRINT, D, E, F, G
RETURN
END
The MULT procedure uses a common block definition statement to define the
block SHARE2. The DIV procedure then uses a common block reference
statement to gain access to all the variables defined in SHARE2. (Note that
MULT must be defined before DIV in order for the common block reference
to succeed.)
Building IDL Applications
Common Blocks
96
Chapter 7: Statements
FOR Statement
The FOR statement is used to execute one or more statements repeatedly, while
incrementing or decrementing a variable with each repetition, until a condition
is met. It is analogous to the DO statement in FORTRAN.
In IDL, there are two types of FOR statements: one with an implicit increment of
1 and the other with an explicit increment. If the condition is not met the first
time the FOR statement is executed, the subject statement is not executed.
FOR Statement with an Increment of One
The FOR statement with an implicit increment of one is written as follows:
FOR Variable = Expression, Expression DO Statement
The variable after the FOR is called the index variable and is set to the value of the
first expression. The subject statement is executed, and the index variable is
incremented by 1 until the index variable is larger than the second expression.
This second expression is called the limit expression. Complex limit and
increment expressions are converted to floating-point type.
Caution The data type of the index variable is determined by the type of the initial
value expression. Keep this fact in mind to avoid the following:
FOR I = 0, 50000 DO ... ...
This loop does not produce the intended result. Converting the longword
constant 50,000 to a short integer yields −15,536 because of truncation. The
loop is not executed. The index variable’s initial value is larger than the limit
variable. The loop should be written as follows:
FOR I = 0L, 50000 DO ... ...
Note also that changing the data type of an index variable within a loop is not
allowed, and will cause an error.
Caution Also be aware of FOR loops that are entered but are not terminated after the
expected number of iterations, because of the truncation effect. For example,
if the index value exceeds the maximum value for the initial data type (and
so is truncated) when it is expected instead to exceed the specified index limit,
then the loop will continue beyond the expected number of iterations.
The following FOR statement continues infinitely:
FOR i = 0B, 240, 16 DO PRINT, i
The problem occurs because the variable i is initialized to a byte type with
0B. After the index reaches the limit value 240B, i is incremented by 16,
FOR Statement
Building IDL Applications
Chapter 7: Statements
97
causing the value to go to 256B, which is interpreted by IDL as 0B, because of
the truncation effect. As a result, the FOR loop “wraps around” and the index
can never be exceeded.
Example A simple FOR statement:
FOR I = 1, 4 DO PRINT, I, I^2
which produces the following output:
1
1
2
4
3
9
4
16
The index variable I is first set to an integer variable with a value of one. The
call to the PRINT procedure is executed, then the index is incremented by
one. This is repeated until the value of I is greater than four at which point
execution continues at the statement following the FOR statement.
Example The next example displays the use of a block structure (instead of a single
statement) as the subject of the FOR statement. The example is a common
process used for computing a count-density histogram. Note: A HISTOGRAM function is provided by IDL.
FOR K = 0, N - 1 DO BEGIN
C = A[K]
HIST(C) = HIST(C)+1
ENDFOR
Example A FOR statement with floating-point index and limit expressions:
FOR X = 1.5, 10.5 DO S = S + SQRT(X)
where X is set to a floating-point variable and steps through the values (1.5,
2.5, ..., 10.5).
The indexing variables and expressions can be integer, longword, floatingpoint, or double-precision. The type of the index variable is determined by
the type of the first expression after the “=” character.
Caution Due to the inexact nature of IEEE floating-point numbers, using floatingpoint indexing can cause “infinite loops” and other problems. This problem
is also manifested in both the C and FORTRAN programming languages. For
example, the numbers 0.1, 0.01, 1.6, and 1.7 do not have exact representations
Building IDL Applications
FOR Statement
98
Chapter 7: Statements
under the IEEE standard. To see this phenomenon, enter the following IDL
command:
PRINT, 0.1, 0.01, 1.6, 1.7, FORMAT=’(f20.10)’
IDL prints the following approximations to the numbers we requested:
0.1000000015
0.0099999998
1.6000000238
1.7000000477
See “Accuracy & Floating-Point Operations” on page 427 of Using IDL for
more information about floating-point numbers.
FOR Statement with Variable Increment
The format of the second type of FOR statement is as follows:
FOR Variable = Expression1, Expression2, Increment DO Statement
This form is used when an increment other than 1 is desired.
The first two expressions describe the range of numbers for the index variable.
The Increment specifies the increment of the index variable. A negative
increment allows the index variable to step downward. In this case, the first
expression must have a value greater than that of the second expression. If not, an
almost infinite loop will result.
Examples
The following examples demonstrate the second type of FOR statement.
FOR K = 100.0, 1.0, -1 DO ...
Decrement, K has the values 100.,
99., ..., 1.
FOR loop = 0, 1023, 2
Increment by 2., loop has the values 0., 2., 4., ..., 1022.
DO ...
FOR mid = bottom, top, (top - bottom)/4.0 DO ...
Divide range from bottom to
top by 4.
Caution If the value of the increment expression is zero, an infinite loop occurs. A
common mistake resulting in an infinite loop is a statement similar to the
following:
FOR X = 0, 1, .1 DO ....
FOR Statement
Building IDL Applications
Chapter 7: Statements
99
The variable X is first defined as an integer variable because the initial value
expression is an integer zero constant. Then the limit and increment expressions are converted to the type of X, integer, yielding an increment value of
zero because .1 converted to integer type is 0. The correct form of the
statement is:
FOR X = 0., 1, .1 DO ....
which defines X as a floating-point variable.
Operation of the FOR Statement
The FOR statement performs the following steps:
1. The value of the first expression is evaluated and stored in the specified variable,
which is called the index variable. The index variable is set to the type of this
expression.
2. The value of the second expression is evaluated, converted to the type of the index
variable, and saved in a temporary location. This value is called the limit value.
3. The value of the third expression, called the step value, is evaluated, typeconverted if necessary, and stored. If omitted, a value of 1 is assumed.
4. If the index variable is greater than the limit value (in the case of a positive step
value) the FOR statement is finished and control resumes at the next statement.
Similarly, in the case of a negative step value, if the index variable is less than the
limit value, control resumes after the FOR statement.
5. The statement or block following the DO is executed.
6. The step value is added to the index variable.
7. Steps 4, 5, and 6 are repeated until the test of Step 4 fails.
Function Definition Statement
FUNCTION Function_Name, Parameter1, Parameter2, ..., Parametern
A function is a program unit containing one or more IDL statements that returns
a value. This unit executes independently of its caller. It has its own local variables
and execution environment. Once a function has been defined, references to the
function cause the program unit to be executed. All functions return a function
value which is given as a parameter in the RETURN statement used to exit the
function. Function names can be up to 128 characters long.
The general format of a function definition is as follows:
Building IDL Applications
Function Definition Statement
100
Chapter 7: Statements
FUNCTION Name, Parameter1, ..., Parametern
Statement1
Statement2
...
...
RETURN, Expression
END
Example To define a function called AVERAGE, which returns the average value of an
array, use the following statements:
FUNCTION AVERAGE, arr
RETURN, TOTAL(arr)/N_ELEMENTS(arr)
END
Once the function AVERAGE has been defined, it is executed by entering the
function name followed by its arguments enclosed in parentheses. Assuming
the variable X contains an array, the statement,
PRINT, AVERAGE(X^2)
squares the array X, passes this result to the AVERAGE function, and prints
the result. Parameters passed to functions are identified by their position or
by a keyword. See “Keyword Parameters” on page 106. For further details
about user-defined functions, see “Defining Procedures and Functions” on
page 109.
Automatic Execution
IDL automatically compiles and executes a user-written function or procedure
when it is first referenced if:
1. The source code of the function is in the current working directory or in a
directory in the IDL search path defined by the system variable !PATH.
2. The name of the file containing the function is the same as the function name
suffixed by .pro or .sav. Under Unix, the suffix should be in lowercase letters.
Note IDL is case-insensitive. However, for some operating systems, IDL only checks
for the lowercase filename based on the name of the procedure or function.
We recommend that all filenames be named with lowercase.
Caution User-written functions must be defined before they are referenced, unless they
meet the above conditions for automatic compilation or the function name
Function Definition Statement
Building IDL Applications
Chapter 7: Statements
101
has been reserved by using the FORWARD_FUNCTION statement described
below. This restriction is necessary in order to distinguish between function
calls and subscripted variable references.
For information on how to access routines, see “Executing Program Files” on
page 29 of Using IDL.
Forward Function Definition
Versions of IDL prior to version 5.0 used parentheses to indicate array subscripts.
Because function calls use parentheses as well, the IDL compiler is not able to
distinguish between arrays and functions by examining the statement syntax.
This problem has been addressed beginning with IDL version 5.0 by the use of
square brackets “[ ]” instead of parentheses to specify array subscripts. See “Array
Subscript Syntax: [ ] vs. ( )” on page 60 for a discussion of the IDL version 5.0 and
later syntax. However, because parentheses are still allowed in array subscripting
statements, the need for a mechanism by which the programmer can “reserve” a
name for a function that has not yet been defined remains. The
FORWARD_FUNCTION statement addresses this need.
As mentioned above, ambiguities can arise between function calls and array
references when a function has not yet been compiled, or there is no file with the
same name as the function found in the IDL path.
For example, attempting to compile the IDL statement:
A = xyz(1, COLOR=1)
will cause an error if the user-written function XYZ has not been compiled and
the filename xyz.pro is not found in the IDL path. IDL reports a syntax error,
because xyz is interpreted as an array variable instead of a function name.
This problem can be eliminated by using the FORWARD_FUNCTION
statement. This statement has the following syntax:
FORWARD_FUNCTION Name1, Name2, ..., NameN
where Name is the name of a function that has not yet been compiled. Any names
declared as forward-defined functions will be interpreted as functions (instead of
as variable names) for the duration of the IDL session.
For example, we can resolve the ambiguity in the previous example by adding a
FORWARD_FUNCTION definition:
FORWARD_FUNCTION XYZ
Building IDL Applications
Define XYZ as the name of a function that has not yet been compiled.
Function Definition Statement
102
Chapter 7: Statements
a = XYZ(1, COLOR=1)
IDL now understands this statement to be a function call instead
of a bad variable reference.
Note Declaring a function that will be merged into IDL via the LINKIMAGE
command with the FORWARD_FUNCTION statement will not have the
desired effect. Routines merged via LINKIMAGE are considered by IDL to be
built-in routines, and thus need no compilation or declaration. They must,
however, be merged with IDL before any routines that call them are compiled.
GOTO Statement
GOTO, Label
The GOTO statement is used to transfer program control to a point in the
program specified by the label. The GOTO statement is generally considered to
be a poor programming practice that leads to unwieldy programs. Its use should
be avoided. However, for those cases in which the use of a GOTO is appropriate,
IDL does provide the GOTO statement.
Note that using a GOTO to jump into the middle of a loop results in an error.
Caution The user must be careful in programming with GOTO statements. It is not
difficult to get into a loop that will never terminate, especially if there is not
an escape (or test) within the statements spanned by the GOTO.
Example An example of the GOTO statement follows:
GOTO, JUMP1
Statements ...
...
JUMP1: X = 2000 + Y
In the above example, the statement at label JUMP1 is executed after the
GOTO statement, skipping any intermediate statements. Note that the label
could also occur before the GOTO statement that refers to the label.
GOTO statements are frequently the subjects of IF statements, as seen in the
statement below:
IF A NE G THEN GOTO, MISTAKE
IF Statement
IF Expression THEN
GOTO Statement
Building IDL Applications
Chapter 7: Statements
103
IF Expression THEN Statement ELSE Statement
The IF statement is used to conditionally execute a statement or a block of
statements.
The expression after the “IF” is called the condition of the IF statement. This
expression (or condition) is evaluated, and if true, the statement following the
“THEN” is executed. If the expression evaluates to a false value, the statement
following the “ELSE” clause is executed. Control passes immediately to the next
statement if the condition is false and the ELSE clause is not present.
Example Examples of the IF statement include the following:
IF A NE 2 THEN PRINT, ’A is not two ’
IF A EQ 1 THEN PRINT, ’A is one’ ELSE PRINT, ’not one ’
The first example contains no ELSE clause. If the value of A is not equal to 2,
“A IS NOT TWO” is printed. If A is equal to 2, the THEN clause is ignored,
nothing is printed, and execution resumes at the next statement. In the second
example above, the condition of the IF statement is (A EQ 1). If the value
of A is equal to 1, “A IS ONE” is printed; otherwise, “NOT ONE” is printed.
Definition of True and False
The condition of the IF statement can be any scalar expression. The definition of
true and false for the different data types is as follows:
•
Byte, integer, and long: odd integers are true, even integers are false.
•
Floating-Point, double-precision floating-point, and complex: non-zero values
are true, zero values are false. The imaginary part of complex numbers is ignored.
•
String: any string with a nonzero length is true, null strings are false.
Example In the following example, the logical statement for the condition is a conjunction of two conditions.
IF (LON GT -40) AND (LON LE -20) THEN ...
If both conditions (LON being larger than -40 and less than or equal to -20)
are true, the statement following the THEN is executed.
Using Statement Blocks with the IF Statement
The THEN and ELSE clauses can be in the form of a block (or group of
statements) with the delimiters BEGIN and END (see “Blocks” on page 90). To
ensure proper nesting of blocks, you can use ENDIF and ENDELSE to terminate
Building IDL Applications
IF Statement
104
Chapter 7: Statements
the block, instead of using the generic END. Below is an example of the use of
blocks within an IF statement.
IF (I NE 0.0) THEN BEGIN
...
ENDIF ELSE BEGIN
...
ENDELSE
End of else clause.
Nesting IF Statements
IF statements can be nested in the following manner:
IF P1 THEN S1 ELSE $
IF P2 THEN S2 ELSE $
...
IF PN THEN SN ELSE SX
If condition P1 is true, only statement S1 is executed; if condition P2 is true, only
statement S2 is executed, etc. If none of the conditions are true, statement SX will
be executed. Conditions are tested in the order they are written. The construction
above is similar to the CASE statement except that the conditions are not
necessarily related.
Procedure Call Statement
Procedure_Name, Parameter1, Parameter2, ..., Parametern
The procedure call statement invokes a system, user-written, or externallydefined procedure. The parameters that follow the procedure’s name are passed
to the procedure. When the called procedure finishes, control resumes at the
statement following the procedure call statement. Procedure names can be up to
128 characters long.
Procedures can come from the following sources:
•
System procedures provided with IDL.
•
User-written procedures written in IDL and compiled with the .RUN command.
•
User-written procedures that are compiled automatically because they reside in
directories in the search path. These procedures are compiled the first time they
are used. See “Function Definition Statement” on page 99.
Procedure Call Statement
Building IDL Applications
Chapter 7: Statements
105
•
Procedures written in IDL, that are included with the IDL distribution, located in
directories that are specified in the search path.
•
Under many operating systems, user-written system procedures coded in FORTRAN, C, or any language that follows the standard calling conventions, which
have been dynamically linked with IDL using the LINKIMAGE or
CALL_EXTERNAL procedures.
Example Some procedures can be called without any parameters. For example:
ERASE
This is a procedure call to a subroutine to erase the screen. There are no
explicit inputs or outputs. Other procedures have one or more parameters.
For example, the statement:
PLOT, CIRCLE
calls the PLOT procedure with the parameter CIRCLE.
Parameter Passing
Parameters passed to procedures and functions are identified by their position or
by a keyword. As their name indicates, the position of positional parameters
establishes the correspondence of the parameters in the call and those in the
definition of the procedure or function. A keyword parameter is a parameter
preceded by a keyword and “=” that identifies the parameter.
Parameters are passed by value or by reference. Parameters that consist of only a
variable name are passed by reference. Expressions, constants, and system
variables are passed by value. The two passing mechanisms are fundamentally
different. The called procedure or function cannot return a value in a parameter
that is passed by value, as the value of the parameter is evaluated and passed into
the called procedure, but is not copied back to the caller. Changes made by the
called procedure are passed back to the caller if the parameter is passed by
reference. See “Parameter Passing Mechanism” on page 120.
Parameters can be of any type or structure, although some system procedures, as
well as user-defined procedures, may require a particular type of parameter for a
specific argument. Parameters also can be expressions which are evaluated, used
in the call, and then discarded. For example:
PLOT, SIN(CIRCLE)
The sine of the array CIRCLE is computed and plotted, then the result of the
computation is discarded.
Building IDL Applications
Procedure Call Statement
106
Chapter 7: Statements
Keyword Parameters
A keyword parameter is a parameter preceded by a keyword and “=” that
identifies the parameter.
For example, the PLOT procedure can be manipulated to retain, rather than
erase, the image on the screen, as well as to draw, using color index 12.
Accomplish these tasks with either of the following calls:
PLOT, X, Y, NOERASE = 1, COLOR = 12
or
PLOT, X, Y, COL = 12, /NOERASE
The two calls produce identical code. Keywords can be abbreviated to the shortest
nonambiguous string. The construct /KEYWORD is equivalent to setting the
keyword parameter to the value 1. For example, /NOERASE is equivalent to
NOERASE = 1. In the above examples, the parameter X is the first positional
parameter because it is not preceded by a keyword. The parameter Y is the second
positional parameter.
The interpretation of keyword arguments is independent of their order. The
placement of keyword arguments does not affect the interpretation of positional
parameters—keyword parameters can appear before, after, or in the middle of
the positional parameters.
Keyword parameters offer the following advantages over positional parameters:
•
Procedures and functions can have a large number of arguments, any of which
may be optional. Only those arguments that are actually used need be present in
the call.
•
It is much easier to remember the names of keyword arguments than to remember
the order of positional arguments.
•
Additional features can be added to existing procedures and functions without
changing the meaning or interpretation of other arguments.
Procedure Definition Statement
PRO Procedure_Name, Parameter1, Parameter2, ..., Parametern
A sequence of one or more IDL statements can be given a name, compiled, and
saved for future use with the procedure definition statement. Once a procedure
has been successfully compiled, it can be executed using a procedure call
statement interactively from the terminal, from a main program, or from another
procedure or function.
Procedure Definition Statement
Building IDL Applications
Chapter 7: Statements
107
The general format for the definition of a procedure is as follows:
PRO Name, Parameter1, ..., Parametern
Statement1
Statements defining procedure.
Statement2
...
End of procedure definition.
END
For more detail on defining procedures see “Defining Procedures and Functions”
on page 109.
Calling a user-written procedure that is in a directory in the IDL search path
(!PATH) causes the procedure to be read from the disk, compiled, and executed
without interrupting program execution.
REPEAT Statement
REPEAT Subject_Statement UNTIL Condition_Expression
The REPEAT statement repetitively executes its subject statement until a
condition is true. The condition is checked after the subject statement is executed.
Therefore, the subject statement is always executed at least once.
Example Some examples of how the REPEAT statement can be used are as follows:
A = 1
B = 10
REPEAT A = A * 2 UNTIL A GT B
This code finds the smallest power of 2 that is greater than B. The subject
statement can also be in the form of a block:
REPEAT BEGIN
NOSWAP = 1
Sort array.
Set flag to true.
FOR I = 0, N - 2 DO IF ARR[I] GT ARR[I + 1]THEN BEGIN
NOSWAP = 0
Swapped elements, clear flag.
T = arr[I] & arr[I] = arr[I + 1] & arr[I + 1] = T
ENDIF
ENDREP UNTIL NOSWAP
Keep going until nothing is moved.
The above example sorts the elements of ARR using the inefficient bubble sort
method. A more efficient way to sort elements is to use IDL’s SORT function.
Building IDL Applications
REPEAT Statement
108
Chapter 7: Statements
WHILE Statement
WHILE Expression DO Statement
WHILE statements are used to execute a statement repeatedly while a condition
remains true. The WHILE statement is similar to the REPEAT statement except
that the condition is checked prior to the execution of the statement.
When the WHILE statement is executed, the conditional expression is tested, and
if it is true, the statement following the DO is executed. Control then returns to
the beginning of the WHILE statement, where the condition is again tested. This
process is repeated until the condition is no longer true, at which point the
control of the program resumes at the next statement.
In the WHILE statement, the subject is never executed if the condition is initially
false.
Example An example of a WHILE statement follows:
WHILE NOT EOF(1) DO READF, 1, A, B, C
In this example, data are read until the end-of-file is encountered.
The next example demonstrates one way to find the first point of an array
greater than or equal to a selected value assuming the array is sorted into
ascending order.
I = 0
Initialize index.
WHILE (arr[I] LT X) AND (I LT N) DO I = I + 1
Increment X until a point larger
than X is found or the end of the
array is reached
Another way to accomplish the same thing is with the WHERE command,
which is used to find the subscripts of the points where ARR[I] is greater than
or equal to X.
WHILE Statement
P = WHERE(arr GE X)
Subscripts of elements of arr that
are greater than or equal to X.
I = P(0)
Save first subscript.
Building IDL Applications
Chapter 8
Defining Procedures
and Functions
The following topics are covered in this chapter:
Procedure & Function Definitions ...... 110
Parameters.......................................... 110
Using Keyword Parameters ................. 113
Keyword Inheritance ........................... 114
Entering Procedure Definitions............ 118
Parameter Passing Mechanism ............ 120
Calling Mechanism ............................. 121
109
110
Chapter 8: Defining Procedures and Functions
Procedures and functions are self-contained modules that break large tasks into
smaller, more manageable ones. Modular programs simplify debugging and
maintenance and, because they are reusable, minimize the amount of new code
required for each application.
New procedures and functions can be written in IDL and called in the same
manner as the system-defined procedures or functions from the keyboard or
from other programs. When a procedure or function is finished, it executes a
RETURN statement that returns control to its caller. Functions always return an
explicit result. A procedure is called by a procedure call statement, while a
function is called by a function reference. For example, if ABC is a procedure and
XYZ is a function, the calling syntax is:
ABC, A, 12
Call procedure ABC with two parameters.
A = XYZ(C/D)
Call function XYZ with one parameter. The result of XYZ is
stored in variable A.
Procedure & Function Definitions
The procedure and function definition statements notify the IDL compiler that a
user-written program module follows. One of these statements must be the first
line in a user-written IDL routine.
The PRO statement defines an IDL procedure. Its syntax is:
PRO Procedure_Name, P1, P2, ..., Pn
The FUNCTION statement defines an IDL function. It’s syntax is:
FUNCTION Function_Name, P1, P2, ..., Pn
Parameters
The variables and expressions passed to the function or procedure from its caller
are parameters. Actual parameters are those appearing in the procedure call
statement or the function reference. In the examples above, the actual parameters
in the procedure call are the variable A and the constant 12, while the actual
parameter in the function call is the value of the expression (C/D).
Formal parameters are the variables declared in the procedure or function
definition. The same procedure or function can be called using different actual
parameters from a number of places in other program units.
Procedure & Function Definitions
Building IDL Applications
Chapter 8: Defining Procedures and Functions
111
Correspondence of Formal and Actual Parameters
The correspondence between the actual parameters of the caller and the formal
parameters of the called procedure is established by position or by keyword.
Positional Parameters
A positional parameter, or plain argument, is a parameter without a keyword. Just
as its name implies, the position of a positional parameter establishes the
correspondence—the n-th formal positional parameter is matched with the n-th
actual positional parameter.
Keyword Parameters
A keyword parameter, which can be either actual or formal, is an expression or
variable name preceded by a keyword and an equal sign (“=”) that identifies
which parameter is being passed.
When calling a routine with a keyword parameter, you can abbreviate the
keyword to its shortest, unambiguous abbreviation. Keyword parameters can
also be specified by the caller with the syntax /KEYWORD, which is equivalent to
setting the keyword parameter to 1 (e.g., KEYWORD = 1). The syntax
/KEYWORD is often referred to, in the rest of this documentation, as setting the
keyword.
Example A procedure is defined with a keyword parameter named TEST.
PRO XYZ, A, B, TEST = T
The caller can supply a value for the formal (keyword) parameter T with the
following calls:
XYZ, TEST = A
Supply only the value of T. A and
B are undefined inside the procedure.
XYZ, TE = A, Q, R
The value of A is copied to formal
parameter T (note the abbreviation for TEST), Q to A, and R to B.
XYZ, Q
Variable Q is copied to formal parameter A. B and T are undefined
inside the procedure.
Note When supplying keyword parameters for a function, the keyword is specified
inside the parentheses:
result = FUNCTION(Arg1, Arg2, KEYWORD = value)
Building IDL Applications
Parameters
112
Chapter 8: Defining Procedures and Functions
Copying Parameters
When a procedure or function is called, the actual parameters are copied into the
formal parameters of the procedure or function and the module is executed.
On exit, via a RETURN statement, the formal parameters are copied back to the
actual parameters, providing they were not expressions or constants. Parameters
can be inputs to the program unit; they can be outputs in which the values are set
or changed by the program unit; or they can be both inputs and outputs.
When a RETURN statement is encountered in the execution of a procedure or
function, control is passed back to the caller immediately after the point of the
call. In functions, the parameter of the RETURN statement is the result of the
function.
Number of Parameters
A procedure or a function can be called with fewer arguments than were defined
in the procedure or function. For example, if a procedure is defined with 10
parameters, the user or another procedure can call the procedure with 0 to 10
parameters.
Parameters that are not used in the actual argument list are set to be undefined
upon entering the procedure or function. If values are stored by the called
procedure into parameters not present in the calling statement, these values are
discarded when the program unit exits. The number of actual parameters in the
calling list can be found by using the system function N_PARAMS. Use the
N_ELEMENTS function to determine if a variable is defined.
Example
An example of an IDL function to compute the digital gradient of an image is
shown in the example below. The digital gradient approximates the twodimensional gradient of an image and emphasizes the edges.
This simple function consists of three lines corresponding to the three required
components of IDL procedures and functions: the procedure or function
declaration, the body of the procedure or function, and the terminating end
statement.
FUNCTION GRAD, image
Define a function called GRAD.
dz + dz .
Result is --------dx
dy
RETURN, ABS(image - SHIFT(image, 1, 0)) + $
ABS(image-SHIFT(image, 0, 1)) Evaluate and return the result.
END
Parameters
End of function.
Building IDL Applications
Chapter 8: Defining Procedures and Functions
113
The function has one parameter called IMAGE. There are no local variables.
Local variables are variables active only within a module (i.e., they are not
parameters and are not contained in common blocks).
The result of the function is the value of the expression used as an argument to
the RETURN statement. Once compiled, the function is called by referring to it
in an expression. Two examples are shown below.
A = GRAD(B)
Store gradient of B in A.
TVSCL, GRAD(abc + def)
Display gradient of IMAGE sum.
Using Keyword Parameters
A short example of a function that exchanges two columns of a 4 × 4
homogeneous, coordinate-transformation matrix is shown below. The function
has one positional parameter, the coordinate-transformation matrix T. The caller
can specify one of the keywords XYEXCH, XZEXCH, or YZEXCH to interchange
the xy, xz, or yz axes of the matrix. The result of the function is the new coordinate
transformation matrix defined below.
FUNCTION SWAP, T, XYEXCH = xy, XZEXCH = xz, YZEXCH = yz
Function to swap columns of T.
XYEXCH swaps columns 0 and 1,
XZEXCH swaps 0 and 2, and
YZEXCH swaps 1 and 2.
IF KEYWORD_SET(XY) THEN S=[0,1] $
Swap columns 0 and 1 if keyword
XYEXCH is set.
ELSE IF KEYWORD_SET(XZ) THEN S=[0,2] $
Check to see if xz is set.
ELSE IF KEYWORD_SET(YZ) THEN S=[1,2] $
Check to see if yz is set.
ELSE RETURN, T
If nothing is set, return.
R = T
Copy matrix for result.
R[S[1], 0] = T[S[0], *]
Exchange two columns using matrix insertion operators and subscript ranges.
R[S[0], 0] = T[S[1], *]
RETURN, R
Return result.
END
Building IDL Applications
Using Keyword Parameters
114
Chapter 8: Defining Procedures and Functions
Typical calls to SWAP are as follows:
Q = SWAP(!P.T, /XYEXCH)
Q = SWAP(Q, /XYEX)
Q = SWAP(INVERT(Z), YZ = 1)
Q = SWAP(Z, XYE = I EQ 0, XZE = I EQ 1, YZE = I EQ 2)
Note that keyword names can abbreviated to the shortest unambiguous string.
The last example sets one of the three keywords according to the value of the
variable I.
This function example uses the system function KEYWORD_SET to determine if
a keyword parameter has been passed and if it is nonzero. This is similar to using
the condition:
IF N_ELEMENTS(P) NE 0 THEN IF P THEN ... ...
to test if keywords that have a true/false value are both present and true.
Keyword Inheritance
Keyword inheritance allows IDL routines to accept keyword parameters not
defined in their function or procedure declaration and pass them on to routines
they call. This greatly simplifies writing “wrapper” routines, which are variations
of a system or user-provided routine. Specifically, keyword inheritance allows
your routines to accept keywords accepted by routines that it calls without
explicitly handling each keyword individually.
There are two distinct mechanisms to handle keyword inheritance: one to pass
keyword parameters by value, and another to pass keyword parameters by
reference.
_EXTRA: Passing Keyword Parameters by Value
You can pass keyword parameters to called routines by value by adding the formal
keyword parameter “_EXTRA” (note the underscore character) to the definition
of your routine. Passing parameters by value means that you are giving the called
routine the contents of an existing IDL variable to work with. In turn, this means
that keyword parameters passed into a routine by value cannot be returned to the
calling routine — there is no variable name into which the value can be placed.
When a routine is defined with the formal keyword parameter _EXTRA, pairs of
unrecognized keywords and values are placed in an anonymous structure. The
name of each unrecognized keyword becomes a tag name, and the keyword value
Keyword Inheritance
Building IDL Applications
Chapter 8: Defining Procedures and Functions
115
becomes the tag value. Changes to this structure created by using the _EXTRA
keyword do not affect variables in the calling program.
When the keyword _EXTRA appears in a procedure or function call, its argument
is either a structure containing additional keyword/value pairs which are inserted
into the argument list, or a string array as described in the next section. The value
of _EXTRA can also be “undefined”, indicating that no additional keyword
parameters were passed.
_REF_EXTRA: Passing Keyword Parameters by Reference
You can pass keyword parameters to called routines by reference by adding the
formal keyword parameter “_REF_EXTRA” (note the underscore character) to
the definition of your routine. Passing parameters by reference means that you
are giving the called routine the name of an existing IDL variable to work with;
IDL takes care of keeping track of the value associated with the name. The values
of keyword parameters specified via _REF_EXTRA are not available to the routine
that is passing the keywords on.
When a routine is defined with the formal keyword parameter _REF_EXTRA,
pairs of unrecognized keywords and values are placed in a storage location that is
accessible to both calling and called routines, and the keyword names are placed
in an IDL string array. The string array can be “deciphered” using the _EXTRA
keyword, which matches the names in the string with the “live” values in the
storage location. This means that if the keywords specify IDL variables, the values
of those variables can be altered by any routine that has access to the variable via
the keyword inheritance mechanism. In this fashion, the values of keyword
parameters can be changed within a routine and passed back to the routine’s
caller.
The “pass by reference” keyword inheritance mechanism is especially useful
when writing object methods, which may be inherited multiple times and which
often wish to change the value of variables available to the calling method. (The
values of object properties are one example of data that can profitably be shared
by objects at various levels in an object hierarchy.)
Accepting Extra Keyword Parameters
While you must choose whether a routine will pass extra keyword parameters by
value or by reference when defining the routine (specifying both _EXTRA and
_REF_EXTRA as formal parameters will cause an error), routines that accept extra
keyword parameters can use either the _EXTRA keyword or the _REF_EXTRA
keyword. However, it is not possible to both have access to the keyword values
and pass them along to called routines by reference within the same routine. This
means that any routine that needs access to the passed keyword parameters must
use _EXTRA in its definition statement, or define the keyword explicitly itself.
Building IDL Applications
Keyword Inheritance
116
Chapter 8: Defining Procedures and Functions
Selective Keyword Redirection
If extra keyword parameters have been passed by reference, you can direct
different inherited keywords to different routines by specifying a string or array
of strings containing keyword names via the _EXTRA keyword. For example,
suppose that we write a procedure named SOMEPROC that passes extra
keywords by reference:
PRO SOMEPROC, _REF_EXTRA = ex
ONE, _EXTRA=[’MOOSE’, ’SQUIRREL’]
TWO, _EXTRA=’SQUIRREL’
END
If we call the SOMEPROC routine with three keywords:
SOMEPROC, MOOSE=moose, SQUIRREL=3, SPY=PTR_NEW(moose)
•
it will pass the keywords MOOSE and SQUIRREL and their values (the IDL variable
moose and the integer 3, respectively) to procedure ONE,
•
it will pass the keyword SQUIRREL at its value to procedure TWO,
•
it will do nothing with the keyword SPY.
Choosing a Keyword Inheritance Mechanism
The “pass by reference” (_REF_EXTRA) keyword inheritance mechanism was
introduced in IDL version 5.1, and in many cases is a good choice even if values
are not being passed back to the calling routine. Because the _REF_EXTRA
mechanism does not create an IDL structure to hold the keyword/value pairs,
overhead is slightly reduced. Two situations lend themselves to use of the
_REF_EXTRA mechanism:
1. You need to pass the values of keyword variables back from a called routine to the
calling routine.
2. Your routine is an “inner loop” routine that may be called many times. If the
routine is called repeatedly, the savings resulting from not creating a new IDL
structure with each call may be significant.
It is important to remember that if the routine that is passing the keyword values
through also needs access to the values of the keywords for some reason, you
must use the “pass by value” (_EXTRA) mechanism.
Note Updating existing routines that use _EXTRA to use _REF_EXTRA is relatively
easy. Since the called routine uses _EXTRA to receive the extra keywords in
Keyword Inheritance
Building IDL Applications
Chapter 8: Defining Procedures and Functions
117
either case, you need only change the _EXTRA to _REF_EXTRA in the definition of the calling routine.
By contrast, the “pass by value” (_EXTRA) keyword inheritance mechanism is
useful in the following situations:
1. Your routine needs access to the values of the extra keywords for some reason.
2. You want to ensure that variables specified as keyword parameters are not changed
by a called routine.
Example: Keywords Passed by Value
One of the most common uses for the “pass by value” keyword inheritance
mechanism is to create “wrapper” routines that extend the functionality of
existing routines. In most “wrapper” routines, there is no need to return values
to the calling routine — the aim is simply to implement the complete set of
keywords available to the existing routine in the wrapper routine.
For example, suppose that procedure TEST is a wrapper to the PLOT command.
The text of such a procedure is shown below:
PRO TEST, a, b, _EXTRA = e, COLOR = color
PLOT, a, b, COLOR = color, _EXTRA = e
END
The procedure definition:
PRO TEST, a, b, _EXTRA = e, COLOR = color
places unrecognized keywords (e.g., any keywords other than COLOR) and their
values into the variable “e”. If there are no unrecognized keywords, e will be
undefined.
When procedure TEST is called with the following command:
TEST, x, y, COLOR=3, LINESTYLE = 4, THICK=5
variable “e”, within TEST, contains an anonymous structure with the value:
{ LINESTYLE: 4, THICK: 5 }
These keyword/value pairs are then be passed from TEST to the PLOT routine
using the _EXTRA keyword:
PLOT, a, b, COLOR = color, _EXTRA = e
Note that keywords passed into a routine via _EXTRA override previous settings
of that keyword. For example, the call:
PLOT, a, b, COLOR = color, _EXTRA = {COLOR: 12}
Building IDL Applications
Keyword Inheritance
118
Chapter 8: Defining Procedures and Functions
specifies a color index of 12 to PLOT.
Example: Keywords Passed by Reference
The “pass by reference” keyword inheritance mechanism allows you to change
the value of a variable in the calling routine’s context from within the routine. To
demonstrate the difference between _EXTRA and _REF_EXTRA, consider the
following simple example procedures:
PRO TEST1, _EXTRA = ex
HELP, _EXTRA = ex
END
PRO TEST2, _REF_EXTRA = ex
HELP, _EXTRA = ex
END
Both TEST1 and TEST2 are simple wrappers to the HELP procedure. Observe the
result when we call each routine, specifying OUTPUT as an extra keyword
parameter, then use the HELP procedure again to determine the value of the
output variable:
TEST1, OUTPUT = out & HELP, out
IDL prints:
% At
TEST1
2 /dev/tty
%
$MAIN$
EX
UNDEFINED = <Undefined>
Compiled Procedures:
$MAIN$
TEST1
Compiled Functions:
Now run TEST2:
TEST2, OUTPUT = out & HELP, out
IDL prints:
OUT
STRING
= Array[8]
Entering Procedure Definitions
Procedures and functions are compiled using the .RUN or .COMPILE executive
commands. The format of these commands is as follows:
Entering Procedure Definitions
Building IDL Applications
Chapter 8: Defining Procedures and Functions
119
.RUN File1 [, Filen, ... ]
.COMPILE File1 [, Filen, ... ]
From 1 to 10 files, each containing one or more program units, can be compiled.
For more information on the .RUN and .COMPILE commands, see “Executive
Commands” on page 31 of the IDL Reference Guide.
To enter program text directly from the keyboard, simply enter .RUN at the
IDL> prompt. IDL will prompt with the “-” character, indicating that it is
compiling a directly entered program. As long as IDL requires more text to
complete a program unit, it prompts with the “-”character. Rather than executing
statements immediately after they are entered, IDL compiles the program unit as
a whole.
Procedure and function definition statements cannot be entered in the singlestatement mode, but must be prefaced by either .RUN or .RNEW.
The first non-empty line the IDL compiler reads determines the type of the
program unit: procedure, function, or main program. If the first non-empty line
is not a procedure or function definition statement, the program unit is assumed
to be a main program. The name of the procedure or function is given by the
identifier following the keyword PRO or FUNCTION. If a program unit with the
same name is already compiled, it is replaced by the new program unit.
Note Regarding Functions
User-defined functions, with the exception of those contained in directories
specified by the IDL system variable !PATH, must be compiled before the first
reference to the function is compiled. This is necessary because the IDL compiler
is unable to distinguish between a reference to a variable subscripted with
parentheses and a call to a presently undefined user function with the same name.
For example, in the statement
A = XYZ(5)
it is impossible to tell by context alone if XYZ is an array or a function.
Note In versions of IDL prior to version 5.0, parentheses were used to enclose array
subscripts. While using parentheses to enclose array subscripts will continue
to work as in previous version of IDL, we strongly suggest that you use
brackets in all new code. See “Array Subscript Syntax: [ ] vs. ( )” on page 60
for additional details.
When IDL encounters references that may be either a function call or a
subscripted variable, it searches the current directory, then the directories
specified by !PATH, for files with names that match the unknown function or
variable name. If one or more files matching the unknown name exist, IDL
Building IDL Applications
Entering Procedure Definitions
120
Chapter 8: Defining Procedures and Functions
compiles them before attempting to evaluate the expression. If no function or
variable with the given name exists, IDL displays an error message.
There are several ways to avoid this problem:
•
Compile the lowest-level functions (those that call no other functions) first, then
higher-level functions, and finally procedures.
•
Place the function in a file with the same name as the function, and place that file
in one of the directories specified by !PATH.
•
Use the FORWARD_FUNCTION definition statement to inform IDL that a given
name refers to a function rather than a variable. See “Forward Function Definition” on page 101.
•
Manually compile all functions before any reference, or use RESOLVE_ROUTINE
or RESOLVE_ALL to compile functions.
Parameter Passing Mechanism
Parameters are passed to IDL system and user-written procedures and functions
by value or by reference. It is important to recognize the distinction between these
two methods.
•
Expressions, constants, system variables, and subscripted variable references are
passed by value.
•
Variables are passed by reference.
Parameters passed by value can only be inputs to program units. Results cannot
be passed back to the caller by these parameters. Parameters passed by reference
can convey information in either or both directions. For example, consider the
following trivial procedure:
PRO ADD, A, B
A = A + B
RETURN
END
This procedure adds its second parameter to the first, returning the result in the
first. The call
ADD, A, 4
adds 4 to A and stores the result in variable A. The first parameter is passed by
reference and the second parameter, a constant, is passed by value.
The following call does nothing because a value cannot be stored in the constant
4, which was passed by value.
Parameter Passing Mechanism
Building IDL Applications
Chapter 8: Defining Procedures and Functions
121
ADD, 4, A
No error message is issued. Similarly, if ARR is an array, the call
ADD, ARR[5], 4
will not achieve the desired effect (adding 4 to element ARR[5]), because
subscripted variables are passed by value. The correct, though somewhat
awkward, method is as follows:
TEMP = ARR[5]
ADD, TEMP, 4
ARR[5] = TEMP
Note IDL structures behave in two distinct ways. Entire structures are passed by
reference, but individual structure fields are passed by value. See “Parameter
Passing with Structures” on page 47 for additional details.
Calling Mechanism
When a user-written procedure or function is called, the following actions occur:
1. All of the actual arguments in the user-procedure call list are evaluated and saved
in temporary locations.
2. The actual parameters that were saved are substituted for the formal parameters
given in the definition of the called procedure. All other variables local to the called
procedure are set to undefined.
3. The function or procedure is executed until a RETURN or RETALL statement is
encountered. Procedures also can return on an END statement. The result of a
user-written function is passed back to the caller by specifying it as the value of a
RETURN statement. RETURN statements in procedures cannot specify a return
value.
4. All local variables in the procedure, those variables that are neither parameters
nor common variables, are deleted.
5. The new values of the parameters that were passed by reference are copied back
into the corresponding variables. Actual parameters that were passed by value are
deleted.
6. Control resumes in the calling procedure after the procedure call statement or
function reference.
Building IDL Applications
Calling Mechanism
122
Chapter 8: Defining Procedures and Functions
Recursion
Recursion (i.e., a program calling itself) is supported for both procedures and
functions.
Example
Here is an example of an IDL procedure that reads and plots the next vector from
a file. This example illustrates using common variables to store values between
calls, as local parameters are destroyed on exit. It assumes that the file containing
the data is open on logical unit 1 and that the file contains a number of 512element, floating-point vectors.
PRO NXT, recno
Read and plot the next record from
file 1. If RECNO is specified, set the
current record to its value and plot
it.
COMMON NXT_COM, lastrec
Save previous record number.
IF N_PARAMS(0) GE 1 THEN lastrec = recno
Set record number if parameter is
present.
IF N_ELEMENTS(lastrec) LE 0 THEN lastrec = 0
Define LASTREC if this is first call.
AA = ASSOC(1, FLTARR(512))
Define file structure.
PLOT, AA[lastrec]
Read and plot record.
lastrec = lastrec + 1
Increment record for next time.
RETURN A
All finished.
END
Once the user has opened the file, typing NXT will read and plot the next record.
Typing NXT, N will read and plot record number N.
Calling Mechanism
Building IDL Applications
Chapter 9
Writing IDL
Programs
The following topics are covered in this chapter:
Informational Routines ....................... 124
Program Control Routines................... 128
Expression Evaluation Order................ 130
Avoid IF Statements ............................ 131
Use Vector and Array Operations......... 132
IDL System Functions & Procedures ... 133
Use Constants of the Correct Type ..... 134
Eliminate Invariant Expressions ........... 134
Virtual Memory .................................. 135
IDL Implementation ........................... 139
123
124
Chapter 9: Writing IDL Programs
While IDL is useful as an ad hoc, interactive data analysis tool, it is also a powerful
programming language. This chapter discusses routines that are useful when
writing programs—from simple procedures and functions to large applications—
in the IDL language, and presents ideas to consider when trying to create the
most efficient programs possible. The routines discussed in this chapter are
useful primarily (though not exclusively) in IDL procedures and functions. These
routines are rarely used interactively. They provide information about variables
and expressions and give the programmer control over program operation.
Routines dealing with error control and handling are discussed in the next
chapter, “Controlling Errors.”
Knowledge of IDL’s implementation and the pitfalls of virtual memory can be
used to greatly improve the efficiency of IDL programs. In IDL, complicated
computations can be specified at a high level. Therefore, inefficient IDL
programs can suffer severe speed penalties — perhaps much more so than with
most other languages.
Techniques for writing efficient programs in IDL are identical to those in other
computer languages with the addition of the following simple guidelines:
•
Use array operations rather than loops wherever possible. Try to avoid loops with
high repetition counts.
•
Use IDL system functions and procedures wherever possible.
•
Access array data in machine address order.
Attention also must be given to algorithm complexity and efficiency, as this is
usually the greatest determinant of resources used.
Informational Routines
Informational routines return information about variables, expressions,
parameters, etc. The routines KEYWORD_SET, N_ELEMENTS, N_PARAMS,
and SIZE are useful in procedures and functions to check if arguments are
supplied. Procedures should be written to check that all required arguments are
supplied and to supply reasonable default values for missing optional parameters.
In addition, TAG_NAMES and N_TAGS, which are discussed in “Advanced
Structure Usage” on page 53, supply information about structure variables.
ARG_PRESENT Function
The ARG_PRESENT function returns TRUE if its parameter will be passed back
to the caller. This function is useful in user-written procedures to determine if a
created value remains within the scope of the calling routine. ARG_PRESENT
Informational Routines
Building IDL Applications
Chapter 9: Writing IDL Programs
125
helps the caller avoid expensive computations and prevents heap leaks. For
example, assume that a procedure exists which depends upon an argument
passed by the caller:
PRO pass_it, i
If the caller does not specify i, the program may not function properly. You can
check to make sure that an argument was specified by using the following
statement:
IF ARG_PRESENT(i) THEN BEGIN
KEYWORD_SET Function
The KEYWORD_SET function returns a 1 (true), if its parameter is defined and
nonzero; otherwise, it returns zero (false). For example, assume that a procedure
is written which performs and returns the result of a computation. If the keyword
PLOT is present and nonzero, the procedure also plots its result as follows:
PRO XYZ, result, PLOT = plot
...
Procedure definition.
Compute result.
IF KEYWORD_SET(PLOT) THEN PLOT, result
Plot result if keyword parame-
ter is set.
END
A call to this procedure that produces a plot is shown in the following statement.
XYZ, R, /PLOT
N_ELEMENTS Function
The N_ELEMENTS function returns the number of elements contained in any
expression or variable. Scalars always have one element. The number of elements
in arrays or vectors is equal to the product of the dimensions. The N_ELEMENTS
function returns zero if its parameter is an undefined variable. The result is always
a longword scalar.
For example, the following expression is equal to the mean of a numeric vector
or array.
TOTAL(arr) / N_ELEMENTS(arr)
The N_ELEMENTS function provides a convenient method of determining if a
variable is defined. The following statement sets the variable abc to zero if it is
undefined; otherwise, the variable is not changed.
IF N_ELEMENTS(abc) EQ 0 THEN abc = 0
Building IDL Applications
Informational Routines
126
Chapter 9: Writing IDL Programs
N_ELEMENTS is frequently used to check for omitted plain and keyword
arguments. N_PARAMS cannot be used to check for the number of keyword
arguments because it returns only the number of plain arguments. An example
of using N_ELEMENTS to check for a keyword parameter is as follows:
PRO ZOOM, image, FACTOR = factor
Display an image with a given
zoom factor. If factor is omitted,
use 4.
IF N_ELEMENTS(factor) EQ 0 THEN factor = 4
Supply default for missing keyword parameter.
Note If you use this method, the variable factor is defined has having the value
4, even though no value was supplied by the user. If the ZOOM procedure
were called within another routine, the variable factor would be defined for
that routine and for any other routines also called by the routine that called
ZOOM. This can lead to unexpected behavior if you pass arguments from
one routine to another.
You can avoid this problem by using different variable names inside the
routine than are used in calling the routine. For example, if you wanted to
supply a default zoom factor in the example above, but did not want to change
the value of factor, you could use an approach similar to the following:
IF N_ELEMENTS(factor) EQ 0 THEN zoomfactor = 4 $
ELSE zoomfactor = factor
You would then set the zoom factor internally using the zoomfactor variable, leaving factor itself unchanged.
N_PARAMS Function
The N_PARAMS function returns the number of positional arguments (not
keyword arguments) present in a procedure or function call. A frequent use is to
call N_PARAMS to determine if all arguments are present and if not, to supply
default values for missing parameters. For example:
PRO XPRINT, XX, YY
CASE N_PARAMS() OF
1: BEGIN
Informational Routines
Print values of XX and YY. If XX
is omitted, print values of YY versus element number.
Check number of arguments.
Single-argument case.
Y = XX
First argument is y values.
X = INDGEN(N_ELEMENTS(Y))
Create vector of subscript indices.
Building IDL Applications
Chapter 9: Writing IDL Programs
127
END
2: BEGIN
Y = YY & X = XX
Two-argument case.
Copy parameters to local arguments.
END
ELSE: MESSAGE, ’Wrong number of arguments’
Print error message.
ENDCASE
Remainder of procedure.
...
END
SIZE Function
The SIZE function returns a vector that contains information indicating the size
and type of the parameter. The returned vector is always of longword type. The
first element is equal to the number of dimensions of the parameter and is zero if
the parameter is a scalar. The following elements contain the size of each
dimension. After the dimension sizes, the last two elements indicate the type of
the parameter and the total number of elements, respectively. The type is
encoded as follows:
Type Code
Data Type
0
Undefined
1
Byte
2
Integer (16-bit)
3
Longword integer (32-bit)
4
Floating point
5
Double-precision floating
6
Complex floating
7
String
8
Structure
9
Double-precision complex floating
10
Pointer
11
Object reference
12
Unsigned integer (16-bit)
Table 9-1: Type Codes Returned by the SIZE Function
Building IDL Applications
Informational Routines
128
Chapter 9: Writing IDL Programs
Type Code
Data Type
13
Unsigned longword integer (32-bit)
14
64-bit integer
15
Unsigned 64-bit integer
Table 9-1: Type Codes Returned by the SIZE Function
Examples
Assume A is an integer array with dimensions of (3,4,5). The statements:
arr = INDGEN(3,4,5)
S = SIZE(arr)
assigns to the variable, S, a six-element vector containing:
S0
3
Three dimensions
S1
3
First dimension
S2
4
Second dimension
S3
5
Third dimension
S4
2
Integer type
S5
60
Number of elements = 3*4*5
A code segment that checks to see if a variable (arr) is two-dimensional and
extracts the dimensions is shown below.
arr = [[1,2,3],[4,5,6]]
Create a variable.
S = SIZE(arr)
Get size vector.
IF S[0] NE 2 THEN $
Check if two dimensional.
MESSAGE, ’Variable a is not two dimensional.’
Print error message.
NX = S[1] & NY = S[2]
Get number of columns and rows.
PRINT, ’Array is ’, NX, ’ columns by ’, NY, ’ rows.’
Program Control Routines
IDL provides the following routines to control the flow of an IDL program:
CALL_FUNCTION, CALL_PROCEDURE, EXECUTE, EXIT, STOP, and WAIT.
Program Control Routines
Building IDL Applications
Chapter 9: Writing IDL Programs
129
The program control procedures are largely self-explanatory with the exception
of the EXECUTE function. CALL_FUNCTION and CALL_PROCEDURE are
used to indirectly call functions and procedures whose names are contained in
strings. The EXIT procedure exits the IDL session. STOP halts execution of a
program or batch file and prints the values of its optional parameters. WAIT, as
its name implies, pauses execution for a given amount of time specified in
seconds.
CALL_FUNCTION and CALL_PROCEDURE
CALL_FUNCTION and CALL_PROCEDURE are used to indirectly call
functions and procedures whose names are contained in strings.
CALL_FUNCTION calls the IDL function specified, passing any additional
parameters as its arguments. The result of the called function is passed back as
the result of the routine. CALL_PROCEDURE calls the procedure, passing any
additional parameters as its arguments.
Although not as flexible as the EXECUTE function, CALL_FUNCTION and
CALL_PROCEDURE are much faster, and should be used in preference to
EXECUTE whenever possible.
EXECUTE
The EXECUTE function compiles and executes one or more IDL statements
contained in its string parameter during runtime.
EXECUTE is limited by two factors:
•
Calls to EXECUTE cannot be nested, so a routine called by EXECUTE cannot use
EXECUTE itself.
•
The need to compile the string at runtime makes EXECUTE inefficient in terms
of speed.
The CALL_FUNCTION and CALL_PROCEDURE routines provide much of the
functionality of EXECUTE without imposing these limitations and should be
used in preference to EXECUTE when possible.
The result of the EXECUTE function is true (1) if the string was successfully
compiled and executed. If an error occurred during either phase, the result is false
(0). If an error occurs, an error message is printed.
Multiple statements in the string should be separated with the “&” character.
GOTO statements and labels are not allowed.
Building IDL Applications
Program Control Routines
130
Chapter 9: Writing IDL Programs
Example
This example code fragment, taken from the routine SVDFIT, calls a function
whose name is passed to SVDFIT via a keyword parameter as a string. If the
keyword parameter is omitted, the function POLY is called.
FUNCTION SVDFIT,..., FUNCT = funct
Function declaration.
...
IF N_ELEMENTS(FUNCT) EQ 0 THEN FUNCT = ’POLY’
Use default name, POLY, for function if not specified.
Z = EXECUTE(’A = ’+FUNCT+’(X,M)’)
Make a string of the form “a =
funct(x,m)”, and execute it.
...
The above example is easily made more efficient by replacing the call to
EXECUTE with the following line:
A = CALL_FUNCTION(FUNCT, X, M)
EXIT
The EXIT procedure quits IDL and exits back to the operating system. All buffers
are flushed and open files are closed. The values of all variables that were not
saved are lost.
STOP
The STOP procedure stops the execution of a running program or batch file.
Control reverts to the interactive mode.
WAIT
The WAIT procedure suspends execution of an IDL program for a specified
period. Note that because of other activity on the system, the duration of
program suspension may be longer than requested.
Expression Evaluation Order
The order in which an expression is evaluated can have a significant effect on
program speed. Consider the following statement, where A is an array:
B = A * 16. / MAX(A)
Expression Evaluation Order
Scale A from 0 to 16.
Building IDL Applications
Chapter 9: Writing IDL Programs
131
This statement first multiplies every element in A by 16 and then divides each
element by the value of the maximum element. The number of operations
required is twice the number of elements in A. A much faster way of computing
the same result is used in the following statement:
B = A * (16./MAX(A))
Scale A from 0 to 16 using only one
array operation.
or
B = 16./MAX(A) * A
Operators of equal priority are
evaluated from left to right. Only
one array operation is required.
The faster method only performs one operation for each element in A, plus one
scalar division. To see the speed difference on your own machine, execute the
following statements:
A = RANDOMU(seed, 512, 512)
t1 = SYSTIME(1) & B = A*16./MAX(A) & t2 = SYSTIME(1)
PRINT, ’Time for inefficient calculation: ’, t2-t1
t3 = SYSTIME(1) & B = 16./MAX(A)*A & t4 = SYSTIME(1)
PRINT, ’Time for efficient calculation: ’, t4-t3
Avoid IF Statements
Programs with array expressions run faster than programs with scalars, loops,
and IF statements. Some examples of slow and fast ways to achieve the same
results follow.
Example—Summing Elements
The first example adds all positive elements of array B to array A.
FOR I = 0, (N-1) DO IF B[I] GT 0 THEN A[I] = A[I] + B[I]
Using a loop will be slow.
A = A + (B GT 0) * B
Fast way: Mask out negative elements using array operations.
A = A + (B > 0)
Faster way: Add B > 0.
When an IF statement appears in the middle of a loop with each element of an
array in the conditional, the loop can often be eliminated by using logical array
expressions.
Building IDL Applications
Avoid IF Statements
132
Chapter 9: Writing IDL Programs
Example—Using Array Operators and the WHERE Function
In the example below, each element of C is set to the square-root of A if A[I] is
positive; otherwise, C[I] is set to minus the square-root of the absolute value of
A[I].
FOR I=0,(N-1) DO IF A[I] LE 0 THEN $
C[I]=-SQRT(-A[I]) ELSE C[I]=SQRT(A[I])
Using an IF statement is slow.
C = ((A GT 0) * 2-1) * SQRT(ABS(A)) Fast way.
The expression (A GT 0) has the value 1 if A[I] is positive and has the value 0
if A[I]is not. (A GT 0)* 2 - 1 is equal to +1 if A[I] is positive or -1 if A[I]
is negative, accomplishing the desired result without resorting to loops or IF
statements.
Another method is to use the WHERE function to determine the subscripts of the
negative elements of A and negate the corresponding elements of the result.
negs = WHERE(A LT 0)
Get subscripts of negative elements.
C = SQRT(ABS(A))
Take root of absolute value.
C[negs] = -C[negs]
Negate elements in C corresponding to negative elements in A.
Use Vector and Array Operations
Whenever possible, vector and array data should always be processed with IDL
array operations instead of scalar operations in a loop. For example, consider the
problem of inverting a 512 × 512 image. This problem arises because
approximately half the available image display devices consider the origin to be
the lower-left corner of the screen, while the other half recognize it as the upperleft corner.
The following example is for demonstration only. The IDL system variable
!ORDER should be used to control the origin of image devices. The ORDER
keyword to the TV procedure serves the same purpose.
A programmer without experience in using IDL might be tempted to write the
following nested loop structure to solve this problem:
FOR I = 0, 511 DO FOR J = 0, 255 DO BEGIN
temp = image[I, J]
Use Vector and Array Operations
Temporarily save pixel image.
Building IDL Applications
Chapter 9: Writing IDL Programs
133
image[I, J] = image[I, 511 - J] Exchange pixel in same column
from corresponding row at bottom.
image[I, 511-J] = temp
ENDFOR
A more efficient approach to this problem capitalizes on IDL’s ability to process
arrays as a single entity:
FOR J = 0, 255 DO BEGIN
temp = image[*, J]
Temporarily save current row.
image[*, J] = image[*, 511-J]
Exchange row with corresponding
row at bottom.
image[*, 511-J] = temp
ENDFOR
At the cost of using twice as much memory, processing can be simplified even
further by using the following statements:
Get a second array to hold inverted
copy.
image2 = BYTARR(512, 512)
FOR J = 0, 511 DO image2[*, J] = image[*, 511-J]
Copy the rows from the bottom up.
Even more efficient is the single line:
image2 = image[*, 511 - INDGEN(512)]
that reverses the array using subscript ranges and array-valued subscripts.
Finally, using the built-in ROTATE function is quickest of all:
image = ROTATE(image, 7)
Inverting the image is equivalent to transposing it and rotating it 270 degrees
clockwise.
IDL System Functions & Procedures
IDL supplies a number of built-in functions and procedures to perform common
operations. These system-supplied functions have been carefully optimized and
are almost always much faster than writing the equivalent operation in IDL with
loops and subscripting.
Building IDL Applications
IDL System Functions & Procedures
134
Chapter 9: Writing IDL Programs
Example
A common operation is to find the sum of the elements in an array or subarray.
The TOTAL function directly and efficiently evaluates this sum at least 10 times
faster than directly coding the sum.
sum = 0. & FOR I = J, K DO sum = sum + array[I]
Slow way: Initialize SUM and
sum each element.
sum = TOTAL(array[J:K])
Efficient, simple way.
Similar savings result when finding the minimum and maximum elements in an
array (MIN and MAX functions), sorting (SORT function), finding zero or
nonzero elements (WHERE function), etc.
Use Constants of the Correct Type
As explained in “Constants and Variables” on page 11, the syntax of a constant
determines its type. Efficiency is adversely affected when the type of a constant
must be converted during expression evaluation. Consider the following
expression:
A + 5
If the variable A is of floating-point type, the constant 5 must be converted from
short integer type to floating point each time the expression is evaluated.
The type of a constant also has an important effect in array expressions. Care
must be taken to write constants of the correct type. In particular, when
performing arithmetic on byte arrays with the intent of obtaining byte results, be
sure to use byte constants; e.g., nB. For example, if A is a byte array, the result of
the expression A + 5B is a byte array, while A + 5 yields a 16-bit integer array.
Eliminate Invariant Expressions
Expressions whose values do not change inside a loop should be moved outside
the loop. For example, in the loop:
FOR I = 0, N - 1 DO arr[I, 2*J-1] = ...,
the expression (2*J-1) is invariant and should be evaluated only once before
the loop is entered:
temp = 2*J-1
FOR I = 0, N-1 DO arr[I, temp] = ....
Use Constants of the Correct Type
Building IDL Applications
Chapter 9: Writing IDL Programs
135
Virtual Memory
The IDL programmer and user must be cognizant of the characteristics of virtual
memory computer systems to avoid penalty. Virtual memory allows the
computer to execute programs that require more memory than is actually present
in the machine by keeping those portions of programs and data that are not being
used on the disk. Although this process is transparent to the user, it greatly affects
the efficiency of the program.
IDL arrays are stored in dynamically allocated memory. Although the program
can address large amounts of data, only a small portion of that data actually
resides in physical memory at any given moment; the remainder is stored on disk.
The portion of data and program code in real physical memory is commonly
called the working set.
When an attempt is made to access a datum in virtual memory not currently
residing in physical memory, the operating system suspends IDL, arranges for the
page of memory containing the datum to be moved into physical memory and
then allows IDL to continue. This process involves deciding where the datum
should go in memory, writing the current contents of the selected memory page
out to the disk, and reading the page with the datum into the selected memory
page. A page fault is said to occur each time this process takes place. Because the
time required to read from or write to the disk is very large in relation to the
physical memory access time, page faults become an important consideration.
When using IDL with large arrays, it is important to have access to sufficient
physical and virtual memory. Given a suitable amount of physical memory, the
parameters that regulate virtual memory require adjustment to assure best
performance. These parameters are discussed below. See “Virtual Memory
System Parameters” on page 138. If you suspect that lack of physical or virtual
memory is causing problems, consult your system manager.
Access Large Arrays by Memory Order
When an array is larger than or close to the working set size (i.e., the amount of
physical memory available for the process), it is preferable to access it in memory
address order.
Consider the process of transposing a large array. Assume the array is a 512 × 512
byte image with a 100 kilobyte working set. The array requires 512 × 512, or
approximately 250 kilobytes. Less than half of the image can be in memory at any
one instant.
In the transpose operation, each row must be interchanged with the
corresponding column. The first row, containing the first 512 bytes of the image,
will be read into memory, if necessary, and written to the first column. Because
arrays are stored in row order (the first subscript varies the fastest), one column
Building IDL Applications
Virtual Memory
136
Chapter 9: Writing IDL Programs
of the image spans a range of addresses almost equal to the size of the entire
image. To write the first column, 250,000 bytes of data must be read into physical
memory, updated, and written back to the disk. This process must be repeated for
each column, requiring the entire array be read and written almost 512 times.
The amount of time required to transpose the array using the method described
above is relatively large.
In contrast, the IDL TRANSPOSE function transposes large arrays by dividing
them into subarrays smaller than the working set size enabling it to transpose a
512 × 512 image in a much smaller amount of time.
Example
Consider the operation of the following IDL statement:
FOR X = 0, 511 DO FOR Y = 0, 511 DO ARR[X, Y] = ...
This statement requires an extremely large execution time because the entire
array must be transferred between memory and the disk 512 times. The proper
form of the statement is to process the points in address order by using the
following statement:
FOR Y = 0, 511 DO FOR X = 0, 511 DO ARR[X, Y] = ...
This approach cuts computing time by a factor of at least 50.
Running Out of Virtual Memory
If you process large images with IDL and use the vendor-supplied default system
parameters (especially if you have a small system), you may encounter the error
message
% Unable to allocate memory.
This error message means that IDL was unable to obtain enough virtual memory
to hold all your data. Whenever you define an array, image, or vector, IDL asks
the operating system for some virtual memory in which to store the data. When
you reassign the variable, IDL frees the memory for re-use.
The first time you get this error, you will either have to stop what you are doing
and exit IDL or delete unused variables containing images or arrays, thereby
releasing enough virtual memory to continue. You can delete the memory
allocation of array variables by setting the variable equal to a scalar value.
If you need to exit IDL, you first should use the SAVE procedure to save your
variables in an IDL save file. Later, you will be able to recover those variables from
the save file using the RESTORE procedure.
The HELP,/MEMORY command tells you how much virtual memory you have
allocated. For example, a 512 × 512 complex floating array requires 8*5122 bytes
Virtual Memory
Building IDL Applications
Chapter 9: Writing IDL Programs
137
or about 2 megabytes of virtual memory because each complex element requires
8 bytes. Deleting a variable containing a 512 × 512 complex array will increase the
amount of virtual memory available by this amount.
Minimizing Virtual Memory
If virtual memory is a problem, try to tailor your programming to minimize the
number of images held in IDL variables. Keep in mind that IDL creates
temporary arrays to evaluate expressions involving arrays. For example, when
evaluating the statement
A = (B + C) * (E + F)
IDL first evaluates the expression B + C and creates a temporary array if either
B or C are arrays. In the same manner, another temporary array is created if either
E or F are arrays. Finally, the result is computed, the previous contents of A are
deleted, and the temporary area holding the result is saved as variable A.
Therefore, during the evaluation of this statement, enough virtual memory to
hold two array’s worth of data is required in addition to normal variable storage.
It is a good idea to delete the allocation of a variable that contains an image and
that appears on the left side of an assignment statement, as shown in the
following program.
FOR I = ... DO BEGIN
Loop to process an image.
...
Processing steps.
A = 0
Delete old allocation for A.
A = Image_Expression
Compute image expression and
store.
...
ENDFOR
End of loop.
The purpose of the statement A=0 is to free the old memory allocation for the
variable A before computing the image expression in the next statement. Because
the old value of A is going to be replaced in the next statement, it makes sense to
free A’s allocation first.
The TEMPORARY Function
Another way to minimize memory use when performing operations on large
arrays is to use the TEMPORARY function. TEMPORARY returns the value of its
argument as a temporary variable and makes the argument undefined. In this
way, you avoid making a new copy of temporary results. For example, assume
that A is a large array. To add 1 to each element in A, you could enter:
Building IDL Applications
Virtual Memory
138
Chapter 9: Writing IDL Programs
A = A+1
However, this statement creates a new array for the result of the addition and
assigns the result to A before freeing the old allocation of A. Hence, the total
storage required for the operation is twice the size of A. The statement:
A = TEMPORARY(A) + 1
requires no additional space.
Virtual Memory System Parameters
♦ Unix: The size of the swapping area(s) determines how much virtual memory
your process is allowed. To increase the amount of available virtual memory, you
must increase the size of the swap device (sometimes called the swap partition).
Increasing the size of a swap partition is a time-consuming task that should be
planned carefully. It usually requires saving the contents of the disk, reformatting
the disk with the new file partition sizes, and restoring the original contents.Some
systems offer the alternative of swapping to a regular file. This is a considerably
easier solution, although it may not be as efficient. Consult your system documentation for details and instructions on how to perform these operations.
♦ VMS: OpenVMS, as it comes from DEC, is not tuned for image processing. To
get the best performance from IDL, you should increase the VMS SYSGEN
parameters, file sizes, and AUTHORIZE quotas that restrict the virtual memory
system. This discussion is on the most elementary level, and the appropriate VMS
manuals should be consulted for more detail.
The first step is to determine how much virtual memory you require. For
example, if you compute complex Fast Fourier Transforms (FFT) on 512 × 512
images, each complex image requires 2 megabytes. Suppose that during a typical
session you need to have four images stored in variables and require enough
memory for two images to hold temporary results, resulting in a total of six
images or 12 megabytes. Rounding up to 16 megabytes gives a reasonable goal.
The following SYSGEN parameters and quotas should be changed to increase the
amount of virtual memory available.
SYSGEN Parameters
WSMAX: This parameter sets the maximum number of pages of any working set
on a system-wide basis. The working set is that portion of virtual memory used
by a process that is actually in physical memory. Although this is an over
simplification, small working set sizes cause page faulting. Page faults waste time
and potentially require disk accesses. Increasing the working set to a size of three
times the size of the largest array to be processed, or at least 2,000 blocks, can
cause dramatic speed improvements.
Virtual Memory
Building IDL Applications
Chapter 9: Writing IDL Programs
139
VIRTUALPAGECNT: This parameter sets the maximum number of virtual pages
(512 bytes/page) that can be used by any one process.
To change the values of SYSGEN parameters, DEC recommends that you run the
AUTOGEN command procedure after adding lines to set the new values of
changed parameters to the end of the file SYS$SYSTEM: MODPARAMS.DAT.
System Files
The sizes of the system page and swap files (SYS$SYSTEM: PAGEFILE.SYS and
SWAPFILE.SYS) must be large enough to contain the virtual memory used by all
active processes. In any event, you cannot have more virtual memory than will fit
in the page file. You can increase the size of these files or create secondary system
files on a disk other than the system disk. If you get the error message
Page file fragmented - continuing
on the system console, your page file is too small. To increase the size of these files,
use the command procedure SYS$UPDATE: SWAPFILES. Use the SYSGEN
INSTALL command to activate system files created on disks other than the system
disk. AUTOGEN can also be used to change the sizes of these files.
Quotas
The following quotas, all of which can be changed on a per user or system basis
using the AUTHORIZE utility, affect virtual page limits and working set sizes.
Pgflquo: The page file quota for each user expressed in blocks. If you increase the
size of the page file, be sure to increase the page file quotas for the users requiring
more virtual memory. Be sure that the page file size is at least as large as the sum
of the quotas of each active user.
WSquo: The working set quota for each user. This quota can be used to allow
some users a larger working set than others. WSquo must not be larger than
WSMAX.
♦ Windows, Macintosh: Consult your Windows or Macintosh system documentation for details on how to configure your system to use virtual memory.
IDL Implementation
IDL programs are compiled into a low-level abstract machine code which is
interpretively executed. The dynamic nature of variables in IDL and the relative
complexity of the operators precludes the use of directly executable code.
Statements are only compiled once, regardless of the frequency of their execution.
The IDL interpreter emulates a simple stack machine with approximately 50
operation codes. When performing an operation, the interpreter must determine
Building IDL Applications
IDL Implementation
140
Chapter 9: Writing IDL Programs
the type and structure of each operand and branch to the appropriate routine.
The time required to properly dispatch each operation may be longer than the
time required for the operation itself.
The characteristics of the time required for array operations is similar to that of
vector computers and array processors. There is an initial set-up time, followed
by rapid evaluation of the operation for each element. The time required per
element is shorter in longer arrays because the cost of this initial set-up period is
spread over more elements. The speed of IDL is comparable to that of optimized
FORTRAN for array operations. When data are treated as scalars, IDL efficiency
degrades by a factor of 30 or more.
IDL Implementation
Building IDL Applications
Chapter 10
Controlling Errors
The following topics are covered in this chapter:
Default Error-Handling Mechanism .... 142
Disappearing Variables ........................ 142
Controlling Errors Using CATCH.......... 143
Controlling Errors Using ON_ERROR ... 145
Controlling Input/Output Errors.......... 146
Error Signaling.................................... 147
Obtaining Traceback Information ....... 148
Error Handling.................................... 149
Math Errors ........................................ 151
141
142
Chapter 10: Controlling Errors
This chapter discusses routines and methods used to check and handle errors that
occur in IDL programs. The routines covered here are rarely used interactively.
IDL divides possible execution errors into three categories: input/output, math,
and all others. There are three main error-handling routines: CATCH,
ON_ERROR, and ON_IOERROR. CATCH is a generalized mechanism for
handling exceptions and errors. The ON_ERROR routine handles regular errors
when an error handler established by the CATCH procedure is not present. The
ON_IOERROR routine allows you to change the default way in which
input/output errors are handled. The FINITE and CHECK_MATH routines
provide control over math errors.
Default Error-Handling Mechanism
In the default case, whenever an error is detected by IDL during the execution of
a program, program execution stops and an error message is printed. The
execution context is that of the program unit (procedure, function, or main
program) in which the error occurred.
Sometimes it is possible to recover from an error by manually entering statements
to correct the problem. Possibilities include setting the values of variables, closing
files, etc., and then entering the command .CONTINUE, which resumes execution
of the program unit at the beginning of the statement that caused the error. (See
“Executive Commands” on page 31 of the IDL Reference Guide for more
information about commands used to stop and start execution.)
As an example, if an error occurs because an undefined variable is referenced, you
can simply define the variable from the keyboard, then continue execution with
.CON. Of course, this is a temporary solution. You should still edit the program
file to fix the problem permanently.
Disappearing Variables
IDL users may find that all their variables have seemingly disappeared after an
error occurs inside a procedure or function. The misunderstood subtlety is that
after the error occurs, IDL’s context is inside the called procedure, not in the main
level. All variables in procedures and functions, with the exception of parameters
and common variables, are local in scope. Typing RETURN or RETALL will make
the lost variables reappear.
RETALL is best suited for use when an error is detected in a procedure and it is
desired to return immediately to the main program level despite nested
procedure calls. RETALL issues RETURN commands until the main program
level is reached.
Default Error-Handling Mechanism
Building IDL Applications
Chapter 10: Controlling Errors
143
The HELP command can be used to see the current call stack (i.e., which
program unit IDL is in and which program unit called it).
Controlling Errors Using CATCH
The CATCH procedure provides a generalized mechanism for handling any type
of errors and exceptions within IDL. Calling CATCH establishes an error handler
for the current procedure that intercepts all errors that can be handled by IDL,
with the exception of non-fatal warnings such as math errors (e.g., floating-point
underflow). The CATCH mechanism is similar to C’s setjmp/longjmp
facilities or C++’s catch/throw facilities.
When an error occurs, each active procedure, beginning with the offending
procedure and proceeding up the call stack to the main program level, is
examined for an error handler (established by a call to CATCH). If an error
handler is found, control resumes at the statement after the call to CATCH. The
index of the error is returned in the argument to CATCH and is also stored in
!ERROR_STATE.CODE. The associated error message is stored in
!ERROR_STATE.MSG. If no error handlers are found, program execution stops,
an error message is issued, and control reverts to the interactive mode.
For more information, see “CATCH” on page 255 and “!ERROR_STATE” on
page 149 of the IDL Reference Guide
Interaction of CATCH, ON_ERROR, and ON_IOERROR
Error handlers established by calls to CATCH supersede calls to ON_ERROR.
However, calls to ON_IOERROR made in the procedure that causes an I/O error
supersede any error handling mechanisms created with CATCH and the program
branches to the label specified by ON_IOERROR. Figure 10-1 is a flow chart of
how errors are handled in IDL.
Canceling an Error Handler
Call CATCH with the CANCEL keyword set to cancel a procedure’s error handler.
This cancellation does not effect other error handlers that may be established in
other active procedures.
Generating an Exception
To generate an exception and cause control to return to the error handler, use the
MESSAGE procedure. Calling MESSAGE generates an exception that sets the
!ERROR system variable to -5 and the !ERR_STRING system variable to the
string used as an argument to MESSAGE. See “Error Signaling” on page 147.
Building IDL Applications
Controlling Errors Using CATCH
144
Chapter 10: Controlling Errors
Error or Exception is Generated
Yes
Is it an I/O error?
No
No
Is ON_IOERROR
routine in use?
Yes
Is there an error handler
defined by the CATCH
routine?
Yes
Handle error with
CATCH-defined error
handler and continue
program execution.
No
Handle error as
indicated by setting of
ON_ERROR routine or
use default error handling.
Controlling Errors Using CATCH
Handle error as
indicated by
ON_IOERROR setting.
Building IDL Applications
Chapter 10: Controlling Errors
145
Example Using CATCH
The following procedure illustrates the use of CATCH:
PRO ABC
A = FLTARR(10)
Define variable A.
CATCH, Error_status
Establish error handler. When errors occur, the index of the error is
re tur n ed in the var iabl e
Error_status. Initially, this argument is set to zero.
IF Error_status NE 0 THEN BEGIN
This statement begins the error
handler.
PRINT, ’Error index: ’, Error_status
PRINT, ’Error message:’, !ERR_STRING
Handle the error by extending A.
A=FLTARR(12)
ENDIF
A[11]=12
Cause an error.
HELP, A
Even though an error occurs in the
line above, program execution
continues to this point because the
event handler extended the definition of A so that the statement can
be re-executed.
END
Running the ABC procedure causes IDL to produce the following output and
control returns to the interactive prompt:
Error index:
-101
Error message:
Attempt to subscript A with <INT (
A
FLOAT
11)> is out of range.
= Array(12)
Controlling Errors Using ON_ERROR
The ON_ERROR procedure determines the action taken when an error is
detected inside a user procedure or function and no error handlers established
with the CATCH procedure are found. The possible options for error recovery are
shown in Table 10-1:
Building IDL Applications
Controlling Errors Using ON_ERROR
146
Chapter 10: Controlling Errors
Value
Action
0
Stop immediately in the context of the procedure or function that caused
the error. This is the default action.
1
Return to the main program level and stop.
2
Return to the caller of the program unit that called ON_ERROR and stop.
3
Return to the program unit that called ON_ERROR and stop.
Table 10-1: Error Recovery Options
One useful option is to use ON_ERROR to cause control to be returned to the
caller of a procedure in the event of an error. The statement:
ON_ERROR, 2
placed at the beginning of a procedure will have this effect. Include this statement
in library procedures and other routines that will be used by others once the
routines have been debugged. This form of error recovery makes debugging a
routine difficult because the routine is exited as soon as an error occurs;
therefore, it should be added once the code is completely tested.
Note that error handlers established by CATCH supersede calls to ON_ERROR
made in the same procedure.
Controlling Input/Output Errors
The default action for handling input/output errors is to treat them exactly like
regular errors and follow the error handling strategy set by ON_ERROR. You can
alter this default by using the ON_IOERROR procedure to specify the label of a
statement to which execution should jump if an input/output error occurs. When
IDL detects an input/output error and an error-handling statement has been
established, control passes directly to the given statement without stopping
program execution. In this case, no error messages are printed.
Note that calls to ON_IOERROR made in the procedure that causes an I/O error
supersede any error handling mechanisms created with CATCH and the program
branches to the label specified by ON_IOERROR.
When writing procedures and functions that are to be used by others, it is good
practice to anticipate and handle errors caused by the user. For example, the
following procedure segment, which opens a file specified by the user, handles the
case of a nonexistent file or read error.
Controlling Input/Output Errors
Building IDL Applications
Chapter 10: Controlling Errors
147
FUNCTION READ_DATA, FILE_NAME
Define a function to read, and return a 100-element, floatingpoint array.
ON_IOERROR, BAD
Declare error label.
OPENR, UNIT, FILE NAME, /GET_LUN
Use the GET_LUN keyword to allocate a logical file unit.
A = FLTARR(100)
Define data array.
READU, UNIT, A
Read it.
GOTO, DONE
Clean up and return.
BAD:
Exception label. Print the error
message.
PRINT, !ERR_STRING
DONE: FREE_LUN, UNIT
Close and free the input/output
unit.
RETURN, A
Return the result. This will be undefined if an error occurred.
END
The important things to note in this example are that the FREE_LUN procedure
is always called, even in the event of an error, and that this procedure always
returns to its caller. It returns an undefined value if an error occurs, causing its
caller to encounter the error.
Error Signaling
The MESSAGE procedure is used by user procedures and functions to issue
errors. It has the form:
MESSAGE, Text
where Text is a scalar string that contains the text of the error message.
The MESSAGE procedure issues error and informational messages using the
same mechanism employed by built-in IDL routines. By default, the message is
issued as an error, the message is output, and IDL takes the action specified by the
ON_ERROR procedure.
As a side effect of issuing the error, appropriate fields of the system variable
!ERROR_STATE are set; the text of the error message is placed in
!ERROR_STATE.MSG, or in !ERROR_STATE.SYS_MSG for the operating
system’s component of the error message. See “Error Handling” on page 149 or
“!ERROR_STATE” on page 39 of the IDL Reference Guide for more information.
Building IDL Applications
Error Signaling
148
Chapter 10: Controlling Errors
As an example, assume the statement:
MESSAGE, ’Unexpected value encountered.’
is executed in a procedure named CALC. IDL would print:
% CALC: Unexpected value encountered.
and execution would halt.
The MESSAGE procedure accepts several keywords that modify its behavior. See
“MESSAGE” on page 745 of the IDL Reference Guide for additional details.
Another use of MESSAGE involves re-signaling trapped errors. For example, the
following code uses ON_IOERROR to read from a file until an error (presumably
end-of-file) occurs. It then closes the file and reissues the error.
OPENR, UNIT, ’DATA.DAT’, /GET_LUN
Open the data file.
ON_IOERROR, EOD
Arrange for jump to label EOD
when an input/output error occurs.
WHILE 1 DO READF, UNIT, LINE
Read every line of the file.
EOD: ON_IOERROR, NULL
An error has occurred. Cancel the
input/output error trap.
FREE_LUN, UNIT
Close the file.
MESSAGE, !ERR_STRING, /NONAME, /IOERROR
Reissue the error. !ERR_STRING
contains the appropriate text. The
IOERROR keyword causes it to be
issued as an input/output error.
Use of NONAME prevents MESSAGE from tacking the name of
the current routine to the beginning of the message string since
!ERR_STRING already contains
it.
Obtaining Traceback Information
It is sometimes useful for a procedure or function to obtain information about its
caller(s). The HELP procedure returns, in a string array, the contents of the
procedure stack when the CALLS keyword parameter is specified. The first
element of the resulting array contains the module name, source filename, and
line number of the current level. The second element contains the same
Obtaining Traceback Information
Building IDL Applications
Chapter 10: Controlling Errors
149
information for the caller of the current level, and so on, back to the level of the
main program.
For example, the following code fragment prints the name of its caller, followed
by the source filename and line number of the call:
HELP, CALLS = A
PRINT, ’called from:’, A[1]
print 2nd element
This results in a message of the following form:
Called from: DIST </usr2/idl/lib/dist.pro (27)>
Programs can readily parse the traceback information to extract the source file
name and line number.
Error Handling
IDL contains a system variable that is updated when errors occur. This system
variable is described below.
!ERROR_STATE
This system variable is a structure. Whenever an error occurs, IDL sets the fields
in this system variable according to the nature of the field. An IDL error is always
comprised of an IDL-generated component, and may also contain an operating
system-generated component.
The fields for the !ERROR_STATE system variable are described below:
•
NAME
A read-only string variable containing the error name of the IDL-generated
component of the last error message. Although the error code—as defined below
in CODE—may change between IDL sessions, the name will always remain the
same. If an error has not occurred in the current IDL session, this field is set to
IDL_M_SUCCESS.
•
BLOCK
A read-only string variable containing the name of the message block for the IDLgenerated component of the last error message. If an error has not occurred in the
current IDL session, this field is set to IDL_MBLK_CORE.
•
CODE
The error code of the IDL-generated component of the last error in IDL. Whenever an error occurs, IDL sets this system variable to the error code (a negative
integer number) of the error. Although the error code may change between IDL
Building IDL Applications
Error Handling
150
Chapter 10: Controlling Errors
sessions, the name—as defined above in NAME—will always remain the same. If
an error has not occurred in the current IDL session, this field is set to 0.
•
SYS_CODE
The error code of the operating system-generated component, if it exists, of the
last error. IDL sets this system variable to the OS-defined error code. This field is
a two-element longword array. If an error has not occurred in the current IDL
session, the array contains all zeros.
On most operating systems, the error code is returned in the first element of the
array (i.e., SYS_CODE[0]) and the second element is set to 0. Some operating
systems (e.g., VMS) can return two separate error codes for some types of
filesystem errors. In these cases, SYS_CODE[1] is also set to an OS-defined error
code.
•
MSG
The error message of the IDL-generated component of the last error. Whenever
an error occurs, IDL sets this field to the error message (a scalar string) that
corresponds to the error code. If an error has not occurred in the current IDL
session, this field is set to the null string, ' '.
•
SYS_MSG
The error message of the operating system-generated component, if it exists of
the last error. When an operating system error occurs, IDL sets this field to the
OS-defined error message string. If an error has not occurred in the current IDL
session, this field is set to the null string, ' '.
•
MSG_PREFIX
A string variable containing the prefix string used for the IDL-generated component of error messages.
Using !ERROR_STATE
At the beginning of an IDL session, !ERROR_STATE contains default
information. To see this information, you can either view !ERROR_STATE from
the System field of the Variable Watch Window (see “The Variable Watch
Window” on page 145 of Using IDL) or you ca n enter PRINT, !ERROR_STATE
at the Command Input Line. After an error has occurred, all of the fields of
!ERROR_STATE display their updated status.
You can use MESSAGE, /RESET_ERROR STATE to reset all the fields in
!ERROR_STATE to their default values. See “MESSAGE” on page 745
Error Handling
Building IDL Applications
Chapter 10: Controlling Errors
151
Math Errors
The detection of math errors, such as division by zero, overflow, and attempting
to take the logarithm of a negative number, is hardware and operating system
dependent. Some systems trap more errors than other systems. On systems that
implement the IEEE floating-point standard, IDL substitutes the special floatingpoint values NaN and Infinity when it detects a floating point math error. (See
“Special Floating-Point Values” on page 152.) Integer overflow and underflow is
not detected. Integer divide by zero is detected on all platforms.
A Note on Floating-Point Underflow Errors
Floating-point underflow errors occur when a non-zero result is so close to zero
that it cannot be expressed as a normalized floating-point number. In the vast
majority of cases, floating-point underflow errors are harmless and can be
ignored. For more information on floating-point numbers, see “Accuracy &
Floating-Point Operations” on page 427 of Using IDL.
Accumulated Math Error Status
IDL handles math errors by keeping an accumulated math error status. This
status, which is implemented as a longword, contains a bit for each type of math
error that is detected by the hardware. When IDL automatically checks and clears
this indicator depends on the value of the system variable !EXCEPT (see
“!EXCEPT” on page 40 of the IDL Reference Guide). The CHECK_MATH
function (see “CHECK_MATH” on page 261 of the IDL Reference Guide) also
allows you to check and clear the accumulated math error status when desired.
!EXCEPT has three possible values:
!EXCEPT=0
Do not report exceptions.
!EXCEPT=1
The default. Report exceptions when the IDL interpreter returns to an interactive
prompt. Any math errors that occurred since the last interactive prompt (or call
to CHECK_MATH) are printed in the IDL command log. A typical message
looks like:
% Program caused arithmetic error: Floating divide by 0
!EXCEPT=2
Report exceptions after each IDL statement is executed. This setting also allows
IDL to report on the program context in which the error occurred, along with the
line number in the procedure. A typical message looks like:
% Program caused arithmetic error: Floating divide by 0
Building IDL Applications
Math Errors
152
Chapter 10: Controlling Errors
% Detected at
JUNK
3 junk.pro
Special Floating-Point Values
Machines which implement the IEEE standard for binary floating-point
arithmetic have two special values for undefined results: NaN (Not A Number)
and Infinity. Infinity results when a result is larger than the largest representation.
NaN is the result of an undefined computation such as zero divided by zero,
taking the square-root of a negative number, or the logarithm of a non-positive
number. In many cases, when IDL encounters the value NaN in a data set, it treats
it as “missing data.” The special values NaN and Infinity are also accessible in the
read-only system variable !VALUES (see “System Variables” on page 22). These
special operands propagate throughout the evaluation process—the result of any
term involving these operands is one of these two special values. For example:
Multiply NaN by 3
PRINT, 3 * !VALUES.F_NAN
IDL prints:
NaN
It is important to remember that the value NaN is literally not a number, and as
such cannot be compared with a number. For example, suppose you have an
array that contains the value NaN:
A = [1.0, 2.0, !VALUES.F_NAN]
PRINT, A
IDL prints:
1.00000
2.00000
NaN
If you try to select elements of this array by comparing them with a number
(using the WHERE function, for example), IDL will generate an error:
PRINT, WHERE(A GT 1.0)
Print the indices of the elements of
A with a value greater than one.
IDL prints:
1
% Program caused arithmetic error: Floating illegal operand
To avoid this problem, use the FINITE function (see “FINITE” on page 483 of the
IDL Reference Guide) to make sure arguments to be compared are in fact valid
floating-point numbers:
PRINT, WHERE(FINITE(A) EQ 1)
IDL prints the indices of the finite elements of A:
Math Errors
Building IDL Applications
Chapter 10: Controlling Errors
0
153
1
To then print the indices of the elements of A that are both finite and greater than
1.0, you could use the command:
PRINT, WHERE(A[WHERE(FINITE(A) EQ 1)] GT 1.0)
IDL prints:
1
Similarly, if you wanted to find out which elements of an array were not valid
floating-point numbers, you could use a command like:
Print the indices of the elements of
A that are not valid floating-point
numbers.
PRINT, WHERE(FINITE(A) EQ 0)
IDL prints:
2
Note that the special value Infinity can be compared to a floating point number.
Thus, if:
B = [1.0, 2.0, !VALUES.F_INFINITY]
PRINT, B
IDL prints:
1.00000
2.00000
Inf
and
PRINT, WHERE(B GT 1.0)
IDL prints:
1
2
You can also compare numbers directly with the special value Infinity:
PRINT, WHERE(B EQ !VALUES.F_INFINITY)
IDL prints:
2
The FINITE Function
Use the FINITE function to explicitly check the validity of floating-point or
double-precision operands on machines which use the IEEE floating-point
standard. For example, to check the result of the EXP function for validity, use
the following statement:
Building IDL Applications
Math Errors
154
Chapter 10: Controlling Errors
A = EXP(EXPRESSION)
Perform exponentiation.
IF NOT FINITE(A) THEN PRINT, ’Overflow occurred’
Print error message.
If A is an array, use the statement:
IF TOTAL(FINITE(A)) NE N_ELEMENTS(A) THEN
error
Integer Conversions
It must be stressed that when converting from floating to any of the integer types
(byte, signed or unsigned short integer, signed or unsigned longword integer, or
signed or unsigned 64-bit integer) if overflow is important, you must explicitly
check to be sure the operands are in range. Conversions to the above types from
floating point, double precision, complex, and string types do not check for
overflow—they simply convert the operand to the target integer type, discarding
any significant bits of information that do not fit.
When run on a Sun workstation, the program:
A = 2.0 ^ 31 + 2
PRINT, LONG(A), LONG(-A), FIX(A), FIX(-A), BYTE(A), BYTE(-A)
(which creates a floating-point number 2 larger than the largest positive
longword integer), prints the following:
2147483647 -2147483648 -1 0 255 0
% Program caused arithmetic error: Floating illegal operand
This result is incorrect.
Caution No error message will appear if you attempt to convert a floating number
whose absolute value is between 215 and 231 - 1 to short integer even though
the result is incorrect. Similarly, converting a number in the range of 256 to
231 - 1 from floating, complex, or double to byte type produces an incorrect
result, but no error message. Furthermore, integer overflow is usually not
detected. Your programs must guard explicitly against it.
Math Errors
Building IDL Applications
Chapter 11
Files and
Input/Output
The following topics are covered in this chapter:
File I/O Overview ............................... 156
Unformatted Input/Output ................. 158
Formatted Input/Output ..................... 158
Opening Files...................................... 160
Closing Files........................................ 161
Logical Unit Numbers (LUNs).............. 162
Using Free Format Input/Output......... 165
Using Explicitly Formatted Input/Output. 169
Format Codes ..................................... 173
Using Unformatted Input/Output ...... 191
Portable Unformatted Input/Output .. 197
Associated Input/Output .................... 202
File Manipulation Operations ................ 206
UNIX-Specific Information .................. 213
VMS-Specific Information ................... 217
Windows-Specific Information ............ 226
Macintosh-Specific Information .......... 227
Scientific Data Formats ....................... 227
Standard Image File Formats .............. 227
155
156
Chapter 11: Files and Input/Output
IDL provides powerful facilities for file input and output. Few restrictions are
imposed on data files by IDL, and there is no unique IDL format. This chapter
describes IDL input/output methods and routines and gives examples of
programs which read and write data using IDL, C, and FORTRAN.
The first section of this chapter provides a description for how IDL input/output
works. It is intentionally brief and is intended to serve only as an introduction.
Additional details are covered in the following sections. For the IDL user, perhaps
the largest single difference between platforms is input/output. The majority of
this chapter covers information that is required in all of the environments IDL
supports. Operating system specific information is concentrated in the final
sections of this chapter.
File I/O Overview
Before any file input or output can be performed, it is necessary to open a file.
This is done using either the OPENR (Open for Reading), OPENW (Open for
Writing), or OPENU (Open for Update) procedures. When a file is opened, it is
associated with a Logical Unit Number, or LUN. All file input and output routines
in IDL use the LUN rather than the filename, and most require that the LUN be
explicitly specified. Once a file is opened, several input/output routines are
available for use. Each routine fills a particular need – the one to use depends on
the particular situation.
There are three exceptions to the need to open any file before performing
input/output on it. Three files are always open – in fact, the user is not allowed to
close them. These files are the standard input (usually the keyboard), the standard
output (usually the IDL log window), and the standard error output (usually the
terminal screen). These three files are associated with LUNs 0, -1, and -2,
respectively. Because these files are always open, there is no need to open them
prior to using them for input/output. The READ and PRINT procedures
automatically use these files, so basic formatted input/output is extremely simple.
Simple Examples
It is easy to use input/output using the default input and output files. The IDL
command:
PRINT, ’Hello World.’
causes IDL to print the line:
Hello World.
on the terminal screen. This happens because PRINT formats its arguments and
prints them to LUN -1, which is the standard output file. It is only slightly more
File I/O Overview
Building IDL Applications
Chapter 11: Files and Input/Output
157
complicated to use other files. The following IDL statements show how the above
“Hello World” example could be sent to a file named hello.dat:
OPENW, 1, ’hello.dat’
Open LUN 1 for hello.dat with
write access.
PRINTF, 1, ’Hello World.’
Do the output operation to the file.
CLOSE, 1
Close the file.
Routines for Input/Output
The following routines are useful when doing input/output operations. See the
documentation for any of these routines in the IDL Reference Guide for more
information.
ASSOC
Map an array structure to a data file. ASSOC provides extremely efficient direct
access to unformatted data and is an important IDL function to understand.
EOF
Check for the end-of-file condition.
FINDFILE
Locate files that match a file specification.
FLUSH
Ensure all buffered data for a LUN has actually been output to the file.
FREE_LUN
Free unique file units.
FSTAT
Get detailed information about any LUN.
GET_KBRD
Read single characters from the keyboard.
GET_LUN
Allocate and free unique file units.
HELP, /FILES
Print information about open files.
POINT_LUN
Position the file pointer.
Building IDL Applications
File I/O Overview
158
Chapter 11: Files and Input/Output
PRINT/PRINTF
Output formatted data to the standard output file (LUN -1).
PRINT/PRINTFF
Output formatted data to the specified LUN.
READ/READF
Read formatted data from the standard input file (LUN 0).
READ/READFF
Read formatted data from the specified LUN.
READ/READFU
Input unformatted data from the specified LUN.
WRITEU
Output unformatted data to the specified LUN.
Unformatted Input/Output
Unformatted Input/Output is the most basic form of input/output. Unformatted
input/output transfers the internal binary representation of the data directly
between memory and the file.
Advantages of Unformatted I/O
Unformatted input/output is the simplest and most efficient form of
input/output. It is usually the most compact way to store data.
Disadvantages of Unformatted I/O
Unformatted input/output is the least portable form of input/output.
Unformatted data files can only be moved easily to and from computers that
share the same internal data representation. It should be noted that XDR
(eXternal Data Representation) files, described in “Portable Unformatted
Input/Output” on page 197, can be used to produce portable binary data.
Unformatted input/output is not directly human readable, so you cannot type it
out on a terminal screen or edit it with a text editor.
Formatted Input/Output
Formatted output converts the internal binary representation of the data to
ASCII characters which are written to the output file. Formatted input reads
Unformatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
159
characters from the input file and converts them to internal form. Formatted I/O
can be either “Free” format or “Explicit” format, as described below.
Advantages of Formatted I/O
Formatted input/output is very portable. It is a simple process to move formatted
data files to various computers, even computers running different operating
systems, as long as they all use the ASCII character set. (ASCII is the American
Standard Code for Information Interchange. It is the character set used by almost
all current computers, with the notable exception of large IBM mainframes.)
Formatted files are human readable and can be typed to the terminal screen or
edited with a text editor.
Disadvantages of Formatted I/O
Formatted input/output is more computationally expensive than unformatted
input/output because of the need to convert between internal binary data and
ASCII text. Formatted data requires more space than unformatted to represent
the same information. Inaccuracies can result when converting data between text
and the internal representation.
Free Format I/O
With free format input/output, IDL uses default rules to format the data.
Advantages of Free Format I/O
The user is free of the chore of deciding how the data should be formatted. Free
format is extremely simple and easy to use. It provides the ability to handle the
majority of formatted input/output needs with a minimum of effort.
Disadvantages of Free Format I/O
The default formats used are not always exactly what is required. In this case,
explicit formatting is necessary.
Explicit Format I/O
Explicit format I/O allows you to specify the exact format for input/output.
Advantages of Explicit I/O
Explicit formatting allows a great deal of flexibility in specifying exactly how data
will be formatted. Formats are specified using a syntax that is similar to that used
in FORTRAN format statements. Scientists and engineers already familiar with
FORTRAN will find IDL formats easy to write. Commonly used FORTRAN
format codes are supported. In addition, IDL formats have been extended to
Building IDL Applications
Formatted Input/Output
160
Chapter 11: Files and Input/Output
provide many of the capabilities found in the scanf () and printf () functions
commonly found in the C language runtime library.
Disadvantages of Explicit I/O
Using explicitly specified formats requires the user to specify more detail—they
are, therefore, more complicated to use than free format.
The type of input/output to use in a given situation is usually determined by
considering the advantages and disadvantages of each method as they relate to
the problem to be solved. Also, when transferring data to or from other programs
or systems, the type of input/output is determined by the application. The
following suggestions are intended to give a rough idea of the issues involved,
though there are always exceptions:
•
Images and large data sets are usually stored and manipulated using unformatted
input/output in order to minimize processing overhead. The IDL ASSOC function is often the natural way to access such data.
•
Data that need to be human readable should be written using formatted input/output.
•
Data that need to be portable should be written using formatted input/output.
Another option is to use unformatted XDR files by specifying the XDR keyword
with the OPEN procedures. This is especially important if moving between
computers with markedly different internal binary data formats. XDR is discussed
in “Portable Unformatted Input/Output” on page 197.
•
Free format input/output is easier to use than explicitly formatted input/output
and about as easy as unformatted input/output, so it is often a good choice for
small files where there is no strong reason to prefer one method over another.
Opening Files
Before a file can be processed by IDL, it must be opened using one of the
procedures described in Table 11-1. All open files are associated with a LUN
(Logical Unit Number) within IDL, and all input/output routines refer to files via
this number. For example, to open the file named data.dat for reading on file unit
1, use the following statement:
OPENR, 1, ’data.dat’
The OPEN procedures can be used with certain keywords to modify their normal
behavior. Some keywords are generally applicable, while others only have effect
under a given operating system. Some operating system specific keywords are
allowed (and ignored) under other operating systems in order to facilitate writing
portable routines.
Opening Files
Building IDL Applications
Chapter 11: Files and Input/Output
161
Procedure Description
OPENR
Opens an existing file for input only.
OPENW
Opens a new file for input and output. Under UNIX, Windows, and on the
Macintosh, if the named file already exists, its old contents are overwritten.
Under VMS, a file with the same name and a higher version number is created.
OPENU
Opens an existing file for input and output.
Table 11-1: IDL File Opening Commands
Platform-Specific Keywords to the OPEN Procedure
Different computers and operating systems perform input/output in different
ways. See “OPEN” on page 783 of the IDL Reference Guide for keywords to the
OPEN procedures that apply under Unix, VMS, Windows, or the Macintosh OS.
Closing Files
After work involving the file is complete, it should be closed. Closing a file
removes the association between the file and its unit number, thus freeing the
unit number for use with a different file. There is usually an operating systemimposed limit on the number of files a user may have open at once. Although this
number is large enough that it rarely causes problems, situations can occur where
a file must be closed before another file may be opened. In any event, it is good
style to only keep needed files open.
There are three ways to close a file:
•
Use the CLOSE procedure.
•
Use the FREE_LUN procedure on a LUN that has been allocated by GET_LUN.
•
Exit IDL. IDL closes all open files when it exits.
Calling the CLOSE procedure is the most common way to close a file unit. For
example, to close file unit number 1, use the following statement:
CLOSE, 1
In addition, if FREE_LUN is called with a file unit number that was previously
allocated by GET_LUN, it calls CLOSE before deallocating the file unit. Finally,
all open files are automatically closed when IDL exits.
Building IDL Applications
Closing Files
162
Chapter 11: Files and Input/Output
Logical Unit Numbers (LUNs)
IDL Logical Unit Numbers (LUNs) fall within the range −2 to 128. Some LUNs
are reserved for special functions as described below.
The Standard Input, Output, and Error LUNs
The three LUNs described below have special meanings that are operating system
dependent:
♦ UNIX: Logical Unit Numbers 0, -1, and -2 are tied to stdin, stdout, and stderr,
respectively. This means that the normal UNIX file redirection and pipe operations work with IDL. For example, the shell command
%idl < idl.inp >& idl.out &
will cause IDL to execute in the background, reading its input from the file idl.inp
and writing its output to the file idl.out. Any messages sent to stderr are also sent
to idl.out.
When using the IDL Development Environment (IDLDE), Logical Unit
Numbers 0, -1, and -2 are tied to stdin (the command line), stdout (the log
window), and stderr (the log window), respectively.
♦ VMS: Logical Unit Numbers 0, -1, and -2 are tied to SYS$INPUT, SYS$OUTPUT,
and SYS$ERROR respectively. This means that the DCL DEFINE command can
be used to redefine where IDL gets commands and writes its output. It also means
that IDL can be used in command and batch files.
When using the IDL Development Environment (IDLDE), Logical Unit Numbers
0, -1, and -2 are tied to SYS$INPUT (the command line), SYS$OUTPUT (the log
window), and SYS$ERROR (the log window), respectively.
♦ Windows and Macintosh: Logical Unit Numbers 0, -1, and -2 are tied to stdin
(the command line), stdout (the log window), and stderr (the log window),
respectively.
These special file units are described in more detail below.
File Unit 0
This LUN represents the standard input stream, which is usually the keyboard.
Therefore, the IDL statement:
READ, X
is equivalent to the following:
READF, 0, X
Logical Unit Numbers (LUNs)
Building IDL Applications
Chapter 11: Files and Input/Output
163
File Unit -1
This LUN represents the standard output stream, which is usually the terminal
screen. Therefore, the IDL statement:
PRINT, X
is equivalent to the following:
PRINTF, -1, X
File Unit -2
This LUN represents the standard error stream, which is usually the terminal
screen.
File Units 1–99
These are the file units for normal interactive use. When using IDL interactively,
the user arbitrarily selects the file units used. The file units from 1 to 99 are
available for this use.
File Units 100–128
These are the file units managed by the GET_LUN and FREE_LUN procedures.
If an IDL procedure or function that uses files is written to explicitly use a given
file unit, there is a chance that it will conflict with other routines that use the same
unit. It is therefore necessary to avoid explicit file unit numbers when writing IDL
procedures and functions. The GET_LUN and FREE_LUN procedures provide a
standard mechanism for IDL routines to obtain unique file units. GET_LUN
allocates a file unit from a pool of free units in the range 100 to 128. This unit will
not be allocated again until it is released by a call to FREE_LUN. Meanwhile, it is
available for the exclusive use of the program that allocated it. A typical
procedure that needs a file unit might be structured as follows:
PRO DEMO
OPENR, UNIT, /GET_LUN
Get a unique file unit and open the
file.
.
.
Body of program goes here.
.
FREE_LUN, UNIT
Return file unit.
END
Since the file is still open,
FREE_LUN will automatically
call CLOSE.
Building IDL Applications
Logical Unit Numbers (LUNs)
164
Chapter 11: Files and Input/Output
Note All IDL procedures and functions that open files should use GET_LUN/
FREE_LUN to obtain file units. Furthermore, the file units between 100 and
128 should never be used unless previously allocated by GET_LUN.
Reading And Writing Very Large Files
IDL on all platforms is able to read and write data from files up to 2^31-1 bytes
in length. On some platforms, it is also able to read and write data from files
longer than this limit. Currently, IDL on Digital Unix, HP-UX, Sun Solaris
(SPARC and x86), and SGI IRIX is able to perform I/O on such files. RSI expects
this list of platforms to increase with future releases.
When reading and writing to files smaller than this limit, there is no difference in
behavior between the platforms that can and those that cannot handle larger files.
IDL uses longword integers for file position arguments (e.g. POINT_LUN,
FSTAT) and keywords, as before. However, when dealing with files that exceed
this limit, IDL uses signed 64-bit integers in order to be able to properly represent
the offset. Consider the following example:
OPENW, 1, ’test.dat’
Open the file
POINT_LUN, -1, POS
Initial position should be 0.
HELP, POS
Print the position and its type.
POINT_LUN, 1, ’000000ffffffffff’x
Move the file pointer past the
signed 32-bit boundary.
POINT_LUN, -1, POS
The position is now too large to
represent as a longword.
HELP, POS
Print the position and its type.
CLOSE, 1
Executing these statements results in the following output:
POS
LONG
=
POS
LONG64
=
0
1099511627775
Initially, the file position is 0, which fits easily into a 32-bit integer. Once the file
position exceeds the range of a signed 32-bit number, IDL automatically shifts to
the 64-bit integer type.
Limitations of Large File Support
There are limitations on IDL’s support for very large files that must be
understood by the IDL programmer:
Reading And Writing Very Large Files
Building IDL Applications
Chapter 11: Files and Input/Output
165
•
On any platform, the amount of data that IDL can transfer in a single operation
is limited by the amount of memory it can allocate. Currently, IDL is a 32-bit
program, and as such, can theoretically address up to 2^31-1 bytes of memory
(approximately 2.3GB). Reading or writing data larger than this limit must be
done in multiple operations. Most systems do not have 2.3 GB of memory
available, and other programs running on the system also compete for the same
memory, so the actual memory available is likely to be considerably smaller.
•
The ability to read or write to very large files is constrained by the ability of the
underlying file system to support such files. Many platforms can only support
large files on certain file systems. For example, many platforms will be unable to
support these operations on NFS mounted file systems because the latest version
of NFS must be in use on both client and server. Some platforms, such HP-UX,
can only support such operations on special large file systems, and only if they are
mounted using the appropriate mount options. Consult your system documentation to determine the limitations present on your system and the procedures for
supporting very large file.
Using Free Format Input/Output
Use of formatted data is most appropriate when the data must be in human
readable form, such as when it is to be prepared or modified with a text editor.
Formatted data also are highly portable between various computers and
operating systems.
In addition to the PRINT, PRINTF, READ, and READF routines already
discussed, the STRING function can be used to generate formatted output that is
sent to a string variable instead of a file. The READS procedure can be used to
read formatted input from a string variable.
The exact format of the character data may be specified to these routines by
providing a format string via the FORMAT keyword. If no format string is given,
default formats for each type of data are applied. This method of formatted
input/output is called free format. Free format input/output is suitable for most
applications involving formatted data. It is designed to provide input/output
abilities with a minimum of programming.
Structures and Free Format Input/Output
IDL structures present a special problem for default formatted input and output.
The default format for displaying structure data is to surround the structure with
curly braces ({}). For example, if you define an anonymous structure:
struct = { A:2, B:3, C:’A String’ }
and then use default formatted output via the PRINT command:
Building IDL Applications
Using Free Format Input/Output
166
Chapter 11: Files and Input/Output
PRINT, struct
IDL prints:
{
2
3 A String}
You might suppose that default formatted input would recognize that the curly
braces are part of the formatting and ignore them. This is not the case, however.
By default, to read the third field in the structure (the string field) IDL will read
from the “A” to the end of the line, including the closing brace.
This behavior, while unsymmetric, seems to be the best choice for default
behavior—displaying the result of the PRINT statement on the computer screen.
We recommend that you use explicitly formatted input/output when reading and
writing structures to disk files, so as not to have to explicitly code around the
possibility that your structure may include strings.
Free Format Input
The following rules are used by IDL to perform free format input:
1. Input is performed on scalar variables. Array and structure variables are treated
as collections of scalar variables. For example,
A = INTARR(5)
READ, A
causes IDL to read five separate values to fill each element of the variable A.
2. If the current input line is empty and there are variables left requiring input, read
another line.
3. If the current input line is not empty but there are no variables left requiring input,
the remainder of the line is ignored.
4. Input data must be separated by commas or white space (tabs, spaces, or new
lines).
5. When reading into a variable of type string, all characters remaining in the current
input line are placed into the string.
6. When reading into numeric variables, every effort is made to convert the input
into a value of the expected type. Decimal points are optional and exponential
(scientific) notation is allowed. If a floating-point datum is provided for an integer
variable, the value is truncated.
7. When reading into a variable of complex type, the real and imaginary parts are
separated by a comma and surrounded by parentheses. If only a single value is
Using Free Format Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
167
provided, it is taken as the real part of the variable, and the imaginary part is set
to zero. For example:
A = COMPLEX(0)
Create a complex variable.
READ, A
IDL prompts for input with a colon:
:(3, 4)
The user enters “(3,4)” and A is set
to COMPLEX(3, 4).
READ, A
IDL prompts for input with a colon:
:50
The user enters “50” and A is set to
COMPLEX(50, 0).
Free Format Output
The following rules are used by IDL to perform free format output:
1. The format used to output numeric data is determined by the data type. The
formats used are summarized in the table below. The formats are specified in the
FORTRAN-like style used by IDL for explicitly formatted input/output.
Data Type
Format
Byte
I4
Int, UInt
I8
Long, ULong
I12
Float
G13.6
Long64, ULong64
I22
Double
G16.8
Complex
’(’, G13.6, ’,’, G13.6, ’)’
Double-precision Complex
’(’, G16.8, ’,’, G16.8, ’)’
String
Output full string on current line.
Table 11-2: Formats Used for Free-Format Output
2. The current output line is filled with characters until one of the following happens:
(a) There is no more data to output.
(b) The output line is full. When output is to a file, the default line width is 80
columns (you can override this default by setting the WIDTH keyword to the
Building IDL Applications
Using Free Format Input/Output
168
Chapter 11: Files and Input/Output
OPEN procedure). When the output is to the standard output, IDL uses the
current width of your tty or command log window.
(c) An entire row is output in the case of multidimensional arrays.
3. When outputting a structure variable, its contents are bracketed with “{” and “}”
characters.
Example: Free Format Input/Output
IDL free format input/output is extremely easy to use. The following IDL
statements demonstrate how to read into a complicated structure variable and
then print the results:
A = {TYPES, A:0B, B:0, C:0L, D:1.0, E:1D, $
F:COMPLEX(0), G: ’string’, E:FLTARR(5)}
Create a structure named “types”
that contains seven of the basic
IDL data types, as well as a floating-point array.
READ, A
Read free-formatted data from input
: 1 2 3 4 5 (6,7) EIGHT
IDL prompts for input with a colon. We enter values for the first six
numeric fields of A and the string.
Note Notice that the complex value was specified as (6, 7). If the parentheses had
been omitted, the complex field of A would have received the value COMPLEX(6, 0), and the 7 would have been input for the next field. When reading
into a string variable, IDL starts from the current point in the input and
continues to the end of the line. Thus, we do not enter values intended for the
rest of the structure on this line.
: 9 10 11 12 13
There are still fields of A that have
not received data, so IDL prompts
for another line of input.
PRINT, A
Show the result.
Executing these statements results in the following output:
{
1
2
Using Free Format Input/Output
3
4.00000
5.0000000
Building IDL Applications
Chapter 11: Files and Input/Output
(
6.00000,
9.00000
169
7.00000)
10.0000
eight
11.0000
12.0000
13.0000
}
When producing the output, IDL uses default rules for formatting the values and
attempts to place as many items as possible onto each line. Because the variable
A is a structure, braces {} are placed around the output. As noted above, when
IDL reads strings it continues to the end of the line. For this reason, it is usually
convenient to place string variables at the end of the list of variables to be input.
For example, if S is a string variable and I is an integer:
READ, S, I
Read into the string first.
: Hello World 34
IDL prompts for input. We enter a
string value followed by an integer.
: 34
The entire previous line was
placed into the string variable S,
and I still requires input. IDL
prompts for another line.
Using Explicitly Formatted Input/Output
The FORMAT keyword can be used with the formatted input/output routines to
explicitly specify the appearance of the data. The syntax of IDL format strings is
extremely similar to that used in FORTRAN. The format string specifies the
format in which data is to be transferred as well as the data conversion required
to achieve that format. The format specification strings supplied by the FORMAT
keyword have the form:
FORMAT = ’(q1f1s1f2s2 ... fnqn)’
where q, f, and s are described below.
Record Terminators
q is zero or more slash (/) record terminators. On output, each record terminator
causes the output to move to a new line. On input, each record terminator causes
the next line of input to be read.
Format Codes
f is a format code. Some format codes specify how data should be transferred
while others control some other function related to how input/output is handled.
The code f can also be a nested format specification enclosed in parentheses. This
is called a group specification and has the following form:
...[n](q1f1s1f2s2 ... fnqn) ...
Building IDL Applications
Using Explicitly Formatted Input/Output
170
Chapter 11: Files and Input/Output
A group specification consists of an optional repeat count n followed by a format
specification enclosed in parentheses. Use of group specifications allows more
compact format specifications to be written. For example, the format
specification:
FORMAT = ’("Result: ", "<",I5,">", "<",I5,">")’
can be written more concisely using a group specification:
FORMAT = ’("Result: ", 2("<",I5,">"))’
If the repeat count is 1 or is not given, the parentheses serve only to group format
codes for use in format reversion (discussed in the next section).
Field Separators
s is a field separator. A field separator consists of one or more commas (,) and/or
slash record terminators (/). The only restriction is that two commas cannot
occur side-by-side.
The arguments provided in a call to a formatted input/output routine are called
the argument list. The argument list specifies the data to be moved between
memory and the file. All data are handled in terms of basic IDL components.
Thus, an array is considered to be a collection of scalar data elements, and a
structure is processed in terms of its basic components. Complex scalar values are
treated as two floating-point values.
Rules for Explicitly Formatted Input/Output
IDL uses the following rules to process explicitly formatted input/output:
1. Traverse the format string from left to right, processing each record terminator
and format code until an error occurs or no data is left in the argument list. The
comma field separator serves no purpose except to delimit the format codes.
2. It is an error to specify an argument list with a format string that does not contain
a format code that transfers data to or from the argument list because an infinite
loop would result.
3. When a slash record terminator (/) is encountered, the current record is completed, and a new one is started. For output, this means that a new line is started. For
input, it means that the rest of the current input record is ignored, and the next
input record is read.
4. When a format code that does not transfer data to or from the argument list is
encountered, process it according to its meaning. The format codes that do not
transfer data to or from the argument list are summarized in Table 11-3.
Using Explicitly Formatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
171
Code
Action
Quoted String
On output, the contents of the string are written out. On input, quoted
strings are ignored.
:
The colon format code in a format string terminates format processing if
no more items remain in the argument list. It has no effect if data still
remains on the list.
$
On output, if a $ format code is placed anywhere in the format string, the
new line implied by the closing parenthesis of the format string is suppressed. On input, the $ format code is ignored.
nH
FORTRAN-style Hollerith string. Hollerith strings are treated exactly like
quoted strings.
nX
Skips n character positions.
Tn
Tab. Sets the character position of the next item in the current record.
TLn
Tab Left. Specifies that the next character to be transferred to or from the
current record is the n-th character to the left of the current position.
TRn
Tab Right. Specifies that the next character to be transferred to or from the
current record is the n-th character to the right of the current position.
Table 11-3: Format Codes that do not Transfer Data
5. When a format code that transfers data to or from the argument list is encountered, it is matched up with the next datum in the argument list. The format codes
that transfer data to or from the argument list are summarized in Table 11-4.
Code
Action
A
Transfer character data.
C()
Transfer calendar (Julian date and/or time) data.
Table 11-4: Format Codes that Transfer Data
Building IDL Applications
Using Explicitly Formatted Input/Output
172
Chapter 11: Files and Input/Output
Code
Action
D
Transfer double-precision, floating-point data.
E
Transfer floating-point data using scientific (exponential) notation.
F
Transfer floating-point data.
G
Use F or E format depending on the magnitude of the value being processed.
I
Transfer integer data.
O
Transfer octal data.
Q
Obtain the number of characters in the input record remaining to be transferred during a read operation. In an output statement, the Q format code
has no effect except that the corresponding input/output list element is
skipped.
Z
Transfer Hexadecimal data.
Table 11-4: Format Codes that Transfer Data
6. On input, read data from the file and format it according to the format code. If
the data type of the input data does not agree with the data type of the variable
that is to receive the result, do the type conversion if possible; otherwise, issue a
type conversion error and stop.
7. On output, write the data according to the format code. If the data type does not
agree with the format code, do the type conversion prior to doing the output if
possible. If the type conversion is not possible, issue a type conversion error and
stop.
8. If the last closing parenthesis of the format string is reached and there are no data
left on the argument list, then format processing terminates. If, however, there are
still data to be processed on the argument list, then part or all of the format
specification is reused. This process is called format reversion.
Format Reversion
In format reversion, the current record is terminated, a new one is initiated, and
format control reverts to the group repeat specification whose opening
parenthesis matches the next-to-last closing parenthesis of the format string. If
the format does not contain a group repeat specification, format control returns
to the initial opening parenthesis of the format string. For example, the IDL
command:
PRINT, FORMAT = ’("The values are: ", 2("<", I1, ">"))’, $
Using Explicitly Formatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
173
INDGEN(6)
results in the output
The values are: <0><1>
<2><3>
<4><5>
The process involved in generating this output is as follows:
1. Output the string “The values are: ”.
2. Process the group specification and output the first two values. The end of the
format specification is encountered, so end the output record. Data are remaining,
so move back to the group specification
2("<", I1, ">")
by format reversion.
3. Repeat Step 2 until no data remain. End the output record. Format processing is
complete.
Format Codes
“A” Format Code
The A format code transfers character data. The format is
[n]A[w]
where:
n
is an optional repeat count (1 ≤ n ≤ 32767) specifying the number of times
the format code should be processed. If n is not specified, a repeat count of
one is used.
w is an optional width (1 ≤ w ≤ 256), specifying the number of characters to be
transferred. If w is not specified, the entire string is transferred. On output,
if w is greater than the length of the string, the string is right justified. On
input, IDL strings have dynamic length, so w specifies the resulting length of
input string variables.
For example, the IDL statement,
PRINT, FORMAT = ’(A6)’, ’123456789’
generates the following output:
123456
Building IDL Applications
Format Codes
174
Chapter 11: Files and Input/Output
Note While an IDL string variable can hold up to 64 Kbytes of information, the
buffer than handles input at the IDL command prompt is limited to 255
characters. If for some reason you need to create a string variable longer than
255 characters at the IDL command prompt, split the variable into multiple
sub-variables and combine them with the “+” operator:
var = var1+var2+var3
This limit only affects string constants created at the IDL command prompt.
“:” Format Code
The colon format code terminates format processing if there are no more data
remaining in the argument list. For example, the IDL statement,
PRINT, FORMAT = ’(6(I1, :, ", "))’, INDGEN(6)
will output the following comma-separated list of integer values:
0, 1, 2, 3, 4, 5
The use of the colon format code prevented a comma from being output
following the final item in the argument list.
“$” Format Code
When IDL completes output format processing, it normally outputs a newline to
terminate the output operation. However, if a “$” format code is found in the
format specification, this default newline is not output. The “$” format code is
only used on output; it is ignored during input formatting. The most common
use for the “$” format code is in prompting for user input. For example, the IDL
statements,
PRINT, FORMAT = ’($, "Enter value: ")’
Prompt for input. Suppress the
carriage return.
READ, VALUE
Read the response.
will prompt for input without forcing the user’s response to appear on a separate
line from the prompt. Under VMS, the “$” format code does not work with files
opened with carriage-return carriage control, which is the default for new files.
However, it does work with explicit or FORTRAN carriage control. FORTRAN
carriage control is described in “Reading FORTRAN-Generated Unformatted
Data with IDL” on page 214.
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
175
“F,” “D,” “E,” and “G” Format Codes
The F, D, E, and G format codes are used to transfer floating-point values between
memory and the specified file. The format is
[n]F[w.d]
[n]D[w.d]
[n]E[w.d] or [n]E[w.dEe]
[n]G[w.d] or [n]G[w.dEe]
where
n
is an optional repeat count (1 ≤ n ≤ 32767) specifying the number of times
the format code should be processed. If n is not specified, a repeat count of 1
is used.
w.d is an optional width specification (1 ≤ w ≤ 256, 1 ≤ d < w). The variable w
specifies the number of characters in the external field. For the F, D, and E
format codes, d specifies the number of positions after the decimal point. For
the G format code, d specifies the number of significant digits displayed.
e
is an optional width (1 ≤ e ≤ 256) specifying the width of exponent part of the
field. IDL ignores this value—it is allowed for compatibility with FORTRAN.
On input, the F, D, E, and G format codes all transfer w characters from the
external field and assign them as a real value to the corresponding input/output
argument list datum.
The F and D format codes are used to output values using fixed-point notation.
The value is rounded to d decimal positions and right-justified into an external
field that is w characters wide. The value of w must be large enough to include a
minus sign when necessary, at least one digit to the left of the decimal point, the
decimal point, and d digits to the right of the decimal point. The code D is
identical to F (except for its default values for w and d) and exists in IDL
primarily for compatibility with FORTRAN.
The E format code is used for scientific (exponential) notation. The value is
rounded to d decimal positions and right-justified into an external field that is w
characters wide. The value of w must be large enough to include a minus sign
when necessary, at least one digit to the left of the decimal point, the decimal
point, d digits to the right of the decimal point, a plus or minus sign for the
exponent, the character “e” or “E”, and at least two characters for the exponent.
Note IDL uses a standard I/O function to format numbers and their exponents. As
a result, different platforms may print different numbers of exponent digits.
Building IDL Applications
Format Codes
176
Chapter 11: Files and Input/Output
The G format code uses the F output style when reasonable and E for other
values, but displays exactly d significant digits rather than d digits following the
decimal point.
On output, if the field provided is not wide enough, it is filled with asterisks (*)
to indicate the overflow condition. If w is zero, the “natural” width for the value
is used—the value is read or output using a default format without any leading
or trailing whitespace, in the style of the C standard input/output library printf
(3S) function. If w, d, or e are omitted, the values specified in Table 11-5 are used.
Data Type
w
d
e
Float, Complex
15
7
2 (3 for Windows)
Double
25
16
2 (3 for Windows)
All Other Types
25
16
2 (3 for Windows)
Table 11-5: Floating Format Defaults
Using a value of zero for the w parameter is useful when reading tables of data in
which individual elements may be of varying lengths. For example, if your data
reside in tables of the following form:
26.01 92.555 344.2
101.0 6.123 99.845
23.723 200.02 141.93
setting the format to
FORMAT = ’(3F0)’
ensures that the correct number of digits are read or output for each element.
Normally, the case of the format code is ignored by IDL. However, the case of the
E and G format codes determines the case used to output the exponent in
scientific notation. Table 11-6 gives examples of several floating-point formats
and the resulting output.
Format
Internal Value
Formatted Output
F
100.0
bbbb100.0000000
F
100.0D
bbbbb100.0000000000000000
F10.0
100.0
bbbbbb100.
Table 11-6: Floating-Point Output Examples (“b” represents a blank space)
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
177
Format
Internal Value
Formatted Output
F10.1
100.0
bbbbb100.0
F10.4
100.0
100.0000
F2.1
100.0
**
e10.4
100.0
1.0000e+02 (e+03 for Windows)
E10.4
100.0
1.0000E+02 (e+03 for Windows)
g10.4
100.0
100.0
g10.4
10000000.0
1.000e+07
Table 11-6: Floating-Point Output Examples (“b” represents a blank space)
“I,” “O,” and “Z” Format Codes
The I, O, and Z format codes are used to transfer integer values to and from the
specified file. The I format code is used to output decimal values, O is used for
octal values, and Z is used for hexadecimal values.
The format is as follows:
[n]I[w] or [n]I[w.m]
[n]O[w] or [n]O[w.m]
[n]Z[w] or [n]Z[w.m]
where
n
is an optional repeat count (1 ≤ n ≤ 32767) specifying the number of times
the format code should be processed. If n is not specified, a repeat count of 1
is used.
w is an optional integer value (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default values used if w is omitted are specified in Table 11-7
Data Type
w
Byte, Int, UInt
7
Long, ULong, Float
12
Long64, ULong64
22
Table 11-7: Integer Format Defaults
Building IDL Applications
Format Codes
178
Chapter 11: Files and Input/Output
Data Type
w
Double
23
All Other Types
12
Table 11-7: Integer Format Defaults
If the field provided is not wide enough, it is filled with asterisks (*) to indicate
the overflow condition. If w is zero, the “natural” width for the value is used—
the value is read or output using a default format without any leading or
trailing white space, in the style of the C standard input/output library printf
(3S) function.
Note that using a value of zero for the w parameter is useful when reading
tables of data in which individual elements may be of varying lengths. For
example, if your data reside in tables of the following form:
26 92 344
101 6 99
23 200 141
setting the format to
FORMAT = ’(3I0)’
ensures that the correct number of digits are read or output for each element.
m On output, m specifies the minimum number of nonblank digits required
(1 ≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted
or zero, the external field is blank filled.
Normally, the case of the format code is ignored by IDL. However, the case of the
Z format codes determines the case used to output the hexadecimal digits A-F.
Table 11-8 gives examples of several integer formats and the resulting output.
Format
Internal
Value
Formatted
Output
I
3000
bbb3000
I6.5
3000
b03000
I5.6
3000
*****
I2
3000
**
Table 11-8: Integer Output Examples (“b” represents a blank space)
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
179
Format
Internal
Value
Formatted
Output
O
3000
bbb5670
O6.5
3000
b05670
O5.6
3000
*****
O2
3000
**
z
3000
bbbbbb8
Z
3000
bbbbBB8
Z6.5
3000
b00bb8
Z5.6
3000
*****
Z2
3000
**
Table 11-8: Integer Output Examples (“b” represents a blank space)
“Q” Format Code
The Q format code returns the number of characters in the input record
remaining to be transferred during the current read operation. It is ignored
during output formatting. Format Q is useful for determining how many
characters have been read on a line. For example, the following IDL statements
count the number of characters in file demo.dat:
OPENR, 1, "demo.dat"
Open file for reading.
N = 0L
Create a longword integer to keep
the count.
WHILE(NOT EOF(1)) DO BEGIN
Count the characters.
READF, 1, CUR, FORMAT = ’(q)’ & N = N + CUR
END
PRINT, FORMAT = ’("counted", N, "characters.")’
Report the result.
CLOSE, 1
Close file.
Quoted String and “H” Format Codes
On output, any quoted strings or Hollerith constants are sent directly to the
output. On input, they are ignored. For example, the IDL statement,
PRINT, FORMAT = ’("Value: ", I0)’, 23
Building IDL Applications
Format Codes
180
Chapter 11: Files and Input/Output
results in the following output:
Value: 23
Notice the use of single quotes around the entire format string and double quotes
around the quoted string inside the format. This is necessary because we are
including quotes inside a quoted string. It would have been equally correct to use
double quotes around the entire format string and single quotes internally.
Another way to specify the string is with a Hollerith constant as follows:
PRINT, FORMAT = ’(7HValue: , I0)’, 23
The format for a Hollerith constant is:
nHc1c2 c3 ... cn
where
n
is the number of characters in the constant (1 ≤ n ≤ 255).
ci
is the characters that make up the constant. The number of characters must
agree with the value provided for n.
“T” Format Code
The T format code specifies the absolute position in the current record. The
format is
Tn
where
n
is the absolute character position within the record to which the current
position should be set (1 ≤ n ≤ 32767).
T
differs from the TL, TR, and X format codes primarily in that it requires an
absolute position rather than an offset from the current position. For
example,
PRINT, FORMAT = ’("First", 20X, "Last", T10, "Middle")’
produces the following output:
FirstbbbbMiddlebbbbbbbbbbLast
where “b” represents a blank space.
“TL” Format Code
The TL format code moves the current position in the external record to the left.
The format is
TLn
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
181
where
n
is the number of characters to move left from the current position
(1 ≤ n ≤ 32767). If the value of n is greater than the current position, the
current position is moved to column one.
TL is used to move backwards in the current record. It can be used on input to
read the same data twice or on output to position the output nonsequentially.
For example,
PRINT, FORMAT = ’("First", 20X, "Last", TL15, "Middle")’
produces the following output:
FirstbbbbbbbbbMiddlebbbbbLast
where “b” represents a blank space.
“TR” and “X” Format Codes
The TR and X format codes move the current position in the record to the right.
The format is
TRn
nX
where
n
is the number of characters to skip (1 ≤ n ≤ 32767). On input, n characters in
the current input record will be passed over. On output, the current output
position is moved n characters to the right.
The TR or X format codes can be used to leave whitespace in the output or to skip
over unwanted data in the input. For example,
PRINT, FORMAT = ’("First", 15X, "Last")’
or
PRINT, FORMAT = ’("First", TR15, "Last")’
results in the following output:
FirstbbbbbbbbbbbbbbbLast
where “b” represents a blank space.
These two format codes differ in one way. Using the X format code at the end of
an output record will not cause any characters to be written unless it is followed
by another format code that causes characters to be output. The TR format code
always writes characters in this situation. Thus,
Building IDL Applications
Format Codes
182
Chapter 11: Files and Input/Output
PRINT, FORMAT = ’("First", 15X)’
does not leave 15 blanks at the end of the line, but the following statement does:
PRINT, FORMAT = ’("First", 15TR)’
“C()” Format Code
The C() format code is used to transfer calendar (Julian date and/or time) data.
The format is
[n]C([c0,c1,…,cx])
where:
n
is an optional repeat count (1 ≤ n ≤ 32767) specifying the number of times
the format code should be processed. If n is not specified, a repeat count of 1
is used.
ci
represents optional calendar format subcodes, or any of the standard format
codes that are allowed within a calendar specification, as described below. If
no ci are provided, the data will be transferred using the standard 24character system format that includes the day, date, time, and year, as shown
in this string:
Thu Aug 13 12:01:32 1979
This default is equivalent (for output) to:
C(CDWA, X, CMoA, X, CDI, X, CHI, ":", CMI, ":", CSI, X, CYI)
Note The C() format code represents an atomic data transfer. Nesting within the
parentheses is not allowed.
Calendar Format Subcodes
The following is a list of the subcodes allowed within the parenthesis of the C
format code:
"CMOA" subcodes
The CMOA subcodes transfers the month portion of a date as a string. The
format for an all upper case month string is:
CMOA[w]
The format for a capitalized month string is:
CMoA[w]
The format for an all lower case month string is:
CmoA[w]
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
183
Note The case of the ‘M’ and ‘O’ of these subcodes will be ignored on input, or if
the MONTHS keyword for the current routine is explicitly set.
For these subcodes:
w is an optional width (0 ≤ w ≤ 256) specifying the number of characters of the
month name to be transferred. If w is not specified, three characters will be
transferred. If w is 0, the natural length of the month name is transferred. On
output, if w is greater than the natural length of the month name, the string
will be right justified.
"CMOI" subcode
The CMOI subcode transfers the month portion of a date as an integer. The
format is as follows:
CMOI[w] or CMOI[w.m]
where:
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 2.
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
“CDI” subcode
The CDI subcode transfers the day portion of a date as an integer. The format is
as follows:
CDI[w] or CDI[w.m]
where:
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 2.
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
"CYI" subcode
The CYI subcode transfers the year portion of a date as an integer. The format is
as follows:
CYI[w] or CYI[w.m]
where:
Building IDL Applications
Format Codes
184
Chapter 11: Files and Input/Output
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 4.
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
"CHI" subcodes
The CHI subcodes transfer the hour portion of a date as an integer. The format
for 24 hour based integer is:
CHI[w] or CHI[w.m]
The format for a 12 hour based integer is:
ChI[w] or ChI[w.m]
For these subcodes:
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 2.
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
"CMI" subcode
The CMI subcode transfers the minute portion of a date as an integer. The format
is as follows:
CMI[w] or CMI[w.m]
where:
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 2.
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
"CSI" subcode
The CSI subcode transfers the seconds portion of a date as an integer. The format
is as follows:
CSI[w] or CSI[w.m]
where:
w is an optional width (1 ≤ w ≤ 256) specifying the width of the field in
characters. The default width is 2.
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
185
m On output, m specifies the minimum number of nonblank digits required (1
≤ m ≤ 256). The field is zero-filled on the left if necessary. If m is omitted or
zero, the external field is blank filled.
"CSF" subcode
The CSF subcode transfers the seconds portion of a date as a floating point value.
The format is as follows:
CSF[w.d]
where:
w.d is an optional width specification (1 ≤ w ≤ 256, 1 ≤ d ≤ w). The variable w
specifies the number of characters in the external field; the default is 5. The
variable d specifies the number of positions after the decimal point; the
default is 2. The value of w must be large enough to include at least one digit
to the left of the decimal point, the decimal point, and d digits to the right of
the decimal point. On output, if the field provided is not wide enough, it is
filled with asterisks (*) to indicate the overflow condition. If w is zero, the
“natural” width for the value is used – the value is read or output using a
default format without any leading or trailing whitespace, in the style of the
C standard library printf (3S) function.
"CDWA" subcodes
The CDWA subcodes transfers the day of week portion of a data as a string. The
format for an all upper case day of week string is:
CDWA[w]
The format for a capitalized day of week string is:
CDwA[w]
The format for an all lower case day of week string is:
CdwA[w]
Note The case of the ‘D’ and ‘W’ of these subcodes will be ignored on input, or if
the DAYS_OF_WEEK keyword for the current routine is explicitly set.
For these subcodes:
w is an optional width (0 ≤ w ≤ 256), specifying the number of characters of the
day of week name to be transferred. If w is not specified, three characters will
be transferred. If w is 0, the natural length of the day of week name is
transferred. On output, if w is greater than the natural length of the day of
week name, the string will be right justified.
Building IDL Applications
Format Codes
186
Chapter 11: Files and Input/Output
"CAPA" subcodes
The CAPA subcodes transfers the am or pm portion of a date as a string. The
format for an all upper case AM or PM string is:
CAPA[w]
The format for a capitalized AM or PM string is:
CApA[w]
The format for an all lower case AM or PM string is:
CapA[w]
Note The case of the first ‘A’ and ‘P’ of these subcodes will be ignored on input, or
if the AM_PM keyword for the current routine is explicitly set.
For these subcodes:
w is an optional width (0 ≤ w ≤ 256), specifying the number of characters of the
AM or PM string to be transferred. If w is not specified, two characters will
be transferred. If w is 0, the natural length of the AM or PM string is
transferred. On output, if w is greater than the natural length of the AM or
PM string, the string will be right justified.
Standard Format Codes Allowed within a Calendar Specification
None of these subcodes are allowed outside of a C() format specifier. In addition
to the subcodes listed above, only quoted strings and “X” format codes are
allowed inside of the C() format specifier.
Example:
To print the current date in the default format:
PRINT, FORMAT=’(C())’, SYSTIME(/JULIAN)
The printed result should look something like:
Fri Aug 14 12:34:14 1998
Example:
To print the current date as a two-digit month value followed by a slash followed
by a two-digit day value:
PRINT, FORMAT=’(C(CMOI,"/",CDI))’,SYSTIME(/JULIAN)
The printed result should look something like:
8/14
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
187
Example: Reading Tables of Formatted Data
IDL explicitly formatted input/output has the power and flexibility to handle
almost any kind of formatted data. A common use of explicitly formatted
input/output involves reading and writing tables of data. Consider a data file
containing employee data records. Each employee has a name (String, 32
columns) and the number of years they have been employed (Integer, 3 columns)
on the first line. The next two lines contain each employee’s monthly salary for
the last twelve months. A sample file named employee.dat with this format might
look like the following:
Bullwinkle
10
1000.0
9000.97
1100.0
5000.0
3000.0
1000.12
Boris
500.0
1300.10
200.0
100.0
100.0
Natasha
2600.0
3500.0
6000.0
900.0
11
400.0
950.0
2000.0
350.0
745.0
3000.0
50.0
60.0
0.25
410.0
797.0
200.36
2000.0
1000.0
10
1050.0
2000.0
1350.0
1500.0
Rocky
400.0
11
1000.0
9000.0
1100.0
5000.0
3000.0
1000.01
0.0
0.0
2000.37
3500.0
6000.0
900.12
The following IDL statements read data with the above format and produce a
summary of its contents:
OPENR, 1, ’employee.dat’
Open data file for input.
name = ’’ & years = 0 & salary = FLTARR(12)
Create variables to hold the name,
number of years, and monthly salary.
PRINT, FORMAT=’("Name", 28X, "Years", 4X, "Yearly Salary")’
Output a heading for the summary.
PRINT, ’========’
Note: The actual dashed line is
longer than is shown here.
WHILE (NOT EOF(1)) DO BEGIN
Loop over each employee.
Building IDL Applications
Format Codes
188
Chapter 11: Files and Input/Output
Read the data on the next employee.
READF, 1, $
FORMAT = ’(A32,I3,2(/,6F10.2))’, name, years, salary
PRINT, FORMAT=’(A32,I5,5X,F10.2)’, name, years, TOTAL(salary)
Output the employee information. Use TOTAL to sum the
monthly salaries to get the yearly
salary.
ENDWHILE
CLOSE, 1
The output from executing these statements on employee.dat is as follows:
Name
Years
Yearly Salary
======================================================
Bullwinkle
10
32501.09
Borris
11
6805.35
Natasha
10
14257.36
Rocky
11
32500.50
Example: Reading Records that Contain Multiple Array Elements
Frequently, data are written to files with each record containing single elements
of more than one array. One example might be a file consisting of observations
of altitude, pressure, temperature, and velocity with each line or record
containing a value for each of the four variables. Because IDL has no equivalent
of the FORTRAN implied DO list, special procedures must be used to read or
write this type of file.
The first approach, which is the simplest, may be used only if all of the variables
have the same data type. An array is created with as many columns as there are
variables and as many rows as there are elements. The data are read into this array,
the array is transposed storing each variable as a row, and each row is extracted
and stored into a variable which becomes a vector. For example, the FORTRAN
program which writes the data and the IDL program which reads the data are as
follows:
FORTRAN Write:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
OPEN (UNIT = 1, STATUS=’NEW’, FILE=’TEST’)
WRITE(1,’(4(1x,g15.5))’)
(ALT(I),PRES(I),TEMP(I),VELO(I),I=1,100)
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
IDL Read:
OPENR, 1, ’test’
189
Open file for input.
A = FLTARR(4,100)
Define variable (NVARS by
NOBS).
READF, 1, A
Read the data.
A = TRANSPOSE(A)
Transpose so that columns become
rows.
ALT = A[*, 0]
Extract the variables.
PRES = A[*, 1]
TEMP = A[*, 2]
VELO = A[*, 3]
Note that this same example may be written without the implied DO list, writing
all elements for each variable contiguously and simplifying matters considerably:
FORTRAN Write:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
OPEN (UNIT = 1, STATUS=’NEW’, FILE=’TEST’)
WRITE (1,’(4(1x,G15.5))’) ALT,PRES,TEMP,VELO
IDL Read:
ALT = FLTARR(100)
Define variables.
PRES = ALT & TEMP = ALT & VELO = ALT
OPENR, 1, ’test’
READF, 1, ALT, PRES, TEMP, VELO
A different approach must be taken when the columns contain different data
types or the number of lines or records are not known. This method involves
defining the arrays, defining a scalar variable to contain each datum in one
record, then writing a loop to read each line into the scalars, and then storing the
scalar values into each array. For example, assume that a fifth variable, the name
of an observer which is of string type, is added to the variable list. The FORTRAN
output routine and IDL input routine are as follows:
FORTRAN Write:
DIMENSION ALT(100),PRES(100),TEMP(100),VELO(100)
CHARACTER * 10 OBS(100)
OPEN (UNIT = 1, STATUS = ’NEW’, FILE = ’TEST’)
WRITE (1,’(4(1X,G15.5),2X,A)’)
(ALT(I),PRES(I),TEMP(I),VELO(I),OBS(I),I=1,100)
Building IDL Applications
Format Codes
190
Chapter 11: Files and Input/Output
IDL Read:
OPENR, 1, ’test’
ALT = FLTARR(200)
Access file. This example will read
files containing from 1 to 200
records.
Define vector, make it large
enough for the biggest case.
PRES = ALT & TEMP = ALT & VELO = ALT Define other vectors using the first.
OBS = STRARR(200)
Define string array.
OBSS = ’’
Define scalar string.
I = 0
Initialize counter.
WHILE NOT EOF(1) DO BEGIN
Read loop.
READF, 1, $
Read scalars.
FORMAT = ’(4(1X, G15.5), 2X, A10)’, $
ALTS, PRESS, TEMPS, VELOS, OBSS
ALT[I] = ALTS & PRES[I] = PRESS & TEMP[I] = TEMPS
VELO[I] = VELOS & OBS[I] = OBSS
Store in each vector.
IF I LT 199 THEN I = I + 1 ELSE STOP, ’Too many records’
Increment counter and check for
too many records.
ENDWHILE
Done.
If desired, after the file has been read and the number of observations is known,
the arrays may be truncated to the correct length using a series of statements
similar to the following:
ALT = ALT[0:I-1]
The above statement represents a worst case example. Reading is greatly
simplified by writing data of the same type contiguously and by knowing the size
of the file. One frequently used technique is to write the number of observations
into the first record so that when reading the data the size is known.
Caution It might be tempting to implement a loop in IDL which reads the data values
directly into array elements, using a statement such as the following:
FOR I = 0, 99 DO READF, 1, ALT[I], PRES[I], TEMP[I], VELO[I]
This statement is incorrect. Subscripted elements (including ranges) are
temporary expressions passed as values to procedures and functions (READF
in this example). Parameters passed by value do not pass results back to the
Format Codes
Building IDL Applications
Chapter 11: Files and Input/Output
191
caller. The proper approach is to read the data into scalars and assign the
values to the individual array elements as follows:
A = 0. & P = 0. & T = 0. & V = 0.
FOR I = 0, 99 DO BEGIN
READF, 1, A, P, T, V
ALT[I] = A & PRES[I] = P & TEMP[I] = T & VELO[I] = V
ENDFOR
Using Unformatted Input/Output
Unformatted input/output involves the direct transfer of data between a file and
memory without conversion to and from a character representation.
Unformatted input/output is used when efficiency is important and portability is
not an issue. It is faster and requires less space than formatted input/output. IDL
provides three procedures for performing unformatted input/output:
READU
Reads unformatted data from the specified file unit.
WRITEU
Writes unformatted data to the specified file unit.
ASSOC
Maps an array structure to a logical file unit, providing efficient and convenient
direct access to data.
This section discusses READU and WRITEU, while ASSOC is discussed in
“Associated Input/Output” on page 202. The READU and WRITEU procedures
provide IDL’s basic unformatted input/output capabilities. They have the form:
READU, Unit, Var1, ..., Varn
WRITEU, Unit, Var1, ..., Varn
where
Unit The logical file unit with which the input/output operation will be
performed.
Vari One or more IDL variables (or expressions in the case of output).
Building IDL Applications
Using Unformatted Input/Output
192
Chapter 11: Files and Input/Output
The WRITEU procedure writes the contents of its arguments directly to the file,
and READU reads exactly the number of bytes required by the size of its
arguments. Both cases directly transfer binary data with no interpretation or
formatting.
Unformatted Input/Output of String Variables
Strings are the only basic IDL data type that do not have a fixed size. A string
variable has a dynamic length that is dependent only on the length of the string
currently assigned to it. Thus, although it is always possible to know the length of
the other types, string variables are a special case. IDL uses the following rules to
determine the number of characters to transfer:
Input
Input enough bytes to fill the original length of the string. The length of the
resulting string is truncated if the data contains a null byte.
Output
Output the number of bytes contained in the string. This number is the same
number returned by the STRLEN function and does not include a terminating
null byte.
Note that these rules imply that when reading into a string variable from a file,
you must know the length of the original string so as to be able to initialize the
destination string to the correct length. For example, the following IDL
statements produce the following output, because the receiving variable A was
not long enough.
OPENW, 1, ’temp.tmp’
Open a file.
WRITEU, 1, ’Hello World’
Write an 11-character string.
POINT_LUN, 1, 0
Rewind the file.
A = ’
Prepare a nine-character string.
’
READU, 1, A
Read back in the string.
PRINT, A
Show what was input.
CLOSE, 1
produce the following, because the receiving variable A was not long enough:
Hello Wor
The only solution to this problem is to know the length of the string being input.
The following IDL statements demonstrate a useful “trick” for initializing strings
to a known length:
Using Unformatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
193
OPENW, 1, ’temp.tmp’
Open a file.
WRITEU, 1, ’Hello World’
Write an 11-character string.
POINT_LUN, 1, 0
Rewind the file.
A = STRING(REPLICATE(32B,11))
Create a string of the desired
length initialized with blanks.
REPLICATE creates a byte array
of 11 elements, each element initialized to 32, which is the ASCII
code for a blank. Passing this byte
array to STRING converts it to a
scalar string containing 11 blanks.
READU, 1, A
Read in the string.
PRINT, A
Show what was input.
CLOSE, 1
This example takes advantage of the special way in which the BYTE and STRING
functions convert between byte arrays and strings. See the description of the
BYTE and STRING functions for additional details.
Example: Reading C-Generated Unformatted Data with IDL
The following C program produces a file containing employee records. Each
record stores the first name of each employee, the number of years he has been
employed, and his salary history for the last 12 months.
#include <stdio.h>
main()
{
static struct rec {
char name[32]; /* Employee’s name */
int years;
/* # of years with company */
float salary[12]; /* Salary for last 12 months */
} employees[] = {
{ {’B’,’u’,’l’,’l’,’w’,’i’,’n’,’k’,’l’,’e’}, 10,
Building IDL Applications
Using Unformatted Input/Output
194
Chapter 11: Files and Input/Output
{1000.0, 9000.97, 1100.0, 0.0, 0.0, 2000.0,
5000.0, 3000.0, 1000.12, 3500.0, 6000.0, 900.0} },{
{’B’,’o’,’r’,’r’,’i’,’s’}, 11,
{400.0, 500.0, 1300.10, 350.0, 745.0, 3000.0,
200.0, 100.0, 100.0, 50.0, 60.0, 0.25} },
{ {’N’,’a’,’t’,’a’,’s’,’h’,’a’}, 10,
{950.0, 1050.0, 1350.0, 410.0, 797.0, 200.36,
2600.0, 2000.0, 1500.0, 2000.0, 1000.0, 400.0} },
{ {’R’,’o’,’c’,’k’,’y’}, 11,
{1000.0, 9000.0, 1100.0, 0.0, 0.0, 2000.37,
5000.0, 3000.0, 1000.01, 3500.0, 6000.0, 900.12}}
};
FILE *outfile;
outfile = fopen("data.dat", "w");
(void) fwrite(employees, sizeof(employees), 1, outfile);
(void) fclose(outfile);
}
Running this program creates the file data.dat containing the employee records.
The following IDL statements can be used to read and print this file:
STR32 = STRING(REPLICATE(32B, 32))
Create a string with 32 characters
so that the proper number of characters will be input from the file.
REPLICATE is used to create a
byte array of 32 elements, each
containing the ASCII code for a
space (32). STRING turns this
byte array into a string containing
32 blanks.
A = REPLICATE({EMPLOYEES, NAME:STR32, YEARS:0L, $
SALARY:FLTARR(12)}, 4)
Create an array of four employee
records to receive the input data.
OPENR, 1, ’data.dat’
Open the file for input.
READU, 1, A
Read the data.
CLOSE, 1
Show the results.
PRINT, A
Executing these IDL statements produces the following output:
{ Bullwinkle
Using Unformatted Input/Output
10
Building IDL Applications
Chapter 11: Files and Input/Output
195
1000.00
9000.97
1100.00
0.00000
0.00000
2000.00
5000.00
3000.00
1000.12
3500.00
6000.00
900.000
}{Borris
11
400.000
500.000
1300.10
350.000
745.000
3000.00
200.000
100.000
100.000
50.0000
60.0000
0.250000
}{ Natasha
10
950.000
1050.00
1350.00
410.000
797.000
200.360
2600.00
2000.00
1500.00
2000.00
1000.00
400.000
}{ Rocky
11
1000.00
9000.00
1100.00
0.00000
0.00000
2000.37
5000.00
3000.00
1000.01
3500.00
6000.00
900.120
}
Example: Reading IDL-Generated Unformatted Data with C
The following IDL program creates an unformatted data file containing a 5 x 5
array of floating-point values:
OPENW, 1, ’data.dat’
Open a file for output.
WRITEU, 1, FINDGEN(5, 5)
Write 5x5 array with each element
set to its 1-dimensional index.
CLOSE, 1
This file can be read and printed by the following C program:
#include <stdio.h>
main()
{
float data[5][5];
FILE *infile; int i, j;
infile = fopen("data.dat", "r");
(void) fread(data, sizeof(data), 1, infile);
(void) fclose(infile);
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++)
printf("%8.1f", data[i][j]);
printf("\n");
}
}
Building IDL Applications
Using Unformatted Input/Output
196
Chapter 11: Files and Input/Output
Running this program gives the following output:
0.0
5.0
10.0
15.0
20.0
1.0
6.0
11.0
16.0
21.0
2.0
7.0
12.0
17.0
22.0
3.0
8.0
13.0
18.0
23.0
4.0
9.0
14.0
19.0
24.0
Example: Reading a Sun Rasterfile from IDL
Sun computers use rasterfiles to store scanned images. This example shows how
to read such an image and display it using IDL. In the interest of keeping the
example brief, a number of simplifications are made, no error checking is
performed, and only 8-bit deep rasterfiles are handled. See the READ_SRF
procedure (the file read_srf.pro in the lib subdirectory of the IDL
distribution) for a complete example. The format used for rasterfiles is
documented in the C header file /usr/include/rasterfile.h. That file provides the
following information:
Each file starts with a fixed header that describes the image. In C, this header is
defined as follows:
struct rasterfile{
int ras_magic; /* magic number */
int ras_width; /* width (pixels) of image */
int ras_height; /* height (pixels) of image */
int ras_depth; /* depth (1, 8, or 24 bits) */
int ras_length; /* length (bytes) of image */
int ras_type; /* type of file */
int ras_maptype; /* type of colormap */
int ras_maplength; /* length(bytes) of colormap */ };
The color map, if any, follows directly after the header information. The image
data follows directly after the color map.
The following IDL statements read an 8-bit deep image from the file ras.dat:
h = {rasterfile, magic:0L, width:0L, height:0L, depth: 0L,$
length:0L, type:0L, maptype:0L, maplength:0L}
Define IDL structure that match-
es the Sun-defined rasterfile structure. A C int variable on a Sun
corresponds to an IDL LONG int.
OPENR, unit, file, /GET_LUN
Open the file, allocating a file unit
at the same time.
READU, unit, h
Read the header information.
Using Unformatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
197
IF ((h.maptype EQ 1) AND (h.maplength NE 0) ) THEN BEGIN
Is there a color map?
maplen = h.maplength/3
Calculate length of each vector.
r=(g=(b=BYTARR(maplen, /NOZERO))) Create three byte vectors to hold
the color map.
READU, unit, r, g, b
Read the color map.
ENDIF
image = BYTARR(h.width, h.height, /NOZERO)
Create a byte array to hold image.
READU, unit, image
Read the image.
FREE_LUN, unit
Free the previously-allocated Logical Unit Number and close the
file.
Portable Unformatted Input/Output
Normally, unformatted input/output is not portable between different machine
architectures because of differences in the way various machines represent binary
data. However, it is possible to produce binary files that are portable by specifying
the XDR keyword with the OPEN procedures. XDR (for eXternal Data
Representation) is a scheme under which all binary data is written using a
standard “canonical” representation. All machines supporting XDR understand
this standard representation and have the ability to convert between it and their
own internal representation.
XDR represents a compromise between the extremes of unformatted and
formatted input/output:
•
It is not as efficient as purely unformatted input/output because it does involve
the overhead of converting between the external and internal binary representations.
•
It is still much more efficient than formatted input/output because conversion to
and from ASCII characters is much more involved than converting between
binary representations.
•
It is much more portable than purely unformatted data, although it is still limited
to those machines that support XDR. However, XDR is freely available and can
be moved to any system.
Building IDL Applications
Portable Unformatted Input/Output
198
Chapter 11: Files and Input/Output
XDR Considerations
The primary differences in the way IDL input/output procedures work with XDR
files, as opposed to files opened normally are as follows:
•
To use XDR, you must specify the XDR keyword when opening the file.
•
The only input/output data transfer routines that can be used with a file opened
for XDR are READU and WRITEU.
•
XDR converts between the internal and standard external binary representations
for data instead of simply using the machine’s internal representation.
•
Since XDR adds extra “bookkeeping” information to data stored in the file and
because the binary representation used may not agree with that of the machine
being used, it does not make sense to access an XDR file without using XDR.
•
OPENW and OPENU normally open files for both input and output. However,
XDR files can only be opened in one direction at a time. Thus, using these
procedures with the XDR keyword results in a file open for output only. OPENR
works in the usual way.
•
The length of strings is saved and restored along with the string. This means that
you do not have to initialize a string of the correct length before reading a string
from the XDR file. (This is necessary with normal unformatted input/output and
is described in “Using Unformatted Input/Output” on page 191).
•
For efficiency reasons, byte arrays are transferred as a single unit; therefore, byte
variables must be initialized to the correct number of elements for the data to be
input, or an error will occur. For example, given the statements,
OPENW, /XDR, 1, ’data.dat’
Open a file for XDR output.
WRITEU, 1, BINDGEN(10)
Write a 10-element byte array.
CLOSE, 1 & OPENR, /XDR, 1, ’data.dat’
Close the file and re-open it for input.
then the statement,
B = 0B & READU, 1, B
Try to read the first byte only.
results in the following error:
% READU: Error encountered reading from file unit: 1.
Portable Unformatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
199
Instead, it is necessary to read the entire byte array back in one operation using a
statement such as:
Read the whole array back at once.
B=BYTARR(10) & READU, 1, B
This restriction does not exist for other data types.
•
Under VMS, XDR is only possible with stream mode files.
IDL XDR Conventions for Programmers
IDL uses certain conventions for reading and writing XDR files. If your only use
of XDR is through IDL, you do not need to be concerned about these conventions
because IDL takes care of it for you. However, programmers who want to create
IDL-compatible XDR files from other languages need to know the actual XDR
routines used by IDL for various data types. The table below summarizes this
information.
Data Type
XDR routine
Byte
xdr_bytes()
Integer
xdr_short()
Long
xdr_long()
Float
xdr_float()
Double
xdr_double()
Complex
xdr_complex()
String
xdr_counted_string()
Table 11-9: XDR Routines Used by IDL
The routines used for type COMPLEX and STRING are not primitive XDR
routines. Their definitions are as follows:
bool_t xdr_complex(xdrs, p)
XDR *xdrs;
struct complex { float r, i} *p;
{
return(xdr_float(xdrs, (char *) &p->r) &&
xdr_float(xdrs, (char *) &p->i));
}
bool_t xdr_counted_string(xdrs, p)
XDR *xdrs;
char **p;
{
int input = (xdrs->x_op == XDR_DECODE);
Building IDL Applications
Portable Unformatted Input/Output
200
Chapter 11: Files and Input/Output
short length;
/* If writing, obtain the length */
if (!input) length = strlen(*p);
/* Transfer the string length */
if (!xdr_short(xdrs, (char *) &length)) return(FALSE);
/* If reading, obtain room for the string */
if (input)
{
*p = malloc((unsigned) (length + 1));
*p[length] = ’\0’; /* Null termination */
}
/* If the string length is nonzero, transfer it */
return(length ? xdr_string(xdrs, p, length) : TRUE);
}
Portable Unformatted Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
201
Example: Reading C-Generated XDR Data with IDL
The following C program produces a file containing different types of data using
XDR. The usual error checking is omitted for the sake of brevity.
#include <stdio.h>
#include <rpc/rpc.h>
[ xdr_complex() and xdr_counted_string() included here ]
main()
{
static struct {
/* Output data */
unsigned char c;
short s;
long l;
float f;
double d;
struct complex { float r, i } cmp;
char *str;
}
data = {1, 2, 3, 4, 5.0, { 6.0, 7.0}, "Hello" };
u_int c_len = sizeof(unsigned char); /* Length of a char */
char *c_data = (char *) &data.c;
/* Addr of byte field */
FILE *outfile;
/* stdio stream ptr */
XDR xdrs;
/* XDR handle */
/* Open stdio stream and XDR handle */
outfile = fopen("data.dat", "w");
xdrstdio_create(&xdrs, outfile, XDR_ENCODE);
/* Output the data */
(void) xdr_bytes(&xdrs, &c_data, &c_len, c_len);
(void) xdr_short(&xdrs, (char *) &data.s);
(void) xdr_long(&xdrs, (char *) &data.l);
(void) xdr_float(&xdrs, (char *) &data.f);
(void) xdr_double(&xdrs, (char *) &data.d);
(void) xdr_complex(&xdrs, (char *) &data.cmp);
(void) xdr_counted_string(&xdrs, &data.str);
/* Close XDR handle and stdio stream */
xdr_destroy(&xdrs);
(void) fclose(outfile);
}
Running this program creates the file data.dat containing the XDR data. The
following IDL statements can be used to read this file and print its contents:
DATA={S, C:0B, S:0, L:0L, F:0.0, D:0.0D, CMP:COMPLEX(0), STR:’’}
Create structure containing correct types.
Building IDL Applications
Portable Unformatted Input/Output
202
Chapter 11: Files and Input/Output
OPENR, /XDR, 1, ’data.dat’
Open the file for input.
READU, 1, DATA
Read the data.
CLOSE, 1
Close the file.
PRINT, DATA
Show the results.
Executing these IDL statements produces the output:
{
(
1
2
6.00000,
3
4.00000
5.0000000
7.00000) Hello}
For further details about XDR, consult the XDR documentation for your
machine. Sun users should consult their Network Programming manual.
Associated Input/Output
Unformatted data stored in files often consists of a repetitive series of arrays or
structures. A common example is a series of images. IDL-associated file variables
offer a convenient and efficient way to access such data.
An associated variable is a variable that maps the structure of an IDL array or
structure variable onto the contents of a file. The file is treated as an array of these
repeating units of data. The first array or structure in the file has an index of zero,
the second has index one, and so on. Such variables do not keep data in memory
like a normal variable. Instead, when an associated variable is subscripted with
the index of the desired array or structure within the file, IDL performs the
input/output operation required to access the data.
When their use is appropriate (the file consists of a sequence of identical arrays
or structures), associated file variables offer the following advantages over
READU and WRITEU for unformatted input/output:
•
Input/output occurs when an associated file variable is subscripted. Thus, it is
possible to perform input/output within an expression without a separate input/output statement.
•
The size of the data set is limited primarily by the maximum size of the file
containing the data instead of the maximum memory available. Data sets too large
for memory can be accessed.
•
There is no need to declare the maximum number of arrays or structures contained in the file.
•
Associated variables systematize access to the data. Direct access to any element
in the file is rapid and simple—there is no need to calculate offsets into the file
and/or position the file pointer prior to performing the input/output operation.
Associated Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
•
203
Associated variables are the most efficient form of IDL input/output.
An associated file variable is created by assigning the result of the ASSOC
function to a variable. See “ASSOC” on page 204 of the IDL Reference Guide for
details.
Example of Using Associated Input/Output
Assume that a file named data.dat exists, and that this file contains a series of
10 x 20 arrays of floating-point data. The following two IDL statements open the
file and create an associated file variable mapped to the file:
OPENU, 1, ’data.dat’
Open the file.
A = ASSOC(1, FLTARR(10, 20, /NOZERO))
Make a file variable. Using the
NOZERO keyword with FLTARR
increases efficiency.
The order of these two statements is not important—it would be equally valid to
call ASSOC first, and then open the file. This is because the association is between
the variable and the logical file unit, not the file itself. It is also legitimate to close
the file, open a new file using the same LUN, and then use the associated variable
without first executing a new ASSOC. Naturally, an error occurs if the file is not
open when the file variable is subscripted in an expression or if the file is open for
the wrong type of access (for example, trying to assign to an associated file
variable linked with a file opened for read-only access).
As a result of executing the two statements above, the variable A is now an
associated file variable. Executing the statement,
HELP, A
gives the following response:
A
FLOAT
= File<data.dat> Array(10, 20)
The associated variable A maps the structure of a 10 x 20, floating-point array
onto the contents of the file data.dat. Thus, the response from the HELP
procedure shows it as having the structure of a two-dimensional array. An
associated file variable only performs input/output to the file when it is
subscripted. Thus, the following two IDL statements do not cause input/output
to happen:
B = A
This assignment does not transfer data from the file to variable B because A is not
subscripted. Instead, B becomes an associated file variable with the same
structure, and to the same logical file unit, as A.
Building IDL Applications
Associated Input/Output
204
Chapter 11: Files and Input/Output
B = 23
This assignment does not result in the value 23 being transferred to the file
because variable B (which became a file variable in the previous statement) is not
subscripted. Instead, B becomes a scalar integer variable containing the value 23.
It is no longer an associated file variable.
Reading Data from Associated Files
Once a variable has been associated with a file, data are read from the file
whenever the associated variable appears in an expression with a subscript. The
position of the array or structure read from the file is given by the value of the
subscript. The following IDL statements give some examples of using file
variables:
Z = A[0]
Copy the contents of the first array
into normal variable Z. Z is now a
10 x 20, floating-point array.
FOR I = 1, 9 DO Z = Z + A[I]
Form the sum of the first 10 arrays
(Z was initialized in the previous
statement to the value of the first
array. This statement adds the following nine to it.).
PLOT, A[3]
Read fourth array and plot it.
PLOT, A[5] - A[4]
Subtract array four from array
five, and plot the result. The result
of the subtraction is then discarded.
Subscripting Associated File Variables on Input
When the structure associated with a file variable is an array, it is possible to
subscript into the array being accessed during input operations. For example, for
the variable A defined above,
Z = A[0, 0, 1]
assigns the value of the first floating-point element of the second array within the
file to the variable Z. The rightmost subscript is taken as the subscript into the file
causing IDL to read the entire array into memory. This resulting array expression
is then further subscripted by the remaining subscripts.
Note Although this ability can be convenient, it also can be very slow because every
access to an array element causes the entire array to be read from memory.
Unless only one element of the array is desired, it is faster to assign the contents
Associated Input/Output
Building IDL Applications
Chapter 11: Files and Input/Output
205
of the array to a normal variable by subscripting the file variable with a single
subscript, then accessing the individual array elements in the normal variable.
Writing Data
When a subscripted associated variable appears on the left side of an assignment
statement, the expression on the right side is written into the file at the given array
position:
A[5] = FLTARR(10, 20)
Sets sixth record to zero.
A[5] = ARR
Writes ARR into the sixth record
after any necessary type conversions.
A[J] = (A[J] + A[J + 1])/2
Averages records J and J+1, and
writes the result into record J.
When writing data, only a single subscript specifying the index of the affected array
or structure in the file is allowed. Thus, it is not possible to index individual elements
of associated arrays on output, although it is allowed for input. To update individual
elements of an array within a file, assign the contents of that array to a normal array
variable, modify the copy, and write the array back by assigning it to the subscripted
file variable.
Files with Multiple Structures
The same file may be associated with a number of different structures. Assume a
number of 128 x 128-byte images are contained on a file. The statement,
ROW = ASSOC(1, BYTARR(128))
will map the file into rows of 128 bytes each. ROW[3] is the fourth row of the first
image, while ROW[128] is the first row of the second image. The statement,
IMAGE = ASSOC(1, BYTARR(128, 128))
maps the file into entire images; IMAGE[4] will be the fifth image.
Offset Parameter
The Offset parameter to ASSOC specifies the position in the file at which the first
array starts. This parameter is useful when a file contains a header followed by
data records. For example, if a UNIX file uses the first 1,024 bytes of the file to
contain header information, followed by 512 x 512-byte images, the statement,
IMAGE = ASSOC(1, BYTARR(512, 512), 1024)
sets the variable IMAGE to access the images while skipping the header.
Building IDL Applications
Associated Input/Output
206
Chapter 11: Files and Input/Output
Under VMS, stream files and RMS block mode files have their offset given in
bytes, and record-oriented files have it specified in records. Thus, the example
above would have worked for VMS if the file was a stream or block mode file.
Assume however, that the file has 512-byte, fixed-length records. In this case,
skipping the first 1,024 bytes is equivalent to skipping the first two records:
IMAGE = ASSOC(1, BYTARR(512, 512), 2)
Efficiency
Arrays are accessed most efficiently if their length is an integer multiple of the
physical block size of the disk holding the file. Common values are 512, 1,024,
and 2,048 bytes. For example, on a disk with 512-byte blocks, one benchmark
program required approximately one-eighth of the time required to read a
512 x 512-byte image that started and ended on a block boundary, as compared
to a similar program that read an image that was not stored on even block
boundaries.
Each time a subscripted associated variable is referenced, one or more records are
read from or written to the file. Therefore, if a record is to be accessed more than
a few times, it is more efficient to read the entire record into a variable. After
making the required changes to the in-memory variable, it can be written back to
the file if necessary.
Unformatted Data from UNIX FORTRAN Programs
Unformatted data files generated by FORTRAN programs under UNIX contain
an extra long word before and after each logical record in the file. ASSOC does
not interpret these extra bytes but considers them to be part of the data. This is
true even if the F77_UNFORMATTED keyword is specified on the OPEN
statement. Therefore, ASSOC should not be used with such files. Instead, such
files should be processed using READU and WRITEU. An example of using IDL
to read such data is given in “Using Unformatted Input/Output” on page 191.
File Manipulation Operations
Locating Files
The FINDFILE function returns an array of strings containing the names of all
files that match its argument string. The argument string may contain any
wildcard characters understood by the command interpreter. Under VMS, this is
DCL. Under UNIX, it is the Bourne shell (/bin/sh). Under Windows it is
COMMAND.COM. On the Macintosh, standard Macintosh OS wildcard
characters are supported. For example, to determine the number of IDL
procedure files that exist in the current directory, use the following statement:
File Manipulation Operations
Building IDL Applications
Chapter 11: Files and Input/Output
207
PRINT, ’# IDL pro files:’,N_ELEMENTS(FINDFILE(’*.pro’))
See “FINDFILE” on page 480 of the IDL Reference Guide for details.
Getting Help and Information
Information about currently open file units is available by using the FILES
keyword with the HELP procedure. If no arguments are provided, information
about all currently open user file units (units 1–128) is given. For example, the
following command can be used to get information about the three special units
(−2, −1, and 0):
HELP, /FILES, -2, -1, 0
This command results in output similar to the following:
Unit
-2
-1
0
Attributes
Write, New, Tty, Reserved
Write, New, Tty, Reserved
Read, Tty, Reserved
Name
<stderr>
<stdout>
<stdin>
See “HELP” on page 537 of the IDL Reference Guide for details.
The FSTAT Function
The FSTAT function can be used to get more detailed information, as well as
information that can be used from within an IDL program. It returns a structure
expression of type FSTAT or FSTAT64 containing information about the file. For
example, to get detailed information about the standard input, the command,
HELP, /STRUCTURES, FSTAT(0)
causes the following to be displayed on the screen:
** Structure FSTAT, 12 tags, length=48:
UNIT
LONG
0
NAME
STRING
’<stdin>’
OPEN
BYTE
1
ISATTY
BYTE
1
ISAGUI
BYTE
0
INTERACTIVE
BYTE
1
READ
BYTE
1
WRITE
BYTE
0
TRANSFER_COUNT LONG
0
CUR_PTR
LONG
51550
SIZE
LONG
0
REC_LEN
LONG
0
Since IDL allows keywords to be abbreviated to the shortest nonambiguous
number of characters,
HELP, /ST, FSTAT(0)
Building IDL Applications
File Manipulation Operations
208
Chapter 11: Files and Input/Output
also will work (and save some typing).
As explained in SectionXXXOnPageYYY, IDL on some platforms can support
files that are longer than 2^31-1 bytes in length. If FSTAT is applied to such a file,
it returns an expression of type FSTAT64 instead of the FSTAT structure shown
above. FSTAT64 differs from FSTAT only in that the TRANSFER_COUNT,
CUR_PTR, SIZE, and REC_LEN fields are signed 64-bit integers (type LONG64)
in order to be able to represent the larger sizes.
The fields of the FSTAT and FSTAT64 structures provide the following
information:
UNIT
The IDL logical unit number (LUN).
NAME
The name of the file.
OPEN
Nonzero if the file unit is open. If OPEN is zero, the remaining fields in FSTAT
will not contain useful information.
ISATTY
Nonzero if the file is actually a terminal instead of a normal file. For example, if
you are using an xterm window on a Unix system and you invoke FSTAT on
logical unit 0 (standard input), ISATTY will be set to 1.
ISAGUI
Nonzero if the file is actually a Graphical User Interface (for example, a logical
unit associated with the IDL Development Environment). Thus, if you are using
IDLDE and you invoke FSTAT on logical unit 0 (standard input), ISAGUI will be
set to 1.
INTERACTIVE
Nonzero if either ISATTY or ISAGUI is nonzero.
READ
Nonzero if the file is open for read access.
WRITE
Nonzero if the file is open for write access.
TRANSFER_COUNT
The number of scalar IDL data items transferred in the last input/output
operation on the unit. This is set by the following IDL routines: READU,
File Manipulation Operations
Building IDL Applications
Chapter 11: Files and Input/Output
209
WRITEU, PRINT, PRINTF, READ, and READF. TRANSFER_COUNT is useful
when attempting to recover from input/output errors.
CUR_PTR
The current position of the file pointer, given in bytes from the start of the file. If
the device is a terminal (ISATTY is nonzero), the value of CUR_PTR will not
contain useful information.
SIZE
The current length of the file in bytes. If the device is a terminal (ISATTY is
nonzero), the value of SIZE will not contain useful information.
REC_LEN
If the file is record-oriented (VMS), this field contains the record length;
otherwise, it is zero.
An Example Using FSTAT
The following IDL function can be used to read single-precision, floating-point
data from a stream file into a vector when the number of elements in the file is
not known. It uses the FSTAT function to get the size of the file in bytes and
divides by four (the size of a single-precision, floating-point value) to determine
the number of values. Note that this approach will not work with VMS variablelength record files:
FUNCTION READ_DATA, file
READ_DATA reads all the floating point values from a stream file
and returns the result as a floating-point vector.
OPENR, /GET_LUN, unit, file
Get a unique file unit and open the
data file.
status = FSTAT(unit)
Get file status.
data = FLTARR(status.size / 4)
Make an array to hold the input
data. The SIZE field of status gives
the number of bytes in the file, and
single-precision, floating-point
values are four bytes each.
READU, unit, data
Read the data.
FREE_LUN, unit
Deallocate the file unit. The file
also will be closed.
RETURN, data
Done.
END
Building IDL Applications
File Manipulation Operations
210
Chapter 11: Files and Input/Output
Assuming that a file named data.dat exists and contains 10 floating-point values,
the READ_DATA function could be used as follows:
A = READ_DATA(’data.dat’)
Read floating-point values from
data.dat.
HELP, A
Show the result.
The following output is produced:
A
FLOAT
= Array(10)
Flushing File Units
For efficiency, IDL buffers its input/output in memory. Therefore, when data are
output, there is a window of time during which data are in memory and have not
been actually placed into the file. Normally, this behavior is transparent to the
user (except for the improved performance). The FLUSH routine exists for those
rare occasions where a program needs to be certain that the data has actually been
written to the file immediately. For example, use the statement,
FLUSH, 1
to flush file unit one.
See “FLUSH” on page 491 of the IDL Reference Guide for details.
Positioning File Pointers
Each open file unit has a current file pointer associated with it. This file pointer
indicates the position in the file at which the next input/output operation will
take place. The file position is specified as the number of bytes from the start of
the file. The first position in the file is position zero. The following statement will
rewind file unit 1 to its start:
POINT_LUN, 1, 0
The following sequence of statements will position it at the end of the file:
tmp = FSTAT(1)
POINT_LUN, 1, tmp.size
POINT_LUN has the following operating-system specific behavior:
♦ UNIX: the current file pointer can be positioned arbitrarily – moving to a position
beyond the current end-of-file causes the file to grow out to that point. The gap
created is filled with zeroes.
File Manipulation Operations
Building IDL Applications
Chapter 11: Files and Input/Output
211
♦ VMS stream files: the current file pointer can be positioned arbitrarily – moving
to a position beyond the current end-of-file causes the file to grow out to that
point. The gap created is filled with zeroes.
♦ VMS block mode and record-oriented files: attempting to move the pointer
past the current end-of-file causes an end-of-file error.
♦ VMS record-oriented files: the file pointer should only be set to record boundaries. Setting it to other positions can result in unexpected behavior.
♦ Windows: the current file pointer can be positioned arbitrarily – moving to a
position beyond the current end-of-file causes the file to grow out to that point.
Unlike UNIX, the gap created is filled with arbitrary data instead of zeroes.
♦ Macintosh: the current file pointer cannot be positioned past the end of the file.
See “POINT_LUN” on page 813 of the IDL Reference Guide for details.
Testing for End-Of-File
The EOF function is used to test a file unit to see if it is currently positioned at the
end of the file. It returns true (1) if the end-of-file condition is true and false (0)
otherwise.
Note the non-diskfile devices always return “false” and, under VMS, nonsequential files or files opened across DECnet always return “false”.
For example, to read the contents of a file and print it on the screen, use the
following statements:
OPENR, 1, ’demo.doc’
Open file demo.doc for reading.
LINE = ’’
Create a variable of type string.
WHILE(NOT EOF(1)) DO BEGIN READF,1,LINE & PRINT,LINE & END
Read and print each line until the
end of the file is encountered.
CLOSE, 1
Done with the file.
See “EOF” on page 450 of the IDL Reference Guide for details.
GET_KBRD
The GET_KBRD function returns the next character available from the standard
input (IDL file unit zero) as a single character string. It takes a single parameter
named WAIT. If WAIT is zero, the function returns the null string if there are no
characters in the terminal typeahead buffer. If it is nonzero, the function waits for
a character to be typed before returning.
Building IDL Applications
File Manipulation Operations
212
Chapter 11: Files and Input/Output
Under Windows, the GET_KBRD function can be used to return Windows
special characters (in addition to the standard keyboard characters). To get a
special character, hold down the Alt key and type the character’s ANSI equivalent
on the numeric keypad while GET_KBRD is waiting. Control + key
combinations are not supported.
See “GET_KBRD” on page 514 of the IDL Reference Guide for details.
Example—Using GET_KBRD
A procedure that updates the screen and exits when the carriage return is typed
might appear as follows:
PRO UPDATE, ...
Procedure definition.
WHILE 1 DO BEGIN
Loop forever.
...
Update screen here...
CASE GET_KBRD(0) OF
Read character, no wait.
’A’: ....
Process letter A.
’B’: ....
Process letter B.
...
Process other alternatives.
STRING("15B): RETURN
Exit on carriage return (ASCII
code = 15 octal).
ELSE:
Ignore all other characters.
ENDCASE
ENDWHILE
END
End of procedure.
Using the STRING Function to Format Data
The STRING function is very similar to the PRINT and PRINTF procedures. It
can be thought of as a version of PRINT that places its formatted output into a
string variable instead of a file. If the output is a single line, the result is a scalar
string. If the output has multiple lines, the result is a string array with each
element of the array containing a single line of the output.
File Manipulation Operations
Building IDL Applications
Chapter 11: Files and Input/Output
213
Example—Using STRING with Explicit Formatting
The IDL statements:
A=STRING(FORMAT=’("The values are:", /, (I))’, INDGEN(5))
Produce a string array.
HELP, A
Show its structure.
FOR I = 0, 5 DO PRINT, A[I]
Print out the result.
produce the following output:
A
STRING
The values are:
0
1
2
3
4
= Array(6)
See “STRING” on page 1077 of the IDL Reference Guide for details.
Reading Data from a String Variable
The READS procedure performs formatted input from a string variable and
writes the results into one or more output variables. This procedure differs from
the READ procedure only in that the input comes from memory instead of a file.
This routine is useful when you need to examine the format of a data file before
reading the information it contains. Each line of the file can be read into a string
using READF. Then the components of that line can be read into variables using
READS.
See the description of READS in the IDL Reference Guide for more details.
UNIX-Specific Information
UNIX offers only a single type of file. All files are considered to be an
uninterpreted stream of bytes, and there is no such thing as record structure at
the operating system level. (By convention, records of text are simply terminated
by the linefeed character, which is referred to as “newline.”) It is possible to move
the current file pointer to any arbitrary position in the file and to begin reading
or writing data at that point. This simplicity and generality form a system in
which any type of file can be manipulated easily using a small set of file
operations.
Building IDL Applications
UNIX-Specific Information
214
Chapter 11: Files and Input/Output
Reading FORTRAN-Generated Unformatted Data with IDL
The UNIX file system considers all files to be an uninterpreted stream of bytes.
Standard FORTRAN I/O considers all input/output to be done in terms of logical
records.
In order to reconcile the FORTRAN need for logical records with UNIX files,
UNIX FORTRAN programs add a longword count before and after each logical
record of data. These longwords contain an integer count giving the number of
bytes in that record. Note that direct-access FORTRAN I/O does not write data
in this format, but simply transfers binary data to or from the file.
The use of the F77_UNFORMATTED keyword with the OPENR statement
informs IDL that the file contains unformatted data produced by a UNIX
FORTRAN program. When a file is opened with this keyword, IDL interprets the
longword counts properly and is able to read and write files that are compatible
with FORTRAN.
Reading data from a FORTRAN file
The following UNIX FORTRAN program produces a file containing a fivecolumn by three-row array of floating-point values with each element set to its
one-dimensional subscript:
PROGRAM ftn2idl
INTEGER i, j
REAL data(5, 3)
OPEN(1, FILE="ftn2idl.dat", FORM="unformatted")
DO 100 j = 1, 3
DO 100 i = 1, 5
data(i,j) = ((j - 1) * 5) + (i - 1)
print *, data(i,j)
100 CONTINUE
WRITE(1) data
END
UNIX-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
215
Running this program creates the file ftn2idl.dat containing the unformatted
array. The following IDL statements can be used to read this file and print out its
contents:
Create an array to contain the fortran array.
data = FLTARR(5,3)
OPENR, lun, ’ftn2idl.dat’, /GET_LUN, /F77_UNFORMATTED
Open the fortran-generated file.
The F77_UNFORMATTED keyword is necessary so that IDL will
know that the file contains unformatted data produced by a UNIX
FORTRAN program.
READU, lun, data
Read the data in a single input operation.
FREE_LUN, lun
Release the logical unit number
and close the fortran file.
PRINT, data
Print the result.
Executing these IDL statements produces the following output:
0.00000
5.00000
10.0000
1.00000
6.00000
11.0000
2.00000
7.00000
12.0000
3.00000
8.00000
13.0000
4.00000
9.00000
14.0000
Caution Because unformatted data produced by UNIX FORTRAN unformatted
WRITE statements are interspersed with extra information before and after
each logical record, it is important that the IDL program read the data in the
same way that the FORTRAN program wrote it. For example, consider the
following attempt to read the above data file one row at a time:
data = FLTARR(5, /NOZERO)
Create an array to contain one row
of the Fortran array.
OPENR, lun, ’ftn2idl.dat’, /GET_LUN, /F77_UNFORMATTED
FOR I = 0, 4 DO BEGIN
One row at a time.
READU, lun, data
Read a row of data.
PRINT, data
Print the row.
ENDFOR
FREE_LUN, lun
Building IDL Applications
Close the file.
UNIX-Specific Information
216
Chapter 11: Files and Input/Output
Executing these IDL statements produces the output:
0.00000
1.00000
2.00000
3.00000
4.00000
% READU: End of file encountered. Unit: 100
File: ftn2idl.dat6
% Execution halted at $MAIN$(0).
Here, IDL attempted to read the single logical record written by the FORTRAN program as if it were written in five separate records. IDL hit the end
of the file after reading the first five values of the first record.
Writing data to a FORTRAN file
The following IDL statements create a five-column by three-row array of
floating-point values with each element set to it’s one-dimensional subscript, and
writes the array to a data file suitable for reading by a FORTRAN program:
data = FINDGEN(5,3)
Create the array.
OPENW, lun, ’idl2ftn.dat’, /GET_LUN, /F77_UNFORMATTED
Open a file for writing. Note that
the F77_UNFORMATTED keyword is necessary to tell IDL to
write the data in a format readable by a FORTRAN program.
WRITEU, lun, data
Write the data.
FREE_LUN, lun
Close the file.
The following FORTRAN program reads the data file created by IDL:
PROGRAM idl2ftn
INTEGER i, j
REAL data(5, 3)
OPEN(1, FILE="idl2ftn.dat", FORM="unformatted")
READ(1) data
DO 100 j = 1, 3
DO 100 i = 1, 5
PRINT *, data(i,j)
100 CONTINUE
UNIX-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
217
END
VMS-Specific Information
Input/output under VMS is a relatively complex topic, involving a large number
of formats and options. VMS files are record-oriented, and it is necessary to take
this into account when writing applications, especially those that will run under
other operating systems. The VMS user faces decisions in the following areas:
Organization
A VMS file can have sequential, relative, or indexed organization. The
organization controls the way in which data is placed in the file and determines
the options for random access. IDL is able to read data from all three
organizations and is able to create sequential or indexed files.
In addition, it is possible to bypass the organization and access a file in “block
mode.” In block mode, most VMS file processing is bypassed. The IDL user can
access a block mode file as if it were simply a stream of uninterpreted bytes. This
is very similar to stream files (although considerably more efficient).
Caution With some file organizations, VMS intermingles housekeeping information
with data. When accessing such a file in block mode, it is easy to corrupt this
information and render the file unusable in its usual mode; however, block
mode will always work. Avoiding such corruption is the user’s responsibility.
Access
The access mode controls how data in a file are accessed. VMS supports
sequential access, random access by key value (indexed files), relative record
number (relative files), or relative file address (all file organizations). IDL does
not support access by relative record number—files are accessed sequentially or
through key value. Random access for sequential files is allowed by file address
using the POINT_LUN procedure.
Record Format
VMS supports fixed-length records, variable-length records, variable length with
fixed-length control field (VFC), and stream format. Of these, the fixed-length
and variable-length record formats are the most useful and are fully supported by
IDL.
It is possible to read the data portion of a VFC file, but not the control field. All
access to stream mode files under IDL is done through the Standard C Library. It
is worth noting that VMS stream files are record oriented (and therefore, fail to
provide much of the flexibility of UNIX stream files) although the VMS Standard
C Library (upon which IDL is implemented) does a good job of concealing this
Building IDL Applications
VMS-Specific Information
218
Chapter 11: Files and Input/Output
limitation. Our experience indicates that input/output using VMS stream mode
files is dramatically slower than the other options and should be avoided when
possible. For unformatted data, using block mode can give similar flexibility as
well as high efficiency.
Byte
Value
ASCII
Character
Meaning
No carriage control—output data directly.
0
(null)
32
(space)
Single-space. A linefeed precedes the output data, and a carriage return follows.
48
0
Double-space. Two linefeeds precede the output data, and a
carriage return follows.
49
1
Page eject. A formfeed precedes the data, and a carriage return
follows.
40
+
Overprint. A carriage return follows the data, causing the next
output line to overwrite the current one.
36
$
Prompt. A linefeed precedes the data, but no carriage return
follows.
other
Same as ASCII space character. Single-space carriage control
Table 11-10: VMS FORTRAN Carriage Control
Record Attributes
When a record is output to the screen or printer, VMS uses its carriage control
attributes to determine how to output each line. Explicit carriage control specifies
that VMS should do nothing, and the user will provide the appropriate carriage
control (if any) in the data. Carriage-return carriage control specifies that each
line should be preceded by a line feed and followed by a carriage return.
FORTRAN carriage control indicates that the first byte of each record contains a
FORTRAN carriage control character. The possible values of this byte are given
in Table 11-10. The default for IDL is carriage-return carriage control.
File Attributes
There are many file attributes that can be adjusted to suit various requirements.
These attributes allow specifying the default name, the initial size of new files, the
amount by which files are extended, whether the file is printed or sent to a batch
queue when closed, file sharing between processes, etc.
VMS-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
219
How IDL Handles Records
With record-oriented files, IDL always transfers at least a single record of data. If
the amount of data required exceeds a single record, more input/output occurs.
For example, consider the case of a file open on unit 1 for output with 80character records. The statement,
WRITEU, UNIT, FINDGEN(512)
requires 2,048 bytes to be output (each floating-point value takes four bytes), and
thus, causes 26 records to be output. The last record will not be entirely full and
is padded at the end with zeroes.
On later input, the same rule is applied in reverse—26 records are read, and the
unused portion of the last one is discarded. The basic rule of input/output with
record-oriented files is that the form of the input and output statements should
match. For instance, the statements,
WRITEU, UNIT, A
WRITEU, UNIT, B
WRITEU, UNIT, C
generate three output records and should be later input with statements of the
following form:
READU, UNIT, A
READU, UNIT, B
READU, UNIT, C
In contrast, the statement
WRITEU, UNIT, A, B, C
generates a single-output record and should be later input with the following
single statement:
READU, UNIT, A, B, C
Reading FORTRAN-Generated Unformatted Data with IDL
The following VMS FORTRAN program produces a file containing a 5 x 5 array
of floating-point values with each element set to its one-dimensional subscript:
INTEGER I, J REAL DATA(5, 5)
OPEN(1, FILE=’data.dat’, FORM=’unformatted’, status=’new’)
DO 100 J = 1, 5
DO 100 I = 1, 5
DATA(I,J) = ((J-1) * 5) + (I-1)
100 CONTINUE
Building IDL Applications
VMS-Specific Information
220
Chapter 11: Files and Input/Output
WRITE(1) DATA
END
Running this program creates the file data.dat containing the unformatted data.
By default, VMS FORTRAN programs create such files using segmented records,
which is a scheme used by FORTRAN to write data records with lengths that
exceed the actual record lengths allowed by VMS. Each segmented record is
written as one or more actual VMS records. Each of the actual records has a 2byte control field prepended that allows FORTRAN to reconstruct the original
record. IDL is able to read and write segmented record files if the OPEN
statement, used to access the file, includes the SEGMENTED keyword. The
following IDL statements can be used to read this file and print out its contents:
OPENR, 1, ’data.dat’, /SEGMENTED
Open the file. The SEGMENTED
keyword is necessary so that IDL
will know that the file contains
VMS FORTRAN segmented
records.
A = FLTARR(5, 5, /NOZERO)
Create an array to contain the array.
READU, 1, A
Read the data in a single input operation.
PRINT, A
Print the result.
Executing these IDL statements produces the following output:
0.00000
5.00000
10.0000
15.0000
20.0000
1.00000
6.00000
11.0000
16.0000
21.0000
2.00000
7.00000
12.0000
17.0000
22.0000
3.00000
8.00000
13.0000
18.0000
23.0000
4.00000
9.00000
14.0000
19.0000
24.0000
As with all record-oriented input/output, it is important that the IDL program
read the data in the same way it was written by the FORTRAN program. For
example, consider the following attempt to read the above data file one row at a
time:
Create an array to contain one row of the array.
OPENR, 1, ’DATA.DAT’, /SEGMENTED
A = FLTARR(5, /NOZERO)
FOR I = 0, 4 DO BEGIN $
One row at a time.
READU, 1, A $
Read a row of data.
PRINT, A $
Print the row.
ENDFOR
VMS-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
221
Executing these IDL statements produces the following output:
0.00000
1.00000
2.00000
3.00000
% End of file encountered on file unit: 1.
% Execution halted at $MAIN$(0).
4.00000
This program attempted to read the single logical record written by the
FORTRAN program as if it were written in five separate records and so, hit the
end of the file after reading the first five values of the first record.
Indexed Files
Creating Indexed Files
Although IDL can read and write indexed files, it cannot create them. The
options for creating indexed files are so numerous that they should be specified
using the VMS CREATE/FDL command. FDL (File Definition Language) is the
standard method for specifying VMS file attributes. The VAX/VMS File
Definition Language Facility Reference Manual (1986) describes FDL in detail.
It is often useful to start with the FDL description for an existing file and then
modify it to suit your new application. The VMS command,
$ ANALYZE/RMS FILE/FDL file.dat
creates a file named file.fdl containing the FDL description for file.dat.
The following is an example of an FDL description for an indexed file named
data.dat with two keys. The first key is a 32-character string containing an
employee name. The second is a 4-byte integer containing the current salary for
that employee:
FILE
NAME data.dat
ORGANIZATION indexed
RECORD
SIZE 36
KEY 0
NAME "Name"
SEG0_LENGTH 32
SEG0_POSITION 0
TYPE string
KEY 1
CHANGES yes
NAME "Salary"
SEG0_LENGTH 4
SEG0_POSITION 32
TYPE bin4
Building IDL Applications
VMS-Specific Information
222
Chapter 11: Files and Input/Output
Assume that this description resides in a file named data.fdl. The following IDL
statement can be used to create data.dat:
SPAWN, ’create/fdl = data.fdl’
Once the file exists, it can be opened within IDL using the KEYED keyword with
the OPENR or OPENU procedures.
Using Indexed Files
Given a file created using the FDL description in the previous section, the IDL
statements below do four things:
•
Add some employee records to the file
•
Print the records out sorted by name
•
Give an employee a raise
•
Print the records sorted by increasing salary
IDL is able to perform both formatted and unformatted input/output with
indexed files.
In this instance, unformatted access is required because the record definition
contains a binary field (salary).
OPENU, UNIT, ’data.dat’, /KEY, /GET_LUN
Open the previously created, empty file.
WRITEU, UNIT, STRING(’Natasha’, FORMAT = "(A,T33)"), 14257L
Add the first record. The STRING
function is used to pad the name to
32 characters using space characters because the data must match
the FDL description of the file exactly.
WRITEU, UNIT, STRING(’Bullwinkle’, FORMAT = "(A,T33)"),
32501L
Second record.
WRITEU, UNIT, STRING(’Rocky’, FORMAT = "(A,T33)"), 32500L
Third record.
WRITEU, UNIT, STRING(’Borris’, FORMAT = "(A,T33)"), 6805L
Fourth and last record.
READ_BY_INDEX, UNIT, 0, ’a’, ’By Name:’
Print the contents of the file, sorted
by name. READ_BY_INDEX is a
VMS-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
223
procedure (described below) that
does the actual work.
NAME = STRING(REPLICATE(32B, 32))
In preparation for giving a raise,
make variables to read the current
information on the employee.
SALARY = 0L
READU, UNIT, NAME, SALARY, KEY_VALUE = ’Bullwinkle’
Read the record for employee Bullwinkle.
WRITEU, UNIT, NAME, SALARY + 10000L, /REWRITE
Update Bullwinkle’s record with
an increased salary. The REWRITE keyword causes the last
input record to be overwritten, instead of creating a new record.
READ_BY_INDEX, UNIT, 1, 0L, ’By Salary:’
Print the contents of the file, sorted
by salary.
FREE_LUN, UNIT
Free the file unit, and close the file.
The procedure READ_BY_INDEX is implemented as follows:
PRO READ_BY_INDEX, UNIT, KI, KV, HEADING
Print the contents of the file sorted
on the index given by KI. KV is the
value the first record should be
matched against. Heading is a
banner comment to be printed before the file contents.
FIRST = 1
Indicates first trip through main
loop.
NAME = STRING(REPLICATE(32B, 32))
Prepare variables to read the
records into.
SALARY = 0L
ON_IOERROR, EOD
The EOF function does not work
with indexed files, so we will use
ON_IOERROR to catch attempts
to read too far.
WHILE 1 DO BEGIN
Loop will be exited on end-of-file.
Building IDL Applications
VMS-Specific Information
224
Chapter 11: Files and Input/Output
First iteration.
IF (FIRST) THEN BEGIN
PRINT, FORMAT=’(/, a)’, HEADING) Output the heading.
READU, UNIT, NAME, SALARY, KEY_ID = KI, KEY_MATCH = 1, $
KEY_VALUE = KV
On first iteration, use keywords to
locate the first record.
FIRST = 0
Indicate that first iteration has
happened.
ENDIF ELSE BEGIN
After the first iteration, use normal
input statement to read sequentially.
READU, UNIT, NAME, SALARY
ENDELSE
Print the record.
PRINT, FORMAT = ’(4X, A, T15, I)’, NAME, SALARY
ENDWHILE
When the above loop tries to read
past end-of-file, execution will be
transferred here.
EOD:
END
Executing the above statements gives the following output:
By Name:
Borris
Bullwinkle
Natasha
Rocky
By Salary:
Borris
Natasha
Rocky
Bullwinkle
6805
32501
14257
32500
6805
14257
32500
42501
Magnetic Tape
Under VMS, IDL offers procedures to directly access magnetic tapes. Data are
transferred between the tape and IDL arrays without using RMS. Optionally,
tapes from IBM mainframe compatible systems may be read or written with
odd/even byte reversal.
VMS-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
225
The routines used to access magnetic tape directly are as follows:
REWIND
Rewind a tape unit.
SKIPF
Skip records or files.
TAPRD
Read from tape.
TAPWRT
Write to tape.
WEOF
Write an end-of-file mark on tape.
To use the IDL magnetic tape procedures, you must define a logical name MTn:
to be equivalent to the actual name of the tape drive you wish to use. This
definition must be done before invoking IDL. You also must have the tape
mounted as a foreign volume.
For example, if you wish to access the tape drive MUA0: as IDL tape unit number
one, issue the following VMS commands before running IDL:
$ MOUNT/FOREIGN MUA0:
$ DEFINE MT1 MUA0:
Then, within IDL, refer to the tape as unit number one. The IDL unit number n
may range from 0 to 9.
Note These unit numbers are not the same as the LUNs used by the other input/output routines. The unit numbers used by the magnetic tape routines are
completely unrelated and come from the last letter of the MT* logical name
used to refer to it.
Magnetic Tape Examples
The following statements skip forward 30 records on the tape mounted on the
drive with the logical name MT2: and print a message if an end-of-file was
encountered.
SKIPF, 2, 30, 1
Building IDL Applications
Skip forward over 30 records on
unit 2.
VMS-Specific Information
226
Chapter 11: Files and Input/Output
IF !ERR NE 30 THEN PRINT, ’end-of-file hit’
Print a message if the requested
number of records were not
skipped.
The next example skips two files backwards and then positions the tape
immediately after the second file mark encountered in reverse.
SKIPF, 0, -2
Go backwards two files.
Position after file if two files were
actually skipped.
IF !ERR EQ -2 THEN SKIPF, 0, 1
The following code segment reads a 512 x 512-byte image from the tape which is
assigned the logical name MT5. It is assumed that the data are written in 2,048byte tape blocks.
a = BYTARR(512, 512)
Define image array.
b = BYTARR(512, 4)
Define an array to hold one tape
block worth of data.
FOR I = 0, 511, 4 DO BEGIN
TAPRD, B, 5
Read next record.
A[0, I] = B
Insert four rows starting at i-th
row.
ENDFOR
Assuming the tape is actually on drive MXB2:, the mount command, which must
be issued to VMS before entering IDL, is as follows:
$ MOUNT MXB2:/FOR "" MT5
This command serves to both
mount the tape and define the logical name MT5 to refer to it, thus
making it unit 5 within IDL.
References
Digital Equipment Corporation (1986), VAX/VMS File Definition Language
Facility Reference Manual, Order Number AA-Z415B-TE, Maynard,
Massachusetts.
Windows-Specific Information
Under Microsoft Windows, a file is read or written as an uninterrupted stream of
bytes—there is no record structure at the operating system level. Files are
Windows-Specific Information
Building IDL Applications
Chapter 11: Files and Input/Output
227
processed as binary or text. Binary files are processed using no translation of
characters. Text files are processed by translating the characters that terminate a
line. Lines are terminated by the character sequence CR LF (carriage return, line
feed). During read operations, if a CR character precedes a LF character, the CR
is removed. During write operations, all LF characters are prepended with a CR
character.
The ASSOC, READU, and WRITEU routines operate in binary mode by default.
The PRINT, PRINTF, READ, and READF routines operate in text mode by
default. You can override the defaults by setting the BINARY or NOAUTOMODE
keywords to the OPEN procedures. See the documentation for the WindowsOnly keywords to “OPEN” on page 783 of the IDL Reference Guide.
Macintosh-Specific Information
Macintosh files store two pieces of information not generally stored by files on
other platforms—the file’s type and its creator. The MACTYPE and
MACCREATOR keywords to the OPEN procedures allow you to explicitly set the
type and creator for files created on a Macintosh. See the documentation for the
Macintosh-Only keywords to “OPEN” on page 783 of the IDL Reference Guide.
Scientific Data Formats
IDL supports the HDF (Hierarchical Data Format), CDF (Common Data
Format), and NetCDF (Network Common Data Format) self-describing,
scientific data formats. Collections of built-in routines provide an interface
between IDL and these formats. Documentation for specific routines and further
discussion of the various formats can be found in IDL Scientific Data Formats
Guide.
Standard Image File Formats
IDL includes routines for reading and writing many standard graphics file
formats. These routines and the types of files they support are listed in the table
below. Documentation on these routines can be found in the online help (enter
“?” at the IDL prompt).
Building IDL Applications
Macintosh-Specific Information
228
Format
Chapter 11: Files and Input/Output
Read/Write
Routines
Query Routine Description
BMP
READ_BMP
WRITE_BMP
QUERY_BMP
Windows Bitmap (.bmp) Format
GIF
READ_GIF
WRITE_GIF
QUERY_GIF
CompuServe Graphics Interchange Format
Interfile
READ_INTERFILE
(Write routine is n/a)
n/a
Interfile version 3.3 Format
JPEG
READ_JPEG
WRITE_JPEG
QUERY_JPEG
Joint Photographic Experts Group files
NRIF
(Read routine is n/a)
WRITE_NRIF
n/a
NCAR Raster Interchange Format
PICT
READ_PICT
WRITE_PICT
QUERY_PICT
Macintosh version 2 PICT files (bitmap only)
PNG
READ_PNG
WRITE_PNG
QUERY_PNG
Portable Network Graphics file
PPM
READ_PPM
WRITE_PPM
QUERY_PPM
PPM/PGM Format
SRF
READ_SRF
WRITE_SRF
QUERY_SRF
Sun Raster File
TIFF
READ_TIFF
WRITE_TIFF
QUERY_TIFF
8-bit or 24-bit Tagged Image File Format
X11 Bitmap
READ_X11_BITMAP
(Write routine is n/a)
n/a
X11 Bitmap format used for reading bitmaps for
IDL widget button labels
XWD
READ_XWD
(Write routine is n/a)
n/a
X Windows Dump format
Table 11-11: IDL-Supported Graphics Standards
Standard Image File Formats
Building IDL Applications
Chapter 12
Pointers
The following topics are covered in this chapter:
Heap Variables ................................... 230
Creating Heap Variables ...................... 231
Saving and Restoring Heap Variables... 232
Pointer Heap Variables ........................ 233
IDL Pointers ........................................ 233
Operations on Pointers ....................... 235
Dangling References........................... 239
Heap Variable “Leakage” .................... 239
Pointer Validity ................................... 241
Freeing Pointers.................................. 242
Pointer Examples................................ 242
229
230
Chapter 12: Pointers
In order to build linked lists, trees, and other dynamic data structures, it must be
possible to access variables via lightweight references that may have more than
one name. Further, these names might have different lifetimes, so the lifetime of
the variable that actually holds the data must be separate from the lifetime of the
tokens that are used to access it.
Beginning with IDL version 5, IDL includes a new pointer data type to facilitate
the construction of dynamic data structures. Although there are similarities
between IDL pointers and machine pointers as implemented in languages such as
C, it is important to understand that they are not the same thing. IDL pointers
are a high level IDL language concept and do not have a direct one-to-one
mapping to physical hardware. Rather than pointing at locations in computer
memory, IDL pointers point at heap variables, which are special dynamically
allocated IDL variables. Heap variables are global in scope, and exist until
explicitly destroyed.
Running the Example Code
The example code used in this chapter is part of the IDL distribution. All of the files
mentioned are located in the doc subdirectory of the examples subdirectory of
the main IDL directory. By default, this directory is part of IDL’s path; if you have
not changed your path, you will be able to run the examples as described here. See
“!PATH” on page 43 of the IDL Reference Guide for information on IDL’s path.
Heap Variables
Heap variables are a special class of IDL variables that have global scope and
explicit user control over their lifetime. They can be basic IDL variables,
accessible via pointers, or objects, accessible via object references. (See “Object
Basics” on page 249 for more information on IDL objects.) In IDL
documentation of pointers and objects, heap variables accessible via pointers are
called pointer heap variables, and heap variables accessible via object references
are called object heap variables.
Note Pointers and object references have many similarities, the strongest of which
is that both point at heap variables. It is important to understand that they
are not the same type, and cannot be used interchangeably. Pointers and
object references are used to solve different sorts of problems. Pointers are
useful for building dynamic data structures, and for passing large data around
using a lightweight token (the pointer itself) instead of copying data. Objects
are used to apply object oriented design techniques and organization to a
system. It is, of course, often useful to use both in a given program.
Heap variables are global in scope, but do not suffer from the limitations of
COMMON blocks. That is, heap variables are available to all program units at all
Heap Variables
Building IDL Applications
Chapter 12: Pointers
231
times. (Remember, however, that IDL variables containing pointers to heap
variables are not global in scope and must be declared in a COMMON block if
you want to share them between program units.)
Heap variables:
•
Facilitate object oriented programming.
•
Provide full support for Save and Restore. Saving a pointer or object reference
automatically causes the associated heap variable to be saved as well. This means
that if the heap variable contains a pointer or object reference, the heap variables
they point to are also saved. Complicated self-referential data structures can be
saved and restored easily.
•
Are manipulated primarily via pointers or object references using built in language operators rather than special functions and procedures.
•
Can be used to construct arbitrary, fully general data structures in conjunction
with pointers.
Note If you have used versions of IDL prior to version 5, you may be familiar with
handles. Because IDL pointers provide a more complete and robust way of
building dynamic data structures, Research Systems recommends that you
use pointers rather than handles when developing new code. See “Obsolete
Routines” on page 1391 of the IDL Reference Guide for a discussion of
Research Systems’ policy on language features that have been superseded in
this manner.
Creating Heap Variables
Heap variables can be created only by the pointer creation function PTR_NEW
or the object creation function OBJ_NEW. (See “Object Basics” on page 249 for
a discussion of object creation.) Copying a pointer or object reference does not
create a new heap variable. This is markedly different from the way IDL handles
“regular” variables. For example, with the statement:
A = 1.0
you create a new IDL floating-point variable with a value of 1.0. The following
statement:
B = A
creates a second variable with the same type and value as A.
Building IDL Applications
Creating Heap Variables
232
Chapter 12: Pointers
In contrast, if you create a new heap variable with the following command:
C = PTR_NEW(2.0d)
the variable C contains not the double-precision floating-point value 2.0, but a
pointer to a heap variable that contains that value. Copying the variable C with
the following statement:
D = C
does not create another heap variable, but rather creates a second pointer to the
same heap variable. In this example, the HELP command would reveal:
% At
A
B
C
D
$MAIN$
FLOAT
FLOAT
POINTER
POINTER
=
1.00000
=
1.00000
= <PtrHeapVar1>
= <PtrHeapVar1>
The variables C and D are both pointers to the same heap variable. (The actual
name assigned to a heap variable is arbitrary.) Changing the value stored in the
heap variable would be reflected when dereferencing either C or D (dereferencing
is discussed in “Dereference” on page 236).
Destroying or redefining either C, D, or both variables would leave the contents
of the heap variable unchanged. When all pointers or references to a given heap
variable are destroyed, the heap variable still exists and holds whatever memory
has been allocated for it. See “Heap Variable “Leakage”” on page 239 for further
discussion. If the heap variable itself is destroyed, pointers to the heap variable
may still exist, but will be invalid. See “Dangling References” on page 239.
Saving and Restoring Heap Variables
The SAVE and RESTORE procedures work for heap variables just as they work
for all other supported types. When IDL saves a pointer or object reference in a
save file, it recursively saves the heap variables that are referenced by that pointer
or object reference. SAVE handles circular data structures correctly. You can build
a large, complicated, self-referential data structure, and then save the entire
construct with a call to SAVE to save the single pointer or object reference that
points to the head of the structure. For example, you can save a pointer to the root
of a binary tree and the entire tree will be saved.
The internal identifier of a given heap variable is dynamically allocated at run
time, and will differ between IDL sessions. As a result, the RESTORE operation
maps all saved pointers and object references to their new values in the current
session.
Saving and Restoring Heap Variables
Building IDL Applications
Chapter 12: Pointers
233
Pointer Heap Variables
Pointer heap variables are IDL heap variables that are accessible only via pointers.
While there are many similarities between object references and pointers, it is
important to understand that they are not the same type, and cannot be used
interchangeably. Pointer heap variables are created using the PTR_NEW and
PTRARR functions. For more information on objects, see “Object Basics” on
page 249.
IDL Pointers
As illustrated above, you must use a special IDL routine to create a pointer to a
heap variable. Two routines are available: PTR_NEW and PTRARR. Before
discussing these functions, however, it is useful to examine the concept of a null
pointer.
Null Pointers
The Null Pointer is a special pointer value that is guaranteed to never point at a
valid heap variable. It is used by IDL to initialize pointer variables when no other
initializing value is present. It is also a convenient value to use at the end nodes in
data structures such as trees and linked lists.
It is important to understand the difference between a null pointer and a pointer
to an undefined or invalid heap variable. The second case is a valid pointer to a
heap variable that does not currently contain a usable value. To make the
difference clear, consider the following IDL statements:
A = PTR_NEW()
The variable A contains a null
pointer.
B = PTR_NEW(/ALLOCATE_HEAP)
The variable B contains a pointer
to a heap variable with an undefined value.
HELP, A, B, *B
IDL prints:
A
POINTER
= <NullPointer>
B
POINTER
= <PtrHeapVar1>
<PtrHeapVar1>
UNDEFINED = <Undefined>
Building IDL Applications
Pointer Heap Variables
234
Chapter 12: Pointers
The primary difference is that it is possible to write a useful value into a pointer
to an undefined variable, but this is never possible with a null pointer. For
example:
Attempt to assign the value 34 to
the null pointer.
*A = 34
IDL prints:
% Unable to dereference NULL pointer: A.
% Execution halted at:
$MAIN$
*B = 34
Assign the value 34 to a previously-undefined heap variable.
PRINT, *B
IDL prints:
34
Similarly, the null pointer is not the same thing as the result of PTR_NEW(0).
PTR_NEW(0) returns a pointer to a heap variable that has been initialized with
the integer value 0.
The PTR_NEW Function
Use the PTR_NEW function to create a single pointer to a new heap variable. If
you supply an argument, the newly-created heap variable is set to the value of the
argument. For example, the command:
ptr1 = PTR_NEW(FINDGEN(10))
creates a new heap variable that contains the ten-element floating point array
created by FINDGEN, and places a pointer to this heap variable in ptr1.
Note that the argument to PTR_NEW can be of any IDL data type, and can
include any IDL expression, including calls to PTR_NEW itself. For example, the
command:
ptr2 = PTR_NEW({name:’’, next:PTR_NEW()})
creates a pointer to a heap variable that contains an anonymous structure with
two fields: the first field is a string, the second is a pointer. We will develop this
idea further in the examples at the end of this chapter.
If you do not supply an argument, the newly-created pointer will be a null
pointer. If you wish to create a new heap variable but do not wish to initialize it,
use the ALLOCATE_HEAP keyword.
See “PTR_NEW” on page 857 of the IDL Reference Guide for further details.
IDL Pointers
Building IDL Applications
Chapter 12: Pointers
235
The PTRARR Function
Use the PTRARR function to create an array of pointers of up to eight
dimensions. By default, every element of the array created by PTRARR is set to
the null pointer. For example:
ptarray = PTRARR(2,2)
Create a 2 by 2 array of null pointers.
HELP, ptarray, ptarray(0,0)
Display the contents of the ptarray
variable, and of the first array element.
IDL prints:
PTARR
POINTER
= Array(2, 2)
<Expression>
POINTER
= <NullPointer>
If you want each element of the array to point to a new heap variable (as opposed
to being a null pointer), use the ALLOCATE_HEAP keyword. Note that in either
case, you will need to initialize the array with another IDL statement.
See “PTRARR” on page 860 of the IDL Reference Guide for further details.
Operations on Pointers
Pointer variables are not directly usable by many of the operators, functions, or
procedures provided by IDL. You cannot, for example, do arithmetic on them or
plot them. You can, of course, do these things with the heap variables referenced
by such pointers, assuming that they contain appropriate data for the task at
hand. Pointers exist to allow the construction of dynamic data structures that
have lifetimes that are independent of the program scope they are created in.
There are 4 IDL operators that work with pointer variables: assignment, dereference,
EQ, and NE. The remaining operators (addition, subtraction, etc.) do not make any
sense for pointer types and are not defined.
Many non-computational functions and procedures in IDL do work with pointer
variables. Examples are SIZE, N_ELEMENTS, HELP, and PRINT. It is worth
noting that the only I/O allowed directly on pointer variables is default formatted
output, where they are printed as a symbolic description of the heap variable they
point at. This is merely a debugging aid for the IDL programmer—input/output
of pointers does not make sense in general and is not allowed. Please note that
this does not imply that I/O on the contents of non-pointer data held in heap
variables is not allowed. Passing the contents of a heap variable that contains nonpointer data to the PRINT command is a simple example of this type of I/O.
Building IDL Applications
Operations on Pointers
236
Chapter 12: Pointers
Assignment
Assignment works in the expected manner—assigning a pointer to a variable
gives you another variable with the same pointer. Hence, after executing the
statements:
A = PTR_NEW(FINDGEN(10))
B = A
HELP, A, B
A and B both point at the same heap variable and we see the output:
A
POINTER
= <PtrHeapVar1>
B
POINTER
= <PtrHeapVar1>
Dereference
In order to get at the contents of a heap variable referenced by a pointer variable,
you must use the dereference operator, which is * (the asterisk). The dereference
operator precedes the variable dereferenced. For example, if you have entered the
above assignments of the variables A and B:
PRINT, *B
IDL prints:
0.00000
1.00000
2.00000
3.00000
6.00000
7.00000
8.00000
9.00000
4.00000
5.00000
That is, IDL prints the contents of the heap variable pointed at by the pointer
variable B.
Dereferencing Pointer Arrays
Note that the dereference operator requires a scalar pointer operand. This means
that if you are dealing with a pointer array, you must specify which element to
dereference. For example, create a three-element pointer array, allocating a new
heap variable for each element:
ptarr = PTRARR(3, /ALLOCATE_HEAP)
To initialize this array such that the heap variable pointed at by the first pointer
contains the integer zero, the second the integer one, and the third the integer
two, you would use the following statement:
FOR I = 0,2 DO *ptarr[I] = I
Operations on Pointers
Building IDL Applications
Chapter 12: Pointers
237
Note The dereference operator is dereferencing only element I of the array for each
iteration. Similarly, if you wanted to print the values of the heap variables
pointed at by the pointers in ptarr, you might be tempted to try the
following:
PRINT, *ptarr
IDL prints:
% Expression must be a scalar in this context: PTARR.
% Execution halted at:
$MAIN$
To print the contents of the heap variables, use the statement:
FOR I = 0, N_ELEMENTS(ptarr)-1 DO PRINT, *ptarr[I]
Dereferencing Pointers to Pointers
The dereference operator can be applied as many times as necessary to access data
pointed at indirectly via multiple pointers. For example, the statement:
A = PTR_NEW(PTR_NEW(47))
assigns to A a pointer to a pointer to a heap variable containing the value 47.
A
47
To print this value, use the following statement:
PRINT, **A
Dereferencing Pointers within Structures
If you have a structure field that contains a pointer, dereference the pointer by
prepending the dereference operator to the front of the structure name. For
example, if you define the following structure:
struct = {data:'10.0’, pointer:ptr_new(20.0)}
you would use the following command to print the value of the heap variable
pointed at by the pointer in the pointer field:
PRINT, *struct.pointer
Defining pointers to structures is another common practice. For example, if you
define the following pointer:
ptstruct = PTR_NEW(struct)
Building IDL Applications
Operations on Pointers
238
Chapter 12: Pointers
you would use the following command to print the value of the heap variable
pointed at by the pointer field of the struct structure, which is pointed at by
ptstruct:
PRINT, *(*pstruct).pointer
Note that you must dereference both the pointer to the structure and the pointer
within the structure.
Dereferencing the Null Pointer
It is an error to dereference the NULL pointer, an invalid pointer, or a nonpointer. These cases all generate errors that stop IDL execution. For example:
PRINT, *45
IDL prints:
% Pointer type required in this context: <INT(
% Execution halted at:
45)>.
$MAIN$
A = PTR_NEW() & PRINT, *A
IDL prints:
% Unable to dereference NULL pointer: A.
% Execution halted at:
$MAIN$
A = PTR_NEW(23) & PTR_FREE, A & PRINT, *A
IDL prints:
% Invalid pointer: A.
% Execution halted at:
$MAIN$
Equality and Inequality
The EQ and NE operators allow you to compare pointers to see if they point at
the same heap variable. For example:
A = PTR_NEW(23)
Make A a pointer to a heap variable containing 23.
B = A
B points at the same heap variable
as A.
C = PTR_NEW()
C contains the null pointer.
PRINT, ’A EQ B: ’, A EQ B & $
PRINT, ’A NE B: ’, A NE B & $
PRINT, ’A EQ C: ’, A EQ C & $
Operations on Pointers
Building IDL Applications
Chapter 12: Pointers
239
PRINT, ’C EQ NULL: ’, C EQ PTR_NEW() & $
PRINT, ’C NE NULL:’, C NE PTR_NEW()
IDL prints:
A EQ B:
1
A NE B:
0
A EQ C:
0
C EQ NULL: 1
C NE NULL: 0
Dangling References
If a heap variable is destroyed, any remaining pointer variable or object reference
that still refers to it is said to contain a dangling reference. Unlike lower level
languages such as C, dereferencing a dangling reference will not crash or corrupt
your IDL session. It will, however, fail with an error message. For example:
A = PTR_NEW(23)
Create a new heap variable.
PRINT, A, *A
Print A and the value of the heap
variable A points to.
IDL prints:
<PtrHeapVar13>
23
PTR_FREE, A
Destroy the heap variable.
PRINT, A, *A
Try to print again.
IDL prints:
% Invalid pointer: A.
% Execution halted at:
$MAIN$
There are several possible approaches to avoiding such errors. The best option is
to structure your code such that dangling references do not occur. You can,
however, verify the validity of pointers or object references before using them (via
the PTR_VALID or OBJ_VALID functions) or use the CATCH mechanism to
recover from the effect of such a dereference.
Heap Variable “Leakage”
Heap variables are not reference counted—that is, IDL does not keep track of
how many references to a heap variable exist, or stop the last such reference from
Building IDL Applications
Dangling References
240
Chapter 12: Pointers
being destroyed—so it is possible to lose access to them and the memory they are
using. For example:
A = PTR_NEW(23)
Create a new heap variable.
A = 0
Set the pointer A equal to the integer zero. The pointer to the heap
variable created with the first command is lost.
Use the HEAP_VARIABLES keyword to the HELP procedure to view a list of heap
variables currently in memory:
HELP, /HEAP_VARIABLES
IDL prints:
<PtrHeapVar14>
INT
=
23
In this case, the heap variable <PtrHeapVar14> exists and has a value of 23, but
there is no way to reference the variable. There are two options: manually create
a new pointer to the existing heap variable using the PTR_VALID function (see
“PTR_VALID” on page 858 of the IDL Reference Guide), or do manual “Garbage
Collection” and use the HEAP_GC command to destroy all inaccessible heap
variables.
Caution Object reference heap variables are subject to the same problems as pointer
heap variables. See “OBJ_VALID” on page 776 of the IDL Reference Guide
for more information.
The HEAP_GC procedure causes IDL to hunt for all unreferenced heap variables
and destroy them. It is important to understand that this is a potentially
computationally expensive operation, and should not be relied on by
programmers as a way to avoid writing careful code. Rather, the intent is to
provide programmers with a debugging aid when attempting to track down heap
variable leakage. In conjunction with the VERBOSE keyword, HEAP_GC makes
it possible to determine when variables have leaked, and it provides some hint as
to their origin.
Caution HEAP_GC uses a recursive algorithm to search for unreferenced heap variables. If HEAP_GC is used to manage certain data structures, such as large
linked lists, a potentially large number of operations may be pushed onto the
system stack. If so many operations are pushed that the stack runs out of room,
IDL will crash.
General reference counting, the usual solution to such leaking, is too slow to be
provided automatically by IDL, and careful programming can easily avoid this
pitfall. Furthermore, implementing a reference counted data structure on top of
Heap Variable “Leakage”
Building IDL Applications
Chapter 12: Pointers
241
IDL pointers is easy to do in those cases where it is useful, and such reference
counting could take advantage of its domain specific knowledge to do the job
much faster than the general case.
Another approach would be to write allocation and freeing routines—layered on
top of the PTR_NEW and PTR_FREE routines—that keep track of all outstanding
pointer allocations. Such routines might make use of pointers themselves to keep
track of the allocated pointers. Such a facility could offer the ability to allocate
pointers in named groups, and might provide a routine that frees all heap variables
in a given group. Such an operation would be very efficient, and is easier than
reference counting.
Pointer Validity
Use the PTR_VALID function to verify that one or more pointer variables point to
valid and currently existing heap variables, or to create an array of pointers to
existing heap variables. If supplied with a single pointer as its argument,
PTR_VALID returns TRUE (1) if the pointer argument points at a valid heap
variable, or FALSE (0) otherwise. If supplied with an array of pointers, PTR_VALID
returns an array of TRUE and FALSE values corresponding to the input array. If no
argument is specified, PTR_VALID returns an array of pointers to all existing
pointer heap variables. For example:
A = PTR_NEW(10)
Create a new pointer and heap
variable.
IF PTR_VALID(A) THEN PRINT, "A points to a valid heap variable." $
ELSE PRINT, "A does not point to a valid heap variable."
IDL prints:
A points to a valid heap variable.
PTR_FREE, A
Destroy the heap variable.
IF PTR_VALID(A) THEN PRINT, "A points to a valid heap variable." $
ELSE PRINT, "A does not point to a valid heap variable."
IDL prints:
A does not point to a valid heap variable.
See “PTR_VALID” on page 858 of the IDL Reference Guide for further details.
Building IDL Applications
Pointer Validity
242
Chapter 12: Pointers
Freeing Pointers
The PTR_FREE procedure destroys the heap variables pointed at by pointers
supplied as its arguments. Any memory used by the heap variable is released, and
the heap variable ceases to exist. PTR_FREE is the only way to destroy a pointer
heap variable; if PTR_FREE is not called on a heap variable, it continues to exist
until the IDL session ends, even if no pointers remain to reference it.
Note that the pointers themselves are not destroyed. Pointers that point to
nonexistent heap variables are known as dangling references, and are discussed
in more detail in “Dangling References” on page 239.
See “PTR_FREE” on page 856 of the IDL Reference Guide for further details.
Pointer Examples
Pointers are useful in building dynamic memory structures, such as linked lists
and trees. The following examples demonstrate how pointers are used to build
several types of dynamic structures. Note that the purpose of these examples is to
illustrate simply and clearly how pointers are used. As such, they may not
represent the “best” or most efficient way to accomplish a given task. Readers
interested in learning more about efficient use of data structures are urged to
consult any good text on data structures.
Creating a Linked List
The following example uses pointers to create and manipulate a linked list. One
procedure reads string input from the keyboard and creates a list of pointers to
heap variables that have the strings as their values. Another procedure prints the
strings, given the pointer to the beginning of the linked list. A third procedure
uses a modified “bubble sort” algorithm to reorder the values so the strings are in
alphabetical order.
Creating the List
The following program prompts the user to enter a series of strings from the
keyboard. After reading each string, it creates a new heap variable containing a
list element—an anonymous structure with two fields; one to hold the string data
and one to hold a pointer to the next list element. Any number of strings can be
entered. When the user is finished entering strings, the program can be exited by
entering a period by itself at the “Enter string:” prompt.
The text of the program shown below can be found in the file ptr_read.pro in
the doc subdirectory of the examples subdirectory of the IDL distribution.
Freeing Pointers
Building IDL Applications
Chapter 12: Pointers
243
PRO ptr_read, first
PTR_READ accepts one argument, a named variable in which
to return the pointer that points at
the beginning of the list.
newstring = ’’
Initialize the input string variable.
llist = {name:’’, next:PTR_NEW()}
Create an anonymous structure to
contain list elements. Note that the
next field is initialized to be a
null pointer.
PRINT, ’Enter a list of names.’
PRINT, ’Enter a period (.) to stop list entry.’
Print instructions for this program.
WHILE newstring NE "." DO BEGIN
Continue accepting input until a
period is entered.
READ, newstring, PROMPT=’Enter string: ’
Read a new string from the keyboard.
IF newstring NE ’.’ THEN BEGIN
Check to see if a pointer called first exists. If not, this is the first element. Create
a pointer called first and initialize it to be a list element. Create a second
pointer to the heap variable pointed at by first.
IF NOT(PTR_VALID(first)) THEN BEGIN
first = PTR_NEW(llist)
current = first
ENDIF
next = PTR_NEW(llist)
Create a pointer to the next list element.
(*current).name = newstring
Set the name field of current to
the input string.
(*current).next = next
Set the next field of current to
the pointer to the next list element.
last = current
Copy the pointer to current.
current = next
Make next the current pointer.
ENDIF
Building IDL Applications
Pointer Examples
244
Chapter 12: Pointers
name:
wilma
first:
next:
name:
biff
name:
cosmo
next:
next:
null
Figure 12-1: One way of visualizing the linked list created by the PTR_READ procedure.
ENDWHILE
IF PTR_VALID(last) THEN (*last).next = PTR_NEW()
Set the next field of the last ele-
ment to the null pointer.
END
End of PTR_READ program.
Run the PTR_READ program by entering the following command at the IDL
prompt:
ptr_read, first
Type a string, press Return, and the program prompts for another string. You can
enter as many strings as you want. Each time a string is entered, PTR_READ
creates a new list element with that string as its value. For example, you could
enter the following three strings (used in the rest of this example):
Enter a list of names.
Enter a period (.) to stop list entry.
Enter string: wilma
Enter string: biff
Enter string: cosmo
Enter string: .
Figure 12-1 shows one way of visualizing the linked list that we’ve created.
Printing the Linked List
The next program in our example accepts the pointer to the first element of the
linked list and prints all the values in the list in order. To illustrate how the list is
linked, we will also print the name of the heap variable that contains each
element, and the name of the heap variable in the next field of that element.
Pointer Examples
Building IDL Applications
Chapter 12: Pointers
245
The text of the program shown below can be found in the file ptr_print.pro
in the doc subdirectory of the examples subdirectory of the IDL distribution.
PRO ptr_print, first
PTR_PRINT accepts one argument, a pointer to the first element
of a linked list returned by
PTR_READ. Note that the
PTR_PRINT program does not
need to know how many elements
are in the list, nor does it need to
explicitly know of any pointer other than the first.
current = first
Create a second pointer to the heap
variable pointed at by first.
WHILE PTR_VALID(current) DO BEGIN
PTR_VALID returns 0 if its argument is not a valid pointer. Note
that the null pointer is not a valid
pointer.
PRINT, current, ’, named ’, (*current).name, $
’, has a pointer to: ’, (*current).next
Print the list element information.
current = (*current).next
Set current equal to the pointer
in its own next field.
ENDWHILE
END
End of PTR_PRINT program.
If we run the PTR_PRINT program with the list generated in the previous
example:
IDL> ptr_print, first
IDL prints:
<PtrHeapVar1>, named wilma, has a pointer to: <PtrHeapVar2>
<PtrHeapVar2>, named biff, has a pointer to: <PtrHeapVar3>
<PtrHeapVar3>, named cosmo, has a pointer to: <NullPointer>
A Simple Sorting Routine for the Linked List
The next example program takes a list generated by PTR_READ and moves the
values so that they are in alphabetical order. The sorting algorithm used in this
program is a variation on the classic “bubble sort”. However, instead of starting
with the last element in the list and letting lower values “rise” to the top, this
Building IDL Applications
Pointer Examples
246
Chapter 12: Pointers
example starts at the top of the list and lets higher (“heavier”) values “sink” to the
bottom of the list. Note that this is not a very efficient sorting algorithm and is
shown as an illustration because of its simplicity. For real sorting applications,
use IDL’s SORT function.
The text of the program shown below can be found in the file ptr_sort.pro in
the doc subdirectory of the examples subdirectory of the IDL distribution.
pro ptr_sort, first
PTR_SORT accepts one argument, a pointer to the first element
of a linked list returned by
PTR_READ. Note that the
PTR_SORT program does not
need to know how many elements
are in the list, nor does it need to
explicitly know of any pointer other than the first.
swap = 1
Initialize swap flag.
llist = {name:’’, next:PTR_NEW()}
Create an anonymous structure to
contain list elements. Note that the
next field is initialized to be a
pointer.
junk = ptr_new(llist)
Create a pointer to this structure,
to be used as “swap space.”
WHILE swap NE 0 DO BEGIN
Continue the sorting until no
swaps are made. If no adjacent elements need to be swapped, the list
is in alphabetical order.
current = first
Create a second pointer to the
heap variable pointed at by
first.
next = (*current).next
Create another pointer to the heap
variable held in the next field of
current.
swap = 0
Set swap flag.
WHILE PTR_VALID(next) DO BEGIN
Continue the sorting until next is
no longer a valid pointer. Note that
the null pointer is not a valid
pointer.
value1 = (*current).name
Pointer Examples
Get values to compare.
Building IDL Applications
Chapter 12: Pointers
247
value2 = (*next).name
IF (value1 GT value2) THEN BEGIN
Compare values and exchange if
first is greater than second.
(*junk).name = (*current).name
(*current).name = (*next).name
(*next).name = (*junk).name
Use the “swap space” pointer to
exchange the name fields of current and next.
current = next
Set current to next to advance
through the list.
swap = 1
Reset swap flag.
ENDIF ELSE current = next
If value1 is less than value2, set
current to next to advance
through the list.
next = (*current).next
Redefine next pointer.
ENDWHILE
ENDWHILE
END
To run the PTR_SORT routine with the list from our previous examples as input,
enter:
ptr_sort, first
We can see the results of the sorting by calling the PTR_PRINT routine again:
ptr_print, first
IDL prints:
<PtrHeapVar1>, named biff, has a pointer to: <PtrHeapVar2>
<PtrHeapVar2>, named cosmo, has a pointer to: <PtrHeapVar3>
<PtrHeapVar3>, named wilma, has a pointer to: <NullPointer>
and we see that now the names are in alphabetical order.
Building IDL Applications
Pointer Examples
248
Chapter 12: Pointers
Example Files—Using Pointers to Create Binary Trees
Two more-complicated example programs demonstrate the use of IDL pointers
to create and search a simple tree structure. These files, named idl_tree.pro
and tree_example.pro, can be found in the doc subdirectory of the
examples subdirectory of the IDL distribution.
To run the tree examples, enter the following commands at the IDL prompt:
.run idl_tree
Compile the routines in idl_tree.
The example routine calls the routines defined in this file.
tree_example
Run the tree_example.
The TREE_EXAMPLE and IDL_TREE routines create a binary tree with ten
nodes whose values are structures that contain random values for two fields,
“Time” and “Data”. The TREE_EXAMPLE routine then prints the tree sorted by
both time and data. It then searches for and deletes the nodes containing the
fourth and second data values. The resulting 8-node trees are again printed in
both time and data order.
A detailed explication of the TREE_EXAMPLE and IDL_TREE routines is
beyond the scope of this chapter. Interested users should examine the files,
starting with tree_example.pro, to see how the trees are created and searched.
Pointer Examples
Building IDL Applications
Chapter 13
Object Basics
The following topics are covered in this chapter:
IDL Object Overview........................... 250
Class Structures................................... 251
Inheritance ......................................... 253
Object Heap Variables ......................... 254
Null Objects........................................ 255
The Object Lifecycle............................ 255
Operations on Objects ....................... 258
Information about Objects ................. 259
Method Routines................................ 261
Method Overriding ............................ 263
Object Examples ................................ 265
249
250
Chapter 13: Object Basics
Traditional programming techniques make a strong distinction between routines written
in the programming language (procedures and functions in the case of IDL) and data to
be acted upon by the routines. Object oriented programming begins to remove this
distinction by melding the two into objects that can contain both routines and data.
Object orientation provides a layer of abstraction that allows the programmer to build
robust applications from groups of reusable elements.
Beginning in version 5, IDL provides a set of tools for developing object-oriented
applications. IDL’s Object Graphics engine is object-oriented, and a class library of graphics
objects allows you to create applications that provide equivalent graphics functionality
regardless of your (or your users’) computer platform, output devices, etc. As an IDL
programmer, you can use IDL’s traditional procedures and functions as well as the new
object features to create your own object modules. Applications built from object modules
are, in general, easier to maintain and extend than their traditional counterparts.
This chapter describes how to use object techniques with IDL. A complete discussion of object
orientation is beyond the scope of this book—if you are new to object oriented programming,
consult one of the many references on object oriented program that are available.
IDL Object Overview
IDL objects are actually special heap variables, which means that they are global in scope
and provide explicit user control over their lifetimes. Object heap variables can only be
accessed via object references. Object references are discussed in this chapter. Heap
variables in general are discussed in detail in “Heap Variables” on page 230.
Briefly, IDL provides support for the following object concepts and mechanisms:
Classes and Instances
IDL objects are created as instances of a class, which is defined in the form of an IDL
structure. The name of the structure is also the class name for the object. The instance
data of an object is an IDL structure contained in the object heap variable, and can only
be accessed by special functions and procedures, called methods, which are associated
with the class. Class structures are discussed in “Class Structures” on page 251.
Encapsulation
Encapsulation is the ability to combine data and the routines that affect the data into a
single object. IDL accomplishes this by only allowing access to an object’s instance data
via that object’s methods. Data contained in an object is hidden from all but the object’s
own methods.
Methods
IDL allows you to define method procedures and functions using all of the programming
tools available in IDL. Method routines are identified as belonging to an object class via
a routine naming convention. Methods are discussed in detail in “Method Routines” on
page 261.
IDL Object Overview
Objects and Object Graphics
Chapter 13: Object Basics
251
Polymorphism
Polymorphism is the ability to create multiple object types that support the same
operations. For example, many of IDL’s graphics objects support an operation called
“Draw,” which sends graphics output to a specified place. The “Draw” operation is
different in different contexts; sending a graphic to a printer is different from writing it to
a file. Polymorphism allows the details of the differences to remain hidden—all you need
to know is that a given object supports the “Draw” operation.
Inheritance
Inheritance is the ability of an object class to inherit the behavior of other object classes. This
means that when writing a new object class that is very much like an existing object class, you
need only program the functions that are different from those in the inherited class. IDL
supports multiple inheritance—that is, an object can inherit qualities from any number of
other existing object classes. Inheritance is discussed in detail in “Inheritance” on page 253.
Persistence
Persistence is the ability of objects to remain in existence in memory after they have been
created, allowing you to alter their behavior or appearance after their creation. IDL
objects persist until you explicitly destroy them, or until the end of the IDL session. In
practice, object persistence removes the need (in traditional IDL programs) to re-execute
IDL commands that create an item (a plot, for example) in order to change a detail of the
item. For example, once you have created a graphic object containing a plot, you can alter
any aspect of the plot “on the fly,” without re-creating it. Similarly, having created an
object containing a plot, you need not recreate the plot in order to print, save to an image
file, or re-display it.
IDL objects also persist in the sense that you can use the SAVE and RESTORE routines to
save and recreate objects between IDL sessions.
Class Structures
Object instance data is contained in named IDL structures. We will use the term class
structure to refer to IDL structures containing object instance data.
Beyond the restriction that class structures must be named structures, there are no limits
on what a class structure contains. Class structures can include data of any type or
organization, including pointers and object references. When an object is created, the
name of the class structure becomes the name of the class itself, and thus serves to define
the names of all methods associated with the class. For example, if we create the following
class structure:
struct = { Class1, data1:0L, data2:FLTARR(10) }
any objects created from the class structure Class1 would have the same two fields
(data1, a long integer, and data2, a ten-element floating-point array) and any
methods associated with the class would have the name Class1::method, where
method is the actual name of the method routine. Methods are discussed in detail in
“Method Routines” on page 261.
Objects and Object Graphics
Class Structures
252
Chapter 13: Object Basics
Note When a new instance of a structure is created from an existing named structure, all of
the fields in the newly-created structure are zeroed. This means that fields containing
numeric values will contain zeros, fields containing string values will contain null strings,
and fields containing pointers or objects will contain null pointers or null objects. In
other words, no matter what data the original structure contained, the new structure will
contain only a template for that type of data. This is true of objects as well; a newly created
object will contain a zeroed copy of the class structure as its instance data.
It is important to realize that creating a class structure does not create an object. Objects
can only be created by calling the OBJ_NEW or OBJARR function with the name of the
class structure as the argument, and can only be accessed via the returned object
reference. In addition, object methods can only be called on object, and not on class
structures themselves.
Automatic Class Structure Definition
If IDL finds a reference to a structure that has not been defined, it will search for a
structure definition procedure to define it. (This is true of all structure references, not just
class structures.) Automatic structure definition is discussed in “Automatic Structure
Definition” on page 54. Briefly, if IDL encounters a structure reference for a structure type
that has not been defined, it searches for a routine with a name of the form
STRUCT__DEFINE
where STRUCT is the name of the structure type. Note that there are two underscores in
the name of the structure definition routine.
The following is an example of a structure definition procedure that defines a structure
that will be used for the class CNAME.
PRO CNAME__DEFINE
struct = { CNAME, data1:0L, data2:FLTARR(10) }
END
This defines a structure named CNAME with 2 data fields (data1, a long integer, and
data2, a ten-element floating-point array). If you tell IDL to create an object of type
CNAME before this structure has been defined, IDL will search for the procedure
CNAME__DEFINE to define the class structure before attempting to create the object. If
the CNAME__DEFINE procedure has not yet been compiled, IDL will use its normal
routine searching algorithm to attempt to find a file named CNAME__DEFINE.PRO. If
IDL cannot find a defined structure or structure definition routine, the object-creation
operation will fail.
Note If you are creating structure definitions on the fly, the possibility exists that you will
run into namespace conflicts — that is, a structure with the same name as the
structure you are attempting to create may already exist. This can be a problem if you
are developing object-oriented applications for others, since you probably do not
have much control over the IDL environment on your clients’ systems. You can avoid
most problems by creating a unique namespace for your routines; Research Systems
does this by prefixing the names of objects with the letters “IDL”. To be completely
Class Structures
Objects and Object Graphics
Chapter 13: Object Basics
253
sure that the objects created by your programs are what you expect, however, you
should have the program inspect the created structures and handle errors appropriately.
Inheritance
When defining a class structure, use the INHERITS specifier to indicate that this structure
inherits instance data and methods from another class structure. For example, if we
defined a class structure called “circle,” as follows:
struct = { circle, x:0, y:0, radius:0 }
we can define a subclass of the “circle” class like this:
struct = { filled_circle, color:0, INHERITS circle }
You can use the INHERITS specifier in any structure definition. However, when the
structure being defined is a class structure (that is, an object will be created from the
structure), inheritance affects both the structure definition and the object methods
available to the object that inherits. The INHERITS specifier is discussed in “Structure
Inheritance” on page 43.
When a class structure inherits from another class structure, it is said to be a subclass of
the class it inherits from. Similarly, the class that is inherited from is called a superclass of
the new class. Defining a subclass of an existing class in this manner has two
consequences. First, the class structure for the subclass is constructed as if the elements of
the inherited class structure were included in-line in the structure definition. In our
example, the command defining the “filled_circle” class above would create the
followings structure definition:
{ filled_circle, color:0, x:0, y:0, radius:0 }
Note that the data fields from the inherited structure definition appear in-line at the point
where the INHERITS specifier appears.
The second consequence of defining a subclass structure that inherits from another class
structure is that when an object is created from the subclass structure, that object inherits
the superclass’ methods as well as its data fields. That is, if an object of the superclass type
has a method, that method is available to objects created from the subclass as well. In our
example above, say we create an object of type circle and define a Print method for
it. Any objects of type filled_circle will also have access to the Print method
defined for circle.
IDL allows multiple inheritance. This means that you can include the INHERITS specifier
as many times as you desire in a structure definition, as long as all of the resulting data
fields have unique names. Data fields must have unique names because when the class
structure definition is built, the tag names are included in-line at the point where the
INHERITS specifier appears. Duplicate tag names will cause the structure definition to
fail; it is your responsibility as a programmer to ensure that tag names are not used more
than once in a structure definition.
Objects and Object Graphics
Inheritance
254
Chapter 13: Object Basics
Note The requirement that names be unique applies only to data fields. It is perfectly
legitimate (and often necessary) for subclasses to have methods with the same names
as methods belonging to the superclass. See “Method Overriding” on page 263 for
details.
If a structure referred to by an INHERITS specifier has not been defined in the current
IDL session, IDL will attempt to define it in the manner described in “Automatic Class
Structure Definition” on page 252.
Object Heap Variables
Object heap variables are IDL heap variables that are accessible only via object references.
While there are many similarities between object references and pointers, it is important
to understand that they are not the same type, and cannot be used interchangeably.
Object heap variables are created using the OBJ_NEW and OBJARR functions. For more
information on heap variables and pointers, see“IDL Pointers” on page 233.
Heap variables are a special class of IDL variables that have global scope and explicit user
control over their lifetime. They can be basic IDL variables, accessible via pointers, or
objects, accessible via object references. In IDL documentation of pointers and objects,
heap variables accessible via pointers are called pointer heap variables, and heap variables
accessible via object references are called object heap variables.
Note Pointers and object references have many similarities, the strongest of which is that
both point at heap variables. It is important to understand that they are not the same
type, and cannot be used interchangeably. Pointers and object references are used to
solve different sorts of problems. Pointers are useful for building dynamic data
structures, and for passing large data around using a lightweight token (the pointer
itself) instead of copying data. Objects are used to apply object oriented design
techniques and organization to a system. It is, of course, often useful to use both in a
given program.
Heap variables are global in scope, but do not suffer from the limitations of COMMON
blocks. That is, heap variables are available to all program units at all times. (Remember,
however, that IDL variables containing pointers to heap variables are not global in scope
and must be declared in a COMMON block if you want to share them between program
units.)
Heap variables:
• Facilitate object oriented programming.
• Provide full support for Save and Restore. Saving a pointer or object reference automatically causes the associated heap variable to be saved as well. This means that if the heap
variable contains a pointer or object reference, the heap variables they point to are also
saved. Complicated self-referential data structures can be saved and restored easily.
• Are manipulated primarily via pointers or object references using built in language
operators rather than special functions and procedures.
Object Heap Variables
Objects and Object Graphics
Chapter 13: Object Basics
255
• Can be used to construct arbitrary, fully general data structures in conjunction with
pointers.
Dangling References
If a heap variable is destroyed, any remaining pointer variable or object reference that still
refers to it is said to contain a dangling reference. Unlike lower level languages such as C,
dereferencing a dangling reference will not crash or corrupt your IDL session. It will,
however, fail with an error message.
There are several possible approaches to avoiding such errors. The best option is to
structure your code such that dangling references do not occur. You can, however, verify
the validity of pointers or object references before using them (via the PTR_VALID or
OBJ_VALID functions) or use the CATCH mechanism to recover from the effect of such
a dereferencing.
Heap Variable “Leakage”
Heap variables are not reference counted—that is, IDL does not keep track of how many
references to a heap variable exist, or stop the last such reference from being destroyed—
so it is possible to lose access to them and the memory they are using. See “Heap
Variables” on page 230 for additional details.
Null Objects
The Null Object is a special object reference that is guaranteed to never point at a valid
object heap variable. It is used by IDL to initialize object reference variables when no
other initializing value is present. It is also a convenient value to use when defining
structure definitions for fields that are object references, since it avoids the need to have
a pre-existing valid object reference.
Null objects are created when you call an object-creation routine but do not specify a class
structure to be used as the new object’s template. The following statement creates a null
object:
nullobj = OBJ_NEW()
The Object Lifecycle
As discussed above, objects are persistent, meaning they exist in memory until you destroy
them. We can break the life of an object into three phases: creation and initialization, use,
and destruction. Object lifecycle routines allow the creation and destruction of object
references; lifecycle methods associated with an object allow you to control what happens
when an object is created or destroyed.
This section will discuss the first and last phases of the object lifecycle; the remainder of this
chapter discusses manipulation of existing objects and use of object method routines.
Objects and Object Graphics
Null Objects
256
Chapter 13: Object Basics
Creation and Initialization
Object references are created using one of two lifecycle routines: OBJ_NEW or OBJARR.
Newly created objects are initialized upon creation in two ways:
1. The object reference is created based on the class structure specified,
2. The object’s INIT method (if it has one) is called to initialize the object’s
instance data (contained in fields defined by the class structure). If the object
does not have an INIT method, the object’s superclasses (if any) are searched
for an INIT method.
The INIT Method
An object’s lifecycle method INIT is a function named Class::INIT (where Class is the
actual name of the class). The purpose of the INIT method is to populate a newly-created
object with instance data. INIT should return a scalar TRUE value (such as 1) if the
initialization is successful, and FALSE (such as 0) if the initialization fails.
The INIT method is unusual in that it cannot be called outside an object-creation operation.
This means that—unlike most object methods—you cannot call the INIT method on an
object directly. You can, however, call an object’s INIT method from within the INIT
method of a subclass of that object. This allows you to specify parameters used by the
superclass’ INIT method along with those used by the INIT method of the object being
created. In practice, this is often done using the _EXTRA keyword. See“Keyword
Inheritance” on page 114 for details.
The OBJ_NEW Function
Use the OBJ_NEW function to create an object reference to a new object heap variable. If
you supply the name of a class structure as its argument, OBJ_NEW creates a new object
containing an instance of that class structure. Note that the fields of the newly-created
object’s instance data structure will all be empty. For example, the command:
obj1 = OBJ_NEW(’ClassName’)
creates a new object heap variable that contains an instance of the class structure
ClassName, and places an object reference to this heap variable in obj1. If you do not
supply an argument, the newly-created object will be a null object.
When creating an object from a class structure, OBJ_NEW goes through the following
steps:
1. If the class structure has not been defined, IDL will attempt to find and call a
procedure to define it automatically. See “Automatic Class Structure Definition”
on page 252 for details. If the structure is still not defined, OBJ_NEW fails and
issues an error.
2. If the class structure has been defined, OBJ_NEW creates an object heap variable
containing a zeroed instance of the class structure.
The Object Lifecycle
Objects and Object Graphics
Chapter 13: Object Basics
257
3. Once the new object heap variable has been created, OBJ_NEW looks for a method
function named Class::INIT (where Class is the actual name of the class). If an
INIT method exists, it is called with the new object as its implicit SELF argument,
as well as any arguments and keywords specified in the call to OBJ_NEW. If the
class has no INIT method, the usual method-searching rules are applied to find
one from a superclass. For more information on methods and method-searching
rules, see “Method Routines” on page 261.
Note OBJ_NEW does not call all the INIT methods in an object’s class hierarchy. Instead,
it simply calls the first one it finds. Therefore, the INIT method for a class should call
the INIT methods of its direct superclasses as necessary.
4. If the INIT method returns true, or if no INIT method exists, OBJ_NEW returns
an object reference to the heap variable. If INIT returns false, OBJ_NEW destroys
the new object and returns the NULL object reference, indicating that the operation failed. Note that in this case the CLEANUP method is not called.
See “OBJ_NEW” in the IDL Reference Guide for further details.
The OBJARR Function
Use the OBJARR function to create an array of objects of up to eight dimensions. Every
element of the array created by OBJARR is set to the null object. For example, the
following command creates a 3 by 3 element object reference array with each element
contain the null object reference:
obj2 = OBJARR(3, 3)
See “OBJARR” in the IDL Reference Guide for further details.
Destruction
Use the OBJ_DESTROY procedure to destroy an object. If the object’s class, or one of its
superclasses, supplies a procedure method named CLEANUP, that method is called, and
all arguments and keywords passed by the user are passed to it. The CLEANUP method
should perform any required cleanup on the object and return. Whether a CLEANUP
method actually exists or not, IDL will destroy the heap variable representing the object
and return.
The CLEANUP method is unusual in that it cannot be called outside an object-destruction
operation. This means that—unlike most object methods—you cannot call the
CLEANUP method on an object directly. You can, however, call an object’s CLEANUP
method from within the CLEANUP method of a subclass of that object.
Note that the object references themselves are not destroyed. Object references that refer
to nonexistent object heap variables are known as dangling references, and are discussed
in more detail in“Dangling References” on page 239.
See “OBJ_DESTROY” in the IDL Reference Guide for further details.
Objects and Object Graphics
The Object Lifecycle
258
Chapter 13: Object Basics
Operations on Objects
Object reference variables are not directly usable by many of the operators, functions, or
procedures provided by IDL. You cannot, for example, do arithmetic on them or plot
them. You can, of course, do these things with the contents of the structures contained in
the object heap variables referred to by object references, assuming that they contain nonobject data.
There are four IDL operators that work with object reference variables: assignment, method
invocation, EQ, and NE. In addition, the structure dot operator (.) is allowed within
methods of a class. The remaining operators (addition, subtraction, etc.) do not make any
sense for object references and are not defined.
Many non-computational functions and procedures in IDL do work with object
references. Examples are SIZE, N_ELEMENTS, HELP, and PRINT. It is worth noting that
the only I/O allowed directly on object reference variables is default formatted output, in
which they are printed as a symbolic description of the heap variable they refer to. This is
merely a debugging aid for the IDL programmer—input/output of object reference
variables does not make sense in general and is not allowed. Please note that this does not
imply that I/O on the contents of non-object instance data contained in heap variables is
not allowed. Passing non-object instance data contained in an object heap variable to the
PRINT command is a simple example of this type of I/O.
Assignment
Assignment works in the expected manner—assigning an object reference to a variable
gives you another variable with the same reference. Hence, after executing the statements:
struct = { cname, data1:0.0 }
A = OBJ_NEW(’cname’)
B = A
HELP, A, B
Define a class structure.
Create an object.
Create a second object reference.
IDL prints:
A
OBJREF
= <ObjHeapVar1(CNAME)>
B
OBJREF
= <ObjHeapVar1(CNAME)>
Note that both A and B are references to the same object heap variable.
Method Invocation
In order to perform an action on an object’s instance data, you must call one of the object’s
methods. (See “Method Routines” on page 261 for more on methods.) To call a method, you
must use the method invocation operator, -> (the hyphen followed by the greater-than
sign). The syntax is:
ObjRef -> Method
where ObjRef is an object reference and Method is a method belonging either to the object’s
class or to one of its superclasses. Method may be specified either partially (using only the
Operations on Objects
Objects and Object Graphics
Chapter 13: Object Basics
259
method name) or completely using both the class name and method name, connected with
two colons:
ObjRef -> Class::Method
Equality and Inequality
The EQ and NE operators allow you to compare object references to see if they
refer to the same object heap variable. For example:
struct = {cname, data:0.0}
Define a class structure.
A = OBJ_NEW(’CNAME’)
Create an object.
B = A
B refers to the same object as A.
C = OBJ_NEW()
C contains a null object reference.
PRINT, ’A EQ B: ’, A EQ B & $
PRINT, ’A NE B: ’, A NE B & $
PRINT, ’A EQ C: ’, A EQ C & $
PRINT, ’C EQ NULL: ’, C EQ OBJ_NEW() & $
PRINT, ’C NE NULL:’, C NE OBJ_NEW()
IDL prints:
A EQ B:
1
A NE B:
0
A EQ C:
0
C EQ NULL: 1
C NE NULL: 0
Information about Objects
Three IDL routines allow you to obtain information about an existing object:
OBJ_CLASS
Use the OBJ_CLASS function to obtain the class name of a specified object, or to obtain
the names of a specified object’s direct superclasses. For example, if we create the
following class structures:
struct = {class1, data1:0.0 }
struct = {class2, data2a:0, data2b:0L, INHERITS class1 }
We can now create an object and use OBJ_CLASS to determine its class and superclass
membership.
A = OBJ_NEW(’class2’)
Objects and Object Graphics
Create an object.
Information about Objects
260
Chapter 13: Object Basics
PRINT, OBJ_CLASS(A)
Print A’s class membership.
IDL prints:
CLASS2
PRINT, OBJ_CLASS(A, /SUPERCLASS)
Print A’s superclasses.
IDL prints:
CLASS1
See “OBJ_CLASS” in the IDL Reference Guide for further details.
OBJ_ISA
Use the OBJ_ISA function to determine whether a specified object is an instance or
subclass of a specified object. For example, if we have defined the object A as above:
IF OBJ_ISA(A, ’class2’) THEN $
PRINT, ’A is an instance of class2.’
IDL prints:
A is an instance of class2.
See “OBJ_ISA” in the IDL Reference Guide for further details.
OBJ_VALID
Use the OBJ_VALID function to verify that one or more object references refer to valid and
currently existing object heap variables. If supplied with a single object reference as its
argument, OBJ_VALID returns TRUE (1) if the reference refers to a valid object heap
variable, or FALSE (0) otherwise. If supplied with an array of object references, OBJ_VALID
returns an array of TRUE and FALSE values corresponding to the input array. For example:
struct = {cname, data:0.0}
Create a class structure.
A = OBJ_NEW(’CNAME’)
Create a new object.
IF OBJ_VALID(A) PRINT, "A refers to a valid object." $
ELSE PRINT, "A does not refer to a valid object."
IDL prints:
A refers to a valid object.
OBJ_DESTROY, A
Destroy the object.
IF OBJ_VALID(A) PRINT, "A refers to a valid object." $
ELSE PRINT, "A does not refer to a valid object."
IDL prints:
A does not refer to a valid object.
See “OBJ_VALID” in the IDL Reference Guide for further details.
Information about Objects
Objects and Object Graphics
Chapter 13: Object Basics
261
Method Routines
IDL objects can have associated procedures and functions called methods. Methods are
called on objects via their object references using the method invocation operator.
While object methods are constructed in the same was as any other IDL procedure or
function, they are different from other routines in the following ways:
• Object methods are defined using a special naming convention that incorporates the name
of the class to which the method belongs.
• All method routines automatically pass an implicit argument named self, which
contains the object reference of the object on which the method is called.
• Object methods cannot be called on their own. You must use the method invocation
operator and supply a valid object reference, either of the class the method belongs to or
of one of that class’ subclasses.
Defining Method Routines
Method routines are defined in the same way as other IDL procedures and functions, with
the exception that the name of the class to which they belong, along with two colons, is
prepended to the method name:
PRO ClassName::Method
IDL statements
END
or
FUNCTION ClassName::Method, Argument1
IDL statements
RETURN, value
END
For example, suppose we create two objects, each with its own “print” method.
First, define two class structures:
struct = { class1, data1:0.0 }
struct = { class2, data2a:0, data2b:0L, INHERITS class1 }
Now we define two “print” methods to print the contents of any objects of either of these
two classes. (If you are typing this at the IDL command line, enter the .RUN command
before each of the following procedure definitions.)
PRO class1::Print1
PRINT, self.data1
END
PRO class2::Print2
PRINT, self.data1
Objects and Object Graphics
Method Routines
262
Chapter 13: Object Basics
PRINT, self.data2a, self.data2b
END
Once these procedures are defined, any objects of class1 have access to the method
Print1, and any objects of class2 have access to both Print1 and Print2
(because class2 is a subclass of—it inherits from—class1). Note that the Print2
method prints the data1 field inherited from class1.
Note It is not necessary to give different method names to methods from different classes,
as we have done here with Print1 and Print2. In fact, in most cases both methods
would have simply been called Print, with each object class knowing only about its
own version of the method. We have given the two procedures different names here
for instructional reasons; see “Method Overriding” on page 263 for a more complete
discussion of method naming.
The Implicit Self Argument
Every method routine has an implicit argument parameter named self. The self
parameter always contains the object reference of the object on which the method is
called. In the method routines created above, self is used to specify which object the
data fields should be printed from.
You do not need to explicitly pass the self argument; in fact, if you try to specify an
argument called self when defining a method routine, IDL will issue an error.
Calling Method Routines
You must use the method invocation operator (->) to call a method on an object. The
syntax is slightly different from other routine invocations:
ObjRef -> Method
For a procedure method.
Result = ObjRef -> Method()
For a function method.
Where ObjRef is an object reference belonging to the same class as the Method, or to one
of that class’ subclasses. We can illustrate this behavior using the Print1 and Print2
methods defined above.
First, define two new objects:
A = OBJ_NEW(’class1’)
B = OBJ_NEW(’class2’)
We can call Print1 on the object A as follows:
A -> Print1
IDL prints:
0.00000
Similarly, we can call Print2 on the object B:
B -> Print2
Method Routines
Objects and Object Graphics
Chapter 13: Object Basics
263
IDL prints:
0.00000
0
0
Since the object B inherits its properties from class1, we can also call Print1 on the
object B:
B -> Print1
IDL prints:
0.00000
We cannot, however, call Print2 on the object A, since class1 does not inherit the
properties of class2:
A -> Print2
IDL prints:
% Attempt to call undefined method: ’CLASS1::PRINT2’.
Searching for Method Routines
When a method is called on an object reference, IDL searches for it as with any procedure
or function, and calls it if it can be found, following the naming convention established
for structure definition routines. (See “Automatic Class Structure Definition” on page
252.) In other words, IDL discovers methods as it needs them in the same way as regular
procedures and functions, with the exception that it searches for files named
classname__method.pro
Note the two underscores.
rather than simply
method.pro
Remember that there are two underscores in the file name, but two colons in the method
routine’s name. See “Executing Program Files” in Using IDL for details.
Note If you are working in an environment where the length of filenames is limited, you
may want to consider defining all object methods in the same .pro file you use to
define the class structure. This practice avoids any problems caused by the need to
prepend the classname and the two underscore characters to the method name. If you
must use different .pro files, make sure that all class (and superclass) definition
filenames are unique in the first eight characters.
Method Overriding
Unlike data fields, method names can be duplicated. This is an important feature that
allows method overriding, which in turn facilitates polymorphism in the design of
object-oriented programs. Method overriding allows a subclass to provide its own
implementation of a method already provided by one of its superclasses. When a method
Objects and Object Graphics
Method Overriding
264
Chapter 13: Object Basics
is called on an object, IDL searches for a method of that class with that name. If found,
the method is called. If not, the methods of any inherited object classes are examined in
the order their INHERITS specifiers appear in the structure definition, and the first
method found with the correct name is called. If no method of the specified name is
found, an error occurs.
The method search proceeds depth first, left to right. This means that if an object’s class
does not provide the method called directly, IDL searches through inherited classes by
first searching the leftmost included class—and all of its superclasses—before proceeding
to the next inherited class to the right. If a method is defined by more than a single
inherited structure definition, the first one found is used and no warning is generated.
This means that class designers should pick non-generic names for their methods as well
as their data fields. For example, suppose we have defined the following classes:
struct = { class1, data1}
struct = { class2, data2a:0, data2b:0.0, inherits class1 }
struct = { class3, data3:’’, inherits class2, inherits class1 }
struct = { class 4, data4:0L, inherits class2, inherits class3 }
Furthermore, suppose that both class1 and class3 have a method called Print
defined.
Now suppose that we create an object of class4, and call the Print method:
A = OBJ_NEW(’class4’)
A -> Print
IDL takes the following steps:
1. Searches class4 for a Print method. It does not find one.
2. Searches the leftmost inherited class (class2) in the class definition structure for
a Print method. It does not find one.
3. Searches any superclasses of class2 for a Print method. It finds the class1
Print method and calls it on A.
Notice that IDL stops searching when it finds a method with the proper name. Thus, IDL
doesn’t find the Print method that belongs to class3.
Specifying Class Names in Method Calls
If you specify a class name when calling an object method, like so:
ObjRef -> classname::method
Where classname is the name of one of the object’s superclasses, IDL will search classname
and any of classname’s superclasses for the method name. IDL will not search the object’s
own class or any other classes the object inherits from.
Method Overriding
Objects and Object Graphics
Chapter 13: Object Basics
265
This type of method call is especially useful when a class has a method that overrides a
superclass method and does its job by calling the superclass method and then adding
functionality. In our simple example from “Calling Method Routines” on page 262,
above, we could have defined a Print method for each class, as follows:
PRO class1::Print
PRINT, self.data1
END
PRO class2::Print
self -> class1::Print
PRINT, self.data2a, self.data2b
END
In this case, to duplicate the behavior of the Print1 and Print2 methods, we make
the following method calls:
A -> Print
IDL prints:
0.00000
B -> Print
IDL prints:
0.00000
0
0
B -> class1::Print
IDL prints:
0.00000
A -> class2::Print
IDL prints:
% CLASS2 is not a superclass of object class CLASS1.
% Execution halted at:
$MAIN$
Object Examples
We have included a number of examples of object-oriented programming as part of the
IDL distribution. Many of the examples used in this volume are included—sometimes in
expanded form— in the object subdirectory of the examples subdirectory of the
main IDL directory. By default, this directory is part of IDL's path; if you have not
changed your path, you will be able to run the examples as described here. See “!PATH”
in Chapter 3 of the IDL Reference Guide for information on IDL's path.
Objects and Object Graphics
Object Examples
266
Object Examples
Chapter 13: Object Basics
Objects and Object Graphics
Chapter 14
Graphics
The following topics are covered in this chapter:
IDL Direct Graphics............................. 268
IDL Object Graphics............................ 268
267
268
Chapter 14: Graphics
Beginning with IDL version 5.0, IDL supports two distinct graphics modes: Direct
Graphics and Object Graphics. Direct Graphics rely on the concept of a current
graphics device; IDL commands like PLOT or SURFACE create images directly on
the current graphics device. Object Graphics use an object-oriented programmers’
interface to create graphic objects, which must then be drawn, explicitly, to a
destination of the programmer’s choosing.
IDL Direct Graphics
If you have used versions of IDL prior to version 5.0, you are already familiar with
IDL Direct Graphics. The salient features of Direct Graphics are:
•
Direct Graphics use a graphics device (‘X’ for X-windows systems displays, ‘WIN’
for Microsoft Windows displays, ‘MAC’ for Macintosh displays, ‘PS’ for PostScript
files, etc.). You switch between graphics devices using the SET_PLOT command,
and control the features of the current graphics device using the DEVICE command.
•
IDL commands that existed in IDL 4.0 use Direct Graphics. Commands like
PLOT, SURFACE, XYOUTS, MAP_SET, etc. all draw their output directly on the
current graphics device.
•
Once a direct-mode graphic is drawn to the graphics device, it cannot be altered
or re-used. This means that if you wish to re-create the graphic on a different
device, you must re-issue the IDL commands to create the graphic.
•
When you add a new item to an existing direct-mode graphic (using a routine like
OPLOT or XYOUTS), the new item is drawn in front of the existing items.
Documentation for IDL Direct Graphics routines is found in four volumes of the
IDL Documentation set: Using IDL, Building IDL Applications, and the IDL
Reference Guide.
IDL Object Graphics
Versions of IDL beginning with version 5.0 include Object Graphics in addition
to Direct Graphics. The salient features of Object Graphics are:
•
Object graphics are device independent. There is no concept of a current graphics
device when using object-mode graphics; any graphics object can be displayed on
any physical device for which a “destination object” can be created.
•
Object graphics are object oriented. Graphic objects are meant to be created and
re-used; you may create a set of graphic objects, modify their attributes, draw them
to a window on your computer screen, modify their attributes again, then draw
IDL Direct Graphics
Building IDL Applications
Chapter 14: Graphics
269
them to a printer device without reissuing all of the IDL commands used to create
the objects. Graphics objects also encapsulate functionality; this means that
individual objects include method routines that provide functionality specific to
the individual object.
•
Object graphics are rendered in three dimensions. Rendering implies many operations not needed when drawing Direct Graphics, including calculation of normal
vectors for lines and surfaces, lighting considerations, and general object overhead. As a result, the time needed to render a given object—a surface, say—will
often be longer than the time taken to draw the analogous image in Direct
Graphics.
•
Object Graphics use a programmer’s interface. Unlike Direct Graphics, which are
well suited for both programming and interactive, ad hoc use, Object Graphics
are designed to be used in programs that are compiled and run. While it is still
possible to create and use graphics objects directly from the IDL command line,
the syntax and naming conventions make it more convenient to build a program
“off line” than to create graphics objects on the fly.
•
Because Object Graphics persist in memory, there is a greater need for the
programmer to be cognizant of memory issues and memory “leakage.” Efficient
design—remembering to destroy unused object references and cleaning up—will
avert most problems, but even the best designs can be memory-intensive if large
numbers of graphic objects (or large datasets) are involved.
Documentation for IDL Object Graphics is found in Objects and Object Graphics.
This volume contains both explanatory material on IDL’s object system and
reference material describing IDL’s object classes.
Building IDL Applications
IDL Object Graphics
270
IDL Object Graphics
Chapter 14: Graphics
Building IDL Applications
Chapter 15
Widgets
The following topics are covered in this chapter:
Widget Types ...................................... 273
Manipulating Widgets......................... 277
Examples of Widget Programming ...... 278
The Widget Application Model ........... 278
Creating Widget Applications.............. 281
Widget Example 1............................... 283
Widget Values ..................................... 284
Widget User Values ............................. 286
Widget Events..................................... 287
Widget Example 2............................... 292
Using Draw Widgets........................... 294
Creating Menus.................................. 295
Controlling Widgets ........................... 300
Widget Example 3 .............................. 302
Widget Sizing ................................... 304
Event Processing And Callbacks ......... 309
Managing Widget Application State . 312
Compound Widgets .......................... 314
Tips on Creating Widget Applications . 315
Compound Widget Example .............. 316
271
272
Chapter 15: Widgets
IDL allows you to construct and manipulate graphical user interfaces using
widgets. Widgets (or controls, in the terminology of some development
environments) are simple graphical objects such as pushbuttons or sliders that
allow user interaction via a pointing device (usually a mouse) and a keyboard.
This style of graphical user interaction offers many significant advantages over
traditional command-line based systems.
IDL widgets are significantly easier to use than other alternatives, such as writing
a C language program using the native window system directly. IDL handles
much of the low-level work involved in using such toolkits. The interpretive
nature of IDL makes it easy to prototype potential user interfaces. In addition to
the user interface, the author of a program written in a traditional compiled
language also must implement any computational and graphical code required
by the program. IDL widget programs can draw on the full computational and
graphical abilities of IDL to supply these components.
The style of widgets IDL creates depends on the windowing system supported by
your host computer. Unix and VMS hosts use Motif widgets, while Microsoft
Windows and Macintosh systems use their native toolkits. Although the different
toolkits produce applications with a slightly different look and feel, most
properly-written widget applications work on all systems without change.
IDL graphical user interfaces are constructed by combining widgets in a treelike
hierarchy. Each widget has one parent widget and zero or more child widgets.
There is one exception: the topmost widget (called a top-level base) is always a
base widget and has no parent.
Programs that use widgets are event driven. In an event driven system, the
program creates an interface and then waits for messages (events) to be sent to it
from the window system. Events are generated in response to user manipulation,
such as pressing a button or moving a slider. The program responds to events by
carrying out the action or computation specified by the programmer, and then
waiting for the next event. This approach to computing is fundamentally
different from the traditional command-based approach.
Note You can use the IDL GUIBuilder to create user interfaces interactively. The
GUIBuilder allows you to create and interface rapidly and generate the IDL
source code to create the interface. For information, see “Using the
IDL GUIBuilder” in Chapter 7 of Using IDL.
Running the Example Code
The example code used in this chapter is part of the IDL distribution. All of the files
mentioned are located in the doc subdirectory of the examples subdirectory of
the main IDL directory. By default, this directory is part of IDL’s path; if you have
Building IDL Applications
Chapter 15: Widgets
273
not changed your path, you will be able to run the examples as described here. See
“!PATH” on page 43 of the IDL Reference Guide for information on IDL’s path.
Widget Types
IDL supports two types of widgets. Widget primitives are the base interface
elements. Compound widgets are more complex interface elements built in the
IDL language from the widget primitives. In addition, there are a number of
dialogs which are widget-like but which do not belong to a widget hierarchy.
Widget Primitives
Widget primitives are created by functions with names like WIDGET_BASE and
WIDGET_BUTTON. IDL provides the following widget primitives:
Base
A base is a widget used to hold other widgets, including other base widgets. Base
widgets can optionally contain scroll bars that allow the base to be larger than the
space on the screen. In this case, only part of the base is visible at any given time,
and the scroll bars are used to control which part is visible.
Base widgets are created by the WIDGET_BASE function. See “WIDGET_BASE”
on page 1205 of the IDL Reference Guide for more information.
Top-level bases are a special class of base widget created without a parent widget
ID. Top-level bases can be organized into an application hierarchy by specifying
the GROUP_LEADER keyword. Top-level bases can be made to float above their
group leaders (via the FLOATING keyword), or can be created as modal bases (via
the MODAL keyword) that interrupt program execution until the user performs
some action. See “The Widget Application Model” on page 278 for additional
discussion of widget applications.
Button
A pushbutton is activated by moving the mouse cursor over the button and
pressing a mouse button. Button widgets are created by the WIDGET_BUTTON
function. See “WIDGET_BUTTON” on page 1222 of the IDL Reference Guide
for more information.
Draw
Draw widgets offer a rectangular area that works like a standard IDL graphics
window. Draw widgets can use either Direct graphics or Object graphics,
depending on how they are created. Any graphical output that can be produced
by IDL can be directed to one of these widgets, either through the WSET function
or by using the object reference of a draw widget’s IDLgrWindow object. Draw
Building IDL Applications
Widget Types
274
Chapter 15: Widgets
widgets can optionally contain scrollbars that allow examining a graphical region
larger than the area containing the widget. Draw widgets are created by the
WIDGET_DRAW function. See “WIDGET_DRAW” on page 1252 of the IDL
Reference Guide for more information.
Droplist
Droplist widgets display a single entry from a list of options. When selected, they
reveal the entire list. When a new option is selected from this list, the list
disappears and the new selection is displayed. On systems using the Motif
window system, Droplist widgets look like buttons with labels that change
depending on the item selected from the drop-down list. Droplist widgets are
created by the WIDGET_DROPLIST function. See “WIDGET_DROPLIST” on
page 1262 of the IDL Reference Guide for more information.
Label
Label widgets display static text. They are similar to single-line text widgets but
are optimized for small labeling purposes. Text widgets should be used to display
large amounts of text. Label widgets are created by the WIDGET_LABEL
function. See “WIDGET_LABEL” on page 1280 of the IDL Reference Guide for
more information.
List
A list widget offers the user a list of text elements from which to choose. Users can
select an item by pointing with the mouse cursor and pressing a button. List
widgets always have a vertical scrollbar and allow selection from a large number
of items. List widgets are created by the WIDGET_LIST function. See
“WIDGET_LIST” on page 1285 of the IDL Reference Guide for more
information.
Message
Message dialogs are modal (or “blocking”) dialog boxes that can display
warnings, informational messages, or error messages. When a message dialog is
displayed, no widgets can be manipulated until the user dismisses the dialog by
clicking on one of its buttons. Message dialogs do not belong to widget
hierarchies; they are instantly created when the DIALOG_MESSAGE function is
called and block all widget activity until dismissed. See “DIALOG_MESSAGE”
on page 423 of the IDL Reference Guide for more information.
Slider
Slider widgets are used to select or indicate a value within a range of possible
integer values. They consist of a rectangular region that represents the possible
range of values. Inside this region is a sliding pointer that displays the current
value. This pointer can be manipulated by the user via the mouse or from within
Widget Types
Building IDL Applications
Chapter 15: Widgets
275
IDL by the WIDGET_CONTROL procedure. Slider widgets are created by the
WIDGET_SLIDER function. See “WIDGET_SLIDER” on page 1291 of the IDL
Reference Guide for more information.
Table
Table widgets are used to display information in tabular format. Individual table
cells (or ranges of cells) can be selected for editing by the user. Table widgets are
created by the WIDGET_TABLE function. See “WIDGET_TABLE” on page 1298
of the IDL Reference Guide for more information.
Text
Text widgets are used to display text and to get text input from the user. They can
have one or more lines and can optionally contain scroll bars that allow viewing
more text than can otherwise be displayed. Text widgets are created by the
WIDGET_TEXT function. See “WIDGET_TEXT” on page 1309 of the IDL
Reference Guide for more information.
Compound Widgets
A compound widget is a complete, self-contained, reusable widget sub-tree that
behaves to a large degree just like a widget primitive, but which is written in the
IDL language. These can be found (along with many other routines that use the
widgets) in the lib subdirectory of the IDL distribution. All compound widget
filenames begin with “CW_” to make them easier to identify. The following types
of compound widgets are included in the IDL distribution.
Animation
The CW_ANIMATE compound widget — along with its associated routines —
displays an animated sequence of images. See “CW_ANIMATE” on page 341 of
the IDL Reference Guide.
Color Manipulation
The CW_CLR_INDEX compound widget displays a color bar and allows the user
to select a color index. See “CW_CLR_INDEX” on page 358 of the IDL Reference
Guide.
The CW_COLORSEL compound widget displays all the colors in the current
colormap and allows the user to select color indices. See “CW_COLORSEL” on
page 360 of the IDL Reference Guide.
The CW_RGBSLIDER compound widget allows the user to adjust color values
using the RGB, CMY, HSV, and HLS color systems. See “CW_RGBSLIDER” on
page 387 of the IDL Reference Guide.
Building IDL Applications
Widget Types
276
Chapter 15: Widgets
Data Entry and Display
The CW_FIELD compound widget simplifies building data-entry interfaces by
combining label and text widgets. See “CW_FIELD” on page 368 of the IDL
Reference Guide.
The CW_FORM compound widget allows you to create simple forms with text,
numeric fields, buttons, and droplists. See “CW_FORM” on page 371 of the IDL
Reference Guide.
Image Manipulation
The CW_DEFROI compound widget allows you to specify a region of interest
within a draw widget. See “CW_DEFROI” on page 362 of the IDL Reference
Guide.
The CW_ZOOM compound widget displays original and zoomed images sideby-side. See “CW_ZOOM” on page 390 of the IDL Reference Guide.
Orientation
The CW_ARCBALL compound widget allows the user to intuitively specify
three-dimensional orientations. See “CW_ARCBALL” on page 350 of the IDL
Reference Guide.
The CW_ORIENT compound widget allows the user to interactively adjust the
three-dimensional drawing transformation. See “CW_ORIENT” on page 380 of
the IDL Reference Guide.
User Interface
The CW_BGROUP compound widget simplifies creation of a cluster of buttons.
Button groups can be simple menus in which each button acts independently,
exclusive groups (also known as “radio buttons”), or non-exclusive groups (often
called “checkboxes”). See “CW_BGROUP” on page 354 of the IDL Reference
Guide.
The CW_FSLIDER compound widget is a version of the slider widget that
handles floating-point values. See “CW_FSLIDER” on page 377 of the IDL
Reference Guide.
The CW_PDMENU compound widget creates pulldown menus, which can
include sub-menus, from a set of buttons. See “CW_PDMENU” on page 382 of
the IDL Reference Guide.
See “Writing Compound Widgets” on page 314 for information on writing your
own compound widgets.
Widget Types
Building IDL Applications
Chapter 15: Widgets
277
Dialogs
A dialog is a widget-like user interface element that is not part of a widget
hierarchy. Dialogs are modal (or “blocking”) elements, which means that when a
dialog is displayed, no other interface elements (widgets or compound widgets)
can be manipulated until the user dismisses the dialog.
File and Directory Selection
File selection dialogs allow you to choose a file or directory via a graphical
interface. The DIALOG_PICKFILE function returns the string containing the
name of the selected file. See “DIALOG_PICKFILE” on page 426 of the IDL
Reference Guide for more information.
Message
Message dialogs can display warnings, informational messages, or error
messages. Message dialogs are created when the DIALOG_MESSAGE function is
called and block all widget activity until dismissed. See “DIALOG_MESSAGE”
on page 423 of the IDL Reference Guide for more information.
Printing
IDL provides two dialogs for controlling printing. DIALOG_PRINTJOB opens a native
dialog that allows you to set the properties of a printer.parameters for a printing job
(number of copies to print, for example). DIALOG_PRINTERSETUP opens a native
dialog for setting the applicable properties for a particular printer. See
“DIALOG_PRINTJOB” on page 429 of the IDL Reference Guide and
“DIALOG_PRINTERSETUP” on page 430 of the IDL Reference Guide for more
information.
Manipulating Widgets
Widgets are controlled via their widget IDs. The widget ID is a long integer
assigned to the widget when it is first created. In practice, the widget ID of a
widget is contained in a named variable that you assign when you call the widget
creation function. For example, you might create a base widget with the following
IDL command:
base = WIDGET_BASE()
Here, the IDL variable base contains the widget ID of the top-level widget base
that is created.
IDL provides several routines that allow you to manipulate and manage widgets:
Building IDL Applications
Manipulating Widgets
278
Chapter 15: Widgets
•
“WIDGET_CONTROL” on page 1230 of the IDL Reference Guide allows you
to realize (make visible on your screen) widget hierarchies, manipulate them,
and destroy them when you are finished.
•
“WIDGET_EVENT” on page 1268 of the IDL Reference Guide allows you to
process events generated by a specific widget hierarchy.
•
“WIDGET_INFO” on page 1271 of the IDL Reference Guide allows you to
obtain information about the state of a specific widget or widget hierarchy.
•
“XMANAGER” on page 1363 of the IDL Reference Guide provides an event
loop and manages events generated by a widget hierarchy.
•
“XREGISTERED” on page 1374 of the IDL Reference Guide allows you to test
whether a specific widget is currently registered with XMANAGER.
These widget manipulation routines are discussed in more detail in the following
sections.
Examples of Widget Programming
A number of simple examples of widget programming can be seen by running the
IDL program EXAMPLES. A widget interface with a pulldown menu of small
widget applications should appear. You can find the .pro files for these
applications in the general subdirectory of the examples subdirectory of the
IDL distribution.
The Widget Application Model
Using widgets, you can create entire IDL applications with graphical user
interfaces. Although widget applications are running “inside” IDL, a welldesigned program can behave and appear just like a stand-alone application.
A widget application consists of a group of top-level bases organized hierarchically.
Groups of widgets are defined by setting the GROUP_LEADER keyword when
creating the widget. Group membership controls how and when widgets are
iconized, which layer they appear in, and when they are destroyed. See
“GROUP_LEADER” on page 1208 of the IDL Reference Guide for additional
information.
Figure 15-1 depicts a widget application group hierarchy consisting of six toplevel bases in three groups: base 1 leads all six bases, base 2 leads bases 4 and 5,
and base 3 leads base 6. What does this mean? Operations that affect base 2 also
affect bases 4 and 5. Operations that affect base 3 also affect base 6. Operations
that affect base 1 affect all six bases—that is, a group includes not only those bases
Examples of Widget Programming
Building IDL Applications
Chapter 15: Widgets
279
that explicitly claim one base as their leader, but also all bases led by those
member bases.
Figure 15-1: A widget application group hierarchy with six top-level bases.
The following IDL commands would create this hierarchy:
base1
base2
base3
base4
base5
base6
=
=
=
=
=
=
WIDGET_BASE()
WIDGET_BASE(GROUP_LEADER=base1)
WIDGET_BASE(GROUP_LEADER=base1)
WIDGET_BASE(GROUP_LEADER=base2)
WIDGET_BASE(GROUP_LEADER=base2)
WIDGET_BASE(GROUP_LEADER=base3)
Iconization
On Motif and Windows platforms, bases and groups of bases can be iconized (or
minimized) by clicking the system minimize control. When a group leader is
iconized, all members of the group are minimized as well. Minimization has no
meaning on the Macintosh.
Layering
Layering is the process by which groups of widgets seem to share the same plane
on the display screen. Within a layer on the screen, widgets have a Z-order, or
front-to-back order, that defines which widgets appear to be on top of other
widgets.
All widgets within a group hierarchy share the same layer—that is, when one
group member has the input focus, all members of the group hierarchy are
Building IDL Applications
The Widget Application Model
280
Chapter 15: Widgets
displayed in a layer that appears in front of all other groups or applications.
Within the layer, the widgets can have an arbitrary Z-order.
Destruction
When a group leader widget is destroyed, either programmatically or by clicking
on the system “close” button, all members of the group are destroyed as well.
See “Iconizing, Layering, and Destroying Groups of Top-Level Bases” on page
1219 of the IDL Reference Guide for detailed information on how group
membership defines widget behavior on different platforms.
Floating bases
Top-level base widgets created with the FLOATING keyword set will float above
their group leaders, even though they share the same layer. Floating bases and
their group leaders are iconized in a single icon (on platforms where iconization
is possible). Floating bases are destroyed when their group leaders are destroyed.
See “FLOATING” on page 1208 of the IDL Reference Guide for additional
information.
Modal bases
Top-level base widgets created with the MODAL keyword will float above their
group leaders, and will suspend processing in the widget application until they
are dismissed. (Dialogs are generally modal.) Modal bases cannot be iconized,
and on some platforms other bases cannot be moved or iconized while the modal
dialog is present. Modal bases cannot have scroll bars or menubars. See
“MODAL” on page 1210 of the IDL Reference Guide for additional information.
See “Iconizing, Layering, and Destroying Groups of Top-Level Bases” on page
1219 of the IDL Reference Guide for detailed information on how modal dialogs
behave on different platforms.
Menubars
Widget applications can have an application-specific menubar, created by the
APP_MBAR keyword to WIDGET_BASE. Currently, application menubars are
equivalent to individual menubars created by the MBAR keyword on Motif and
Windows platforms. On the Macintosh, the menubar defined by APP_MBAR
“takes over” the Macintosh system menubar, while menubars defined by MBAR
are included on an individual top-level base widget.
See “APP_MBAR” on page 1206 of the IDL Reference Guide for additional
information.
The Widget Application Model
Building IDL Applications
Chapter 15: Widgets
281
Creating Widget Applications
An application using widgets goes through the following cycle:
Construct the Widget Hierarchy
You must first build a widget hierarchy. Start with one or more top-level bases
(created with the WIDGET_BASE function) in a hierarchy described by
GROUP_LEADER relationships. Combine other widget creation functions —
WIDGET_BUTTON, CW_PDMENU, etc. — to create and organize the user
interface of your widget application. At this point, the widgets exist only within
IDL—nothing has been created or displayed on the window system.
Provide an Event-Handling Routine
In order for a widget application to do anything, you must provide a routine that
examines events, determines what action to take, and implements the action.
Actions may involve computation, graphics display, or updating the widget
interface itself.
For the best performance, it is important that the program spend most of its time
in the event loop provided by the event handling routine. Some widgets will not
respond rapidly to user manipulation when not in this loop. Widget-based
programs should wait for user-generated events, handle them as quickly as
possible, and quickly return to wait for more events. Event processing is discussed
in detail in “Widget Events” on page 287 and in “Event Processing And Callbacks”
on page 309.
Event handling routines can use the WIDGET_CONTROL procedure to
manipulate widgets. Possible actions include the following:
•
Obtain or change the value of a widget (see “Widget Values” on page 284)
using the APPEND, GET_VALUE, and SET_VALUE keywords.
•
Obtain or change the value of a widget’s user value (discussed in “Widget User
Values” on 286) using the GET_UVALUE and SET_UVALUE keywords.
•
Map and unmap widgets using the MAP keyword. Unmapped widgets are
removed from the screen and become invisible, but they still exist.
•
Change a widget’s sensitivity using the SENSITIVE keyword. When a widget
is insensitive, it indicates the fact by changing its appearance (often by graying
itself or displaying text with dashed lines) and ignores any user input. It is
useful to make widgets insensitive at points where it would be inconvenient
to get events from them (for example, if your program is waiting for input
from another source).
•
Change the settings of toggle buttons using the SET_BUTTON keyword.
Building IDL Applications
Creating Widget Applications
282
Chapter 15: Widgets
•
Push a widget hierarchy behind the other windows on the screen, or pull them
in front using the SHOW keyword.
•
If you expect an operation to be slow, display the “hourglass” cursor while the
application is busy and not able to respond to user actions by setting the
HOURGLASS keyword.
Realize the Widgets
Bring the widget hierarchy into existence using the REALIZE keyword to the
WIDGET_CONTROL procedure. This causes the widgets to be created and
displayed.
Register the Program with the XMANAGER
Register the program with the XMANAGER procedure. Your widget application
then waits for events to be reported to it and reacts as specified in the event
handling routine.
Events are obtained by XMANAGER via the WIDGET_EVENT function and
passed to the calling routine (your event handler) in the form of an IDL structure
variable. Each type of widget returns a different type of structure, the exact form
of which is described in the documentation for the individual widget creation
functions in the IDL Reference Guide. However, every event structure has the
same first three elements. These are long integers named ID, TOP, and
HANDLER. ID is the widget ID of the widget generating the event. TOP is the
widget ID of the top-level base containing ID. HANDLER is important for event
handler functions, which are discussed later in this chapter.
When an event appears, XMANAGER passes it to an event-handling procedure
specified by the program, and the event handler takes some appropriate action
based on the event. This means that multiple widget applications can run
simultaneously — XMANAGER dispatches the events to the appropriate routine.
Destroy the Widgets
When the application has finished (usually when the user clicks on a “Done” or
“Quit” button), destroy the widget hierarchy using the WIDGET_CONTROL
procedure’s DESTROY keyword. This causes all resources related to the hierarchy
to be freed and removes it from the screen.
Handling Widget Application Errors
At times, widget applications may experience errors that stop the processing of
widget events by XMANAGER. This is most common during the development of
the application, when unexpected programming errors are likely to appear.
By default, XMANAGER catches errors and continues processing (see “CATCH”
on page 1363 of the IDL Reference Guide). If you are using XMANAGER to
Creating Widget Applications
Building IDL Applications
Chapter 15: Widgets
283
manage your widget application (as in most cases you should), have explicitly set
CATCH=0, and the widget stops responding, error messages appear in your
command log, and the IDL command prompt reappears, do the following:
1. Enter RETALL at the IDL prompt to return to the main program level.
2. Enter XMANAGER at the IDL prompt. Calling XMANAGER with no parameters
tells it to skip registering a new application and to simply resume event processing.
Note If you do not restart XMANAGER, widget applications will not respond even
if you recompile.
Widget Example 1
The following example demonstrates how simple widget programming can be. It
creates a base widget containing a single button, labelled “Done.” When you
position the mouse cursor over the button and click, the widget is destroyed.
Enter the two procedures listed below — either in a text file named widget1.pro,
or directly into IDL using the .RUN command. Enter widget1 at the IDL prompt
to run the program.
PRO widget1_event, ev
IF ev.select THEN WIDGET_CONTROL, ev.top, /DESTROY
END
PRO widget1
base = WIDGET_BASE()
button = WIDGET_BUTTON(base, value=’Done’)
WIDGET_CONTROL, base, /REALIZE
XMANAGER, ’Widget1’, base
END
Alternately, you can run the program from the IDL distribution by entering:
widget1
at the IDL command prompt. See “Running the Example Code” on page 272 if
IDL does not run the program as expected.
While this simple example does nothing particularly useful, it does illustrate
some basic concepts of event-driven programming. Let’s examine how the
example is constructed.
First, note that the “application” consists of two parts; an event handling routine
and a creation routine. First, let’s examine the second part — the creation routine
— contained in the widget1 procedure.
The widget1 procedure does the following:
Building IDL Applications
Widget Example 1
284
Chapter 15: Widgets
1. Creates a top-level base widget named base. All widget applications have at least
one base.
2. Creates a button widget named button with base as its parent. The value “Done”
is assigned to the button. The value of a button widget is the text that appears on
the button’s face.
3. Realizes the widget hierarchy built on base by calling WIDGET_CONTROL with
the /REALIZE keyword. This causes the widget to appear on your computer
screen.
4. Invokes the XMANAGER routine to manage the widget event loop, providing the
name of the calling routine (widget1) and the name of the top-level base the
widget hierarchy is built on (base).
The first part, contained in the widget1_event procedure, is the event
handling routine for the application. By convention, the XMANAGER procedure
looks for an event handling procedure with the same name as the procedure that
creates the widgets, with “_event” appended to the end. (This default can be
overridden by specifying an event handler directly using the EVENT_HANDLER
keyword to XMANAGER.) When an event is received by XMANAGER, the event
structure is passed to the widget1_event procedure via the ev argument.
In this example, all the event handling routine does is check to see if the event
passed to it was a select event, which is part of the event structure generated by
the button widget. If a select event is received, the routine calls WIDGET_CONTROL
with the DESTROY keyword to destroy the widget hierarchy built on the toplevel base widget that contains the button widget (specified in the top field of the
event structure).
For further discussion of widget events and event structures, see “Widget Events”
on page 287. For details about the event structures returned by different widgets,
see the documentation for each widget in the IDL Reference Guide.
Widget Values
Many widget primitives have values associated with them. Initial values are set
using the VALUE keyword to the widget creation function. The value can be
obtained and/or changed at any time using the GET_VALUE and SET_VALUE
keywords to the WIDGET_CONTROL procedure. Widgets with a value are listed
below:
Button
Type: Scalar string (text) or byte array (bitmap). The value is the button label.
The GET_VALUE keyword cannot be used to obtain bitmaps.
Widget Values
Building IDL Applications
Chapter 15: Widgets
285
To specify text as a button label, use the VALUE keyword as follows:
button = WIDGET_BUTTON(base, VALUE=’Text’)
To specify a bitmap as a button label, use the VALUE keyword as follows:
button = WIDGET_BUTTON(base, VALUE=’mybitmap.bmp’, /BITMAP)
Note that when specifying a bitmap as a button label, you must use the BITMAP
keyword.
Draw
Type: Integer. The value is the IDL window number for use with graphics
routines, such as WSET. This value cannot be set or modified.
Label
Type: Scalar string. The value is the label text.
List or Droplist
Type: Scalar string or string array. The value represents the list elements. This
value can only be set; it cannot be retrieved.
Slider
Type: Integer. The value is the current slider position.
Table
Type: Any data type or types, organized either in a two-dimensional array or as a
vector of structures. The value is the contents of the table.
If the value is specified as a two-dimensional array, all data must be of the same
type.
If the value is specified as a vector of structures, all of the structures must have the same
structure definition. Individual fields within the structures can be of any data type. The
structures must contain one field for each column (if the COLUMN_MAJOR keyword
to WIDGET_TABLE is set) or one field for each row (if the ROW_MAJOR keyword to
WIDGET_TABLE is set, or if neither keyword is set).
Text
Type: Scalar string or string array. The value is the contents of the text widget.
When setting this value, the APPEND keyword to WIDGET_CONTROL causes
the new text to be appended to the old text instead of replacing it.
Widget Values of Compound Widgets
Many compound widgets also have associated values. Initial values can often be
specified using the VALUE keyword to the creation routine. Note, however, that
Building IDL Applications
Widget Values
286
Chapter 15: Widgets
in some cases widget values of compound widgets cannot be set until after the
widget is realized; values are thus set, obtained, or changed using the
GET_VALUE and SET_VALUE keywords to the WIDGET_CONTROL
procedure. See the documentation for the individual compound widget creation
routines in the IDL Reference Guide for more detailed information. Compound
widgets with a value are listed below:
CW_ARCBALL
Type: 3 by 3 array. The value is the three-dimensional rotation matrix.
CW_BGROUP
Type: Integer or Vector. For “normal” button groups, there is no value. For
exclusive button groups, the value is the integer index of the selected button. For
non-exclusive button groups, the value is a vector indicating which buttons are
selected. The initial value of a button group can be set using the SET_VALUE
keyword to CW_BGROUP.
CW_CLR_INDEX
Type: Integer. The value is the index of the color selected. The value cannot be set
before the widget is realized.
CW_COLORSEL
Type: Integer. The value is the index of the color selected. The value cannot be set
before the widget is realized.
CW_FIELD
Type: String. The value is the string value of the text portion of the field widget.
CW_FORM
Type: Structure. The value is a structure of tag/value pairs for each field in the
form. The value cannot be set before the widget is realized.
CW_FSLIDER
Type: Floating-point number. The value is the numeric value of the slider.
CW_ZOOM
Type: byte array. The value is the current array displayed. Note that you must use
the SET_VALUE keyword to WIDGET_CONTROL to display the original image.
Widget User Values
Every widget primitive and compound widget has the potential to carry a userspecified value of any IDL data type and organization. That is, every widget
Widget User Values
Building IDL Applications
Chapter 15: Widgets
287
contains a variable that can store arbitrary information. This value is ignored by
the widget and is for the programmer’s convenience only.
The initial user value is specified using the UVALUE keyword to the widget
creation function. If no initial value is specified, the user value is undefined. Once
the widget exists, its user value can be examined and/or changed using the
GET_UVALUE and SET_UVALUE keywords to the WIDGET_CONTROL
procedure. The widget user value should not be confused with the concept of
widget values described above.
User Values Simplify Event Handling
User values can be used to simplify event-handling. If each widget in a widget
hierarchy has a distinct user value, you need only check the user value of any
event to determine which widget generated it. In practice, this means you do not
need to keep track of the widget IDs of all the widgets in your widget hierarchy in
order to determine what to do with a given event.
User Values Can Simulate Global Variables
Another use for user variables is to simulate a variable that is “known” in more
than one IDL routine. For example, you can set the user value of a top-level base
widget equal to one or more widget IDs. You then have an easy way to “import”
the widget IDs from your widget creation routine into your event handling
routine.
We will take advantage of both of these aspects of user values in our next example,
“Widget Example 2” on page 292.
Widget Events
The concept of events and event processing underlies every aspect of widget
programming. It is important to understand how IDL handles widget events in
order to use widgets effectively.
What are Widget Events?
A widget event is a message returned from the window system as the result of user
interactions such as pressing a button or otherwise manipulating a widget. In
response to an event, a widget program usually performs some action for the user
(e.g., opens a file, updates a plot).
Structure of Widget Events
As events arrive from the window system, IDL saves them in a queue for the target
widget. They are delivered to the IDL program as IDL structures by the
Building IDL Applications
Widget Events
288
Chapter 15: Widgets
WIDGET_EVENT function. Every widget event structure has the same first three
fields: these are long integers named ID, TOP, and HANDLER.
•
ID is the widget ID of the widget generating the event.
•
TOP is the widget ID of the top-level base containing ID.
•
HANDLER is the widget ID of the widget associated with the event handling
routine. The importance of HANDLER will become apparent when we discuss
event routines and compound widgets, below.
Event structures for different widgets may contain other fields as well. The exact
form of the event structure for any given widget is described in the
documentation for that widget’s creation function in the IDL Reference Guide.
Processing Widget Events
All widget event processing in IDL is handled by the WIDGET_EVENT function.
Note that while we will discuss WIDGET_EVENT here for completeness, in most
cases you will not want to call WIDGET_EVENT directly. The IDL XMANAGER
routine provides a convenient, simplified interface to WIDGET_EVENT and
allows IDL to take over the task of managing multiple widget applications.
See “XMANAGER” on page 1363 of the IDL Reference Guide.
Calling the WIDGET_EVENT Function
In its simplest form, the WIDGET_EVENT function is called with a widget ID
(usually, the ID of a widget base) as its argument. WIDGET_EVENT checks the
queue of undelivered events for that widget or any of its children. If an event is
present, it is immediately dequeued and returned. If no event is available,
WIDGET_EVENT blocks until one arrives and then returns it. Typically, the
request is made for a top-level base, so WIDGET_EVENT returns events for any
widget in that widget hierarchy (also called a widget tree).
This simple usage suffers from a major weakness. Since each call to
WIDGET_EVENT is looking for events from a specified widget hierarchy, it is
not possible to receive events for more than one widget hierarchy at a time. It is
important to be able to run multiple widget applications (each with a separate
top-level base) simultaneously. An example would be an image processing
application, a colortable manipulation tool, and an on-line help reader all
running together.
One solution to this problem is to call WIDGET_EVENT with an array of widget
identifiers instead of a single ID. In this case, WIDGET_EVENT returns events
for any widget hierarchy in the list. This solution is effective, but it still requires
that you maintain a complete list of all interesting top-level base identifiers,
which implies that all cooperating applications need to know about each other.
Widget Events
Building IDL Applications
Chapter 15: Widgets
289
The most powerful way to use WIDGET_EVENT is to call it without any
arguments at all. Called this way, it will return events for any currently-realized
widgets that have expressed an interest in being managed. (You specify that a
widget wants to be managed by setting the MANAGED keyword to the
WIDGET_CONTROL procedure.) This form of WIDGET_EVENT is especially
useful when used in conjuction with widget event callback routines, discussed in
“Event Processing And Callbacks” on page 309.
Managing Events with XMANAGER
As discussed above, WIDGET_EVENT provides basic widget event-handling
capabilities. However, it is extremely rare for a user-written widget program to
actually call WIDGET_EVENT directly. Instead, your programs should call the
XMANAGER procedure, which provides a convenient, simplified interface to
WIDGET_EVENT.
A widget application creates and realizes its widgets, and then calls XMANAGER.
XMANAGER arranges for an event-handling procedure supplied by the
application to be called when events for it arrive. The application is shielded from
the details of calling WIDGET_EVENT and interacting with other widget
applications that may be running simultaneously.
For these reasons, widget applications should always use XMANAGER in
preference to calling WIDGET_EVENT directly. The file xmng_tmpr.pro,
found in the lib subdirectory of the main IDL directory, is a template for writing
widget applications that use XMANAGER.
A Note About Blocking in XMANAGER
Beginning with IDL version 5.0, most versions of IDL’s command-processing
front-end are able to support an active command line while running properly
constructed widget applications. What this means is that—provided the widget
application is properly configured—the IDL command input line is available for
input while a widget application is running and widget events are being
processed.
There are currently 5 separate IDL command-processing front-end implementations:
•
Apple Macintosh Integrated Development Environment (IDLDE)
•
Microsoft Windows IDLDE
•
Motif IDLDE (Unix and VMS)
•
Unix plain tty
•
VMS plain tty
Building IDL Applications
Widget Events
290
Chapter 15: Widgets
All of these front-ends are able to process widget events except for the VMS plain
tty. VMS users can still enjoy an active command line by using the IDLDE
interface.
If the command-processing front-end can process widget events (that is, if the
front-end is not the VMS plain tty), it is still necessary for widget applications to
be well-behaved with respect to blocking widget event processing. Since in most
cases XMANAGER is used to handle widget event processing, this means that in
order for the command line to remain active, all widget applications must be run
with the NO_BLOCK keyword to XMANAGER set. (Note that since
NO_BLOCK is not the default, it is quite likely that some application will block.)
If a single application runs in blocking mode, the command line will be
inaccessible until the blocking application exits. When a blocking application
exits, the IDL command line will once again become active.
JUST_REG vs. NO_BLOCK
Although their names imply a similar function, the JUST_REG and NO_BLOCK
keywords perform very different services. It is important to understand what they
do and how they differ.
The JUST_REG keyword tells XMANAGER that it should simply register a client
and then return immediately. The result is that the client becomes known to
XMANAGER, and that future calls to XMANAGER will take this client into
account. Therefore, JUST_REG only controls how the registering call to
XMANAGER should behave. The client can still be registered as requiring
XMANAGER to block by setting NO_BLOCK=0. In this case, future calls to
XMANAGER will block.
Note JUST_REG is useful in situations where you suspect blocking might occur—
if the active command line is not supported and you wish to keep it active
before beginning event processing, or if blocking will be requested at a later
time. If no blocking will occur or if the blocking behavior is useful, it is not
necessary to use JUST_REG.
The NO_BLOCK keyword tells XMANAGER that the registered client does not
require XMANAGER to block if the command-processing front-end is able to
support active command line event processing. XMANAGER remembers this
attribute of the client until the client exits, even after the call to XMANAGER that
registered the client returns. NO_BLOCK is just a “vote” on how XMANAGER
should behave—the final decision is made by XMANAGER by considering the
NO_BLOCK attributes of all of its current clients as well as the ability of the
command-processing front-end in use to support the active command line.
Widget Events
Building IDL Applications
Chapter 15: Widgets
291
Blocking vs. Non-blocking Applications
The issue of blocking in XMANAGER requires some explanation. IDL widget
events are not processed until the WIDGET_EVENT function is called to handle
them. Otherwise, they are queued by IDL indefinitely. Knowing how and when
to call WIDGET_EVENT is the primary service provided by XMANAGER.
There are two ways blocking is typically handled:
1. The first call to XMANAGER processes events by calling WIDGET_EVENT as
necessary until no managed widgets remain on the screen. This is referred to as
“blocking” because XMANAGER does not return to the caller until it is done, and
the IDL command line is not available.
2. XMANAGER does not block, and instead, the part of IDL that reads command
input also watches for widget events and calls WIDGET_EVENT as necessary
while also reading command input. This is referred to as “non-blocking” or “active
command line” mode.
XMANAGER will block unless all of the following conditions are met:
•
The command-processing front-end is able to process widget events (that is, the
front-end is not the VMS plain tty).
•
All registered widget applications have the NO_BLOCK keyword to XMANAGER set.
•
No modal dialogs are displayed. (Modal dialogs always block until dismissed.)
In general, we suggest that new widget applications be written with XMANAGER
blocking disabled (that is, with the NO_BLOCK keyword set). Since a widget
application that does block event processing for itself will block event processing for
all other widget applications (and the IDL command line) as well, we suggest that
older widget applications be upgraded to take advantage of the new, non-blocking
behavior by adding the NO_BLOCK keyword to most calls to XMANAGER.
Features Reserved to XMANAGER
Because XMANAGER buffers you from direct handling of widget events, it
requires that you not explicitly specify certain event handling features for the toplevel base of your widget application. To be able to work with XMANAGER,
widget applications should avoid the following pitfalls. If you ignore the
suggestions below, your changes will conflict with those made by XMANAGER:
•
Do not specify an event-handling function or procedure on the top-level base of a
widget application using the EVENT_FUNC or EVENT_PRO keywords to the
widget creation functions or WIDGET_CONTROL. Instead, provide the name of
the event handler routine to XMANAGER via the EVENT_HANDLER keyword.
Building IDL Applications
Widget Events
292
Chapter 15: Widgets
•
Do not specify a death notification procedure on the top-level base of a widget
application using the KILL_NOTIFY keyword to the widget creation functions or
WIDGET_CONTROL. Instead, provide the name of your “cleanup” routine to
XMANAGER via the CLEANUP keyword.
For a detailed discussion of XMANGER, see “XMANAGER” on page 1363 of the
IDL Reference Guide.
The XREGISTERED Function
The XMANAGER procedure does not restrict applications to only a single
running copy. Indeed, it is desirable for most applications to allow multiple
simultaneous instances to run. However, there are some applications that should
only allow a single instance at a time, either because it makes logical sense or
because a weakness in the implementation requires it. An obvious example of this
is an application that uses a COMMON block to maintain its current state (see
“Managing Widget Application State” on page 312).
The XREGISTERED function can be used in such applications to ensure that
only a single copy can run at a time. Place the following statement at the start of
the routine:
IF XREGISTERED('routine_name') THEN RETURN
where routine_name is the name of the widget application.
See “XREGISTERED” on page 1374 of the IDL Reference Guide for further
information.
Widget Example 2
The following example demonstrates how user values can be used to simplify
event processing and to pass variables between routines. It creates a base widget
with three buttons and a text field that reports which button was pressed.
Enter the two procedures listed below — either in a text file named widget2.pro,
or directly into IDL using the .RUN command. Enter widget2 at the IDL prompt
to run the program.
PRO widget2_event, ev
WIDGET_CONTROL, ev.top, GET_UVALUE=textwid
WIDGET_CONTROL, ev.id, GET_UVALUE=uval
CASE uval OF
’ONE’ : WIDGET_CONTROL, textwid, SET_VALUE=’Button One Pressed’
’TWO’ : WIDGET_CONTROL, textwid, SET_VALUE=’Button Two Pressed’
’DONE’: WIDGET_CONTROL, ev.top, /DESTROY
ENDCASE
END
Widget Example 2
Building IDL Applications
Chapter 15: Widgets
293
PRO widget2
base = WIDGET_BASE(/COLUMN)
button1 = WIDGET_BUTTON(base, VALUE=’One’, UVALUE=’ONE’)
button2 = WIDGET_BUTTON(base, VALUE=’Two’, UVALUE=’TWO’)
text = WIDGET_TEXT(base, XSIZE=20)
button3 = WIDGET_BUTTON(base, value=’Done’, UVALUE=’DONE’)
WIDGET_CONTROL, base, SET_UVALUE=text
WIDGET_CONTROL, base, /REALIZE
XMANAGER, ’Widget2’, base
END
Alternately, you can run the program from the IDL distribution by entering:
widget2
at the IDL command prompt. See “Running the Example Code” on page 272 if
IDL does not run the program as expected.
Once again, let’s examine the creation routine, widget2, first. We first create a
top-level base, this time specifying the COLUMN keyword to ensure that the
widgets contained in the base are stacked vertically. We create two buttons with
values “One” and “Two,” and user values “ONE” and “TWO.” Remember that the
value of a button widget is also the button’s label. We create a text widget, and
specify its width to be 20 characters using the XSIZE keyword. The last button is
the “Done” button, with a the user value “DONE.”
Next follow two calls to the WIDGET_CONTROL procedure. The first sets the
user value of the top-level base equal to the widget ID of our text widget. This will
allow us easy access to the text widget from our event handling routine. The
second realizes the top-level base and all its child widgets. Finally, we invoke the
XMANAGER to manage the widget application.
The widget2_event routine is slightly more complicated than its predecessor.
We begin by using WIDGET_CONTROL to retrieve the widget ID of the our text
widget from the user value of the top-level base. We can do this because we know
that the widget ID of our top-level base is contained in the TOP field of the widget
event structure — thus, ev.top contains the widget ID of the base widget. We
use the GET_UVALUE keyword to store the widget ID of the text widget in the
variable textwid.
Next, we use WIDGET_CONTROL and the GET_UVALUE keyword to retrieve
the user value of the widget that generated the event. Again, we can do this
because we know that the widget ID of the widget that generated the event is
stored in the ID field of the event structure. We then use a CASE statement to
compare the user value of the widget, now stored in the variable uval, with the
Building IDL Applications
Widget Example 2
294
Chapter 15: Widgets
list of possible user values (which we know, have set them explicitly in the
creation routine) to determine which button was pressed and act accordingly.
In the CASE statement, we check to see if uval is the user value associated with
either button one or button two. If it is, we use WIDGET_CONTROL and the
SET_VALUE keyword to alter the value of the text widget, whose ID we stored in
the variable textwid. If uval is ’DONE’, we recognize that the user has clicked
on the “Done” button and use WIDGET_CONTROL to destroy the widget
hierarchy.
Using Draw Widgets
Draw widgets are graphics windows that appear as part of a widget hierarchy
rather than appearing as an independent window. Like other graphics windows,
draw widgets can be created to use either Direct or Object graphics. (See
“Graphics” on page 267 for a discussion of IDL’s two graphics modes.) Draw
widgets allow designers of IDL graphical user interfaces to take advantage of the
full power of IDL graphics in their displays.
Using Direct Graphics in Draw Widgets
Standard Direct graphics windows are created using the WINDOW procedure,
while Direct graphics draw widgets are created using the WIDGET_DRAW
function with the GRAPHICS_LEVEL keyword set equal to one. Draw widgets
use Direct graphics by default. Once created, Direct graphics windows and draw
widgets are used in the same way.
All IDL Direct graphics windows are referred to by a window number. Unlike
windows created by the WINDOW procedure, the window number of a Direct
graphics draw widget cannot be assigned by the user. In addition, the window
number of a draw widget is not assigned until the draw widget is actually realized,
and thus cannot be returned by WIDGET_DRAW when the widget is created.
Instead, you must use the WIDGET_CONTROL procedure to retrieve the
window number, which is stored in value of the draw widget, after the widget has
been realized.
Unlike normal graphics windows, creating a draw widget does not cause the
current graphics window to change to the new widget. You must use the WSET
procedure to explicitly make the draw widget the current graphics window. The
following IDL statements demonstrate the required steps:
base = WIDGET_BASE()
Create a base widget.
draw = WIDGET_DRAW(base, XSIZE = 256, YSIZE = 256)
Attach a 256 x 256 draw widget.
WIDGET_CONTROL, /REALIZE, base
Using Draw Widgets
Realize the widgets.
Building IDL Applications
Chapter 15: Widgets
295
WIDGET_CONTROL, draw, GET_VALUE = index
Obtain the window index.
WSET, index
Set the new widget to be the current graphics window
If you attempt to get the value of a draw widget before the widget has been
realized, IDL returns the value -1, which is not a valid index.
Using Object Graphics in Draw Widgets
Standard Object graphics windows are IDLgrWindow objects, whereas Object
graphics draw widgets are created using the WIDGET_DRAW function with the
GRAPHICS_LEVEL keyword set equal to two. Once created, Object graphics
windows and draw widgets are used in the same way.
All IDL Object graphics windows are referred to by an object reference. Since you
do not explicitly create the IDLgrWindow object used in a draw widget, you must
retrieve the object reference by using the WIDGET_CONTROL procedure to get
the value of the draw widget. As with Direct graphics draw widgets, the window
object is not created—and thus the object reference cannot be retrieved—until
after the draw widget is realized.
Scrolling Draw Widgets
Another difference between a draw widget and either a graphics window created
with the WINDOW procedure or an IDLgrWindow object is that draw widgets
can include scroll bars. Setting the APP_SCROLL keyword or the SCROLL
keyword to the WIDGET_DRAW function causes scrollbars to be attached to the
drawing widget, which allows the user to view images or graphics larger than the
visible area. Use the APP_SCROLL keyword when displaying images, or anything
drawn in device units or pixels. Use the SCROLL keyword when a draw widget is
going to display graphics drawn in data units (e.g., PLOT, CONTOUR,
SURFACE).
The IDL SLIDE_IMAGE routine is an example of a widget application that uses
both regular and scrolling draw widgets. See “WIDGET_DRAW” on page 1252
of the IDL Reference Guide for details, or inspect the file slide_image.pro in
the lib subdirectory of your main IDL directory for an example.
Creating Menus
Menus allow a user to select one or more options from a list of options. IDL
widgets allow you to build a number of different types of menus for your widget
application.
Building IDL Applications
Creating Menus
296
Chapter 15: Widgets
Button Groups
One approach to menu creation is to build an array of buttons. With a button
menu, all options are visible to the user all the time. To create a button menu, do
the following:
1. Call the WIDGET_BASE function to create a base to hold the buttons. Use the
COLUMN and ROW keywords to determine the layout of the buttons.
2. Call the WIDGET_BUTTON function once for each button to be added to the
base created in the previous step.
Because menus of buttons are common, IDL provides a compound widget
named CW_BGROUP to create them. Using CW_BGROUP rather than a series
of calls to WIDGET_BUTTON simplifies creation of a menu of buttons and also
simplifies event handling by providing a single event structure for the group of
buttons. For example, the following IDL statements create a button menu with
five choices:
values = [’One’, ’Two’, ’Three’, ’Four’, ’Five’]
base = WIDGET_BASE()
bgroup = CW_BGROUP(base, VALUE=values, /COLUMN)
WIDGET_CONTROL, base, /REALIZE
In this example, one call to CW_BGROUP replaces five calls to
WIDGET_BUTTON.
Exclusive or Nonexclusive Buttons
Buttons in button groups normally act as independent entities, returning a
selection event (a one in the select field of the event structure) or similar value
when pressed. Groups of buttons can also be made to act in concert, as either
exclusive or non-exclusive groups. In contrast to normal button groups, both
exclusive and non-exclusive groups display which buttons have been selected.
Exclusive button groups allow only one button to be selected at a given time.
Clicking on an unselected button deselects any previously-selected buttons. Nonexclusive button groups allow any number of buttons to be selected at the same
time. Clicking on the same button repeatedly selects and deselects that button.
The following code creates three button groups. The first group is a “normal”
button group as created in the previous example. The next is an exclusive group,
and the third is a non-exclusive group. The widget created by this code is shown
in Figure 15-2.
values = [’One’, ’Two’, ’Three’, ’Four’, ’Five’]
base = WIDGET_BASE(/ROW)
Creating Menus
Building IDL Applications
Chapter 15: Widgets
297
Figure 15-2: Normal Menu (left), Exclusive Menu (center)
and Non-exclusive Menu (right)
bgroup1 = CW_BGROUP(base, VALUE=values, /COLUMN, $
LABEL_TOP=’Normal’, /FRAME)
bgroup2 = CW_BGROUP(base, VALUE=values, /COLUMN, /EXCLUSIVE, $
LABEL_TOP=’Exclusive’, /FRAME)
bgroup3 = CW_BGROUP(base, VALUE=values, /COLUMN, /NONEXCLUSIVE, $
LABEL_TOP=’Nonexclusive’, /FRAME)
WIDGET_CONTROL, base, /REALIZE
Lists
A second approach to menu creation is to provide the user with a list of options
in the form of a scrolling or drop-down list. A scrolling list is always displayed,
although it may not show all items in the list at all times. A drop-down list shows
only the selected item until the user clicks on the list, at which time it displays the
entire list. Both lists allow only a single selection at a time.
The following example code creates uses the WIDGET_LIST and WIDGET_DROPLIST
functions to create two menus of five items each. While both lists contain five
items, the scrolling list displays only three at a time, because we specify this with
the YSIZE keyword. The widget created by this code is shown in Figure 15-3.
values = [’One’, ’Two’, ’Three’, ’Four’, ’Five’]
Figure 15-3: A scrolling list and a drop-down list.
Building IDL Applications
Creating Menus
298
Chapter 15: Widgets
base = WIDGET_BASE(/ROW)
list = WIDGET_LIST(base, VALUE=values, YSIZE=3)
drop = WIDGET_DROPLIST(base, VALUE=values)
WIDGET_CONTROL, base, /REALIZE
Pulldown Menus
A third approach to menu creation involves menus that appear as a single button
until the user selects the menu, at which time the menu pops up to display the list
of possible selections. Buttons in such a pulldown menu can activate other
pulldown menus to any desired depth. The method for creating a pulldown
menu is as follows:
1. The topmost element of any pulldown menu is a button, created with the MENU
keyword to the WIDGET_BUTTON function.
2. The top-level button has one or more child widget buttons attached. (That is, one
or more buttons specify the first button’s widget ID as their “parent.”) Each button
can either be used as is, in which case pressing it causes an event to be generated,
or it can be created with the MENU keyword and have further child widget buttons
attached to it. If it has child widgets, pushing it causes a pulldown menu containing the child buttons to pop into view.
3. Menu buttons can be the parent of other buttons to any desired depth.
Because pulldown menus are common, IDL provides a compound widget named
CW_PDMENU to create them. Using CW_PDMENU rather than a series of calls
to WIDGET_BUTTON simplifies creation of a pulldown menu in the same way
the CW_BGROUP simplifies the creation of button menus.
The following example uses CW_PDMENU to create a pulldown menu. The
result is shown in Figure 15-4. First, we create an array of anonymous structures
to contain the menu descriptions.
desc = REPLICATE({ flags:0, name:’’ }, 6)
The desc array contains six copies of the empty structure. Each structure has two
fields: flags and name. Next, we populate these fields with values:
desc.flags = [ 1, 0, 1, 0, 2, 2 ]
desc.name = [ ’Operations’, ’Predefined’, ’Interpolate’, $
’Linear’, ’Spline’, ’Quit’ ]
The value of the flags field specifies the role of each button. In this example, the
first and third buttons start a new sub-menu (values are 1), the second and fourth
buttons are plain buttons with no other role (values are 0), and the last two
buttons end the current sub-menu and return to the previous level (values are 2).
The value of the name field is the value (or label) of the button at each level.
base = WIDGET_BASE()
Creating Menus
Building IDL Applications
Chapter 15: Widgets
299
Figure 15-4: Pulldown menu created with CW_PDMENU.
menu = CW_PDMENU(base, desc)
WIDGET_CONTROL, base, /REALIZE
The format of the menu description used by CW_PDMENU in the above
example requires some explanation. CW_PDMENU views a menu as consisting
of a series of buttons, each of which can optionally lead to a sub-menu. The
description of each button consists of a structure supplying its name and a flag
field that tells what kind of button it is (starts a new sub-menu, ends the current
sub-menu, or a plain button within the current sub-menu). The description of
the complete menu consists of an array of such structures corresponding to the
flattened menu. Comparing the description used in the code above with the
result shown in Figure 15-4 should help to clarify this issue.
Menus on Top-Level Bases
A final approach to providing menus in your widget application is to attach the
menus directly to the top-level base widget. Menus attached to a top-level base
widget are created just like pulldown menus created from button widgets, but
they do not appear as buttons. Menus created in this way are children of a special
sub-base of the top-level base, created by specifying the MBAR keyword when the
top-level base is created.
For example, the following code creates a top-level base widget and attaches a
menu titled MENU1 to it. MENU1 contains the choices ONE, TWO, and
THREE.
base = WIDGET_BASE(MBAR=bar)
menu1 = WIDGET_BUTTON(bar, VALUE=’MENU1’, /MENU)
button1 = WIDGET_BUTTON(menu1, VALUE=’ONE’)
button2 = WIDGET_BUTTON(menu1, VALUE=’TWO’)
button3 = WIDGET_BUTTON(menu1, VALUE=’THREE’)
draw = WIDGET_DRAW(base, XSIZE=100, YSIZE=100)
WIDGET_CONTROL, base, /REALIZE
Building IDL Applications
Creating Menus
300
Chapter 15: Widgets
The resulting widget is shown in Figure 15-5.
Figure 15-5: Menu attached to a top-level base.
Controlling Widgets
The WIDGET_CONTROL procedure allows you to realize, manage, and destroy
widget hierarchies. It is often used to change the default behavior or appearance
of previously-realized widgets.
Some keywords to WIDGET_CONTROL affect only certain types of widgets, others
affect any type of widget, and some affect the widget system in general without being
tied to a single widget ID or widget type. See “WIDGET_CONTROL” on page 1230
of the IDL Reference Guide for complete details. We discuss here only a few of the
more common uses of this procedure.
Realizing Widget Hierarchies
As we have seen in the above examples, widgets must be realized before they
appear on screen. In most cases, you will want to realize your entire widget
hierarchy at the same time. Do this with the statement
WIDGET_CONTROL, base, /REALIZE
were base is the widget ID of the top-level base widget for your widget hierarchy.
Killing Widget Hierarchies
The standard way to kill a widget hierarchy is with the statement
WIDGET_CONTROL, base, /DESTROY
where base is the widget ID of the top-level base widget of the hierarchy to be
killed. Usually, IDL programs that use widgets issue this statement in their eventhandling routine in response to the application “Done” button.
In addition, some window managers place a pulldown menu on the frame of the
top-level base widget that allows the user to kill the entire hierarchy. Using the
Controlling Widgets
Building IDL Applications
Chapter 15: Widgets
301
window manager to kill a widget hierarchy is equivalent to using the
WIDGET_CONTROL procedure.
When designing widget applications, you should always include a “Done” button
in the application itself, because some window managers do not provide the user
with a kill option from the outer frame.
Retrieving or Changing Widget Values
As we discussed previously, you can use WIDGET_CONTROL to retrieve or
change widget values using the GET_VALUE and SET_VALUE keywords.
Similarly, you can retrieve or change widget user values with the GET_UVALUE
and SET_UVALUE keywords.
For example, you could use the following command in an event handling
procedure to save the user value of the widget that generates an event into an IDL
variable named uval:
WIDGET_CONTROL, event.id, GET_UVALUE=uval
Similarly, you could use the following commands to retrieve the value of a draw
widget named drawwid and make that draw widget the current graphics
window:
WIDGET_CONTROL, drawwid, GET_VALUE=draw
WSET, draw
Sensitizing Widgets
When a widget is sensitive, it has normal appearance and can receive user input.
When a widget is insensitive, it ignores any input directed at it. Use sensitivity to
control when a user is allowed to manipulate a widget. Note that while most
widgets change their appearance when they become insensitive, some simply stop
generating events.
Set the SENSITIVE keyword equal to zero to desensitize a widget, or to a nonzero
value to make it sensitive. For example, you might wish to make a group of
buttons named bgroup insensitive after some user input. You would use the
following command:
WIDGET_CONTROL, bgroup, SENSITIVE=0
Indicating Time-Consuming Operations
In an event driven environment, it is important that the interface be highly
responsive to the user’s manipulations. This means that widget event handlers
should be written to execute quickly and return. However, sometimes the event
handler has no option but to perform an operation that is slow. In such a case, it
Building IDL Applications
Controlling Widgets
302
Chapter 15: Widgets
is a good idea to give the user feedback that the system is busy. This is easily done
using the HOURGLASS keyword just before the expensive operation is started:
WIDGET_CONTROL, /HOURGLASS
This command causes IDL to turn on an hourglass-shaped cursor for all IDL
widgets and graphics windows. The hourglass remains active until the next event
is processed, at which point the previous cursor is automatically restored.
Using Timer Events
In addition to the normal widget events discussed previously, IDL allows the user
to make timer event requests by using the TIMER keyword. Such events are useful
in many applications that are time dependent, such as animation. The syntax for
making such a request is:
WIDGET_CONTROL, Widget_Id, TIMER=interval_in_seconds
Widget_Id can be the ID of any type of widget. When such a request is made, IDL
generates a timer request after the requested time interval has passed. Timer
events consist of a structure with only the standard three fields — no additional
information is provided.
It is up to the programmer to differentiate between a normal event and a timer
event for a given widget. The usual way to solve this problem is to make timer
requests for widgets that do not otherwise generate events, such as base or label
widgets.
Each timer request causes a single event to be generated. To generate a steady
stream of timer events, you must make a new timer request in the event handler
routine each time a timer event is delivered.
Widget Example 3
The following example program creates a small widget application consisting of
a draw widget and a droplist menu. One of three plots is displayed in the draw
widget depending on the selection made from the droplist. To add to the
excitement, we will use timer events to change the color table used in the draw
window every three seconds.
Enter the two procedures listed below — either in a text file named widget3.pro,
or directly into IDL using the .RUN command. Enter widget3 at the IDL prompt
to run the program.
PRO widget3_event, ev
We need to save the value of the seed variable for the random number generator
between calls to the event-handling routine. We do this using a COMMON block.
Widget Example 3
Building IDL Applications
Chapter 15: Widgets
303
COMMON wid3, seed
Retrieve the widget ID of the draw widget and make it the current IDL graphics
window:
WIDGET_CONTROL, ev.top, GET_UVALUE=drawID.
WSET, drawID
Check the type of event structure returned. If it is a timer event, change the color
table index to a random number between 0 and 40. (See “Event Processing And
Callbacks” on page 309 for more on identifying widget types from returned event
structures.)
IF (TAG_NAMES(ev, /STRUCTURE_NAME) EQ ’WIDGET_TIMER’) $
THEN BEGIN
table = FIX(RANDOMU(seed)*41)
Pick a random number.
LOADCT, table
Load the color table.
WIDGET_CONTROL, ev.id, TIMER=3.0 Reset the timer.
ENDIF
If the event is a droplist event, change the type of plot displayed in the draw
widget. Note the use of the index field of events returned from the droplist
widget to determine the value selected.
IF (TAG_NAMES(ev, /STRUCTURE_NAME) EQ ’WIDGET_DROPLIST’) $
THEN BEGIN
CASE ev.index OF
0: PLOT, DIST(150)
1: SURFACE, DIST(150)
2: SHADE_SURF, DIST(150)
3: WIDGET_CONTROL, ev.top, /DESTROY
ENDCASE
ENDIF
END
PRO widget3
Create a base widget containing a draw widget and a droplist menu.
select = [’Plot’, ’Surface’, ’Shaded Surface’, ’Done’]
Building IDL Applications
Widget Example 3
304
Chapter 15: Widgets
base = WIDGET_BASE(/COLUMN)
draw = WIDGET_DRAW(base, XSIZE=150, YSIZE=150)
dlist = WIDGET_DROPLIST(base, VALUE=select)
Realize the widget hierarchy, then retrieve the value of the draw widget and store
it in the user value of the base widget. (Note that we are using Direct graphics for
the draw widget, so the value is and IDL graphics window ID.) Finally, set the
timer value of the draw widget.
WIDGET_CONTROL, base, /REALIZE
WIDGET_CONTROL, draw, GET_VALUE=drawID
WIDGET_CONTROL, base, SET_UVALUE=drawID
WIDGET_CONTROL, draw, TIMER=0.0
Set the droplist to display “Shaded Surface” and place a shaded surface in the
draw widget:
WIDGET_CONTROL, dlist, SET_DROPLIST_SELECT=2
WSET, drawID
SHADE_SURF, DIST(150)
XMANAGER, ’widget3’, base
Register the widget with the
XMANAGER.
END
Alternately, you can run the program from the IDL distribution by entering:
widget3
at the IDL command prompt. See “Running the Example Code” on page 272 if
IDL does not run the program as expected.
This example is intentionally silly. The intent is to demonstrate the use of draw
widgets, menus, and timer events with a minimum of other issues to complicate
things. However, it is easy to imagine applications wherein a graphics window
containing a plot or some other information is updated periodically by a timer.
The method used here can easily be applied to more realistic situations.
Widget Sizing
This section explains how IDL widgets size themselves, widget geometry
concepts, and how to explicitly size and position widgets.
Widget Sizing
Building IDL Applications
Chapter 15: Widgets
305
Widget Geometry Terms and Concepts
Widget geometry, or the size and layout of widgets, is determined by many
interrelated factors. In the following discussion, the following terms are used:
•
Geometry: The size and position of a widget.
•
Natural Size: The natural, or implicit, size of a widget is the size a widget has if no
external constraints are placed on it. For example, a label widget has a natural size
that is determined by the size of the text it is displaying and space for margins.
These values are influenced by such things as the size of the font being displayed
and characteristics of the low-level (i.e., operating-system level) widget or control
used to implement the IDL widget.
•
Explicit Size: The explicit, or user-specified, size of a widget is the size set when an
IDL programmer specifies one of the size keywords to an IDL widget creation
function or WIDGET_CONTROL.
How Widget Geometry is Determined
IDL uses the following rules to determine the geometry of a widget:
•
The explicit size of a widget, if one is specified, takes precedence over the natural
size. That is, the user-specified size is used if available.
•
If an explicit size is not specified, the natural size of the widget—at the time the
widget is realized—is used. Once realized, the size of a widget does not automatically change when the value of the widget changes, unless the widget’s dynamic
resize property has been set. Dynamic resizing is discussed in more detail below.
Note that any realized widget can be made to change its size by calling
WIDGET_CONTROL with any of the sizing keywords.
•
Children of a “bulletin board” base (i.e., a base that was created without setting
the COLUMN or ROW keywords) have an offset of (0,0) unless an offset is
explicitly specified via the XOFFSET or YOFFSET keywords.
•
The offset keywords to widgets that are children of ROW or COLUMN bases are
ignored, and IDL calculates the offsets to lay the children out in a grid. This
calculation can be influenced by setting any of the ALIGN or BASE_ALIGN
keywords when the widgets are created.
Building IDL Applications
Widget Sizing
306
Chapter 15: Widgets
Dynamic Resizing
Realized widgets, by default, do not automatically resize themselves when their
values change. This is true whether the widget was created with an explicit size or
the widget was allowed to size itself naturally. This behavior makes it easy to
create widget layouts that don’t change size too frequently or “flicker” due to
small changes in a widget’s natural size.
This default behavior can be changed for label, button, and droplist widgets. Set
the DYNAMIC_RESIZE keyword to WIDGET_LABEL, WIDGET_BUTTON, or
WIDGET_DROPLIST to make a widget that automatically resizes itself when its
value changes. Note that the XSIZE and YSIZE keywords should not be used with
DYNAMIC_RESIZE. Setting explicit sizing values overrides the dynamic resize
property and creates a widget that will not resize itself.
Explicitly Specifying the Size and Location of Widgets
The XSIZE (and SCR_XSIZE), YSIZE (and SCR_YSIZE), XOFFSET, and
YOFFSET keywords, when used with a standard base widget parent (a base
created without the COLUMN or ROW keywords—also called a “bulletin board”
base), allow you to specify exactly how the child widgets should be positioned.
Sometimes this is a very useful option. However, in general, it is best to avoid this
style of programming. Although these keywords are usually honored, they are
merely hints to the widget toolkit and might be ignored.
Explicitly specifying the size and offset makes a program inflexible and unable to
run gracefully on various platforms. Often, a layout of this type will look good on
one platform, but variations in screen size and how the toolkit works will cause
widgets to overlap and not look good on another platform. The best way to
handle this situation is to use nested row and column bases to hold the widgets
and let the widgets arrange themselves. Such bases are created using the
COLUMN and ROW keywords to the WIDGET_BASE function.
Sizing Keywords
When explicitly setting the size of a widget, IDL allows you to control three
aspects of the size:
•
The virtual size is the size of the potentially viewable area of the widget. The virtual
size may be larger than the actual viewable area on your screen. The virtual size
of a widget is determined by either the widget’s value, or the XSIZE and YSIZE
keywords to the widget creation routine.
•
The viewport size is the size of the viewable area on your screen. If the viewport
size is smaller than the virtual size, scroll bars may be present to allow you to view
different sections of the viewable area. When creating widgets for which scroll
bars are appropriate, you can add scroll bars by setting the SCROLL keyword to
Widget Sizing
Building IDL Applications
Chapter 15: Widgets
307
the widget creation routine. You can explicitly set the size of the viewport area
using the X_SCROLL_SIZE and Y_SCROLL_SIZE keywords when creating base,
draw, and table widgets.
Note With draw widgets, you can set the APP_SCROLL or the SCROLL keyword.
Use the APP_SCROLL keyword when displaying images, or anything drawn
in device units or pixels. Use the SCROLL keyword when a draw widget is
going to display graphics drawn in data units (e.g., PLOT, CONTOUR,
SURFACE).
•
The screen size is the size of the widget on your screen. You can explicitly specify
a screen size using the SCR_XSIZE and SCR_YSIZE keywords to the widget
creation routine. Explicitly-set viewport sizes (set with X_SCROLL_SIZE or
Y_SCROLL_SIZE) are ignored if you specify the screen size.
For example, Figure 15-6 shows the result of the following WIDGET_DRAW
command:
draw = WIDGET_DRAW(base, XSIZE=384, YSIZE=384, $
X_SCROLL_SIZE=192, Y_SCROLL_SIZE = 192, SCR_XSIZE=200)
View Size (Y_SCROLL_SIZE)
Screen Size (SCR_XSIZE)
Virtual Size (XSIZE & YSIZE)
Figure 15-6: Visual description of widget sizes.
Building IDL Applications
Widget Sizing
308
Chapter 15: Widgets
In this case, the XSIZE and YSIZE keywords set the virtual size to 384 x 384 pixels. The
X_SCROLL_SIZE and Y_SCROLL_SIZE keywords set the viewport size to 192 x 192
pixels. Finally, the SCR_XSIZE keyword overrides the X_SCROLL_SIZE keyword
and forces the screen size of the widget (in the X-dimension) to 200 pixels, including
the scroll bar.
Controlling Widget Size after Creation
A number of keywords to the WIDGET_CONTROL procedure allow you to
change the size of a widget after it has been created. (You will find a list of the
keywords to WIDGET_CONTROL that apply to each type of widget at the end
of the widget creation routine documentation.) Note that keywords to
WIDGET_CONTROL may not control the same parameters as their
counterparts associated with widget creation routines. For example, while the
XSIZE and YSIZE keywords to WIDGET_DRAW control the virtual size of the
draw widget, the XSIZE and YSIZE keywords to WIDGET_CONTROL (when
called with the widget ID of a draw widget) control the viewport size of the draw
widget.
Units of Measurement
You can specify the unit of measurement used for most widget sizing operations.
When using a widget creation routine, or when using WIDGET_CONTROL or
WIDGET_INFO, set the UNITS keyword equal to 0 (zero) to specify that all
measurements are in pixels (this is the default), to 1 (one) to specify that all
measurements are in inches, or to 2 (two) to specify that all measurements are in
centimeters.
Note The UNITS keyword does not affect all sizing operations. Specifically, the
value of UNITS is ignored when setting the XSIZE or YSIZE keywords to
WIDGET_LIST, WIDGET_TABLE, or WIDGET_TEXT.
Finding the Size of the Screen
When creating the top-level base for an application, sometimes it is useful to know
the size of the screen. This information is available via the GET_SCREEN_SIZE
function. GET_SCREEN_SIZE returns a two-element integer array specifying the
size of the screen, in pixels. See “GET_SCREEN_SIZE” in Chapter 9 of the IDL
Reference Guide for details.
Preventing Layout Flicker
After a widget hierarchy has been realized, adding or destroying widgets in that
hierarchy causes IDL to recalculate and set new geometries for every widget in the
hierarchy. When a number of widgets are added or destroyed, these calculations
occur between each change to the hierarchy, resulting in unpleasant screen
“flashing” as the user sees a brief display of each intermediate widget configuration.
Widget Sizing
Building IDL Applications
Chapter 15: Widgets
309
This behavior can be eliminated by using the UPDATE keyword to
WIDGET_CONTROL.
The top-level base of every widget hierarchy has an UPDATE attribute that
determines whether or not changes to the hierarchy are displayed on screen.
Setting UPDATE to 0 turns off immediate updates and allows you to make a large
number of changes to a widget hierarchy without updating the screen after each
change. After all of your changes have been made, setting UPDATE to 1 causes the
final widget configuration to be displayed on screen.
For example, consider the following main-level program that realizes an
unmapped base, then adds 200 button widgets to the previously-realized base:
time = SYSTIME(1)
b = WIDGET_BASE(/COLUMN, XSIZE=400, YSIZE=400, MAP=0)
WIDGET_CONTROL, b, /REALIZE
FOR i = 0, 200 DO button = WIDGET_BUTTON(b, VALUE=STRING(i))
WIDGET_CONTROL, b, /MAP
PRINT, ’time used: ’, SYSTIME(1) - time
END
This program takes over 50 seconds to run on an HP 9000/720 workstation. If the
base had been mapped, the user would see the base “flashing” as each button was
added to the base. Altering the example to use the UPDATE keyword reduces the
execution time to 0.7 seconds:
time = SYSTIME(1)
b = WIDGET_BASE(/COLUMN, XSIZE=400, YSIZE=400, MAP=0)
WIDGET_CONTROL, b, /REALIZE, UPDATE=0
FOR i = 0, 200 DO button = WIDGET_BUTTON(b, VALUE=STRING(i))
WIDGET_CONTROL, b, /MAP, /UPDATE
PRINT, ’time used: ’, SYSTIME(1) - time
END
Note Do not attempt to resize a widget on the Windows platform while UPDATE
is turned off. Doing so may prevent IDL from updating the screen properly.
Event Processing And Callbacks
Previously we mentioned that when IDL receives an event, it is queued until a call
to WIDGET_EVENT is made, when the event is dequeued and returned. That is
a simplified description of what actually happens.
All events for a given widget are processed in the order that they are generated.
The event processing performed by WIDGET_EVENT consists of the following
steps, applied iteratively:
•
WIDGET_EVENT waits for an event from one of the specified widgets to arrive.
Building IDL Applications
Event Processing And Callbacks
310
Chapter 15: Widgets
•
Starting with the widget that the event belongs to, move up the widget hierarchy looking
for a widget that has an event-handling procedure or function associated with it. Such
routines are associated with a widget via the EVENT_PRO and EVENT_FUNC keywords to the widget creation functions or the WIDGET_CONTROL procedure.
•
If an event-handling procedure is found, it is called with the event as its argument.
The HANDLER field of the event is set to the widget ID of the widget associated
with the handling procedure. When the procedure returns, WIDGET_EVENT
returns to the first step above and starts searching for events. Hence, eventhandling procedures are said to “swallow” events.
•
If an event-handling function is found, it is called with the event as its argument.
The HANDLER field of the event is set to the widget ID of the widget associated
with the handling function.
When the function returns, its value is examined. If the value is not a structure,
it is discarded and WIDGET_EVENT returns to the first step. This behavior
allows event-handling functions to selectively act like event-handling procedures
and “swallow” events.
If the returned value is a structure, it is checked to ensure that it has the standard
first 3 fields: ID, TOP, and HANDLER. If not, an error is issued. Otherwise, the
returned value replaces the event found in the first step and WIDGET_EVENT
continues moving up the widget tree looking for another event handler routine,
as described in step 2, above.
Hence, event functions are said to “rewrite” events. This ability to rewrite events
is the basis of compound widgets which combine several widgets to give the
appearance of a single, more complicated widget. Compound widgets are an
important widget programming concept, and are discussed on page 314.
•
If an event reaches the top of a widget hierarchy without being swallowed by an
event handler, it is returned as the value of WIDGET_EVENT.
•
If WIDGET_EVENT was called without an argument, and there are no widgets
left on the screen that are being managed (as set via the MANAGED keyword to
the WIDGET_CONTROL procedure) and could generate events,
WIDGET_EVENT ends the search and returns an empty event (i.e., a standard
widget event structure with the top three fields set to zero).
Identifying Widget Type from an Event
Given a widget event structure, often you need to know what type of widget
generated it without having to match the widget ID in the event structure to all
the current widgets. This information is available by specifying the
STRUCTURE_NAME keyword to the TAG_NAMES function:
Event Processing And Callbacks
Building IDL Applications
Chapter 15: Widgets
311
PRINT, ’Event structure type: ’, $
TAG_NAMES(EVENT, /STRUCTURE_NAME)
This works because each widget type generates a different event structure. The
event structure generated by a given widget type is documented in the
description of the widget creation function for that type.
When using this technique, be aware that although all the basic widgets use
named structures for their events, many compound widgets return anonymous
structures. This technique does not work well in that case because anonymous
structures lack a recognizable name.
Note Always check for a distinct type of widget event. Research Systems will
continue to add new widgets with new event structures, so it is important not
to make assumptions about the contents of a random widget event structure.
The structure of existing widget events will remain stable, so checking for a
particular type of widget event will always work.
Keyboard Focus Events
Base, table, and text widgets can be set to generate keyboard focus events.
Generating and examining keyboard focus events allows you to determine when
a given widget has either gained or lost the keyboard focus—that is, when it is
brought to the foreground or when it is covered by another window.
Set the KBRD_FOCUS_EVENTS keyword to WIDGET_BASE, WIDGET_TABLE,
or WIDGET_TEXT to generate keyboard focus events. You can then use your
event-handling procedure to cache the widget ID of the last widget (with keyboard
focus events enabled) to have the keyboard focus. One situation where this is useful
is when you have an application menu (created with the MBAR or APP_MBAR
keyword to WIDGET_BASE) and you wish to perform an action in a text widget
based on the menu item selected. Although the event generated by the user’s
menu selection has the menu’s base as its top-level widget ID, if you generate and
track keyboard focus events for the text widget, you can “remember” which widget
the action triggered by the menu selection should affect. Note that in this example,
keyboard focus events are not generated for the menubar’s base.
Interrupting the Event Loop
Beginning with IDL version 5, IDL has the ability to process commands from the
IDL command line while simultaneously processing widget events. This means
that the IDL command will remain active even when widget applications are
running.
It is possible to interrupt the event function by sending the interrupt character
(Control-C or Command-C). However, you may find that even after sending the
Building IDL Applications
Event Processing And Callbacks
312
Chapter 15: Widgets
interrupt, IDL does not immediately interrupt the event loop. IDL will interrupt
the process that is “on top”—that is, if several applications are running at once,
the interrupt will be handled by the first application to receive it.
If your widget application is the only active application, and sending the
interrupt does not cause it to break, move the mouse cursor across (or click on)
one of the widgets.
This works because when IDL is in the event function, it only checks for the
interrupt between event notifications from the window system. Such events do
not necessarily translate one-to-one into IDL widget events because the window
system typically generates a large number of events related to the window
system’s operation that IDL quietly handles. Moving the mouse cursor across the
widgets typically generates some of these events which gives IDL a chance to
notice the interrupt and act on it.
Note Do not interrupt the event loop by placing a STOP or EXIT command in the
event-handler or in a callback routine. The presence of either command will
cause the widget routine to exit with an error.
Managing Widget Application State
Usually, a widget application or compound widget has some information, or
state, associated with it. This is a natural consequence of the fact that the
application is usually divided into at least two separate routines, one that creates
and realizes the application and another that handles events. These multiple
routines need shared access to certain types of information such as the widget IDs
of the component widgets and data being used by the application.
One obvious answer to this problem is to use a COMMON block to hold the
state. However, this solution is undesirable because it prevents more than a single
copy of the application from running at the same time. It is easy to imagine the
chaos that would ensue if multiple instances of the same application were using
the same common block without some sort of interlocking.
A better solution to this problem is to use the user value of one of the widgets to
store state information for the application. Since this user value can be of any
type, a structure can be used to store any number of state-related values. Using
this technique, multiple instances of the same widget code can exist
simultaneously.
In our previous discussions, the HANDLER field of widget event structures was
described without giving any compelling reason for its existence. That is because
event processing and compound widgets must be understood before the need for
HANDLER becomes clear. Recall that when WIDGET_EVENT finds an event to
Managing Widget Application State
Building IDL Applications
Chapter 15: Widgets
313
return, it moves up the widget tree looking for an event-handling routine
registered to the widgets in between its current position and the top-level base of
the widget application. If such a routine is found, it is called with the event as its
argument, and the HANDLER field of this event is set to the widget ID of the
widget where the event routine was found. Since compound widgets have event
handlers associated with their root widget, the HANDLER field gives the event
handler the widget ID of the root widget. This allows the event handler for a
compound widget instance to easily locate the location of its state information
relative to this root.
IDL programmers are often tempted to store the state information directly in the
user value of the root widget, but this is not a good idea. The user value of a
compound widget is reserved for the user of the widget, just like any basic widget.
Therefore, you should store the state information in the user value of one of the
child widgets below the root. As a convention, the user value of the first child is
often used, leading to event handlers structured as follows:
FUNCTION EVENT_FUNC, event
; Get state from the first child of the compound widget root:
child = WIDGET_INFO(event.handler, /CHILD)
WIDGET_CONTROL, child, GET_UVALUE=state, /NO_COPY
; Execute event-handling code here.
; Restore the state information before exiting routine:
WIDGET_CONTROL, child, SET_UVALUE=state, /NO_COPY
; Return result of function
RETURN, result
END
Notice the use of the NO_COPY keyword in the above example. This keyword
behaves similarly to the TEMPORARY function, and prevents IDL from
duplicating the memory used by the user value during the GET_UVALUE and
SET_UVALUE operations. This is an important efficiency consideration if your
code generates many events or the size of the state data is large.
Sometimes, an application will find that it needs to use the user value of all its
child widgets for some other purpose, and there is no convenient place to keep
the state information. One way to work around this problem is to interpose an
extra base between the root base and the rest of the widgets:
ROOT = WIDGET_BASE(parent)
EXTRA = WIDGET_BASE(root)
In such an approach, the remaining widgets would all be children of EXTRA
rather than ROOT.
Building IDL Applications
Managing Widget Application State
314
Chapter 15: Widgets
Compound Widgets
Widget primitives can be used to construct many varied user interfaces, but
complex programs written with them suffer the following drawbacks:
•
Large widget applications become difficult to maintain. As an application grows,
it becomes more difficult to properly write and test. The resulting program suffers
from poor organization.
•
Good ideas can be difficult to reuse. Most larger applications are constructed from
smaller sub-units. For example, a color table editor might contain control panel,
color selection and color-index selection sub-units. These sub-units are often
complicated tools that could be used profitably in other programs. To reuse such
sub-units, the programmer must understand the existing application and then
transplant the interesting parts into the new program — at best a tedious and
error-prone proposition.
Compound widgets solve these problems. A compound widget is a complete, selfcontained, reusable widget sub-tree that behaves to a large degree just like a
primitive widget. Complex widget applications written with compound widgets
are much easier to maintain than the same application written without them.
Using compound widgets is analogous to using subroutines and functions in
programming languages.
Writing Compound Widgets
Compound widgets are written in the same way as any other widget application.
They are distinguished from regular widget applications in the following ways:
•
Compound widgets usually have a base widget at the root of their hierarchies.
This base contains the subwidgets that make up the cluster. From the user’s point
of view, this single widget is the compound widget — its children are hidden from
the users view.
•
It is important that the compound widget not make use of the base’s user value.
This user value should be reserved for use by the caller of the compound widget
in order to preserve the illusion that the compound widget works just like any of
the basic widgets.
•
The root widget of the compound widget always has an event handler function
associated with it via the EVENT_FUNC keyword to the widget creating function
or the WIDGET_CONTROL procedure. This event handler manages events from
its sub-widgets and generates events for the compound widget. By swallowing
events from the widgets that comprise the compound widget and generating
events that represent the compound widget, it presents the illusion that the
compound widget is acting like a basic widget.
Compound Widgets
Building IDL Applications
Chapter 15: Widgets
315
•
If the compound widget has a value that can be set, it should be assigned a value
setting procedure via the PRO_SET_VALUE keyword to the widget creating
function or the WIDGET_CONTROL procedure.
•
If the compound widget has a value that can be retrieved, it should be assigned a
value retrieving function via the FUNC_GET_VALUE keyword to the widget
creating function or the WIDGET_CONTROL procedure.
For an example of how a compound widget might be written, see “Compound
Widget Example” on page 316.
Tips on Creating Widget Applications
The following are some ideas to keep in mind when writing widget applications
in IDL.
•
When writing new applications, decompose the problem into sub-problems and
write reusable compound widgets to implement them. In this way, you will build
a collection of reusable widget solutions to general problems instead of hard-tomodify, monolithic programs.
•
Use the GROUP_LEADER keyword to WIDGET_BASE to define the relationships
between parts of your application. Group leadership/membership relationships
make it easy to group widgets appropriately for iconization, layering, and destruction.
•
Use the MBAR (and APP_MBAR) keyword to WIDGET_BASE to create application-specific menubars. Use keyboard focus events to track which widget menu
options should affect.
•
Use existing compound widgets when possible. In particular, use the CW_BGROUP
and CW_PDMENU compound widgets to create menus. These functions are easier
to use that writing the menu code directly, and your intent will be more quickly
understood by others reading your code.
•
The many advantages of the XMANAGER procedure dictate that all widget
programs should use it. There are few if any reasons to call the WIDGET_EVENT
procedure directly.
•
Use CATCH to handle any unanticipated errors. The CATCH branch can free any
pointers, pixmaps, logical units, etc., to which the calling routine will not have
access, and reset IDL session-wide settings like color tables and system variables.
•
If all else fails, it is possible to use the value of the WIDGET_INFO function to
execute special-case code for each platform’s user interface toolkit. It is desirable,
Building IDL Applications
Tips on Creating Widget Applications
316
Chapter 15: Widgets
however, to avoid large-scale special-case programming because this makes maintenance of the finished program more difficult.
Portability Issues
Although IDL widgets are essentially the same on all supported platforms, there
are some differences that can complicate writing applications that work well
everywhere. The following hints should help you write such applications:
•
Avoid specifying the absolute size and location of widgets whenever possible.
(That is, avoid using the XSIZE, YSIZE, XOFFSET, and YOFFSET keywords.) The
different user interface toolkits used by different platforms create widgets with
slightly different sizes and layouts, so it is best to use bases that order their child
widgets in rows or columns and stay away from explicit positioning. If you must
use these keywords, try to isolate the affected widgets in a sub-base of the overall
widget hierarchy to minimize the overall effect.
•
When using a bitmap to specify button labels, be aware that some toolkits prefer
certain sizes and give sub-optimal results with others. Also, if you are specifying
a color bitmap, use the BITMAP keyword.
•
Try to place text, label, and list widgets in locations where their absolute size can
vary without making the overall application look bad. The font used by the
different toolkits have different physical sizes that can cause these widgets to have
different proportions.
It is reasonably easy to write applications that will work in all environments
without having to resort to much special-case programming. It is very helpful to
have a machine running each environment available so that the design can be
tested on each iteratively until a suitable layout is obtained.
Compound Widget Example
The following example incorporates ideas from the previous sections to show
how you might approach the task of writing a compound widget. The widget is
called CW_DICE, and it simulates a single six-sided die. Figure 15-7 shows the
appearance of XDICE, an application that uses two instances of CW_DICE.
XDICE is discussed on “Using CW_DICE in a Widget Program” on page 323.
Note cw_dice.pro can be found in the lib subdirectory of the IDL distribution. xdice.pro can be found in the doc subdirectory of the examples
subdirectory of the IDL distribution. You should examine these files for
additional details and comments not included here. We present sections of
the code here for didactic purposes—there is no need to re-create either of
these files yourself.
Compound Widget Example
Building IDL Applications
Chapter 15: Widgets
317
The CW_DICE compound widget has the following features:
•
It uses a button widget. The current value of the die is displayed as a bitmap label
on the button itself. When the user presses the button, the die “rolls” itself by
displaying a sequence of bitmaps and then settles on a final value. An event is
generated that returns this final value.
•
Timer events are used to create the rolling effect. This allows the dice to give the
same appearance on machines of varying performance levels.
•
The die can be set to a specific value via the SET_VALUE keyword to the
WIDGET_CONTROL procedure. If the desired value is outside of the range 1
through 6, the die is rolled as if the user had pressed the button and a final value
is selected randomly. Using WIDGET_CONTROL does not cause an event to be
issued. This follows the IDL convention that user actions cause events while
programmatic changes do not.
•
The current value of the die can be obtained via the GET_VALUE keyword to the
WIDGET_CONTROL procedure.
Almost any compound widget will have some state associated with it. The
following is the state of CW_DICE:
1. The current value.
2. The number of times the die should “tumble” before settling on a final value.
3. The amount of time to take between tumbles.
4. When a roll is in progress, a count of how many tumbles are left before a final
value is displayed.
5. The bitmaps to use for the 6 possible die values.
6. The seed to use for the random number generator.
The first four items are stored in a per-widget structure kept in one of the child
widget’s user values. Since the bitmaps never change, it makes sense to keep them
in a COMMON block to be accessed freely by all the CW_DICE routines. It also
makes sense to use a single random number seed for the entire CW_DICE class
rather than one per instance to avoid the situation where multiple dice, having
been created at the same time, have the same seed and thus display the same value
on each roll.
It is rare that the use of a COMMON block in a compound widget makes sense.
Notice, however, that we’re only keeping read-only data (bitmaps) or data that
can be overwritten at any time with no negative effects (random number
generator seed).
Building IDL Applications
Compound Widget Example
318
Chapter 15: Widgets
Given the above decisions, it is now possible to write the CW_DICE procedure:
PRO cw_dice, parent, value, UVALUE=uvalue, $
TUMBLE_CNT=tumble_cnt, TUMBLE_PERIOD=tumble_period
Value is an optional argument
that lets the caller set the initial die
value to a value between 1 and 6.
UVALUE will simply be passed on
to the root base of CW_DICE. The
TUMBLE keywords let the user
adjust the tumble count and period.
COMMON CW_DICE_BLK, seed, faces
This COMMON block holds the
bitmaps and random number
generator seed.
IF NOT KEYWORD_SET(tumble_cnt) THEN tumble_cnt=10
Provide defaults for the keywords.
IF (tumble_cnt lt 1) then tumble_cnt=10
Guard against a nonsensical request.
IF NOT KEYWORD_SET(tumble_period) THEN tumble_period=.05
Default tumble period in seconds.
IF (tumble_period lt 0) then tumble_period=.05
IF NOT KEYWORD_SET(uvalue) uvalue=0
ON_ERROR, 2
Return to caller if an error occurs.
faces=LONARR(192)
Generate the die face bitmaps. The
actual code for this is omitted here
because it doesn’t add much to the
example, but it can be found in the
CW_DICE.PRO file.
IF(N_ELEMENTS(value) EQ 0) THEN value = FIX(6*RANDOMU(seed) + 1)
Use RANDOMU to pick the initial value of the die unless the user
provided one.
state = { value:value, tumble_cnt:FIX(tumble_cnt), $
tumble_period:tumble_period, remaining:0 }
Construct a state variable for this
instance.
base = WIDGET_BASE(parent, UVALUE=uvalue, $
Compound Widget Example
Building IDL Applications
Chapter 15: Widgets
319
EVENT_FUNC=’CW_DICE_EVENT’, $
FUNC_GET_VALUE=’CW_DICE_GET_VALUE’, $
PRO_SET_VALUE=’CW_DICE_SET_VALUE’)
Create the base widget, passing the
UVALUE through for the caller.
Notice that we also register an
event function and GET/SET value routines which will be called by
WIDGET_CONTROL on our
behalf.
die = WIDGET_BUTTON(base, VALUE=faces[*, *, value-1])
Create the die, setting its bitmap to
the current value.
WIDGET_CONTROL, WIDGET_INFO(base, /CHILD), $
SET_UVALUE=state, /NO_COPY
RETURN, base
Save the state in the first child’s
user value. Notice the use of the
NO_COPY keyword for efficiency.
The result of a compound widget is
always the ID of its topmost widget.
END
The above code makes reference to two routines named CW_DICE_SET_VAL and
CW_DICE_GET_VAL. By using the FUNC_GET_VALUE and PRO_SET_VALUE
keywords to WIDGET_BASE, WIDGET_CONTROL can call these routines
whenever the user makes a WIDGET_CONTROL SET_VALUE or GET_VALUE
request:
PRO cw_dice_set_val, id, value
This is the SET_VALUE routine
for CW_DICE. The number and
type of the arguments is defined by
WIDGET_CONTROL. Id is the
widget ID of a CW_DICE, and
value is the users requested value.
COMMON CW_DICE_BLK, seed, faces
stash = WIDGET_INFO(id, /CHILD)
Get the ID of the first child of the
CW_DICE widget. This is where
the state information is stored.
WIDGET_CONTROL, stash, GET_UVALUE=state, /NOCOPY
Get the state structure.
Building IDL Applications
Compound Widget Example
320
Chapter 15: Widgets
if (value < 1) or (value > 6) THEN BEGIN
If the value is outside the range
[1,6] then roll the die as if the user
pressed the button.
CW_DICE_ROLL, stash, state
CW_DICE_ROLL rolls the dice.
It’s a separate function because our
event handler also needs to use it.
ENDIF ELSE BEGIN
If the value is in the range [1,6]
then simply set the die to that value
without rolling.
state.value=value
WIDGET_CONTROL, stash, SET_VALUE=faces[*,*, value-1]
Set the new bitmap on the button.
We take advantage of the fact that
stash must be the widget ID of the
button widget, since the base only
has one child.
ENDELSE
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
Restore the state in the child
UVALUE.
END
FUNCTION cw_dice_get_val, id
This is the GET_VALUE routine
for CW_DICE. The number and
type of the arguments is defined by
WIDGET_CONTROL. Id is the
widget ID of a CW_DICE. The return value of this function must be
the current value of the compound
widget, as defined by that widget.
stash = WIDGET_INFO(id, /CHILD)
Get the ID of the first child of the
CW_DICE widget. This is where
the state information is stored.
WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
Get the state structure.
Compound Widget Example
Building IDL Applications
Chapter 15: Widgets
ret = state.value
321
Get the current value from the
state structure.
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
Restore the state in the child
UVALUE.
RETURN, ret
END
CW_DICE_SET_VALUE makes reference to a procedure named CW_DICE_ROLL
that does the actual dice rolling. Rolling is implemented as follows:
1. If this is the initial call to CW_DICE_ROLL, then pick the final value that will end up
being displayed and enter this into the widget’s state. Hence, WIDGET_CONTROL,
/GET_VALUE reports the final value instead of one of the intermediate “tumble”
values no matter when it is called.
2. If this is not the final tumble, pick a random intermediate value and display that.
Then, make another timer event request for the next tumble.
3. If this is the final tumble, use the saved final value.
4. CW_DICE_ROLL works in cooperation with the event handler function for
CW_DICE. Each timer event causes the event handler to be called and the event
handler in turn calls CW_DICE_ROLL to process the next tumble.
PRO cw_dice_roll, dice, state
Roll the specified die. Dice is the
widget ID of the button holding
the bitmap, and state is the state as
extracted from the CW_DICE
UVALUE by the caller.
COMMON CW_DICE_BLK, seed, faces
IF (state.remaining EQ 0) THEN BEGIN First time.
state.remaining = state.tumble_cnt
Set the counter for the number of
tumbles remaining.
state.value = FIX(6*RANDOMU(seed)+1) Determine final value now.
ENDIF
IF (state.remaining EQ 1) THEN BEGIN Last time.
value = state.value
Use the previously-saved final result.
ENDIF ELSE BEGIN
Not the last time.
Building IDL Applications
Compound Widget Example
322
Chapter 15: Widgets
value = FIX(6 * RANDOMU(seed) + 1)
Generate an intermediate value.
WIDGET_CONTROL, dice, TIMER=state.tumble_period
Since this isn’t the last tumble,
make the next timer request.
ENDELSE
WIDGET_CONTROL, dice, SET_VALUE=faces[*,*, value-1]
Display the correct bitmap.
state.remaining = state.remaining-1 Decrement tumble counter.
END
This leads us to the event handler function:
FUNCTION cw_dice_event, event
base = event.handler
The primary use for the HANDLER field of event structures is to
make finding the root of a compound widget easy.
stash = WIDGET_INFO(base, /CHILD)
Get the ID of the first child of the
CW_DICE widget. This is where
the state information is stored.
WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY
Get the state structure.
CW_DICE_ROLL, stash, state
Roll the die and display a new bitmap.
if (TAG_NAMES(event, /STRUCTURE_NAME) NE ’WIDGET_TIMER’) THEN $
This event handler expects to see
button press events generated from
a user action as well as TIMER
events from CW_DICE_ROLL.
We only want to issue events for
the button presses. Even though
the die still has several tumbles left,
we know that the final value is in
the state now.
ret = { CW_DICE_EVENT, ID:base, TOP:event.top, $
HANDLER:0L, VALUE:state.value} $
ELSE ret = 0
Compound Widget Example
Create an event.
By not returning an event structure, we cause the event to be swallowed by WIDGET_EVENT.
Building IDL Applications
Chapter 15: Widgets
323
WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY
Restore the state in the child
UVALUE.
RETURN, ret
END
Figure 15-7: The XDICE Example Program
Using CW_DICE in a Widget Program
Having written a compound widget, it is natural to want to use it in a real
application. We can use CW_DICE to implement an application named XDICE.
XDICE displays two dice as well as a “Roll” button. Pressing either die causes it
to roll individually. Pressing the “Roll” button causes both dice to roll together. A
text widget at the bottom always displays the current value in textual form.
XDICE is shown in Figure 15-7.
Note xdice.pro can be found in the doc subdirectory of the examples
subdirectory of the IDL distribution. You can run the program from the IDL
distribution by entering:
xdice
at the IDL command prompt. See “Running the Example Code” on page 272
if IDL does not run the program as expected. You should examine the files for
additional details and comments not included here.
PRO xdice, GROUP=group
Building IDL Applications
Providing standard keywords usually found in other widget applications is a nice finishing touch.
GROUP is easy to support since we
just pass it to XMANAGER.
Compound Widget Example
324
Chapter 15: Widgets
base = WIDGET_BASE(/COLUMN, title=’Pair O’’ Dice’)
Create the top-level base that holds
everything else.
bgroup = CW_BGROUP(base, [’Done’, ’Roll’], /ROW, SPACE=50)
A button group compound widget
is used to implement the Done and
Roll buttons. The SPACE keyword
simply causes the buttons to be
spread out from each other.
dice = WIDGET_BASE(base, /ROW, XPAD=20)
Create a row base to hold the dice.
XPAD moves the first die away
from the left side of the application
and helps center the dice.
d1 = CW_DICE(dice)
The first die.
d2 = CW_DICE(dice)
The second die.
WIDGET_CONTROL, d1, GET_VALUE=d1v
We need the initial dice values to
set the label appropriately. We
could have specified initial values
for the calls to CW_DICE above,
but it seems better to let them be
different on each invocation.
WIDGET_CONTROL, d2, GET_VALUE=d2v
str=STRING(FORMAT=’("Current Value: ",I1,", ",I1)’, d1v, d2v)
Format the initial label text.
label = WIDGET_LABEL(base, value=str)
This label is used to textually display the current dice values.
state = { bgroup:bgroup, d1:d1, d2:d2, label:label }
Information that is needed in the
event handler.
WIDGET_CONTROL, base, SET_UVALUE=state, /NO_COPY, /REALIZE
Save useful information in the
base UVALUE, and realize the application.
Compound Widget Example
Building IDL Applications
Chapter 15: Widgets
325
XMANAGER, ’XDICE’, base, GROUP=group
Pass control to XMANAGER.
END
The following event handler is called by XMANAGER to process events for the
XDICE application:
PRO xdice_event, event
WIDGET_CONTROL, event.top, GET_UVALUE=state, /NO_COPY
Recover the state.
IF (event.id EQ state.bgroup) THEN BEGIN
Either the Done or Roll button was
pressed.
IF (event.value EQ 0) THEN BEGIN
The Done button.
WIDGET_CONTROL, /DESTROY, event.top Destroy the application.
RETURN
Return now to avoid trying to update the widget label we just destroyed.
ENDIF ELSE BEGIN
The Roll button.
WIDGET_CONTROL, state.d1, SET_VALUE=-1
Roll the first die by asking for an
out of range value.
WIDGET_CONTROL, state.d2, SET_VALUE=-1
Roll the second die.
ENDELSE
ENDIF
WIDGET_CONTROL, state.d1, GET_VALUE=d1v
Get value of first die.
WIDGET_CONTROL, state.d2, GET_VALUE=d2v
Get value of second die.
str = STRING(format=’("Current Value: ",I1,", ",I1)’, d1v, d2v)
Format the initial label text.
WIDGET_CONTROL, state.label, SET_VALUE=str
Update the label.
WIDGET_CONTROL, event.top, SET_UVALUE=state, /NO_COPY
Restore the state.
END
Building IDL Applications
Compound Widget Example
326
Compound Widget Example
Chapter 15: Widgets
Building IDL Applications
Chapter 16
Building CrossPlatform Applications
The following topics are covered in this chapter:
Which Operating System is Running? 328
File and Path Specifications ................ 329
Environment Variables ........................ 331
Files and I/O ...................................... 331
Math Exceptions ................................ 334
Operating System Access ................... 334
Display Characteristics and Palettes .... 335
Fonts ................................................. 335
Printing ............................................. 335
SAVE and RESTORE ............................ 336
Widgets ............................................. 336
Using External Code .......................... 339
Licensing ........................................... 339
DataMiner Issues ............................... 339
327
328
Chapter 16: Building Cross-Platform Applications
IDL is designed as a platform-independent environment for data analysis and
programming. Because of this, the vast majority of IDL’s routines operate the
same way no matter what type of computer system you are using. IDL’s crossplatform development environment makes it easy to develop an application on
one type of system for use on any system IDL supports.
Despite IDL’s cross-platform nature, there are differences between the computers
that make up a multi-platform environment. Operating systems supply resources
in different ways. While IDL attempts to abstract these differences and provide a
common environment for all Windows, Macintosh, Unix, and VMS machines,
there are some cases where the discrepancies cannot be overcome. This chapter
discusses aspects of IDL that you may wish to consider when developing an
application that will run on multiple types of computer.
Note This chapter is not an exhaustive list of differences between versions of IDL
for different platforms. Rather, it covers issues you may encounter when
writing cross-platform applications in IDL.
Which Operating System is Running?
In some cases, in order to effectively take platform differences into account, your
application will need to execute different code segments on different systems.
Operating system and IDL version information is contained in the IDL system
variable !VERSION (see “!VERSION” on page 45 of the IDL Reference Guide).
For example, you could use an IDL CASE Statement that looks something like the
following to execute code that pertains to a particular operating system family:
CASE !VERSION.OS_FAMILY OF
’MacOS’
: Code for Macintosh
’unix’
: Code for Unix
’vms’
: Code for VMS
’Windows’
: Code for Windows
ENDCASE
Writing conditional IDL code based on platform information should be a last
resort, used only if you cannot accomplish the same task in a platformindependent manner.
Which Operating System is Running?
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
329
File and Path Specifications
Different operating systems use different path specification syntax and directory
separation characters. Table 16-1 summarizes the different characters used by
different operating systems; see “!PATH” on page 43 of the IDL Reference Guide
for further details on path specification.
Operating System Directory Separator Path Element Separator
MacOs
: (colon)
, (comma)
Unix
/ (forward slash)
: (colon)
VMS
. (dot)
, (comma)
Windows
\ (backward slash)
; (semicolon)
Table 16-1: Directory and Path Element Separator Characters
As a result of these differences, specifying filenames and paths explicitly in your IDL
application can cause problems when moving your application to a different
platform. You can effectively isolate your IDL programs from platform-specific file
and path specification issues by using the FILEPATH and DIALOG_PICKFILE
functions (see “FILEPATH” on page 478 of the IDL Reference Guide and
“DIALOG_PICKFILE” on page 426 of the IDL Reference Guide).
Choosing Files at Runtime
To allow users of your application to choose a file at runtime, use the
DIALOG_PICKFILE function. DIALOG_PICKFILE will always return the file
path with the correct syntax for the current platform. Other methods (such as
reading a file name from a text field in a widget program) may or may not provide
a proper file path.
Selecting Files Programmatically
To give your application access to a file you know to be installed on the host, use
the FILEPATH function. By default, FILEPATH allows you to select files that are
included in the IDL distribution tree. Chances are, however, that a file you supply
as part of your own application is not included in the IDL tree. You can still use
FILEPATH by explicitly specifying the root of the directory tree to be searched.
For example, suppose your application is installed in a subdirectory named
MYAPP of the root directory of the filesystem that contains the IDL distribution.
You could use the FILEPATH function and set the ROOT_DIR keyword to the
Building IDL Applications
File and Path Specifications
330
Chapter 16: Building Cross-Platform Applications
Figure 16-1: A possible directory hierarchy for an IDL
application.
root directory of the filesystem, and use the SUBDIRECTORY keyword to select
the MYAPP directory. If you are looking for a file named myapp.dat, the
FILEPATH command looks like this:
file = FILEPATH(’myapp.dat’, ROOT_DIR=root, SUBDIR=’MYAPP’)
The problem that remains is how to specify the value of root properly on each
platform. This is one case where it is very difficult to avoid writing some
platform-specific code. We could write an IDL CASE statement each time the
FILEPATH function is used. Instead, the following code segment sets an IDL
variable to the string value of the root of the filesystem, and passes that variable
to the ROOT_DIR keyword. The CASE statement looks like this:
CASE !VERSION.OS_FAMILY OF
’MacOS’
: rootdir = STRMID(!DIR, 0, STRPOS(!DIR, ’:’))
’unix’
: rootdir = ’/’
’vms’
: rootdir = ’SYS$SYSDEVICE:’
’Windows’ : rootdir = STRMID(!DIR, 0, 2)
ENDCASE
file = FILEPATH(’myapp.dat’, ROOT=rootdir, SUBDIR=’MYAPP’)
Note that the root directories under Unix and VMS are well defined, whereas the
root directories on machines running the Macintosh OS or Microsoft Windows
must be determined by parsing the IDL system variable !DIR. On the Macintosh,
the rootdir variable takes the value of !DIR up to the first directory separator
character (a colon, in this case). On machines running Microsoft Windows, the
root is assumed to be the drive letter of the hard drive and the following colon —
usually “C:”.
File and Path Specifications
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
331
Environment Variables
Unix and VMS versions of IDL have the ability to use environment variables (or
logical names, under VMS) to store information about the environment in which
IDL is running. Typically, environment variables are used to store information
like the path to the main IDL directory, or to a batch file to be read and executed
when IDL starts up. See “Environment Variables Used by IDL” on page 22 of
Using IDL for details.
Microsoft Windows systems also have the ability to use environment variables to
store information, but this form of information storage is much less common
under Windows. On the Macintosh, there is no analogue of the environment
variable.
Rather than using environment variables, the IDL Development Environment
stores information in preferences; the mechanisms used to store preferences is
different between platforms, but is generally transparent to you. Configuration
settings you specify in the preferences dialogs of the IDL Development
Environment are saved and are available to the IDE the next time it is started.
What does this all mean in the context of writing IDL applications for multiple
platforms? Simply this: don’t rely on environment variables in your programs
unless you know that:
1. the target platform supports environment variables, and
2. the appropriate environment variables are defined as you wish them to be on the
target platform.
Files and I/O
IDL’s file input and file output routines are designed to work identically on all
platforms, where possible. In the case of basic operations, such as opening a text
file and reading its contents, importing an image format file into an IDL array, or
writing ASCII data to a file on a hard disk, IDL’s I/O routines work the same way
on all platforms. In more complicated cases, however, such as reading data stored
in binary data format files, different operating systems may use files that are
structured differently, and extra care may be necessary to ensure that IDL reads
or writes files in the proper way.
Before attempting to write a cross-platform IDL application that uses more than
basic file I/O, you should read and understand the sections in chapter 11 of
Building IDL Applications that apply to the platforms your application will
Building IDL Applications
Environment Variables
332
Chapter 16: Building Cross-Platform Applications
support. The following are a few topics to think about when writing IDL
applications that do input/output.
Byte Order Issues
Computer systems on which IDL runs support two ways of ordering the bytes
that make up an arbitrary scalar: big endian, in which multiple byte numbers are
stored in memory beginning with the most significant byte, and little endian, in
which numbers are stored beginning with the least significant byte. The following
table lists the processor types and operating systems IDL supports and their byte
ordering schemes:
Processor Type
Operating System
Byte Ordering
Digital Alpha AXP
Digital Unix
little-endian
Alpha VMS
little-endian
Windows NT
little-endian
Hewlett Packard PA-RISC
HP-UX
big-endian
IBM RS/6000
AIX
big-endian
Intel x86
Linux
little-endian
Solaris x86
little-endian
Windows
little-endian
Motorola PowerPC
Macintosh OS
big-endian
SGI R4000 and up
Irix
big-endian
Sun SPARC
SunOS
big-endian
Solaris
big-endian
Table 2: Byte ordering schemes used by platforms that support IDL.
The IDL routines BYTEORDER and SWAP_ENDIAN allow you to convert
numbers from big endian format to little endian format and vice versa. It is often
easier, however, to use the XDR (for eXternal Data Representation) format to
store data that you know will be used by multiple platforms. XDR files write
binary data in a standard “canonical” representation; as a result, the files are
slightly larger than pure binary data files. XDR files can be read and written on
any platform that supports IDL. XDR is discussed in detail in “Portable
Unformatted Input/Output” on page 197 of Building IDL Applications.
Files and I/O
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
333
Logical Unit Numbers
Logical Unit Numbers (LUNs) are assigned to individual files when the files are
opened by the IDL OPENR/OPENU/OPENW commands, and are used to
specify which file IDL should read from or write to. There are a total of 128 LUNs
available for assignment to files. While it is possible to assign any of the integers
between 1-99 to a given file, when writing applications for others it is good
programming practice to let IDL assign and manage the LUNs itself. By using the
GET_LUN keyword to the OPEN routines, you can ask IDL to assign a free
Logical Unit Number between 100-128 to the specified file. Letting IDL assign the
LUN from the list of free unit numbers ensures that your application does not
attempt to use a LUN already in use by someone else’s application. See the
description of the GET_LUN keyword to “OPEN” on page 783 of the IDL
Reference Guide and “Logical Unit Numbers (LUNs)” on page 162 of Building
IDL Applications.
Macintosh File Pointer
IDL provides the POINT_LUN procedure to allow you to explicitly position the
file pointer anywhere within an open file. Note, however, that on the Macintosh,
the POINT_LUN routine cannot be used to position the file pointer past the end
of the file, as it can on other platforms.
Macintosh File Types and Creators
The Macintosh file system attaches two pieces of information to each file that is
not used by other operating systems. The Macintosh file type specifies what type
of data is stored in the file—for example, a file may contain text, an image, or
unspecified binary information. The Macintosh file creator specifies which
application created the file.
Text files saved by IDL on the Macintosh have the default file type “TEXT”. Binary
files saved by IDL on the Macintosh have the default file type “BIN ” (note that
the fourth character is a space). All files created by IDL have the default creator
type “MIDL”. The default types can be overridden using the MACCREATOR and
MACTYPE keywords to the OPEN routines. See “OPEN” on page 783 of the IDL
Reference Guide for details.
Naming of IDL .pro Files
When naming IDL .pro files used in cross-platform applications, be aware of the
various platforms’ file naming conventions and limitations. For example, the “$”
character is not allowed in a filename under VMS.
Building IDL Applications
Files and I/O
334
Chapter 16: Building Cross-Platform Applications
Be careful with case when naming files. For example, while Microsoft Windows
systems present file names using mixed case, file names are in fact caseinsensitive. File names are case-insensitive under VMS as well. Under Unix and
the Macintosh operating system, file names are case sensitive—file.pro is
different from File.pro. When writing cross-platform applications, you should
avoid using filenames that are different only in case. The safest course is to use
filenames that are all lower case.
Remember, too, that IDL commands are themselves case-insensitive. If entered at
the IDL command prompt, the following are equivalent:
IDL> command
IDL> COMMAND
IDL> CommanD
One upshot of this is that if you have filenames that differ only in case and you
use IDL’s automatic compilation feature, on platforms where case matters, IDL
will look for the lower-case version of the file name first. You can specify casesensitive filenames if you use the .COMPILE and .RUN executive commands—
but again, we recommend that you use unique file names always.
Math Exceptions
The detection of math errors, such as division by zero, overflow, and attempting
to take the logarithm of a negative number, is hardware and operating system
dependent. Some systems trap more errors than other systems. Beginning with
version 5.1, IDL uses the IEEE floating-point standard on all supported systems.
As a result, IDL always substitutes the special floating-point values NaN and
Infinity when it detects a math error. (See “Special Floating-Point Values” on
page 152 of Building IDL Applications for details on NaN and Infinity.)
Operating System Access
While IDL provides ways to interact with each operating system under which it
runs, it is not generally useful to use operating-system native functions in a crossplatform IDL program. If you find that you must use operating-system native
features, be sure to determine the current operating system (as described in
“Which Operating System is Running?” on page 328) and branch your code
accordingly.
Math Exceptions
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
335
Display Characteristics and Palettes
Finding Screen Size
Use the GET_SCREEN_SIZE function to determine the size of the screen on
which your application is displayed. Writing code that checks the screen size
allows your application to handle different screen sizes gracefully.
Number of Colors Available
Use the N_COLORS and TABLE_SIZE fields of the !D system variable to
determine the number of colors supported by the display and the number of
color-table entries available, respectively.
Make sure that your application handles relatively small numbers of colors (less
than 256, say) gracefully. For example, Microsoft Windows reserves the first 20
colors out of all the available colors for its own use. These colors are the ones used
for title bars, window frames, window backgrounds, scroll bars, etc. If your
application is running on a Windows machine with a 256-color display, it will
have at most 236 colors available to work with.
Similarly, make sure that your application handles TrueColor (24-bit or 32-bit
color) displays as well. If your application uses IDL’s color tables, for example,
you will need to force the application into 8-bit mode using the command
DEVICE, DECOMPOSED=0
to be use indexed-color mode on a machine with a TrueColor display.
Fonts
IDL uses three font systems for writing characters on the graphics device,
whether that device be a display monitor or a printer: Hershey (vector) fonts,
TrueType (outline) fonts, and device (hardware) fonts. Fonts are discussed in
detail in chapter 6 of the IDL Reference Guide.
Both TrueType and Vector fonts are displayed identically on all of the platforms
that support IDL. This means that if your cross-platform application uses either
the TrueType fonts supplied with IDL or the Vector fonts, there is no need for
platform-dependent code.
Printing
IDL displays operating-system native dialogs using the DIALOG_PRINTJOB and
DIALOG_PRINTERSETUP functions. Since the dialogs that control printing
Building IDL Applications
Display Characteristics and Palettes
336
Chapter 16: Building Cross-Platform Applications
and printer setup differ between systems, so do the options and capabilities
presented via IDL’s print dialogs. If your IDL application uses IDL’s printing
dialogs, make sure that your interface calls the dialog your user will expect for the
platform in question.
SAVE and RESTORE
Unless your cross-platform application supports VMS, there are no platformspecific issues to be concerned with. However, if you distribute your application
via IDL SAVE files, remember that files containing IDL routines are not
necessarily compatible between IDL releases. Always save your original code and
re-save when a new version of IDL is released. SAVE files containing data are
always compatible between releases of IDL.
If your application supports VMS, you should be aware that SAVE files created on
VMS machines with IDL versions before release 5.1 stored floating-point
numbers in VAX format. Beginning with version 5.1, IDL stores all floating-point
numbers in IEEE format. When IDL reads an older data file created on a VAX, it
automatically converts the floating-point numbers from VAX format to IEEE
format.
Note also that if you are restoring a file created with VAX IDL version 1, you must
restore on a machine running VMS.
Widgets
IDL’s user interface toolkit is designed to provide a “native” look and feel to
widget-based IDL applications. Where possible, widget toolkit elements are built
around the operating system’s native dialogs and controls; as a result, there are
instances where the toolkit behaves differently from operating system to
operating system. This section describes a number of platform-dependencies in
the IDL widget toolkit. Consult the descriptions of the individual DIALOG and
WIDGET routines in the IDL Reference Guide for complete details.
Dialog Routines
IDL’s DIALOG_ routines (DIALOG_PICKFILE, etc.) rely on operating system
native dialogs for most of their functionality. This means, for example, that when
you use DIALOG_PICKFILE in an IDL application, a Windows user will see the
Windows-native file selection dialog, a Macintosh user will see the appropriate
Macintosh-native file selection dialog (there are two), and Motif users will see the
Motif file selection dialog. Consult the descriptions of the individual DIALOG
routines in the IDL Reference Guide for notes on the platform dependencies.
SAVE and RESTORE
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
337
Base Widgets
Base widgets (created with the WIDGET_BASE routine) play an especially
important role in creating widget-based IDL applications because their behavior
controls the way the application and its components are iconized, layered, and
destroyed. See “Iconizing, Layering, and Destroying Groups of Top-Level Bases”
on page 1219 of the IDL Reference Guide for details about the platformdependent behavior.
Positioning Widgets within a Base Widget
The widget geometry management keywords to the WIDGET_BASE routine
allow a great deal of flexibility in positioning child widgets within a base widget.
When building cross-platform applications, however, making use of IDL’s
explicit positioning features can be counterproductive.
Because IDL attempts to provide a platform-native look on each platform,
widgets depend on the platform’s current settings for font, font size, and
“window dressing” (things like the thickness of borders and three-dimensional
appearance of controls). As a result of the platform-specific appearance of each
widget, attempting to position individual widgets manually within a base will
seldom give satisfactory results on all platforms. Instead, insert widgets inside
base widgets that have the ROW or COLUMN keywords set, and let IDL
determine the correct geometry for the current platform automatically. You can
gain a finer degree of control over the layout by placing groups of widgets within
sub-base widgets (that is, base widgets that are the children of other base
widgets). This allows you to control the column or row layout of small groups of
widgets within the larger base widget.
In particular, refrain from using the X/YSIZE and X/YOFFSET keywords in crossplatform applications. Using the COLUMN and ROW keywords instead will
cause IDL to calculate the proper (platform-specific) size for the base widget
based on the size and layout of the child widgets.
Fonts used in Widget Applications
You can specify the font used in a widget via the FONT keyword. In general, the
default fonts used by IDL widgets will most closely approximate the look of a
platform-native application. If you choose to specify the fonts used in your
widget application, however, note that the different platforms have different fontnaming schemes for device fonts. While device fonts will provide the best
performance for your application, specifying device fonts for your widgets
requires that you write platform-dependent code as described in “Which
Operating System is Running?” on page 328. You can avoid the need for
platform-dependent code by using the TrueType fonts supplied with IDL; there
Building IDL Applications
Widgets
338
Chapter 16: Building Cross-Platform Applications
may be a performance penalty when the fonts are initially rendered. See chapter
6 of the IDL Reference Guide for details.
Application Menu Bars
The Macintosh is unique among the platforms on which IDL runs in that it
provides a single menu bar at the top of the screen for the currently-active
application. The APP_MBAR keyword to the WIDGET_BASE function allows
your application to “take over” the Macintosh system menu when your IDL
application is active. If you wish to place the menu for your application in an
individual window, use the MBAR keyword instead. Code that uses the
APP_MBAR keyword acts as if the MBAR keyword had been specified. See
“APP_MBAR” on page 1206 of the IDL Reference Guide for details.
Motif Resources
Use the RESOURCE_NAME keyword to apply standard X Window System
resources to a widget on a Motif system. Resources specified via the
RESOURCE_NAME keyword will be quietly ignored on Windows and
Macintosh systems. See “RESOURCE_NAME” on page 1211 of the IDL
Reference Guide for details. In general, you should not expect to be able to
duplicate the level of control available via X Window System resources on other
platforms.
WIDGET_STUB
On Motif platforms, you can use the WIDGET_STUB routine to include widgets
created outside IDL (that is, with the Motif widget toolkit) in your IDL
applications. The WIDGET_STUB mechanism is only available under Unix and
VMS, and is thus not suitable for use in cross-platform applications that will run
under Microsoft Windows or on the Macintosh. WIDGET_STUB is described in
the External Development Guide.
Widget Events Inconsistencies
Different windowing systems provide different types of events when graphical
items are displayed and manipulated. IDL attempts to provide consistent
functionality on all windowing systems, but is not always completely successful.
Two inconsistencies that have caused confusion in the past are:
•
Widgets
Enter/Exit tracking events are not generated by some windowing systems. IDL
attempts to provide appropriate enter/exit events, but behaviors may differ on
different platforms.
Building IDL Applications
Chapter 16: Building Cross-Platform Applications
•
339
When an IDL draw widget (created with the WIDGET_DRAW function) is
realized on screen, an expose event is generated under Microsoft Windows but
not on other platforms.
Handle individual widget events carefully, and be sure to test your code on all
platforms supported by your application.
Using External Code
The use of programs written in languages other than IDL—either by calling code
from an IDL program via CALL_EXTERNAL or LINKIMAGE or via the callable
IDL mechanism—is an inherently platform-dependent process. Writing a crossplatform IDL program that uses CALL_EXTERNAL or LINKIMAGE requires
that you provide the appropriate programs or shared libraries for each platform
your application will support, and is beyond the scope of this chapter. Similarly,
the Callable IDL mechanism is necessarily different from platform to platform.
See the External Development Guide for details on writing and using external code
along with IDL.
Licensing
If your cross-platform application is distributed as IDL code or IDL SAVE files,
you need not concern yourself with licensing issues—you can assume that
anyone who can run your code has access to a licensed copy of IDL. If you plan
to distribute your application as a Runtime or Embedded IDL application,
consult the IDL Runtime Guide for details on licensing for your application.
DataMiner Issues
The IDL DataMiner provides a platform-independent interface to IDL’s Open
Database Connectivity (ODBC) features. Note, however, that the ODBC drivers
that allow connection to different databases are platform-dependent, and may
require platform-dependent coding. In addition, the dialogs called by the
DIALOG_DBCONNECT function are provided by the specific ODBC driver in
use, and will be different from data source to data source.
Building IDL Applications
Using External Code
340
DataMiner Issues
Chapter 16: Building Cross-Platform Applications
Building IDL Applications
Index
This index is cross-referenced for the three volumes
of the main IDL documentation set—Using IDL,
Building IDL Applications, Object Graphics, and the
IDL Reference Guide. Page numbers for Using IDL
are followed by a “U”, page numbers for Building
IDL Applications are followed by a “B”, page numbers
for Object Graphics are followed by an “O”, and page
numbers for the Reference Guide are followed by an
“R”.
Symbols
! character 58R
!C system variable 46R
!D system variable 46R
!D.TABLE_SIZE system variable 47R, 1164R
!D.WINDOW system variable 1199R, 1317R, 1346R
!DIR system variable 42R
!DLM_PATH system variable 42R
!DPI system variable 38R
!DTOR system variable 38R
!EDIT_INPUT system variable 24U, 42R
!ERR system variable 38R, 1114R, 1203R
!ERROR_STATE system variable 143B, 149B, 39R,
745R, 780R, 1082R
MSG 147B, 1082R
MSG_PREFIX 745R
SYS_MSG 147B
!EXCEPT system variable 40R
!HELP_PATH system variable 42R
!JOURNAL system variable 43R, 582R
!MAP system variable 359U, 38R
!MAP1 system variable 723R
!MORE system variable 43R
!MOUSE system variable 40R, 332R
!ORDER system variable 382U, 48R, 1154R, 1162R
!P system variable 49R
!P.FONT system variable 66R
!P.MULTI system variable 306U, 162R
!P.T system variable 107R, 323R, 380R, 984R, 985R,
1095R, 1109R
Index-1
Index-2
!P.T3D system variable 323R
!PATH system variable 43R, 462R
!PI system variable 38R
!PROMPT system variable 45R
!QUIET system variable 45R, 745R
!RADEG system variable 38R
!VALUES system variable 38R
!VERSION system variable 45R
!WARN system variable 41R
!X system variable 52R
!Y system variable 52R
!Z system variable 52R
" character 59R
# of Rows/Columns base property 202U
# operator 272U, 430U, 31B
## operator 273U, 431U, 31B
$ character 31U, 59R
& character 59R
’ character 58R
* character 60R
. character 59R
.COMPILE executive command 32R
.CONTINUE executive command 33R
.EDIT executive command 33R
.GO executive command 33R
.OUT executive command 33R
.RETURN executive command 33R
.RUN executive command 34R
.SIZE executive command 1393R
.SKIP executive command 35R
.STEP executive command 35R
.STEPOVER executive command 36R
.TRACE executive command 36R
.Xdefaults file 1211R
: character 59R
; character 59R
< operator 272U, 30B
> operator 272U, 30B
>> button 247U
? character 61R
? command 242U
?: ternary operator 36B
@ character 32U, 60R
^ character 271U, 29B
Numerics
24-bit images 1155R
2D rendering of 3D volumes 850R
Index
3D
images
reconstructed from 2D arrays 939R
viewing coordinate system 323R
rendering 740R
transformations 343U, 314R, 350R, 380R, 984R,
985R, 1095R, 1109R, 1186R
volume slices 1027R
3D text 82O
64-bit data type
long 12B
unsigned long 12B
64-bit integer
arrays 593R, 686R
data type, converting to 689R
vectors 686R
A
A keyword 587R, 1098R
A_CORRELATE function 423U, 435U, 468U, 187R
abbreviating keywords 111B
aborting IDL 30U
about IDL 9U, 2B, 14O, 23R
ABOVE keyword 733R
ABS function 189R
ABSDEV keyword 598R
absolute deviation 755R
ABSOLUTE keyword 444R
absolute value 189R
accuracy
of floating-point operations 427U
of numerical algorithms 426U
ACMODE keyword 1145R
ACOS function 190R
action routines, Motif 74U
active command line 289B, 1365R
ACTIVE keyword 1271R
actual parameters 110B, 111B
Add method 182O, 286O, 354O, 389O, 397O
addition
array elements 1123R
operator 270U, 29B
AddPolygon method 376O
address, RSI postal 16U, 9B, 20O, 29R
ADDSYSVAR, see Obsolete Routines
adjacency list, Delaunay triangulation 1131R
ADJCT,see Obsolete Routines
Index Numerics ... AUsing IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
Adobe
Font Metrics files 854R
Type Manager 74R, 136R
ADVANCE keyword 725R
AFTER keyword 229R
AITOFF keyword 724R
Aitoff map projection 365U, 724R
Alber’s
equal area conic map projection 724R
equal-area conic map projection 372U
ALBERS keyword 724R
ALIAS keyword 286O
aliasing, sampled data analysis 409U
ALIGN_BOTTOM keyword 1205R
ALIGN_CENTER keyword 1205R, 1222R, 1280R
ALIGN_LEFT keyword 1205R, 1222R, 1280R
ALIGN_RIGHT keyword 1205R, 1222R, 1280R
ALIGN_TOP keyword 1205R
aligning text 1379R
Alignment 203U
Alignment base property 203U
Alignment button property 213U
ALIGNMENT keyword 384O, 671R, 1230R, 1298R,
1379R
Alignment label property 221U
alignment of text objects 82O
Alignment table property 234U
ALL keyword 185O, 187O, 208O, 221O, 232O, 240O,
250O, 257O, 263O, 272O, 280O, 290O, 292O,
297O, 304O, 311O, 318O, 326O, 336O, 346O,
356O, 357O, 362O, 371O, 383O, 391O, 394O,
399O, 401O, 405O, 418O, 429O, 273R, 982R
ALL_EVENTS keyword 368R, 1298R
ALL_KEYS keyword 537R
ALL_TABLE_EVENTS keyword 1230R
ALL_TEXT_EVENTS keyword 1231R, 1309R
ALL_VALUE keyword 246R
ALLOCATE_HEAP keyword 857R, 860R
allocated memory, returning amount of 539R
Allow Closing base property 203U
Allow Moving base property 204U
ALOG function 191R
ALOG10 function 192R
alpha blending 126O
alpha blending (image objects) 115O
alpha channel 114O
ALPHA keyword 529R, 677R
Altura Software 250U
AM_PM keyword 209O
Index-3
AMBIENT keyword 407O
AMOEBA function 463U, 193R
ampersand 59R
analytic signal 411U
AND operator 274U, 32B
Angstrom symbol 68R
animation 343U
compound widget 275B
flickering images 485R
MPEG files 757R, 758R, 760R, 762R
widget interface 341R, 1357R
ANISOTROPY keyword 251O
ANNOTATE procedure 196R
annotations
help topics 244U
of displayed images 196R
on plots 293U
text objects 81O
anonymous structures 262U, 42B
ANOVA, see Obsolete Routines
ANOVA_UNEQUAL, see Obsolete Routines
ANSI keyword 1001R
apostrophe 58R
APP_KEYPAD keyword 1001R
APP_MBAR keyword 1206R
APP_SCROLL keyword 1252R
APPEND keyword 784R, 1232R, 1337R
AppleScript 438R
applications, written in IDL 2B
approximating models, statistical 282R
arc-cosine 190R
architecture, current version in use 45R
arc-sine 203R
arc-tangent 206R
ARG_PRESENT function 124B, 198R
arguments
checking existence of 198R
described 184R
arguments, described 180O
arithmetic errors 151B
ARRAY keyword 463R, 918R
array operators
CHOLDC 267R
CHOLSOL 268R
COND 290R
CRAMER 319R
DETERM 417R
EIGENVEC 446R
ELMHES 448R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index A ... A
Index-4
Index
GS_ITER 525R
HQR 551R
INVERT 576R
LU_COMPLEX 694R
LUDC 696R
LUMPROVE 697R
LUSOL 699R
NORM 769R
SVDC 1096R
SVSOL 1102R
TRIQL 1140R
TRIRED 1142R
TRISOL 1143R
arrays
and matrices 429U
changing dimensions of 945R
concatenation 273U, 31B
creating
64-bit integer
(L64INDGEN function) 593R
(LON64ARR function) 686R
any type (MAKE_ARRAY function) 705R
byte
(BINDGEN function) 220R
(BYTARR function) 233R
complex
(CINDGEN function) 270R
(COMPLEXARR function) 287R
(DCINDGEN function) 395R
(DCOMPLEXARR function) 398R
double-precision
(DBLARR function) 394R
(DCINDGEN function) 395R
(DCOMPLEXARR function) 398R
(DINDGEN function) 435R
integer
(INDGEN function) 561R
(INTARR function) 570R
longword
(LINDGEN function) 603R
(LONARR function) 687R
single-precision, floating-point
(FINDGEN function) 482R
(FLTARR function) 490R
string
(SINDGEN function) 1020R
(STRARR function) 1073R
unsigned 64-bit
(ULON64ARR function) 1171R
Index A ... A
unsigned 64-bit integer
(UL64INDGEN function) 1169R
unsigned integer
(UINDGEN function) 1166R
unsigned longword
(ULINDGEN function) 1170R
(ULONARR function) 1172R
definition 260U
efficient accessing 206B
extracting sub-arrays 467R
filling with a scalar value 949R
finding number of elements in 764R
floating-point 482R
incrementing elements 548R
interactive editing tool (XVAREDIT
procedure) 1378R
memory allocation under VMS 23U
multiplying 430U
of structures 49B, 949R
operators, see array operators
resizing 291R, 461R, 935R
returning
maximum value 731R
minimum value 747R
subscripts of non-zero elements 1203R
type 1022R
reversing indices 960R
rotating 972R
searching for objects 986R, 989R
shifting elements 1013R
size 1022R
sorting 1046R
sparse 464U
stored in structure form 464U
subscripts
definition 261U
ranges 64B
returning non-zero elements 1203R
summing elements 1123R
symmetric 430U
transposing 1126R
unique elements of (UNIQ function) 1175R
updating 223R
ARROW procedure 200R
ARROW_ANGLE keyword 640R
ARROW_END keyword 640R
ARROW_SIZE keyword 640R
ARROW_START keyword 640R
ARROWSIZE keyword 488R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
AS_STRING keyword 438R
ASCENDING keyword 444R
ASCII keyword 1331R
ASCII_TEMPLATE function 202R
ASIN function 203R
ASPECT keyword 559R, 806R
assignment 258B
operator 270U, 28B
pointers 236B
statement 85B
ASSOC function 157B, 160B, 204R
associated I/O 202B
associated variables 204R
asterisk 60R
at sign (character) 60R
ATAN function 206R
ATOL keyword 692R
atomic graphic objects 28O, 37O
ATTENUATION keyword 281O
Attribute objects 30O, 38O
attribute objects 64O
attributes
draw widget 229U
droplist 224U
label widget 221U
listbox 226U
slider 222U
table widget 234U
autocorrelation 187R
autocovariance 187R
automatic compilation 29U, 100B
automatic structure definition 54B, 252B
autoregressive moving average filters 414U
autoregressive time-series forecasting 1147R, 1149R
AVANTGARDE keyword 116R
average
mean 755R
median 738R
moving 1043R, 1151R
AVERAGE_LINES keyword 116R
AX keyword 323R, 380R, 984R, 1005R, 1008R, 1091R,
1095R
axes 310U, 74O, 205O, 106R
date labels for 594R
direction 209O
end points 56R
gridstyles 210O, 53R
linear 56R
location 210O
Index-5
logarithmic 305U, 211O, 56R
[XYZ]LOG keywords 208R, 307R, 801R,
1006R, 1093R
margins 53R
range 290U, 52R, 54R
range (CRANGE, EXACT, EXTEND,
RANGE) 208O
scaling 288U, 54R
style 54R
system variables for 52R
thickness 212O, 55R
thickness, (XYZ)THICK keyword 107R
titles 213O, 56R, 109R
AXIS keyword 442O, 443O
axis object 29O, 205O
axis objects 74O
creating 74O
range values 74O
tick labels 80O
titles 80O
using 74O
AXIS procedure 310U, 207R
AY keyword 323R
AZ keyword 323R, 380R, 984R, 1005R, 1008R, 1091R,
1095R
azimuthal equidistant map projection 365U, 724R
AZIMUTHAL keyword 724R
azimuthal map projections 362U
B
B_LENGTH keyword 225R
B_VALUE keyword 246R
"Back" button 247U
BACK_CHARACTER keyword 402R
BACK_WORD keyword 402R
BACKCAST keyword 1149R
back-face 149O
back-face culling 149O
background color 148R
for graphics windows 451R
BACKGROUND keyword 100R, 210R, 1193R, 1363R
BACKGROUND system variable field 49R
background tasks 1247R
for widgets 302B
backing store 132R, 144R, 1318R
for draw widgets 351R, 1256R, 1260R
for zoom widgets 391R
IDLDE for Macintosh 130U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index B ... B
Index-6
Index
IDLDE for Motif 62U
IDLDE for Windows 106U
BACKPROJECT keyword 964R
backprojection 963R
back-substitution 1102R
backward index list (for histograms) 546R
BACKWARD keyword 1151R
BAD_ID keyword 1232R, 1268R
bandpass filters 414U
bandstop filters 414U
bar charts 299U, 210R
BAR_PLOT procedure 210R
BARNAMES keyword 210R
BAROFFSET keyword 210R
BARSPACE keyword 210R
BARWIDTH keyword 210R
base 10 logarithm 192R
base widgets 273B, 1205R
attributes 202U
bulletin board bases 306B, 1218R
changing title of 1248R
column 1207R
column bases 1207R
events 210U
events returned by 1221R
exclusive 1208R
exclusive and non-exclusive 1218R
keyboard focus events 1209R
mapping and unmapping 1240R
nonexclusive 1211R
positioning 1247R
top-level bases 1219R
resize events 1216R
row bases 1213R
top-level 1205R
using 165U
base, setting attributes 202U
base, setting events 210U
BASE_ALIGN_BOTTOM keyword 1206R
BASE_ALIGN_CENTER keyword 1206R
BASE_ALIGN_LEFT keyword 1206R
BASE_ALIGN_RIGHT keyword 1206R
BASE_ALIGN_TOP keyword 1206R
BASE_STYLE keyword 659R
BASELINE keyword 384O
BASELINES keyword 211R
BASERANGE keyword 211R
batch
mode 32U
Index B ... B
processing 60R
batch files 32U
using as startup file 33U
IDLDE for Macintosh 132U
IDLDE for Motif 64U
IDLDE for Windows 108U
BEGIN statement 90B
Bell, ringing the terminal 18B
BELOW keyword 733R
benchmarks 1120R
Bernoulli distribution 221R
BESELI function 213R
BESELJ function 214R
BESELY function 215R
Bessel functions
BESELI 213R
BESELJ 214R
BESELY 215R
BETA function 216R
incomplete 554R
BETAI, see Obsolete Routines
big endian byte ordering 235R, 1104R
bi-level images 1118R
bilinear (Tustin) transform 420U
BILINEAR function 445U, 217R
bilinear interpolation 445U, 217R, 935R
BILINEAR keyword 716R, 964R
BIN keyword 1342R
BIN_DATE function 219R
binary interpolation 573R
BINARY keyword 116R, 787R
binary SAVE and RESTORE 982R
binary trees 248B
BINDGEN function 220R
binomial distribution 221R
BINOMIAL function 221R
BINOMIAL keyword 887R, 891R
binomial random deviates 887R, 891R
bins, histogram 546R
BINSIZE keyword 544R, 546R
bit shift operation 581R
bitmap
button labels 1226R, 1228R, 1352R
byte array 340R
files
reading (READ_BMP) 901R
standard file format I/O routines 228B
writing (WRITE_BMP) 1320R
labels, creating 340R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
Bitmap button property 213U
Bitmap Editor 174U
opening 213U
tools 175U
BITMAP keyword 1222R
bitmaps
adding to buttons 174U
BITS_PER_PIXEL keyword 116R
BKMAN keyword 116R
BLAS_AXPY procedure 223R
BLEND_FUNCTION keyword 264O
BLK_CON function 423U, 225R
blob coloring 596R
BLOB keyword 488R
block convolution 225R
BLOCK field 192O
BLOCK keyword 191O, 199O, 443R, 788R, 1040R,
1082R, 1352R, 1354R, 1361R, 1369R, 1370R,
1371R, 1377R
blocks 90B
BLUE keyword 625R
BLUE_VALUES keyword 242O, 305O
BMP files
adding to button widgets 174U
displaying on buttons 213U
reading (READ_BMP) 901R
standard file format I/O routines 228B
supplied 174U
writing (WRITE_BMP) 1320R
BOLD keyword 117R
BOOK keyword 117R, 781R
Bookman font 116R
bookmark menu (online help) 244U
Boolean operators 274U, 32B
BORDER_GAP keyword 273O
BOTTOM keyword 328O, 363O, 685R, 1091R, 1361R
bottom margin, setting 53R
BOTTOM_STRETCH keyword 304O, 306O
boundaries, specifying for maps 360U
BOUNDS keyword 407O, 588R, 1052R, 1129R
BOUT keyword 1052R
box charts 299U
BOX_CURSOR procedure 227R
boxcar average 1043R
boxcar filter 417U
BREAKPOINT procedure 229R
breakpoints
debugging with 140U
removing 229R
Index-7
returning information on 537R
setting 230R
BREAKPOINTS keyword 537R
BRIGHT keyword 329R
Bristol Technology 28U, 250U
browse << buttons (online help) 247U
BROWSE_LINES keyword 202R
BROYDEN function 462U, 231R
Broyden’s method 462U, 231R
bubble sort 245B
BUFFER keyword 612R, 625R, 649R, 665R, 907R
Buffer object 32O
buffer object 216O
buffer objects 138O
creating 139O
buffered output 449R, 491R
buffers 491R
flushing 459R
type-ahead 514R
BUFSIZE keyword 784R
bugs
debugging in IDL 138U
reporting math 426U
reporting problems 13U, 5B
bulletin board bases 306B, 1218R
button
bar(online help system) 247U
groups 354R
labels, creating 340R
mouse with CURSOR procedure 332R
widgets 273B, 1222R
bitmap labels 1226R, 1228R, 1352R
button release events 1224R
events returned by 1228R
groups 354R
setting pointer focus 1238R
toggle 1227R
button widgets
adding menus to 173U
setting attributes 213U
setting properties 212U
using 165U
BUTTON_EVENTS keyword 1253R
BUTTON_UVALUE keyword 354R
BY_VALUE keyword 579R
BYPASS_TRANSLATION keyword 117R
BYTARR function 233R
byte
arguments and strings 75B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index B ... B
Index-8
Index
arrays 220R, 233R
data type 12B
scaling values into a range of bytes 238R
swapping 235R
swapping short integers 236R
type, converting to 234R
BYTE function 76B, 234R
BYTE keyword 561R, 705R
BYTEORDER procedure 235R
BYTSCL function 384U, 238R
C
C_ANNOTATION keyword 320U, 328U, 301R
C_CHARSIZE keyword 320U, 328U, 301R
C_CHARTHICK keyword 301R
C_COLOR keyword 251O
C_COLORS keyword 301R
C_CORRELATE function 423U, 435U, 469U, 240R
C_EDIT, see Obsolete Routines
C_FILL_PATTERN keyword 252O
C_LABELS keyword 320U, 328U, 302R
C_LINESTYLE keyword 252O, 302R
C_ORIENTATION keyword 302R
C_SPACING keyword 302R
C_THICK keyword 252O, 302R
C_VALUE keyword 252O
C0 keyword 587R
C1 keyword 587R
CALDAT procedure 242R
CALENDAR procedure 244R
CALL_EXTERNAL 1404, 1406
CALL_EXTERNAL function 245R
CALL_FUNCTION function 129B, 252R
CALL_PROCEDURE procedure 129B, 253R, 254R
CALL_VMS, see Obsolete Routines
calling
external modules from IDL 245R
IDL functions from a string 252R
IDL methods from a string 253R
IDL procedures from a string 254R
mechanism for procedures 121B
routines written in other languages 245R, 606R
sequence 184R
calling sequence
function methods 180O
procedure methods 180O
CALLS keyword 148B, 537R
"Cancel" button 1232R
Index C ... C
CANCEL keyword 143B, 202R, 255R, 424R, 530R
CANCEL_BUTTON keyword 1232R
caret 271U, 29B
carrot 271U, 29B
case folding 76B
CASE statement 92B
CAST keyword 776R, 858R
CATCH keyword 1363R
CATCH procedure 143B, 255R
catch, C++ language 255R
ccolors
Motif colormaps see colormaps
CD procedure 257R
CDECL keyword 246R
CDF files 1387R
CEIL function 259R
cell drawing (contour method) 319U
CELL_FILL keyword 303R
CENTER keyword 312R, 964R
CENTIMETERS keyword 1154R, 1157R
central map projection 363U, 724R
CENTRAL_AZIMUTH keyword 729R
CGM driver 148R
CHANGE keyword 333R
change value event 223U
changing directories 257R
changing widget values 301B
changing working directory, Macintosh 135U
CHANNEL keyword 265O, 100R, 451R, 1154R, 1162R
CHANNEL system variable field 49R
channels (in image objects) 114O
CHAR_DIMENSIONS keyword 384O
characters
character sets 79R
non-printable 18B
plotting in graphics windows 1379R
size 1380R
special 26U
CHARSIZE keyword 100R, 711R, 725R, 1380R
CHARSIZE system variable field 49R, 52R
CHARTHICK keyword 101R, 1380R
CHARTHICK system variable field 49R
CHEBYSHEV function 260R
CHECK keyword 232R, 417R, 767R
CHECK_MATH function 428U, 151B, 261R
checkbox widgets
creating 212U
laying out 213U
setting attributes 213U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
setting properties 212U
checkboxes 212U
using 165U
CHI_SQR, see Obsolete Routines
CHI_SQR1, see Obsolete Routines
CHILD keyword 1271R
children, of widgets 1271R
CHISQ keyword 678R, 1098R
CHISQR keyword 604R
CHISQR_CVF function 265R
CHISQR_PDF function 266R
Chi-square distribution 265R, 266R
Chi-square error statistic, minimizing 604R
Chi-square goodness-of-fit test 330R, 1375R
CHOLDC procedure 459U, 267R
Cholesky decomposition 267R, 268R
CHOLSOL function 460U, 268R
chromacoded editor, Windows 112U
CINDGEN function 270R
CIR_3PNT procedure 271R
class 188O
object 250B
structure 251B
structures
zeroed 252B
CLEANUP keyword 1364R
Cleanup method 183O, 189O, 206O, 217O, 229O,
238O, 248O, 256O, 261O, 270O, 278O, 286O,
296O, 302O, 310O, 316O, 324O, 334O, 343O,
354O, 360O, 370O, 377O, 381O, 389O, 397O,
402O, 425O
CLEAR keyword 229R, 846R
CLEAR_EVENTS keyword 1232R
clearing breakpoints 229R
CLIENTSERVER keyword 680R
CLIP keyword 101R, 725R
CLIP system variable field 49R
Clipboard object 32O
clipboard object 228O
clipboard objects
creating 139O
clipboard support, graphics windows
Macintosh 120U
Windows 88U
clipping planes 47O
clipping window 49R
clock, system 1105R
CLOSE keyword 117R, 904R, 1322R, 1359R
CLOSE procedure 273R
Index-9
CLOSE_DOCUMENT keyword 117R
CLOSE_FILE keyword 117R
CLOSED keyword 303R
closing
(image processing) function 433R
contours 303R
files 161B
open file units 273R
graphics output files 117R
CLUST_WTS function 476U, 274R
cluster
analysis 274R, 275R
weights 274R
CLUSTER function 476U, 275R
CMY color system 387R
CMY keyword 387R
coastlines 708R
COASTS keyword 708R
code
IDL GUIBuilder generated 159U
modifying generated 159U
CODE keyword 1082R
COEFF keyword 330R
COEFFICIENTS keyword 796R
COLD keyword 1201R
COLMAJOR keyword 918R
colon (character) 59R
color 58O
and destination objects 59O
and digital data 58O
indexed 58O
palette objects 60O
RGB 59O
specifying color values 60O
COLOR field 192O
COLOR keyword 285U, 209O, 218O, 242O, 252O,
282O, 319O, 328O, 338O, 357O, 363O, 373O,
385O, 392O, 426O, 101R, 118R, 200R, 451R, 640R,
656R, 671R, 708R, 711R, 726R, 760R, 908R, 1177R,
1184R, 1201R
color mapping
voxel values 125O
Color Model
draw area property 229U
color model
for windows 135O
printers 140O
color models 58O
COLOR system variable field 49R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index C ... C
Index-10
Index
color tables 386U
colors1.tbl file 685R, 754R
common block 391U
creating and modifying with XPALETTE 1371R
example 161U
for LJ device 674R
gamma correction 505R
histogram equalization 528R
histogram equalizing 527R
HLS (Hue, Lightness, Saturation) 550R
HSV (Hue, Saturation, Value) 553R
LHB (Lightness, Hue, Brightness) 855R
loading 388U, 1159R
loading into variables(GET keyword) 1160R
loading predefined 685R, 1361R
maximum indices for draw widgets 1253R
modifying predefined colortable files 754R
obtaining 391U
predefined 389U
setting maximum number of indices 1317R
stretching 1075R
switching between devices 392U
Tektronix 4115 1116R
wrapping (MULTI procedure) 763R
COLOR_CONVERT procedure 277R
COLOR_EDIT, see Obsolete Routines
COLOR_INDEX keyword 387R
COLOR_INDICES keyword 196R
COLOR_MODEL keyword 223O, 234O, 348O, 420O,
432O, 1253R
COLOR_QUAN function 279R
COLOR_VALUES keyword 358R
colorbar object 30O, 238O
Colorbar objects 116O
COLORBAR_PROPERTIES keyword 660R
colormaps (Motif IDLDE) 67U
colors
background 49R, 100R, 148R, 451R
converting between color systems 277R
default index 49R
gamma correction (GAMMA_CT) 505R
indices 393U, 121R, 358R, 360R, 387R
luminance of (CT_LUMINANCE function) 329R
manipulation compound widgets 275B
maximum number available 1164R
maximum number for draw widgets 1253R
palette
Macintosh 130U
Windows 114U
Index C ... C
pixel depth, Macintosh 130U
quantization 279R
reducing number in an image 944R
reserving for IDL 67U
resources,for widgets 1213R
setting maximum number of indices 1317R
shared colormap 138R
systems 386U, 387R, 1159R
tables, See color tables
COLORS common block 391U
Colors draw area property 229U
COLORS keyword 118R, 211R, 280R, 351R, 1253R,
1317R
column bases 1207R
COLUMN keyword 306B, 354R, 368R, 374R, 448R,
551R, 696R, 697R, 699R, 1064R, 1096R, 1102R,
1207R, 1348R
Column Labels table property 234U
COLUMN_LABELS keyword 1232R, 1299R
COLUMN_MAJOR keyword 1299R
COLUMN_WIDTHS keyword 1232R, 1271R, 1299R
column-major format 429U
COLUMNS keyword 273O
combination 473R
combining 51O
combining contour and surface plots 344U
combining transformations 51O
COMFIT function 437U, 282R
COMM keyword 982R
command input buffer, displaying 539R
Command Input Line
IDLDE for Macintosh 118U
anchoring 129U
IDLDE for Motif 41U
IDLDE for Windows 86U
command line options, Motif 68U, 74U
command recall 24U
buffer 938R
command stream substitutions, Motif 74U
command-line switches 20U
commands
displaying previously-executed 539R
executive 31R, 46R
.COMPILE 32R
.CONTINUE 33R
.EDIT 33R
.GO 33R
.OUT 33R
.RETURN 33R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
.RUN 34R
.SIZE 1393R
.SKIP 35R
.STEP 35R
.STEPOVER 36R
.TRACE 36R
COMMENT_SYMBOL keyword 898R
comments 85B
common blocks 93B
widgets and 312B
common methods 27O
COMPILE executive command See commands
compiling files
IDLDE for Macintosh 123U
IDLDE for Motif 48U
IDLDE for Windows 93U
compiling functions and procedures 29U, 952R, 954R
displaying 540R
Macintosh 135U
complex
arrays, creating 270R, 287R, 395R, 398R
arrays, rounding 288R
conjugate 293R
data type 285R, 396R
numbers 258U, 17B
returning imaginary part of 560R
returning real part of 486R
returning the magnitude of 189R
polynomials 502R
complex data type 13B
COMPLEX function 285R
COMPLEX keyword 561R, 705R
COMPLEXARR function 287R
COMPLEXROUND function 288R
Component Sizing common property 197U
Composite classes
Object Graphics 144O
composite classes 144O
COMPOSITE_FUNCTION keyword 407O
compositing 126O
compound widgets 275B, 314B
animation 275B
color manipulation 275B
CW_ANIMATE 341R
CW_ARCBALL 350R
CW_BGROUP 354R
CW_CLR_INDEX 358R
CW_COLORSEL 360R
CW_DEFROI 362R
Index-11
CW_DICE 366R
CW_FIELD 368R
CW_FORM 371R
CW_FSLIDER 377R
CW_ORIENT 380R
CW_PDMENU 382R
CW_RGBSLIDER 387R
CW_ZOOM 390R
data entry 276B
example 188U
handling events 199U
image manipulation 276B
in IDL GUIBuilder code 188U
orientation 276B
user interface 276B
writing 316B
COMPRESS keyword 716R
COMPRESSION keyword 1337R
compression, JPEG 907R, 1324R
COMPUTE_MESH_NORMALS function 289R
ComputeBounds method 403O
Computed Tomography 963R
ComputeDimensions method 239O, 270O
Computer Graphics Metafile 148R
computing inner products 430U
CON_COLOR keyword 726R
concatenation
array 273U, 31B
string 74B
concave polygons 71O, 375O
CONCEALED keyword 998R
COND function 460U, 290R
CONDITION keyword 230R
condition number 454U, 460U, 290R
conditional expression 36B
CONEANGLE keyword 282O
CONFINE keyword 998R
conformal conic map proejction 371U
CONGRID function 291R, 935R
CONGRID keyword 1040R
CONIC keyword 724R
CONJ function 293R
conjugate, complex 293R
CONNECTIVITY keyword 1132R
constants
complex 258U, 17B
decimal 14B
double-precision 258U, 16B
floating-point 258U, 16B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index C ... C
Index-12
Index
hexidecimal 14B
integer 257U, 14B
ivalues 257U, 15B
octal 14B
string 258U, 259U, 17B
CONSTRAIN keyword 442O, 443O
CONSTRAINED_MIN procedure 463U, 294R
container object 182O
"Contents" button (online help system) 247U
contents tab (online help system) 248U
context 30U, 142B
CONTEXT keyword 781R
context number 781R
CONTINENT keyword 359U, 363U, 726R
continental boundaries 708R
continents, drawing 360U
contingency table 330R
CONTINGENT, see Obsolete Routines
CONTINUE executive command See commands
CONTINUE keyword 745R, 809R
CONTINUE_ON_ERROR keyword 952R
CONTINUOUS keyword 1382R
contour object 29O, 247O
contour objects 86O
creating 86O
contour plots 318U, 300R
closing contours 303R
filled (FILL keyword) 303R
filling 330U
indicating direction of grade 331U
labeling 328U
overlaying with images 324U, 559R
polar 815R
smoothing 329U
with images and surface plots 1015R
CONTOUR procedure 318U, 343U, 300R
contrast, gamma correction 505R
control characters
alt-F4 61R
command-period 61R
command-q 61R
control-\ 61R
control-break 61R
control-C 61R
control-D 61R
control-Y 61R
control-Z 61R
CONTROL keyword 402R
Control Panel, IDLDE for Motif 41U
Index C ... C
modifying 72U
controlling the device cursor 395U
controls see widgets 272B
convergence criterion 768R
CONVERGENCE keyword 678R, 1201R
CONVERT_COORD function 287U, 339U, 309R
converting
colors between color systems 277R
coordinate systems 309R
converting expressions
between host and network byte ordering 235R
to 64-bit integer type 689R
to byte type 234R
to complex type 285R, 396R
to double-precision type 442R
to integer type 484R
to longword type 688R
to single-precision floating-point type 486R
to string type 1077R
to unsigned 64-bit integer type 1174R
to unsigned integer type 1167R
to unsigned longword type 1173R
convex polygons 71O, 375O
CONVOL function 423U, 311R
convolution 225R, 311R
Cooley-Tukey algorithm 411U
COORD2TO3 function 314R
coordinate conversion 51O
coordinate systems and scaling 42O
coordinate transformations 51O
coordinates
3D transformations 314R, 350R, 380R, 984R,
985R, 1095R, 1109R, 1186R
clipping 101R
converting 287U, 339U
2D to 3D 314R
between coordinate systems 338R
map coordinates 723R
systems 309R
data 285U
defining 3D systems 323R
device 286U, 102R
normal 286U, 104R
COPY keyword 118R, 992R
copying help topics 243U
copying pixels from one window to another 118R
COR keyword 964R
CORRECTED keyword 330R
correction, gamma 505R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
CORREL_MATRIX, see Obsolete Routines
CORRELATE function 435U, 476U, 315R
correlation analysis 431U
correlation/covariance matrix 315R
Kendall’s tau rank 882R
lagged autocorrelation 187R
lagged crosscorrelation 240R
multiple 701R
partial 795R
Pearson’s correlation 315R
Spearman’s rho rank 882R
correlation coefficient 431U
CORRELATE 315R
Kendalls’s 882R
M_CORRELATE 701R
multiple 701R
P_CORRELATE 795R
partial 795R
Pearson 315R
R_CORRELATE 882R
rank 882R
Spearman’s 882R
COS function 317R
COSH function 318R
cosine 317R
hyperbolic 318R
inverse 190R
COSINES, see Obsolete Routines
count accumulation 548R
COUNT keyword 185O, 192O, 463R, 480R, 771R,
776R, 858R, 898R, 1048R
Count method 184O
COUNTRIES keyword 708R
country boundaries 708R
COURIER keyword 118R
COVAR keyword 678R, 1098R
COVARIANCE keyword 187R, 241R, 315R, 796R
CRAMER function 460U, 319R
Cramer’s rule 319R
CRAMV keyword 330R
CRANGE keyword 208O
CRANGE system variable field 52R
CREATE_INSTANCE keyword 218O, 426O
CREATE_STRUCT function 321R
CREATE_VIEW procedure 323R
creating
heap variables 231B
realizing widgets 1241R
system variables 409R
Index-13
windows 1317R
creating multiple 212U
CREATOR_TYPE keyword 301O
cross correlation 240R
cross covariance 240R
CROSSP function 326R
CRVLENGTH function 438U, 452U, 327R
CT_LUMINANCE function 329R
CTI_TEST function 448U, 476U, 330R
CUBE keyword 280R
cubic convolution interpolation 573R, 821R
CUBIC keyword 291R, 573R, 821R, 964R, 970R
cubic spline interpolation 445U, 1054R, 1056R
parametric 446U
Culling 149O
current IDL session, returning information on 537R
CURRENT keyword 257R, 505R
current working directory 257R
cursor
box 227R
changing appearance 119R
controlling position 395U
displaying 1157R
graphics on Tektronix terminals 126R
hiding 1157R
hourglass 301B, 1238R
positioning 1157R
reading position of 313U, 894R
returning events from draw widgets 1255R
setting to crosshair 118R
specifying pattern 119R
type 118R
CURSOR procedure 313U, 332R
and Tektronix terminals 126R
CURSOR_CROSSHAIR keyword 118R
CURSOR_IMAGE keyword 119R
CURSOR_STANDARD keyword 119R
CURSOR_XY keyword 120R
curve fitting 282R
and surface fitting 436U
COMFIT 282R
CRVLENGTH 327R
CURVEFIT 335R
GAUSS2DFIT 508R
GAUSSFIT 511R
LADFIT 598R
LINFIT 604R
LMFIT 677R
MIN_CURVE_SURF 748R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index C ... C
Index-14
Index
POLY_FIT 824R
POLYFITW 831R
REGRESS 947R
SFIT 1002R
SVDFIT 1098R
CURVEFIT function 436U, 437U, 335R
customizing
IDLDE for Macintosh 128U
IDLDE for Motif 57U
IDLDE for Windows 102U
cutoff value
Chi-square distribution 265R
F distribution 471R
Gaussian distribution 506R
T distribution 1107R
CUTTING_PLANE keyword 1193R
CUTTING_PLANES keyword 408O
CV_COORD function 338R
CVTTOBM function 340R
CW_ANIMATE function 341R
CW_ANIMATE_GETP procedure 345R
CW_ANIMATE_LOAD procedure 346R
CW_ANIMATE_RUN procedure 348R
CW_ARCBALL function 350R
CW_BGROUP function 354R
CW_BSELECTOR, see Obsolete Routines
CW_CLR_INDEX function 358R
CW_COLORSEL function 360R
CW_DEFROI function 362R
CW_DICE function 316B, 366R
CW_FIELD function 368R
CW_FORM function 371R
CW_FSLIDER function 377R
CW_LOADSTATE, see Obsolete Routines
CW_ORIENT function 380R
CW_PDMENU function 298B, 382R, 1224R
CW_RGBSLIDER function 387R
CW_SAVESTATE, see Obsolete Routines
CW_TMPL procedure 389R
CW_ZOOM function 390R
CYCLE keyword 346R, 1358R
cyclical fluctuation 467U
cylindrical coordinates 338R
cylindrical equidistant map projection 371U, 724R
CYLINDRICAL keyword 724R
cylindrical map projections 368U
Index D ... D
D
D keyword 882R, 965R
D_VALUE keyword 246R
dangling references 239B, 255B
DARK keyword 329R
data coordinates 285U
converting to other types 309R
data entry
compound widgets 276B
field widget 368R
DATA keyword 265O, 318O, 328O, 338O, 362O, 373O,
101R, 200R, 309R, 333R, 833R, 1201R
data picking 130O, 132O
example 132O
data types
64-bit
long 12B
unsigned long 12B
byte 12B
complex 13B
double-precision complex 13B
double-precision floating-point 13B
floating-point 13B
integer 12B
long integer 12B
string 13B
unsigned
integer 12B
long 12B
data, tabulated 444U
DATA_NAMES keyword 1027R
DATA_START keyword 899R
DATA_VALUES keyword 252O
DATA0 keyword 408O
DATA1 keyword 408O
DATA2 keyword 408O
DATA3 keyword 408O
DATANAME keyword 1342R
DATAX keyword 319O, 364O
DATAY keyword 319O
date
converting calendar to Julian 583R
converting from string to binary 219R
converting Julian to calendar 242R
displaying calendars 244R
labeling axes with 594R
returning current 1105R
DATE_FORMAT keyword 594R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
Daubechies wavelet filter 1348R
Davidon-Fletcher-Powell minimization 463U, 420R
day, returning current 1105R
DAYS_OF_WEEK keyword 209O
DBLARR function 394R
DCINDGEN function 395R
DCL interpreter symbols
defining 996R
deleting 411R
DCOMPLEX function 396R
DCOMPLEX keyword 561R, 705R
DCOMPLEXARR function 398R
DDE routines, see Obsolete Routines
deallocated memory, returning amount of 539R
debugging 27U, 138U, 31R, 229R
IDLDE for Macintosh 123U
IDLDE for Motif 48U
IDLDE for Windows 93U
Macintosh 119U
PROFILER prcedure 846R
decimal 14B
DECOMPOSED keyword 120R
decomposition
Cholesky 267R, 268R
LU 696R, 699R
singular value 1096R, 1103R
DECREASE keyword 987R, 990R
default button 1233R
default font 64O, 84O, 385O
DEFAULT keyword 246R, 788R
default visual class 172R
DEFAULT_BUTTON keyword 1233R
DEFAULT_CANCEL keyword 424R
DEFAULT_FONT keyword 1233R
DEFAULT_NO keyword 424R
DEFINE_KEY procedure 399R
defining
command or help path 462R
keys 399R
region of interest 407R
system variables 409R
defining method routines 261B
note for Windows 3.11 users 263B
DEFROI function 407R
DEFSYSV procedure 409R
DEGREES keyword 338R, 675R, 742R, 1132R, 1135R
Delaunay triangulation 1131R
DELAY keyword 436R
DELAY_DESTROY keyword 1233R
Index-15
DELETE keyword 784R
DELETE_CHARACTER keyword 403R
DELETE_COLUMNS keyword 1233R
DELETE_CURRENT keyword 403R
DELETE_EOL keyword 403R
DELETE_LINE keyword 403R
DELETE_ROWS keyword 1234R
DELETE_SYMBOL procedure 411R
DELETE_WORD keyword 403R
deleting
DCL interpreter symbols 411R
variables 413R
windows 1199R
DELIMITER keyword 383R, 899R
delimiters, string 258U, 17B
DELLOG procedure 412R
DELVAR procedure 413R
DEMI keyword 121R
DEMO keyword 680R
DEMO_MODE function 414R
density function 546R
DEPTH_CUE keyword 392O, 408O
DEPTH_Q keyword 850R
dereference operator, pointers 236B
DERIV function 415R
derived variables 472U
DERIVSIG function 416R
DESCENT keyword 222O, 233O, 347O, 419O, 430O
de-sensitizing widgets 1242R
destination device 134O
DESTINATION keyword 207O, 249O, 262O, 279O,
289O, 317O, 325O, 335O, 361O, 382O, 404O
Destination objects 31O
destination objects 134O
and color 59O
drawing to 134O
DESTROY keyword 300B, 1234R
destroying
widgets 300B, 1234R
windows 1199R
destroying objects 257B
DETACH keyword 1027R
DETERM function 460U, 417R
determinant of a square matrix 417R
deviation, mean absolute 736R
device
backing store 144R
CGM 148R
coordinates 286U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index D ... D
Index-16
Index
converting to other types 309R
cursor, controlling 395U
display channels 49R
flags 46R
font 124R
for graphics output 111R
graphics
independent 268B
output 111R
height 143R
HP-GL 150R
independent graphics 268B
LJ 151R
Macintosh (MAC) 154R
Microsoft Windows (WIN) 170R
monochrome 145R
name of 46R
Null 154R
number of color table indices 47R
number of colors 46R
offset 142R
PCL 154R
PostScript 156R
Printer 156R
Regis terminals 168R
resolution of 48R
size of display 48R
Tektronix 169R
width 142R
X Windows 171R
Z-buffer 178R
Device fonts 66R
device independent graphics 23O
DEVICE keyword 102R, 309R, 333R, 538R, 607R, 608R,
1201R
DEVICE procedure 111R, 419R
DF keyword 330R, 592R
DF24 keyword 533R
DFPMIN procedure 463U, 420R
DFR8 keyword 533R
DIAGONAL keyword 987R, 990R
DIALOG keyword 619R, 623R, 641R, 655R, 656R, 671R
DIALOG_MESSAGE function 423R
DIALOG_PARENT keyword 424R, 426R, 429R, 430R
DIALOG_PICKFILE function 426R
DIALOG_PRINTERSETUP function 277B, 430R
DIALOG_PRINTJOB 140O
DIALOG_PRINTJOB function 277B, 429R
DIALOG_PRINTSETUP 140O
Index D ... D
dialogs
file selection 277B
message 277B
message dialog box 423R
modal 423R
printing 277B
dialogs for printing 140O
dice widget 366R
dicer 354U, 1027R
DICOM 151O
DIFFEQ_23, see Obsolete Routines
DIFFEQ_45, see Obsolete Routines
differences among platforms
Macintosh 134U
Windows 112U
differentiation,CONVOL function 311R
digital dissolve effect 436R
digital filters 414U
Digital Imaging Communications in Medicine 151O
digital signal processing 398U
DIGITAL_FILTER function 414U, 423U, 431R
DILATE function 432R
dilation operator 432R
DIMENSION keyword 705R
DIMENSIONS keyword 223O, 226O, 234O, 242O,
265O, 298O, 346O, 393O, 420O, 432O, 437O,
613R, 623R, 626R, 641R, 649R, 656R, 666R, 1023R
DINDGEN function 435R
Direct Graphics 268B, 23O
clipboard support
Macintosh 120U
Windows 88U
font use 66R
direct manipulation of object graphics 130O
DIRECT_COLOR keyword 121R
DirectColor visuals 120R
direction
light source for shaded surface plots 994R
of grade 331U
DIRECTION keyword 209O, 282O
directories
changing 257R
main directory system variable 42R
popping 837R
printing 843R
pushing 861R
DIRECTORY keyword 426R, 441R
disappearing variables 142B
Discrete Fourier Transform 400U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
discrete wavelet transform 413U
DISP_TEXT, see Obsolete Routines
DISPLAY environment variable 23U
Display Headers table property 234U
DISPLAY keyword 432O
DISPLAY_NAME keyword 424R, 426R, 429R, 430R,
517R, 1207R
displaying images 381U, 1153R
flickering 485R
true-color 1154R
with intensity scaling 1164R
displaying text
ASCII files 1354R
in a graphics window 1379R
displays
graphics driver, Windows 113U
size 48R
DISSOLVE procedure 436R
DIST function 437R
distributing IDL applications 2B
DITHER keyword 280R, 908R
dithering 144R, 145R
Floyd-Steinberg 124R
ordered 129R
threshold 140R
division operator 271U, 29B
DLffDICOM
DumpElements method 156O
DLffDXF
GetPalette method 199O
DLM keyword 538R
DO statement 91B
DO_APPLE_SCRIPT procedure 438R
DOC_LIBRARY procedure 440R
document windows
IDLDE for Macintosh 119U
IDLDE for Windows 86U
documentation headers, extracting 440R
dollar sign 59R
Doppler frequency 1188R
DOTS keyword 1184R
DOUBLE function 442R
DOUBLE keyword 188R, 216R, 232R, 241R, 267R,
268R, 274R, 275R, 315R, 327R, 417R, 421R, 444R,
446R, 448R, 465R, 475R, 502R, 551R, 556R, 561R,
576R, 590R, 598R, 601R, 604R, 678R, 694R, 696R,
697R, 699R, 704R, 705R, 735R, 736R, 767R, 796R,
824R, 839R, 862R, 864R, 866R, 968R, 1025R,
1054R, 1056R, 1061R, 1063R, 1064R, 1067R,
Index-17
1069R, 1096R, 1099R, 1102R, 1123R, 1125R,
1140R, 1142R, 1143R, 1148R, 1149R, 1151R,
1179R, 1348R
double-clicks 1290R
double-precision
arrays, creating 394R, 435R
complex data type 13B
floating-point data type 13B
type, converting to 442R
DOWN keyword 333R
DOWNHILL keyword 331U, 252O, 303R
drag events
for floating-point slider widgets 377R
for RGB slider widgets 387R
for slider widgets 1291R, 1296R
in draw widgets 1234R, 1255R
DRAG keyword 377R, 387R, 1291R
Draw method 217O, 229O, 287O, 343O, 416O, 425O
draw widgets 273B, 294B, 135O, 1252R
attributes 229U
backing store 231U, 1260R
changing size 1234R, 1235R
color model 229U
colors used in 229U
events 232U
determining if set 1272R
returned by 1259R
returning 1234R
example application using 156U
graphics type 230U
motion events 1255R
mouse events 232U
mouse motion events 233U
obtaining window number of 1257R
properties 229U
renderer type 230U
returning events 1234R
scrolling 231U
scrolling area 231U
using 166U
view change events 233U
viewport move 233U
viewport, position 1236R, 1243R
DRAW_BUTTON_EVENTS keyword 1234R, 1272R
DRAW_DIMENSIONS keyword 613R, 626R, 649R,
666R
DRAW_EXPOSE_EVENTS keyword 1234R, 1272R
DRAW_INSTANCE keyword 218O, 426O
DRAW_MOTION_EVENTS keyword 1234R, 1272R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index D ... D
Index-18
Index
DRAW_VIEWPORT_EVENTS keyword 1234R, 1272R
DRAW_XSIZE keyword 1234R
DRAW_YSIZE keyword 1235R
DRAWABLE keyword 196R
drawing
arrows 200R
continents 708R
lines (PLOTS procedure) 809R
objects (ANNOTATE procedure) 196R
drawing to a printer object 140O
droplist widgets 274B, 1262R
events 224U
events returned by 1266R
initial value 224U
returning
current selection 1272R
number of elements 1272R
select event 225U
setting 1243R
setting attributes 224U
setting properties 224U
title 224U
using 165U
DROPLIST_NUMBER keyword 1272R
DROPLIST_SELECT keyword 1272R
DTOGFLOAT keyword 237R
DTOL keyword 523R
DTOVAX keyword 235R
DTOXDR keyword 235R
DXF object 188O
DXF_TYPE field 192O
dynamic memory, returning amount in use 539R
DYNAMIC_RESIZE keyword 306B, 1222R, 1235R,
1262R, 1272R, 1280R
dynamically loaded modules, keyword 538R
E
E_CONTINENTS keyword 726R
E_CONTOUR keyword 1015R
E_GRID keyword 726R
E_HORIZON keyword 726R
E_SURFACE keyword 1015R
earth,interpolating irregularly-sampled data over 1131R
edge detection,CONVOL function 311R
edge enhancement
ROBERTS function 969R
SOBEL function 1045R
EDGE_TRUNCATE keyword 312R, 1043R
Index E ... E
EDGE_WRAP keyword 312R
EDIT executive command See commands
EDIT keyword 377R
edit menu (online help) 243U
EDIT_CELL keyword 1235R
EDITABLE keyword 1235R, 1300R, 1310R
Editable table property 235U
Editable text property 216U
editor windows, IDLDE
Macintosh 119U
Motif 42U
Windows 87U
efficiency
constants 134B
if statements 131B
programming 124B
system functions and procedures 133B
vector and array operations 132B
EFONT procedure 443R
EIGEN_II see EIGENVEC
EIGEN_II, see Obsolete Routines
EIGENQL function 444U, 444R
eigenvalues 438U, 444R, 446R, 448R, 551R, 1140R
complex 440U
real 439U
repeated 441U, 443U
EIGENVALUES keyword 796R
EIGENVEC function 444U, 446R
eigenvectors 438U, 444R, 446R, 1140R
complex 440U
real 439U
repeated 443U
EIGENVECTORS keyword 444R
EIGHT keyword 596R
EIGHTBIT keyword 1001R
EJECT keyword 122R
electronic mail address, RSI 16U, 9B, 20O, 30R
elements, number of 764R
ELLIPSOID keyword 729R
ELMHES function 444U, 448R
EMBEDDED keyword 680R
EMPTY procedure 449R
emptying
file buffers 491R
graphics buffers 449R
ENABLE_FORMATTING keyword 385O, 672R
ENCAPSULATED keyword 122R, 1017R
encapsulated PostScript 160R
encapsulation 250B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
ENCODING keyword 123R
END statement 90B
END_OF_FILE keyword 403R
END_OF_LINE keyword 403R
end-of-file 450R, 1200R
ENTER_LINE keyword 403R
Entering Procedure Definitions 118B
environment variables
adding or changing 997R
DISPLAY 23U
HHLOCAL 245U
HOME 245U
IDL_ARRAY_MEMORY_SIZE 23U
IDL_DEVICE 22U
IDL_DIR 22U
IDL_DLM_PATH 22U
IDL_HELP_PATH 22U
IDL_PATH 22U
IDL_STARTUP 22U, 34U
LM_LICENSE_FILE 23U
PATH 20U
returning 520R
returning value of 519R
setting 520R
TERM 23U
UNIX 519R
used by IDL 22U
EOF function 157B, 450R
EPS keyword 421R, 465R, 502R, 863R, 865R, 867R
EPS machine-specific parameter 703R
EPSI files 130R
EPSNEG machine-specific parameter 703R
EPSTOP keyword 296R
EQ operator 277U, 35B
object references 259B
pointers 238B
EQUAL_VARIANCE, see Obsolete Routines
equal-area map projection 372U
equivalence strings 1145R, 1146R
Erase method 218O, 426O
ERASE procedure 451R
erasing IDL windows 451R
ERODE function 452R
erosion operator, morphologic 452R
ERROR keyword 280R, 424R, 613R, 619R, 623R, 626R,
630R, 641R, 645R, 650R, 655R, 656R, 666R, 672R,
784R
ERROR keyword
621R
Index-19
ERRORF function 455R
errors
default error-handling mechanism 142B
error bars 456R, 794R, 808R
error function(ERRORF) 455R
floating-point 427U
floating-point underflow 151B
handling 142B
CATCH procedure 143B, 255R
input/output 146B
ON_ERROR procedure 145B, 779R
ON_IOERROR procedure 780R
OPEN procedure 784R
input/output 146B
Macintosh 136U
math 151B
messages
generating (MESSAGE procedure) 745R
modal widget dialog 423R
returning text of 1082R
placing error status in variable 784R
signalling(MESSAGE procedure) 147B
system variables 149B
system variables for 149B
ERRPLOT procedure 456R
ESC keyword 1071R
ESCAPE keyword 403R
ESTIMATES keyword 511R
Euclidean norm 769R
EVEN keyword 738R
event driven programming 272B
EVENT_FUNC keyword 1207R, 1222R, 1235R, 1253R,
1262R, 1272R, 1285R, 1291R, 1300R, 1310R
EVENT_FUNCT keyword 355R, 358R
EVENT_HANDLER keyword 1364R
EVENT_PRO keyword 1207R, 1223R, 1235R, 1253R,
1262R, 1273R, 1285R, 1291R, 1300R, 1310R
events 237U
basic structure returned by all widgets 1270R
button press 215U
button release 1224R
clearing 1232R
common properties 199U
compound, handling 199U
destruction 200U
draw area mouse 232U
draw area mouse motion 233U
draw area view changes 233U
draw area widget 232U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index E ... E
Index-20
Index
draw viewport move 233U
droplist 224U
droplist select 225U
focus 210U
handling in IDL GUIBuilder code 159U, 181U,
182U, 185U, 191U
interrupting the event loop 311B
keyboard focus 311B
kill request 210U
listbox 227U
listbox selection 227U
post creation 201U
processing 1269R
realize 200U
release for buttons 214U
returned by
button widgets 1228R
draw widgets 1259R
droplist widgets 1266R
list widgets 1290R
slider widgets 1296R
text widgets 1314R
top-level base widgets 1221R
returning
base resize events 1216R
handler procedure name 1272R
keyboard focus events 1209R, 1301R, 1311R
sending to widgets 1242R
setting button 215U
slider 223U
slider change value 223U
table cell select 237U
table column width change 238U
table data invalid 239U
table focus 238U
table insert character 239U
table insert string 239U
table text delete 238U
table text selection 240U
text delete 218U
text focus 218U
text inserts 218U, 219U
text selection 219U
text widget 218U
timer 200U, 302B
top-level base kill events 1215R
tracking 200U
widget 287B
EXACT keyword 210O, 600R
Index E ... E
example 146O, 147O
example files
norm_coord.pro 53O
obj_axis.pro 75O
obj_logaxis.pro 76O
obj_plot.pro 100O
obj_tess.pro 71O
obj_vol.pro 122O
penta.pro 69O
rot_text.pro 84O
sel_obj.pro 131O
surf_track.pro 110O, 441O
test_surface.pro 53O
trackball_define.pro 55O
EXCELL keyword 1375R
exclamation point 58R, 79R
EXCLUSIVE keyword 355R, 1208R
EXECUTE function 129B, 252R, 253R, 254R, 458R
executive commands See commands, executive
EXFREQ keyword 331R
EXIT procedure 130B, 459R
exiting IDL 21U, 459R
EXP function 460R
EXPAND procedure 461R
EXPAND_PATH function 462R
EXPAND_TO_BYTES keyword 928R
EXPINT function 465R
explicitly formatted I/O 159B, 169B
exponential
integral 465R
natural 460R
random deviates 887R, 891R
EXPONENTIAL keyword 282R, 587R
exponentiation operator 271U, 29B
EXPOSE_EVENTS keyword 1253R
expressions
efficiency of evaluation 130B
returning information on 537R
structure of 278U, 280U, 37B, 38B
type of 278U, 37B
EXTEND keyword 210O
EXTENDED_LEGO keyword 364O
EXTENDSIZE keyword 788R
external
editors, Motif 80U
sharable object 245R
EXTRA keyword (keyword inheritance) 115B
EXTRA keyword (keyword inheritance) 114B
EXTRAC function 467R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
EXTRACT_SLICE function 469R
EXTRAPOLATE keyword 1128R, 1135R, 1197R
EXTRUSION field 192O
EYE keyword 393O
eye position 45O
F
F distribution 471R, 472R
F_CVF function 471R
F_PDF function 472R
F_TEST, see Obsolete Routines
F_TEST1, see Obsolete Routines
F_VALUE keyword 246R
F77_UNFORMATTED keyword 785R
FACT keyword 1382R, 1384R
FACTORIAL function 473R
false, definition of 103B
far clipping plane 47O
Fast Fourier Transform 400U
implementation 410U
Fast Fourier transform 474R
FFT function 423U, 474R
field
plots 488R, 806R
widget 368R
FIELDFONT keyword 368R
FILE keyword 307O, 273R, 426R, 441R, 685R, 754R,
1361R
File menu (online help) 243U
file units 162B
allocating 516R
returning information about 538R
See also logical unit numbers
setting file position pointer 813R
file, saving images to 118O
FILE_LUN keyword 1023R
FILE_UNIT keyword 1180R
FILENAME keyword 298O, 301O, 420O, 123R, 623R,
955R, 982R, 1352R
FILEPATH function 478R
files
CDF 1387R
closing 161B, 117R, 273R, 493R
displaying ASCII 1354R
end-of-file 211B, 1200R
file units, See file units
filenames 123R
Macintosh differences 134U
Index-21
Windows differences 113U
finding 426R, 480R
finding in IDL distribution 478R
flushing file units 210B
formats
BMP 228B
GIF 228B
Interfile 228B
JPEG 228B
NRIF 228B
PICT 228B
PNG 228B
PPM 228B
SRF 228B
TIFF 228B
X11 Bitmap 228B
XWD 228B
freeing logical unit numbers 493R
HDF 1388R
help and information 207B
IDL GUIBuilder
generated 159U
generating code 179U
generating resource 179U
IDL code 179U
regeneration 180U
resource 179U
indexed 221B
input/output 156B
locating 206B
logical unit number 162B
Macintosh path 44R
Macintosh-specific information 227B
manipulation operations 206B
Message-of-the-Day
IDLDE for Macintosh 134U
IDLDE for Windows 110U
modifying generated 159U
MPEG 119O
multiple structures 205B
netCDF 1389R
opening 160B, 783R
pointer position 210B
CUR_PTR keyword 495R
POINT_LUN procedure 813R
under Windows 114U
printing to 841R
reading
and writing,Windows 113U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index F ... F
Index-22
Index
ASCII data 898R
binary data from 933R
data 895R
unformatted binary data 933R
record-oriented 219B
returning information on open 537R
selecting 426R
selection dialogs 277B
size of 495R
skipping records 1026R
special functions (IOCTL function) 578R
specifying search path
IDLDE for Macintosh 132U, 133U
IDLDE for Motif 66U
IDLDE for Windows 109U
updating records (REWRITE keyword) 1344R
VMS-specific information 217B
Windows-specific information 226B
with indexed organization 896R
writing formatted output 841R
writing unformatted binary data 1344R
FILES keyword 207B, 538R
FILL keyword 252O, 303R, 1177R
FILL_COLOR keyword 273O
FILL_CONTINENTS keyword 708R
FILL_DIST system variable field 46R
FILL_PATTERN keyword 328O, 827R
FILLCONTOUR, see Obsolete Routines
filled contours 330U, 303R
filling
plotting symbols 1177R
polygons 298U, 826R, 829R
FILLVAL keyword 461R
FILTER keyword 426R
filtering
convolution 225R
digital filters 431R
digitial 431R
filenames 426R
frequency domain 474R
Hanning windows 529R
histogram equalization 544R
Lee filter algorithm 600R
mean 1043R
median 738R
morpholigic dilation 432R
morphologic erosion 452R
Roberts 969R
Sobel 1045R
Index F ... F
filters
bandpass 414U
bandstop 414U
boxcar 417U
digital 414U
highpass 414U
lowpass 414U
notch 419U
rectangular 417U
find tab (online help system) 249U
FIND_BY_UNAME keyword 182U, 1273R
FINDFILE function 157B, 206B, 480R
FINDGEN function 482R
Finding an appropriate view volume 47O
finding files 426R
finding text
IDLDE for Macintosh 122U
IDLDE for Motif 46U
IDLDE for Windows 92U
finite
impulse response filters 414U
numbers 483R
FINITE function 428U, 153B, 483R
FITA keyword 678R
FIX function 484R
FIX_FILTER keyword 426R
FIXED keyword 788R
fixed pixels 326U
FIXED_SIZE keyword 227R
FLAGS system variable field 46R
flashing colormaps 67U
FLICK procedure 485R
FLOAT function 486R
FLOAT keyword 561R, 705R, 1338R
Floating base property 204U
FLOATING keyword 368R, 1208R
floating point conversions 1404
floating-point
accuracy 427U
arithmetic 703R
arrays 482R, 490R
converting type to 486R
data type 13B
errors 151B
mantissa 703R
native format 235R
precision 703R
slider widgets 377R
underflow errors 151B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
XDR format 235R
floating-point format 1402
FLOOR function 487R
flow
control 142R
field, plotting 488R, 1182R
FLOW3 procedure 488R
FLOYD keyword 124R
FLTARR function 490R
FLUSH procedure 157B, 491R
focus events 311B, 1209R, 1239R, 1274R, 1301R, 1311R
FOCUS keyword 282O
folders, Macintosh 44R
FOLLOW keyword 320U, 304R
FONT keyword 273O, 385O, 102R, 124R, 355R, 368R,
383R, 1223R, 1280R, 1285R, 1292R, 1300R, 1310R,
1354R
font object 30O, 256O
FONT property of text objects 84O
modifiers 258O
font objects 64O
FONT system variable field 49R
FONT_INDEX keyword 124R
FONT_SIZE keyword 124R
FONTNAME keyword 672R
fonts
character sets 79R
default for widgets 1233R
device 66R
Direct Graphics 66R
displaying vector fonts 1017R
displaying X Windows fonts 1356R
editing 443R
examples of TrueType fonts 86R
examples of vector fonts 89R
finding current X windows font 124R
finding names of 124R
finding number of 125R
hardware 294U, 66R
Hershey 65R
Object Graphics 66R
outline 65R
positioning commands 81R
PostScript 853R
selecting 294U
specifying
IDLDE for Macintosh 129U, 131U
IDLDE for Motif 65U
IDLDE for Windows 109U
Index-23
TrueType 65R, 74R, 136R
vector 65R
FONTSIZE keyword 672R
FOR statement 91B, 96B
FORCE_DEMO keyword 680R
formal parameters 110B, 111B, 181O, 185R
Format Codes 173B
FORMAT keyword 74B, 75B, 298O, 377R, 841R, 896R,
931R, 1077R, 1236R, 1300R
FORMAT_AXIS_VALUES function 492R
formatted I/O 158B
forms, creating 371R
FORRD procedure seeREADU
FORRD, see Obsolete Routines
FORRD_KEY procedure seeREADU
FORRD_KEY, see Obsolete Routines
Fortran file formats 785R
FORTRAN keyword 789R
forward difference 1148R
FORWARD keyword 1151R
FORWARD_CHARACTER keyword 403R
FORWARD_FUNCTION statement 101B
FORWARD_WORD keyword 403R
FORWRT procedure seeWRITEU
FORWRT, see Obsolete Routines
FOUR_BITS keyword 1320R
four-dimensional displays 832R
Fourier transform 400U, 474R
Frame common property 197U
FRAME keyword 346R, 351R, 355R, 358R, 361R, 369R,
378R, 380R, 387R, 390R, 760R, 1208R, 1223R,
1254R, 1262R, 1281R, 1286R, 1292R, 1300R,
1310R, 1359R
FRAME_RATE keyword 299O
free format I/O 159B, 165B
FREE keyword 1317R
FREE_LUN procedure 157B, 273R, 493R
freeing pointers 242B
frequency response function 421U
FRIEDMAN, see Obsolete Routines
FROM_CYLIN keyword 338R
FROM_POLAR keyword 338R
FROM_RECT keyword 338R
FROM_SPHERE keyword 338R
FRONT_TYPE keyword 1201R
FSTAT function 157B, 207B, 494R
FSTAT structure 494R
FTOVAX keyword 235R
FTOXDR keyword 235R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index F ... F
Index-24
Index
FULL_PATH keyword 782R
FULL_TRANSLATION keyword 1146R
FULL_WINDOW keyword 1040R
FULSTR function 466U, 496R
FUNC_GET_VALUE keyword 1208R, 1223R, 1236R,
1254R, 1263R, 1281R, 1286R, 1292R, 1301R, 1310R
FUNCT procedure 497R
function definition statement 99B
function keys
defining 399R, 405R
for different keyboards 1000R
returning definitions 537R, 538R
FUNCTION keyword 608R
function methods
calling sequence for 180O
FUNCTION_NAME keyword 193R, 678R, 1099R
FUNCTION_VALUE keyword 194R
functions 29U, 119B
calling sequence for 184R
compiled 975R
defining 99B
definition statements 110B
displaying compiled 540R
forward definition 101B
FUNCTIONS keyword 975R
FV_TEST function 448U, 498R
FVALUE keyword 1132R
FX_ROOT function 462U, 500R
FZ_ROOTS function 462U, 502R
G
gamma correction 505R
GAMMA function 504R
gamma function 504R
incomplete 557R
logarithm of 682R
GAMMA keyword 304O, 306O, 887R, 891R
gamma random deviates 887R, 891R
GAMMA_CT procedure 505R
GAP keyword 273O
garbage collection 536R
GAUSS, see Obsolete Routines
GAUSS_CVF function 506R
GAUSS_PDF function 507R
GAUSS2DFIT function 508R
GAUSSFIT function 438U, 511R
Gaussian
distribution 506R, 507R
Index G ... G
elimination method 576R
integral 513R
iterated quadrature 449U, 563R, 566R
two-dimensional fit 508R
GAUSSINT function 513R
Gauss-Krueger map projection 369U, 725R
Gauss-Seidel iteration 525R
ge 39R
GE operator 277U, 35B
general perspective map projection 366U, 725R
general triangles 375O
GEOM keyword 250O
GEOMETRIC keyword 282R
GEOMETRY keyword 1273R
geometry of widgets 305B
GEOMX keyword 252O
GEOMY keyword 253O
GEOMZ keyword 253O
GEOTIFF keyword 921R, 1338R
GET keyword 388U, 1160R
Get method 184O
GET_BOUNDS.PRO 48O
GET_CURRENT_FONT keyword 124R
GET_DECOMPOSED keyword 124R
GET_DRAW_VIEW keyword 1236R
GET_FONTNAMES keyword 124R
GET_FONTNUM keyword 125R
GET_GRAPHICS_FUNCTION keyword 125R
GET_KBRD function 157B, 211B, 514R
GET_LUN keyword 785R
GET_LUN procedure 157B, 273R, 493R, 516R
GET_NAMES keyword 685R
GET_PATH keyword 427R
GET_SCREEN_SIZE function 517R
GET_SCREEN_SIZE keyword 308B, 125R
GET_SYMBOL function 518R
GET_TRANSLATION keyword 281R
GET_UVALUE keyword 1236R
GET_VALUE keyword 1237R
GET_VISUAL_DEPTH keyword 125R
GET_VISUAL_NAME keyword 125R
GET_WINDOW_POSITION keyword 126R
GET_WRITE_MASK keyword 126R
GetByName method 288O, 355O, 390O, 398O
GetContents method 190O
GetContiguousPixels method 219O, 230O, 344O, 427O
GetCTM method 206O, 248O, 261O, 279O, 289O,
316O, 325O, 335O, 360O, 381O, 404O
GetEntity mehod 192O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
GETENV function 519R, 520R
GetFontnames method 219O, 231O, 345O, 417O, 427O
GETHELP, see Obsolete Routines
GetPalette method 199O
GetProperty method 207O, 220O, 232O, 240O, 249O,
257O, 262O, 271O, 280O, 290O, 297O, 304O,
311O, 317O, 326O, 336O, 346O, 356O, 361O,
371O, 382O, 391O, 399O, 405O, 418O, 428O
GetRGB method 303O
GetTextDimensions method 221O, 232O, 347O, 418O,
429O
GFLOATTOD keyword 237R
GIF files
reading 904R
standard file format I/O routines 228B
writing 1322R
GIN_CHARS keyword 126R
GLINESTYLE keyword 711R, 726R
GLINETHICK keyword 711R, 726R
GLYPH_WIDTH keyword 273O
GNOMIC keyword 724R
gnomic map projection 363U, 724R
gnomonic map projection 363U, 724R
GO executive command See commands
GOMPERTZ keyword 282R
GOODFIT, see Obsolete Routines
GOTO statement 102B
GOURAUD keyword 994R
Gouraud shading 349U, 994R
GOUT keyword 1052R
grade, direction of 331U
GRAPHIC_PROPERTIES keyword 660R
graphics
clipboard support
Windows 88U
coordinate systems 285U, 335U
cursor positioning 332R
device independent graphics 23O
devices 268B, 23O, 111R
device independent graphics 268B
DEVICE procedure 419R
erasing 451R
returning information about current 538R
setting 992R
driver information, Windows 113U
functions
getting 125R
setting 137R
image file formats
Index-25
BMP 901R, 1320R
GIF 904R, 1322R
Interfile 906R
JPEG 907R, 1324R
NRIF 1327R
PICT 910R, 1328R
SRF 916R, 1333R
TIFF 921R, 1337R
X11 bitmap 928R
XWD 930R
keywords (collected) 99R
modes 268B, 23O
object-oriented 268B, 24O
printing 28U
two-dimensional arrays 318U
windows, IDLDE
backing store
Macintosh 130U
Motif 62U
Windows 106U
changing preferences
Macintosh 130U
Windows 106U
OS clipboard support
Macintosh 120U
Windows 88U
window layout
Macintosh 130U
Motif 43U, 61U
Windows 106U
graphics hierarchy 36O
graphics tree 36O
Graphics Type draw area property 230U
GRAPHICS_TIMES procedure 1120R
GRAPHICS_TREE keyword 223O, 234O, 348O, 420O,
432O
graphs 86O
graticule 360U
GRAY keyword 433R, 453R
GRAYSCALE keyword 908R
GREEN keyword 626R
GREEN_VALUES keyword 242O, 306O
GREYSCALE keyword 265O
grid
across a plot (TICKLEN keyword) 108R
for plots (TICKLEN keyword) 302U
GRID keyword 359U, 363U, 574R, 727R
Grid Layout base property 204U
GRID_LAYOUT keyword 1208R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index G ... G
Index-26
Index
GRID3 function 445U, 522R
gridding 1134R
and interpolation 444U
spherical 1052R, 1131R, 1134R
GRIDSTYLE keyword 210O
GRIDSTYLE system variable field 53R
GROUP keyword 202R, 427R, 443R, 662R, 1027R,
1040R, 1352R, 1354R, 1356R, 1359R, 1361R,
1369R, 1370R, 1371R, 1377R, 1378R
GROUP_LEADER keyword 1208R, 1223R, 1237R,
1254R, 1263R, 1281R, 1286R, 1292R, 1301R,
1310R, 1364R
growth trends 282R
GS keyword 588R, 1053R, 1129R
GS_ITER function 460U, 525R
GT operator 277U, 36B
guard digits 703R
GUIBuilder
generating files 89U
IDLDE windows 87U
GUIBuilder, See IDL GUIBuilder
H
H_EQ_CT function 527R
H_EQ_INT function 528R
halftoning 144R
halting program execution 1070R
HAMMER keyword 724R
Hammer-Aitoff map projection 366U, 724R
Hamming window 408U
HandiHelp 242U
Handle Events common event 199U
HANDLE_CREATE, see Obsolete Routines
HANDLE_FREE, see Obsolete Routines
HANDLE_INFO, see Obsolete Routines
HANDLE_MOVE, see Obsolete Routines
HANDLE_VALUE, see Obsolete Routines
HANNING function 423U, 529R
Hanning window 407U
hardware fonts 66R
HDF (Hierarchical Data Format) files 1388R
HDF_BROWSER function 530R
HDF_READ function 533R
HEADER keyword 899R
HEADER_DEFINE keyword 1320R
heap variables 230B, 254B
creating 231B, 857R
destroying 856R
Index H ... H
garbage collection 536R
leakage 239B, 255B
object 230B, 250B, 254B
pointer 233B
saving and restoring 232B
HEAP_GC procedure 536R
HEAP_VARIABLES keyword 538R
HEIGHT keyword 1354R
Height listbox property 226U
Height text property 216U
help
menu, online help viewer 246U
online 242U
ONLINE_HELP procedure 781R
HELP keyword 384R, 1223R
HELP procedure 252U, 157B, 537R
HELP_VM, see Obsolete Routines
Helper objects 31O, 38O
HELVETICA keyword 126R
Hershey fonts 65O, 65R
Hershey, Dr. A. V. 66R
Hessenberg array or matrix 448R, 551R
Hewlett-Packard Graphics Language, see HP-GL
hexadecimal 14B
HHLOCAL environment variable 245U
hidden line removal 106O
HIDDEN_LINES keyword 328O, 364O
HIDE keyword 210O, 242O, 253O, 265O, 274O, 282O,
291O, 319O, 328O, 338O, 364O, 385O, 400O,
409O, 641R, 657R, 672R, 1157R
hiding cursor 1157R
hierarchy 36O
HIFAC keyword 683R
highpass filters 414U
high-resolution continent outlines 377U
HILBERT function 423U, 541R
Hilbert transform 411U
HINTS keyword 409O
HIRES keyword 377U, 708R, 727R
HIST_2D function 542R
HIST_EQUAL function 544R
histogram
equalization
H_EQ_CT function 527R
interactive (H_EQ_INT function) 528R
plot 399U
plotting mode 297U, 105R
HISTOGRAM function 546R
HISTOGRAM keyword 319O, 650R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
HLS color system 277R, 387R, 1159R
HLS keyword 388U, 388R, 1160R
HLS procedure 391U, 550R
HLS_RGB keyword 277R
home directory
IDLDE for Macintosh 132U
IDLDE for Motif 66U
IDLDE for Windows 107U
HOME environment variable 245U
homogeneous coordinates 334U
HORIZON keyword 727R
HORIZONTAL keyword 1091R
horizontal slider, See slider widgets
HOTSPOT keyword 438O
hourglass cursor 301B
(for widgets) 1238R
saving 1269R
HOURGLASS keyword 301B, 1238R
Householder
method 1142R
reductions 444R
HP9000 keyword 1001R
HP-GL
driver 150R
files 146R
HQR function 444U, 551R
HSIZE keyword 200R
HSV color system 277R, 387R, 1159R
HSV keyword 388U, 388R, 1160R
HSV procedure 391U, 553R
HSV_RGB keyword 277R
HSV_TO_R, see Obsolete Routines
HTHICK keyword 200R
HTML 250U, 251U, 751R
HTONL keyword 236R
HTONS keywords 236R
hyperbolic
cosine 318R
sine 1021R
tangent 1113R
HYPERBOLIC keyword 283R
HyperHelp 250U
HyperText Markup Language 250U, 251U, 751R
hypothesis testing 446U
Chi-square model validation 1375R
contingency test for independence 330R
F-variances test 498R
Kruskal-Wallis H-test 591R
Lomb frequency test 683R
Index-27
Mann-Whitney U-test 977R
median delta test 733R
normality test 498R, 1121R
runs test for randomness 884R
sign test 980R
t-means test 1121R
Wilcoxon rank-sum test 977R
I
I/O, see input/output
I_VALUE keyword 247R
IBETA function 554R
IBETA machine-specific parameter 703R
IBM keyword 1001R
ICONIC keyword 1347R
ICONIFY keyword 1238R
Iconify method 430O
iconifying
widgets 1238R
windows 1347R
iconifying windows 137O
icons, editing 1352R
IDENTITY function 460U, 556R
IDL
applications,distributing 2B
Code Profiler 141U
Development Environment (IDLDE)
Macintosh 118U
Motif 40U
Windows 84U
Direct Graphics 268B, 23O
for Macintosh 154R
for Windows 170R
Object Graphics 268B, 23O
online help 242U
pointers 233B
runtime licensing 2B
statements 84B
IDL documentation 15O
IDL GUIBuilder 150U
# of Rows/Columns property 202U
Alignment label property 221U
Alignment property 203U, 213U
Alignment table property 234U
Allowing Closing property 203U
Allowing Moving property 204U
base widget attributes 202U
base widget events 210U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index I ... I
Index-28
Index
base widget properties 202U
base widgets, using 165U
Bitmap Editor 174U
Bitmap property 213U
button attributes 213U
button widgets, using 165U
buttons, adding bitmaps 174U
buttons, adding menus 173U
checkbox attributes 213U
checkbox widgets, using 165U
checkboxes, creating 212U
Color Model draw area property 229U
color table example 161U
Colors draw area property 229U
Column Labels table property 234U
common events 199U
compiling and running example 162U
Component Sizing property 197U
copying or cutting widgets 177U
creating draw area, example 156U
creating multiple checkboxes 212U
creating multiple radio buttons 212U
defining menus, example 153U
deleting widgets 178U
Display Headers table property 234U
draw area events 232U
draw widget properties 229U
draw widgets, using 166U
droplist attributes 224U
droplist events 224U
droplist properties 224U
droplists, using 165U
Editable table property 235U
Editable text property 216U
event code, example 191U
event code, handling example 182U
event code, integrating interfaces 185U
event code, understanding 181U
example application 153U
files, generating multiple times 180U
files, IDL code 179U
files, portable resource 179U
Floating property 204U
Frame property 197U
generating code 159U, 179U
generating resource files 179U
Graphics Type draw area property 230U
Grid layout property 204U
Handle Events common event 199U
Index I ... I
Height listbox property 226U
Height text property 216U
horizontal slider, using 165U
Initial Value droplist property 224U
Initial Value listbox property 226U
Initial Value text property 216U
integrating multiple interfaces 185U
Label property 214U
label widget attributes 221U
label widget properties 221U
label widgets, using 165U
Layout property 205U
listbox attributes 226U
listbox events 227U
listbox properties 226U
listbox widgets, using 165U
Maximum Value slider property 222U
menus, editing 171U
Minimize/Maximize property 206U
Minimum Value slider property 222U
Modal property 206U
modifying code, example 159U
moving widgets 177U
Multiple listbox property 226U
Name property 196U
No Release property 214U
OnButton draw area event 232U
OnButton Press event property 215U
OnCellSelect table event 237U
OnChangeValue slider event 223U
OnColWidth table event 238U
OnDelete table event 238U
OnDelete text event 218U
OnDestroy event property 200U
OnExpose draw area event 233U
OnFocus event property 210U
OnFocus table event 238U
OnFocus text event 218U
OnInsertCh text event 218U
OnInsertChar table event 239U
OnInsertString table event 239U
OnInsertString text event 219U
OnInvalidData table event 239U
OnKillRequest event property 210U
OnMotion draw area event 233U
OnRealize event property 200U
OnSelectValue droplist event 225U
OnSelectValue listbox event 227U
OnSizeChange event property 210U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
OnTextSelect table event 240U
OnTextSelect text event 219U
OnTimer event property 200U
OnTracking event property 200U
OnViewportMoved draw area event 233U
operating on widgets 176U
parent base, changing for widget 177U
pasting widgets 177U
Position slider property 222U
PostCreation event property 201U
Properties dialog 166U
radio button attributes 213U
radio button widgets, using 165U
radio buttons, creating 212U
redoing operations 178U
Renderer draw area property 230U
Resize Columns table property 235U
resizing widgets 177U
Retain draw area property 231U
Row Labels table property 236U
Row/Column Major table property 235U
Scroll draw area property 231U
Scroll property 206U
Scroll table property 236U
Scroll text property 217U
selecting widgets 176U
Sensitive property 198U
setting button events 215U
setting button properties 212U
setting text widget attributes 216U
setting text widget events 218U
slider events 223U
slider properties 222U
smooth example 161U
Space property 207U
starting 151U
Suppress Value slider property 222U
System Menu property 207U
table events 237U
table widget attributes 234U
table widget properties 234U
table widgets, using 166U
test mode 158U
Text label property 221U
text widgets properties 216U
text widgets, using 165U
Title Bar property 208U
Title droplist property 224U
Title property 207U
Index-29
Title slider property 223U
toolbar 164U
tools 164U
Type property 214U
undoing operations 178U
vertical slider, using 165U
Viewport Columns table property 236U
Viewport Rows table property 237U
Visible property 208U
Widget Browser 191U
Widget Browser, using 169U
widgets, changing parent base of 177U
widgets, cutting, copying or pasting 177U
widgets, deleting 178U
widgets, moving 177U
widgets, resizing 177U
widgets, selecting 176U
Width listbox property 227U
Width text property 217U
Word Wrapping text property 217U
writing event-handling code 159U
X Offset property 198U
X Pad property 208U
X Scroll draw area property 231U
X Scroll property 209U
X Size property 198U
Y Offset property 198U
Y Pad property 209U
Y Scroll draw area property 231U
Y Scroll property 209U
Y Size property 199U
IDL object overview 250B
IDL objects 255B
IDL_ARRAY_MEMORY_SIZE locg 23U
IDL_ARRAY_MEMORY_SIZE logical name 23U
IDL_Container
Add method 182O
class 182O
Cleanup method 183O
Count method 184O
Get method 184O
Init method 185O, 200O
IsContained method 186O
Move method 186O
Remove method 187O
IDL_DEVICE environment variable 22U
IDL_DIR environment variable 22U
IDL_DLM_PATH environment variable 22U
IDL_FONT keyword 220O, 231O, 345O, 417O, 428O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index I ... I
Index-30
Index
IDL_HELP_PATH environment variable 22U
IDL_PATH environment variable 22U
IDL_STARTUP environment variable 22U, 34U
IDL_TREE example routine 248B
IDLDE windows
Editor
Macintosh 119U
Motif 42U
Windows 87U
Graphics
Macintosh 130U
Motif 43U
Windows 106U
GUIBulder 87U
IDLffDICOM
Cleanup method 155O
GetChildren method 157O
GetDescription method 158O
GetElement method 160O
GetGroup method 162O
GetLength method 163O
GetParent method 164O
GetPreamble method 165O
GetReference method 166O
GetValue method 168O
GetVR method 171O
Init method 172O
Read method 173O
IDLffDXF 188O
Cleanup method 189O
GetContents method 190O
GetEntity method 192O
Init method 200O
PutEntity method 200O
Read method 201O
RemoveEntity method 202O
Reset method 202O
SetPalette method 202O
Write method 203O
IDLgrAxis
class 29O, 205O
Cleanup method 206O
GetCTM method 206O
GetProperty method 207O
Init method 208O
SetProperty method 214O
IDLgrBuffer
class 32O
Cleanup method 217O
Index I ... I
Draw method 217O
Erase method 218O
GetFontnames method 219O, 231O, 345O, 417O,
427O
GetProperty method 220O
GetTextDimensions method 221O
Init method 222O
Pickdata method 224O
Read method 225O
Select method 226O
SetProperty method 227O
IDLgrBuffer class 216O
IDLgrClipboard
class 32O
Cleanup method 229O
Draw method 229O
GetContiguousPixels method 230O
GetProperty method 232O
GetTextDimensions method 232O
Init method 233O
Pickdata method 235O
IDLgrClipboard object 228O
IDLgrColorbar
class 30O, 238O
Cleanup method 238O
ComputeDimensions method 239O
GetProperty method 240O
Init method 241O
SetProperty method 245O
IDLgrColorbar object 238O
IDLgrContour
class 29O
Cleanup method 248O
GetCTM method 248O
GetProperty method 249O
Init method 250O
SetProperty method 255O
IDLgrContour object 247O
IDLgrFont
class 30O, 256O
Cleanup method 256O
GetProperty method 257O
Init method 257O
SetProperty method 259O
IDLgrImage
class 29O, 260O
Cleanup method 261O
GetCTM method 261O
GetProperty method 262O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
Init method 263O
SetProperty method 268O
IDLgrLegend
class 30O
Cleanup method 270O
ComputeDimensions method 270O
GetProperty method 271O
Init method 272O
SetProperty method 276O
IDLgrLight
class 29O, 278O
Cleanup method 278O
GetCTM method 279O
GetProperty method 280O
Init method 281O
SetProperty method 284O
IDLgrModel
Add method 286O
class 28O, 285O
Cleanup method 286O
Draw method 287O
GetByName method 288O
GetCTM method 289O
GetProperty method 290O
Init method 290O
Remove method 292O
Reset method 293O
Rotate method 293O
Scale method 294O
SetProperty method 294O
Translate method 295O
IDLgrMPEG
class 32O
Cleanup method 296O
GetProperty method 297O
Init method 298O
Put method 300O
Save method 300O
SetProperty method 301O
IDLgrMPEG object 296O
IDLgrPalette
class 31O, 302O
Cleanup method 302O
GetProperty method 304O
GetRGB method 303O
Init method 305O
LoadCT method 306O
NearestColor method 307O
SetProperty method 308O
Index-31
SetRGB method 308O
IDLgrPattern
class 31O, 310O
Cleanup method 310O
GetProperty method 311O
Init method 312O
SetProperty method 313O
IDLgrPlot
class 29O, 315O
Cleanup method 316O
GetCTM method 316O
GetProperty method 317O
Init method 318O
SetProperty method 322O
IDLgrPolygon
class 29O, 324O
Cleanup method 324O
GetCTM method 325O
GetProperty method 326O
Init method 327O
SetProperty method 333O
IDLgrPolygon objects 92O
IDLgrPolyline
class 29O, 334O
Cleanup method 334O
GetCTM method 335O
GetProperty method 336O
Init method 337O
SetProperty method 341O
IDLgrPrinter
class 32O, 342O
Cleanup method 343O
Draw method 343O
GetContiguousPixels method 344O
GetProperty method 346O
GetTextDimensions method 347O
Init method 347O
NewDocument method 350O
NewPage method 350O
Pickdata method 351O
SetProperty method 352O
IDLgrScene
Add method 354O
class 28O, 353O
Cleanup method 354O
GetByName method 355O
GetProperty method 356O
Init method 356O
Remove method 357O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index I ... I
Index-32
Index
SetProperty method 358O
IDLgrSurface
class 30O, 359O
Cleanup method 360O
GetCTM method 360O
GetProperty method 361O
Init method 362O
SetProperty method 368O
IDLgrSymbol
class 31O, 370O
Cleanup method 370O
GetProperty method 371O
Init method 372O
SetProperty method 373O
IDLgrTessellator
AddPolygon method 376O
class 31O, 375O
Cleanup method 377O
Init method 377O
Reset method 378O
Tessellate method 378O
IDLgrText
class 30O, 380O
Cleanup method 381O
GetCTM method 381O
GetProperty method 382O
Init method 383O
SetProperty method 387O
IDLgrView
Add method 389O
class 28O, 388O
GetByName method 390O
GetProperty method 391O
Init method 391O
Remove method 394O
SetProperty method 395O
IDLgrViewgroup
Add method 397O
class 28O
Cleanup method 397O
GetByName method 398O
GetProperty method 399O
Init method 399O
Remove method 400O
SetProperty method 401O
IDLgrViewgroup object 396O
IDLgrVolume
class 30O, 402O
Cleanup method 402O
Index I ... I
ComputeBounds method 403O
GetCTM method 404O
GetProperty method 405O
Init method 406O
PickVoxel method 412O
SetProperty method 413O
IDLgrVRML
class 32O
Draw method 416O
GetProperty method 418O
GetTextDimensions method 418O
Init method 419O
Pickdata method 421O
SetProperty method 422O
IDLgrVRML object 414O
IDLgrWindow
class 32O, 424O
Cleanup method 425O
Draw method 425O
Erase method 426O
GetContiguousPixels method 219O, 427O
GetProperty method 428O
GetTextDimensions method 429O
Iconify method 430O
Init method 431O
maximum size 136O, 424O
Pickdata method 434O
Read method 435O
Select method 436O
SetCurrentCursor method 437O
SetProperty method 438O, 439O
IDS keyword 355R, 374R, 384R
IEEE floating point 1402
IEEE standard 256U, 152B, 153B
IEXP machine-specific parameter 703R
IF statement 102B
avoiding 131B
IGAMMA function 557R
IHDR keyword 1320R
IIDLffDICOM
Reset method 174O
IMAGE keyword 438O, 346R, 760R, 1005R, 1009R,
1359R
image object 29O, 260O
image objects 114O
alpha blending 115O
creating 114O
interleaving 116O
palettes 116O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
saving to a file 118O
saving to an MPEG file 119O
using 115O
image processing 429U
IMAGE_CONT procedure 324U, 559R
IMAGE_COORD keyword 827R
IMAGE_DATA keyword 221O, 429O
IMAGE_INDEX keyword 880R, 923R
IMAGE_INTERP keyword 827R
IMAGE_SIZE keyword 362R
images 260O
annotating 196R
bi-level 1118R
color channel 265O
combining with 3D graphics 347U
copying areas 118R
defining region of interest 407R
displaying 381U, 390R, 485R, 1040R, 1153R,
1157R, 1159R, 1161R, 1164R
displaying with intensity scaling 1164R
displaying, Macintosh 130U
dissolve effect 436R
image manipulation compound widgets 276B
JPEG 907R
magnified 1382R, 1384R
monochrome 145R
MPEG files 757R, 758R, 760R, 762R
orientation 382U
overlaying with contour plots 324U
overview 380U
position in display 382U
processing 380U
profiling 844R, 848R
raster 380U
reading from display 385U, 395U, 1161R
region labeling 596R
Roberts edge enhancement 969R
rotating 972R
routines 380U
scaling 384U
searching for objects 986R
sharing data 267O
size of display 383U
smoothing 1043R
Sobel edge enhancement 1045R
thinning 1118R
transfer direction 48R
true-color 1162R
warping 820R
Index-33
warping to maps 715R, 718R
with surface and contour plots 1015R
zooming 390R
IMAGINARY function 560R
imaginary part of complex numbers 560R
implicit self argument 262B
INCHES keyword 126R, 1154R, 1157R
include files 29U
incomplete
beta function 554R
gamma function 557R
INCREASE keyword 987R, 990R
incrementing array elements 548R
INDEPENDENT keyword 645R, 650R
INDEX keyword 199O, 202O, 705R
index tab (online help system) 248U
INDEX_COLOR keyword 126R
Indexed color model 58O
INDEXED_COLOR keyword 613R, 626R, 650R, 666R
INDGEN function 561R
infinite impulse response filters 414U
Infinity norm 460U, 769R
infinity, undefined result 152B
information about objects 259B
INFORMATION keyword 424R
INFORMATIONAL keyword 745R
Informational Routines 124B
inheritance 253B
object 251B
INIT keyword 227R
Init method 185O, 200O, 208O, 222O, 233O, 241O,
250O, 257O, 263O, 272O, 281O, 290O, 298O,
305O, 312O, 318O, 327O, 337O, 347O, 356O,
362O, 372O, 377O, 383O, 391O, 399O, 406O,
419O, 431O, 442O
Initial Value droplist property 224U
Initial Value listbox property 226U
Initial Value text property 216U
initialization of objects 33O
INITIALSIZE keyword 789R
inner products (computing) 430U
INP, see Obsolete Routines
INPUT keyword 547R, 1135R
input/output
associated 202B
associated variables 204R
bitmap files 901R
BMP files 1320R
CDF 1387R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index I ... I
Index-34
Index
closing files 273R
emptying buffers 449R, 491R
end of file mark 1200R
error handling 146B
errors 780R
explicit format 159B, 169B
format codes 173B
format reversion 172B
formatted 158B, 841R
free format 159B, 165B
GIF files 904R, 1322R
HDF 1388R
Interfile files 906R
JPEG files 907R, 1324R
magnetic tape 224B
netCDF 1389R
NRIF files 1327R
opening files 783R
PGM files 913R, 1331R
PICT files 910R, 1328R
portable 197B
PPM files 913R, 1331R
reading
ASCII files 898R
formatted data 895R
formatted data from a string 931R
from a prompt 896R
from tape unit 1114R
unformatted binary data 933R
SRF files 916R, 1333R
TIFF files 921R, 1337R
unformatted 158B, 191B
portable 197B
string variables 192B
UNIX FORTRAN unformatted data files 206B
updating records (REWRITE keyword) 1344R
wave files 926R, 1342R
writing
to tape unit 1115R
unformatted binary data 1344R
X11 Bitmaps 928R
XDR 198B
XWD files 930R
INPUT_FOCUS keyword 1238R
INSERT_COLUMNS keyword 1238R
INSERT_OVERSTRIKE_TOGGLE keyword 403R
INSERT_ROWS keyword 1238R
instance
object 250B
Index I ... I
Instancing 149O
instancing 137O, 149O
INSTANCING keyword 613R, 626R, 650R, 666R
INT keyword 705R
INT_2D function 450U, 453U, 563R
INT_3D function 450U, 453U, 566R
INT_TABULATED function 453U, 568R
INTARR function 570R
integer 484R
arrays 561R, 570R
constants 257U, 15B
conversions, errors in 154B
data type 12B
data type, converting to 484R
INTEGER keyword 369R
integration 449U
bivariate functions 450U
INT_2D 563R
INT_3D 566R
INT_TABULATED 568R
QROMB 862R
QROMO 864R
QSIMP 866R
RK4 967R
tabulated functions 568R
trivariate functions 451U
univariate functions 862R, 864R, 866R
INTENSITY keyword 282O, 505R
interactive graphics 137O
instancing 137O
Interactive Support 242U
Interactive Surface Example 110O
INTERCHANGES keyword 696R
Interfile files
reading 906R
standard file format I/O routines 228B
INTERIOR keyword 376O
INTERLACED keyword 299O
INTERLEAVE keyword 266O
interleaving (image objects) 114O
INTERP keyword 292R, 559R, 970R, 1015R, 1382R
INTERPOL function 445U, 571R
INTERPOLATE function 445U, 573R
INTERPOLATE keyword 409O, 993R, 1193R
interpolating
function 445U
interpolation 444U, 573R
bilinear 217R, 935R
cubic convolution 573R, 821R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
cubic spline 1054R, 1058R, 1059R
INTERPOL 571R
irregularly-gridded data 1134R
irregularly-sampled data over earth 1131R
KRIG2D 586R
linear 571R
MIN_CURVE_SURF 748R
of irregularly-gridded data 586R, 748R
POLAR_SURFACE 817R
quintic 1136R
spherical 1052R
SPL_INIT 1054R
SPL_INTERP 1056R
interpolation of voxel values 127O
interpreter symbols, DCL
defining 996R
deleting 411R
returning values 518R
interrupting program execution 30U
INTERVAL keyword 811R, 1059R, 1202R
invalid widget ID’s 1268R
inverse
cosine 190R
of a complex array or matrix 694R
sine 203R
subspace iteration 446R
tangent 206R
INVERSE keyword 475R, 694R, 1348R
INVERT function 460U, 576R
IOCTL function 578R
IOERROR keyword 745R
IRND machine-specific parameter 703R
IRREGULAR keyword 304R
irregularly-gridded data 1131R, 1134R
ISA keyword 185O
IsContained method 186O
ISHFT function 581R
ISO Latin 1 encoding 68R
ISOLATIN1 keyword 127R
isosurfaces, displaying 351U, 1010R
ISOTROPIC keyword 360U, 304R, 729R, 800R
ISSUE_ERROR keyword 1146R
IT machine-specific parameter 703R
ITALIC keyword 127R
ITEM_COLOR keyword 274O
ITEM_LINESTYLE keyword 274O
ITEM_NAME keyword 274O
ITEM_OBJECT keyword 274O
ITEM_THICK keyword 274O
Index-35
ITEM_TYPE keyword 275O
ITER keyword 421R, 602R, 678R, 839R
iterative
biconjugate gradient 601R
Gaussian quadrature 563R, 566R
improvement of a solution 697R
ITMAX keyword 232R, 421R, 446R, 465R, 602R, 678R,
768R, 839R
ITOL keyword 601R
J
JFIF, see JPEG
JMAX keyword 683R, 863R, 865R, 867R
JOIN, see Obsolete Routines
JOURNAL procedure 35U, 582R
journaling 35U
JPEG files
reading 907R
standard file format I/O routines 228B
writing 1324R
JULDAY function 583R
Julian date
converting from calendar 583R
converting to calendar 242R
JUST_REG keyword 1364R
K
K keyword 863R, 865R
Kaiser filter 414U
KBRD_FOCUS_EVENTS keyword 1209R, 1239R,
1274R, 1301R, 1311R
KEEP keyword 1382R
KEEP_PIXMAPS keyword 1359R
KENDALL keyword 882R
Kendall’s tau rank correlation 882R
kernel, convolving an array with 311R
KEY_ID keyword 896R, 934R
KEY_MATCH keyword 896R, 934R
KEY_VALUE keyword 896R, 934R
keyboard
defining keys 399R
focus events 311B, 1209R, 1239R, 1274R, 1301R,
1311R
numeric keypads 1001R
returning characters from 514R
shortcuts
IDLDE for Motif 55U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index J ... K
Index-36
Index
IDLDE for Windows 100U
KEYED keyword 789R
KEYS keyword 538R
keys, defining for different keyboards 1000R
KEYWORD_SET function 124B, 125B, 585R
keywords
arguments,checking existence of 198R
described 181O, 185R
graphics 99R
identifying as set 585R
inheritance 114B
meaning of slash character 181O, 185R
parameters 111B
passing 113B
searching 781R
setting 111B, 181O, 185R
KEYWORDS keyword 608R
KILL_ANYWAY keyword 345R
KILL_NOTIFY keyword 1209R, 1223R, 1239R, 1254R,
1263R, 1281R, 1286R, 1292R, 1301R, 1311R
killing widgets 300B
KMEANS, see Obsolete Routines
KRIG2D function 445U, 586R
kriging 445U, 586R
KRUSKAL_WALLIS, see Obsolete Routines
Kruskal-Wallis H-Test 591R
kurtosis 590R, 755R
KURTOSIS function 590R
KW_TEST function 448U, 476U, 591R
KX keyword 1002R
L
L64 keyword 561R
L64_VALUE keyword 247R
L64INDGEN function 593R
L64SWAP keyword 236R
Label button property 214U
LABEL keyword 351R, 358R, 711R, 727R
label widgets 274B, 1280R
attributes, setting 221U
setting properties 221U
using 165U
LABEL_DATE function 594R
LABEL_LEFT keyword 355R
LABEL_REGION function 596R
LABEL_TOP keyword 355R
labeling regions 596R
Index L ... L
LADFIT function 438U, 598R
lagged
autocorrelation 187R
cross correlation 241R
Laguerre’s method 502R
LAMBERT keyword 724R
Lambert’s conformal conic map projection 371U, 724R
Lambert’s equal-area map projection 365U, 724R
LANDSCAPE keyword 348O, 127R
landscape orientation 159R
for IDL plots (LANDSCAPE keyword) 127R
laser printers 157R
LAST_MESSAGE keyword 538R
LAT0 keyword 719R
LAT1 keyword 719R
LATALIGN keyword 711R, 727R
LATDEL keyword 363U, 712R, 727R
LATLAB keyword 712R, 727R
LATLON, see Obsolete Routines
LATMAX keyword 716R
LATMIN keyword 716R
LATNAMES keyword 712R
LATS keyword 712R
LAYER field 192O
LAYER keyword 192O, 199O
Layout base property 205U
LE operator 277U, 36B
leakage (in freqency plots) 405U
least absolute deviation 438U, 598R
least squares fit 437U, 438U, 335R, 511R, 824R, 831R,
1098R
LEEFILT function 600R
legend object 30O
legend objects 97O
LEGEND_PROPERTIES keyword 662R
LEGENDRE keyword 1099R
LEGO keyword 1091R
LEGO, see Obsolete Routines
LEN keyword 488R
LENGTH keyword 388R, 766R, 806R, 1182R, 1184R
length of strings 1080R
LEVELS keyword 328U, 304R
license manager 414R
lifecycle
methods 255B
routines 255B
LIGHT keyword 127R, 994R
light object 29O, 278O
light objects 104O, 107O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
creating 108O
types of lights 108O
using 108O
light source 278O
changing parameters of 350U
shading 349U, 994R
lighting 126O, 149O
LIGHTING keyword 291O
LIGHTING_MODEL keyword 410O
LIMIT keyword 360U, 729R
LIMSER keyword 296R
LINBCG function 466U, 601R
LINDGEN function 603R
line
drawing
method for contours 300R
PLOTS procedure 809R
editing 24U
enabling and disabling 42R
interval 46R
styles 103R
LINE keyword 650R
LINE_FILL keyword 827R
linear
algebra, See linear algebra 431U
correlation 431U
interpolation 573R
linear-log plots 801R
regression 438U, 947R
systems 453U
overdetermined 454U
underdetermined 456U
linear algebra
CHOLDC 267R
CHOLSOL 268R
COND 290R
CRAMER 319R
DETERM 417R
EIGENVEC 446R
ELMHES 448R
GS_ITER 525R
HQR 551R
INVERT 576R
LINBCG 601R
LU_COMPLEX 694R
LUDC 696R
LUMPROVE 697R
LUSOL 699R
NORM 769R
Index-37
SVDC 1096R
SVSOL 1102R
TRIQL 1140R
TRIRED 1142R
TRISOL 1143R
LINEAR keyword 1128R
LINESTYLE field 192O
LINESTYLE keyword 319O, 329O, 338O, 364O, 102R,
641R, 657R
LINESTYLE system variable field 49R
linestyles, table of 103R
LINFIT function 438U, 604R
linked lists 242B
using pointers to create 242B
LINKIMAGE 1404
LINKIMAGE procedure 245R, 606R
LIST keyword 789R
list widgets 274B, 1285R
determining
currently selected element
LIST_SELECT keyword 1274R
topmost element
LIST_TOP keyword 1274R
double-clicks 1290R
events returned by 1290R
number 1274R
selecting multiple items 1274R, 1286R
setting 1243R
LIST_NUM_VISIBLE keyword 1274R
LIST_NUMBER keyword 1274R
LIST_SELECT keyword 1274R
LIST_TOP keyword 1274R
listbox widgets
attributes 226U
events 227U
initial value 226U
multiple selections, allowing 226U
selection events 227U
setting height 226U
setting properties 226U
using 165U
width 227U
LISTREP, see Obsolete Routines
LISTWISE, see Obsolete Routines
little endian byte ordering 1104R
LIVE_CONTOUR procedure 612R
LIVE_CONTROL procedure 619R
LIVE_DESTROY procedure 621R
LIVE_EXPORT procedure 623R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index L ... L
Index-38
Index
LIVE_IMAGE procedure 625R
LIVE_INFO procedure 630R
LIVE_LINE procedure 640R
LIVE_LOAD procedure 644R
LIVE_OPLOT procedure 645R
LIVE_PLOT procedure 649R
LIVE_PRINT procedure 655R
LIVE_RECT procedure 656R
LIVE_STYLE procedure 659R
LIVE_SURFACE procedure 665R
LIVE_TEXT procedure 671R
LJ device
color tables for 674R
LJ driver 151R
LJLCT procedure 674R
LL_ARC_DISTANCE function 675R
LM_LICENSE_FILE environment variable 23U
LMFIT function 677R
LMGR function 680R
LMHOSTID keyword 681R
LN03, see Obsolete Routines
LNGAMMA function 682R
LNP_TEST function 448U, 683R
LOAD_FILE keyword 197R
LoadCT method 306O
LOADCT procedure 389U, 685R
loading color tables 1159R
LOCATION keyword 210O, 266O, 282O, 393O, 432O,
613R, 626R, 641R, 650R, 657R, 666R, 672R
location of graphics 42O
location of text 81O
location of widgets 306B
LOCATIONS keyword 385O
LOG keyword 211O
logarithm
base 10 192R
natural 191R
of the gamma function 682R
logarithmic
axes, [XYZ]LOG keywords 208R, 307R, 801R,
1006R, 1093R
scaling 305U
logarithmic plots 76O
logging an IDL session 582R
logical names (VMS)
defining 998R
deleting 412R
searching tables 1145R
logical names, see environment variables
Index L ... L
logical unit numbers 162B
!D system variable field 47R
allocating 516R
for journal file 43R
freeing 493R
FSTAT function 494R
getting 785R
obtaining status information 494R
returning information about 538R
setting file position pointer 813R
LOGIN.COM file 20U
LOGISTIC keyword 283R
log-linear plots 208R, 307R, 801R, 1006R, 1093R
LOGSQUARE keyword 283R
Lomb Normalized Periodogram 683R
LON0 keyword 719R
LON1 keyword 719R
LON64ARR function 686R
LONALIGN keyword 712R, 727R
LONARR function 687R
LONDEL keyword 363U, 712R, 727R
LONG function 688R
long integer data type 12B
LONG keyword 369R, 561R, 706R, 1340R
LONG64 function 689R
longjmp, C language 255R
longword
arrays 603R, 687R, 1171R
data type, converting to 688R
unsigned arrays 1170R
LONLAB keyword 713R, 727R
LONMAX keyword 716R
LONMIN keyword 716R
LONNAMES keyword 713R
LONS keyword 713R
lossy compression 907R, 1324R
LOW keyword 352U, 1011R
lower margin, setting 53R
LOWER_ONLY keyword 1091R
lowercase, converting strings to 1081R
lowpass filters 414U
LPF_BAND keyword 987R, 990R
LSODE function 690R
LSWAP keyword 236R
LT operator 278U, 36B
LU decomposition 694R, 696R, 699R
LU_COMPLEX function 460U, 694R
LUBKSB, see Obsolete Routines
LUDC procedure 460U, 696R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
LUDCMP, see Obsolete Routines
luminance 329R
LUMPROVE function 460U, 697R
LUN’s (logical unit numbers) 162B, 493R
Macintosh differences 136U
LUSOL function 460U, 699R
M
M_CORRELATE function 435U, 476U, 701R
MACCREATOR keyword 787R, 1048R
MACHAR function 428U, 703R
MACHEP machine-specific parameter 703R
machine-specific parameters 703R
Macintosh
backing store 130U
color palette 130U
compiling functions and procedures 135U
display device (MAC) 112R, 154R
displaying images 130U
editor windows 119U
errors 136U
IDLDE 118U
changing working directory 135U
LUN (logical unit number) differences 136U
mouse differences 134U
optimizing performance with memory 133U
path specification 44R
pixel depth 130U
positioning file pointers 136U
reading and writing files 136U
saving/restoring files 136U
specifying file search path 132U, 133U
using batch files 132U
MACTYPE keyword 787R
magnetic tape 224B
magnifying arrays 935R
magnitude
of a complex number 189R
of spectra 404U
magnitude-based ranks 892R
main
directory
IDLDE for Macintosh 132U
IDLDE for Motif 66U
IDLDE for Windows 107U
programs 29U
window, setting preferences
IDLDE for Macintosh 128U
Index-39
IDLDE for Motif 58U
IDLDE for Windows 59U, 104U
MAJOR keyword 211O, 243O
MAKE_ARRAY function 705R
Maker Interchange Format 250U
MAKETREE, see Obsolete Routines
MANAGE_STYLE keyword 613R, 626R, 650R, 666R
MANAGED keyword 1239R, 1275R
managing the state of a widget application 312B
MANN_WHITNEY, see Obsolete Routines
Mann-Whitney U-Test 977R
MAP keyword 355R, 1209R, 1239R
map projections 358U, 723R
Aitoff 365U, 724R
Alber’s equal area conic 724R
Alber’s equal-area conic 372U
azimuthal 362U
azimuthal equidistant 365U, 724R
boundaries, specifying 360U
cylindrical 368U
cylindrical equidistant 371U, 724R
drawing boundaries over 708R
drawing continent boundaries 359U, 726R
drawing parallels and meridians 711R
gnomonic(central, gnomic) 363U, 724R
Hammer-Aitoff 366U, 724R
high-resolution outlines 377U
Lambert’s conformal conic 371U, 724R
Lambert’s equal area 365U, 724R
Mercator 369U, 724R
Miller 724R
Miller cylindrical 371U
Mollweide 374U, 725R
orthographic 362U, 725R
Robinson 373U
satellite 366U, 725R
sinusoidal 373U, 725R
stereographic 362U, 725R
Transverse Mercator (UTM) 369U, 725R
warping images to maps 375U, 715R, 718R
MAP_ALL keyword 281R
MAP_CONTINENTS procedure 358U, 360U, 708R
MAP_GRID procedure 358U, 360U, 711R
MAP_IMAGE function 358U, 715R
MAP_PATCH function 718R
MAP_PROJ_INFO routine 721R
MAP_SET procedure 358U, 723R
mapping widgets 1209R
MARGIN system variable field 53R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index M ... M
Index-40
Index
margins, setting 53R
marquee selector 227R
MASK keyword 438O
MATCH_PREVIOUS keyword 402R
math errors 151B
mathematical operators 270U, 28B
mathematics 426U
matrices, multiplying 272U, 31B
MATRIX keyword 1186R
matrix operators
CHOLDC 267R
CHOLSOL 268R
COND 290R
CRAMER 319R
DETERM 417R
EIGENVEC 446R
ELMHES 448R
GS_ITER 525R
HQR 551R
INVERT 576R
LU_COMPLEX 694R
LUDC 696R
LUMPROVE 697R
LUSOL 699R
NORM 769R
SVDC 1096R
SVSOL 1102R
TRIQL 1140R
TRIRED 1142R
TRISOL 1143R
See also sparse arrays
MAX function 731R
MAX keyword 238R, 390R, 547R, 747R
MAX_ARGS keyword 608R
MAX_VALUE keyword 309U, 253O, 320O, 365O,
304R, 716R, 719R, 792R, 800R, 1005R, 1092R,
1135R
MAXEXP machine-specific parameter 703R
MAXIMIZE keyword 296R
maximum intensity projection 126O
MAXIMUM keyword 378R, 1293R
maximum operator 272U, 30B
maximum size of drawable 136O, 424O
maximum value
for slider widgets 1293R
of an array 731R
Maximum Value slider property 222U
MAXIMUM_INTENSITY keyword 1193R
MAXV keyword 544R
Index M ... M
MAXVAL keyword 461R, 878R, 913R
MBAR keyword 384R, 1209R
MD_TEST function 448U, 733R
MDC keyword 733R
MDEV keyword 756R
mean
absolute deviation 736R
MOMENT function 755R
of distribution 591R
MEAN function 735R
MEANABSDEV function 736R
median
Median Delta Test 733R
MOMENT function 755R
smoothing 738R
MEDIAN function 423U, 738R
MEDIAN keyword 736R
MEDIUM keyword 127R
memory
allocation under VMS 23U
conserving by using temporary variables 1117R
dynamic memory in use 539R
graphics system use 269B, 24O
optimizing performance
IDLDE for Macintosh 133U
IDLDE for Windows 58U, 103U
MEMORY keyword 539R
menu bars 1206R, 1209R
Menu Editor
opening 92U
Menu Editor, using 171U
MENU keyword 1224R
menus 295B
editing in IDL GUIBuilder 171U
menu bars 1206R, 1209R
menu items
IDLDE for Macintosh 120U
IDLDE for Motif 43U
IDLDE for Windows 88U
online help 242U
pulldown 298B, 1224R
system, using 207U
MENUS, see Obsolete Routines
MERCATOR keyword 724R
Mercator map projection 369U, 724R
meridians, drawing 359U, 711R, 727R
mesh plots 1090R
MESH_OBJ procedure 740R
MESHNAME keyword 1342R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
MESHNAMES keyword 927R
message dialogs 277B, 423R
MESSAGE keyword 227R
MESSAGE procedure 147B, 745R
message widgets 274B
message-of-the-Day file
IDLDE for Macintosh 134U
IDLDE for Windows 110U
MESSAGES keyword 539R
messages,suppressing informational 45R
METHOD keyword 557R
method overriding 263B
methods 261B
defining routines 261B
Windows 3.11 263B
invocation 258B
object 250B
Microsoft Windows
mouse differences 113U
Microsoft Windows display device (WIN) 112R, 170R
MIDEXP keyword 865R
MIDINF keyword 865R
MIDPNT keyword 865R
MIDSQL keyword 865R
MIDSQU keyword 865R
MIF 250U
Miller cylindrical map projection 371U
MILLER keyword 724R
Miller map projection 724R
MIN function 747R
MIN keyword 238R, 391R, 547R, 731R
MIN_ARGS keyword 608R
MIN_CURVE_SURF function 329U, 445U, 300R, 748R
MIN_VALUE keyword 253O, 320O, 365O, 304R, 716R,
792R, 800R, 1005R, 1092R, 1136R
MINEXP machine-specific parameter 703R
minimization 462U, 420R, 838R
downhill-simplex method. 463U
See also optimization
Minimize/Maximize base property 206U
minimum and maximum values of plot data 95O
minimum curvature surface 445U, 748R
MINIMUM keyword 378R, 1293R
minimum operator 272U, 30B
minimum value
for slider widgets (MINIMUM keyword) 1293R
of an array 747R
Minimum Value slider property 222U
MINOR keyword 211O, 243O
Index-41
MINOR system variable field 53R
MINUS_ONE keyword 292R
MINV keyword 544R
MIPS keyword 1001R
MIPSEB_DBLFIXUP, see Obsolete Routines
missing data 309U
in CONTOUR plots 304R
in irregular grids 1129R, 1136R
in map projections 716R
in plots 792R, 800R, 1005R, 1092R
in reconstruced images 941R
in rotated images 971R
in velocity fields 1185R
in warped images 821R
MISSING keyword 592R, 717R, 719R, 821R, 941R,
971R, 1129R, 1136R, 1185R
MISSING_VALUE keyword 899R
MK_HTML_HELP procedure 251U, 751R
MLINESTYLE keyword 709R, 728R
MLINETHICK keyword 709R, 728R
Modal base property 206U
modal dialogs, creating 206U
MODAL keyword 1028R, 1210R, 1275R, 1354R, 1361R,
1365R
MODE keyword 941R
model object 28O, 285O
model objects 37O
MODIFYCT procedure 391U, 754R
modules
compiled 540R
dynamically loaded 538R
modulo operator 271U, 30B
MOLLWEIDE keyword 725R
Mollweide map projection 374U, 725R
MOMENT function 755R
MONTHS keyword 211O, 595R
MORE keyword 785R
morphology
dilation operator 432R
erosion operator 452R
Mosaic 251U, 751R
MOTION_EVENTS keyword 1255R
mouse
double-clicks 1290R
emulating three-button 113U, 134U
Macintosh differences 134U
reading position of 313U, 894R
reading positon with the CURSOR procedure 332R
returning events from draw widgets 1255R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index M ... M
Index-42
Index
mouse cursor, setting 137O
MOUSE keyword 442O, 443O
Move method 186O
MOVIE, see Obsolete Routines
movies
MPEG 757R, 758R, 760R, 762R
moving averages 1043R, 1151R
filters 414U
MPEG object 32O, 296O
MPEG objects 119O
MPEG_CLOSE keyword 1360R
MPEG_CLOSE procedure 757R
MPEG_FILENAME keyword 1358R
MPEG_OPEN function 758R
MPEG_OPEN keyword 1358R
MPEG_PUT procedure 760R
MPEG_SAVE procedure 762R
MPROVE, see Obsolete Routines
MSE keyword 1147R
MT_OFFLINE keyword 579R
MT_REWIND keyword 579R
MT_SKIP_FILE keyword 579R
MT_SKIP_RECORD keyword 579R
MT_WEOF keyword 579R
Müller’s method 500R
MULTI keyword 441R
MULTI procedure 763R
MULTI system variable field 50R
MULTICOMPARE, see Obsolete Routines
multidimensional minimzation 463U
multiple correlation coefficient 433U, 701R
Multiple Document Panel
IDLDE for Motif 41U
IDLDE for Windows 85U
MULTIPLE keyword 904R, 905R, 1286R, 1322R
Multiple listbox property 226U
multiple plots on a page 306U, 50R
MULTIPLE_FILES keyword 427R
multiplication operator 271U, 29B
multiplying arrays and matrices 430U
multivariate analysis
contingency table 330R
Kruskal-Wallis H-test 591R
multiple correlation 701R
partial correlation 795R
multivariate functions
CTI_TEST 330R
KW_TEST 591R
M_CORRELATE 701R
Index N ... N
P_CORRELATE 795R
MUST_EXIST keyword 427R
N
N keyword 806R
N_CLUSTERS keyword 274R, 275R
N_COLORS keyword 223O, 234O, 304O, 420O
N_COLORS system variable field 46R
N_DIMENSIONS keyword 1023R
N_ELEMENTS function 112B, 124B, 125B, 764R
N_ELEMENTS keyword 1023R
N_ITERATIONS keyword 274R
N_LEVELS keyword 253O
N_PARAMS function 112B, 124B, 126B, 765R
N_TAGS function 766R
N0 keyword 884R
N1 keyword 884R
Name common property 196U
NAME keyword 211O, 243O, 253O, 258O, 266O, 275O,
282O, 291O, 306O, 312O, 320O, 329O, 339O,
346O, 365O, 373O, 385O, 400O, 410O, 539R,
613R, 627R, 641R, 645R, 651R, 657R, 663R, 666R,
672R, 1082R, 1275R, 1378R
NAME system variable field 46R
named
structures 262U, 42B
variables 184R, 185R
named variables 181O
names
of structure tags 1111R
of variables 265U, 21B
NaN (not-a-number) 152B
NAN keyword 238R, 547R, 590R, 731R, 735R, 736R,
747R, 756R, 1025R, 1044R, 1069R, 1123R, 1165R,
1179R
NaN values 1402
NARROW keyword 127R
native format (floating-point values) 235R
natural exponential funciton 460R
natural logarithm 191R
Navigate menu (online help) 246U
Navigation Dialog (online help) 248U
NCALLS keyword 194R
NCAR binary encoding 127R, 128R
NCAR keyword 127R
NCAR Raster Interchange Format files, writing 1327R
NCOLORS keyword 348O, 432O, 358R, 685R, 1361R
NCOLS keyword 919R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
NCOPIES keyword 349O
NE operator 278U, 36B
object references 259B
pointers 238B
near and far clipping planes 47O
NearestColor method 307O
negation operator 271U, 29B
NEGATIVE keyword 509R
NEGEP machine-specific parameter 703R
nesting of procedures and functions 537R, 540R
netCDF 1389R
Netscape 251U, 751R
new page 451R
new page (printing) 141O
NEW_AXES keyword 646R
NEW_WINDOW keyword 1383R
NewDocument method 350O
NewPage method 350O
NEWTON function 462U, 767R
Newton’s method 461U, 568R, 767R
NEXT_LINE keyword 404R
NFRAMES keyword 348R
NGRD machine-specific parameter 703R
NLAT keyword 1053R
NLEVELS keyword 305R
NLON keyword 1053R
NMAX keyword 194R
No Release button property 214U
NO_ALIAS keyword 998R
NO_BALANCE keyword 448R
NO_BLOCK keyword 1358R, 1365R
NO_COPY keyword 266O, 410O, 857R, 1186R, 1211R,
1224R, 1240R, 1255R, 1263R, 1281R, 1287R,
1293R, 1301R, 1311R
NO_DIVIDE keyword 1186R
NO_DRAW keyword 614R, 619R, 621R, 627R, 642R,
646R, 651R, 657R, 667R, 672R
NO_HEADER keyword 1302R
NO_KILL keyword 342R
NO_NEWLINE keyword 1240R, 1311R
NO_POLISH keyword 502R
NO_RELEASE keyword 355R, 374R, 1224R
NO_STATUS keyword 614R, 627R, 651R, 667R
NO_TOOLBAR keyword 614R, 627R, 651R, 667R
NOAUTOMODE keyword 787R
NOBORDER keyword 728R
NOCLIP keyword 103R
NOCLIP system variable field 51R
NOCLISYM keyword 1049R
Index-43
NODATA keyword 104R
NOECHO keyword 402R
NOEDIT keyword 369R
NOERASE keyword 104R, 728R
NOERASE system variable field 51R
NOFILL keyword 407R
noise, filtering 738R
NOLATIN keyword 853R
NOLOGNAM keyword 1049R
NOMARK keyword 844R
NOMESHDEF keyword 1342R
NONAME keyword 745R
NONE keyword 789R
NONEXCLUSIVE keyword 355R, 1211R
noninteractive mode 32U, 34U
nonlinear equations 461U
BROYDEN 231R
CONSTRAINED_MIN 294R
FX_ROOT 500R
FZ_ROOTS 502R
NEWTON 767R
nonparametric tests 447U
LNP_TEST 683R
MD_TEST 733R
R_TEST 884R
RS_TEST 977R
S_TEST 980R
XSQ_TEST 1375R
non-printable characters 18B
NOPREFIX keyword 745R
NOPRINT keyword 746R
NOREGION keyword 407R
NORM function 460U, 769R
NORM keyword 1202R
norm_coord.pro (example file) 53O
normal
coordinates 286U
converting to other types 309R
distribution (Gaussian) 506R, 507R
random deviates 891R
Normal Computations 148O
normal computations 92O
NORMAL keyword 104R, 309R, 333R, 833R
NORMALIZED keyword 200R
normally-distributed random numbers 886R
NORMALS keyword 329O
NOSHELL keyword 1048R
NOSHOW keyword 1374R
NOSTDIO keyword 787R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index N ... N
Index-44
Index
and TRANSFER_COUNT 1344R
NOT operator 274U, 32B
notch filter 419U
NOTEXT keyword 211O
NOTIFY keyword 1049R
NOTIFY_REALIZE keyword 1211R, 1224R, 1240R,
1255R, 1264R, 1282R, 1287R, 1293R, 1302R, 1311R
NOTTYRESET keyword 1048R
NOWAIT keyword 333R, 1049R, 1268R
NOZERO keyword 233R, 287R, 398R, 490R, 570R,
686R, 687R, 706R, 778R, 860R, 1168R, 1171R,
1172R
NR_BETA, see Obsolete Routines
NR_BROYDN, see Obsolete Routines
NR_CHOLDC, see Obsolete Routines
NR_CHOLSL, see Obsolete Routines
NR_DFPMIN, see Obsolete Routines
NR_ELMHES, see Obsolete Routines
NR_EXPINT, see Obsolete Routines
NR_FULSTR, see Obsolete Routines
NR_HQR, see Obsolete Routines
NR_INVERT, see Obsolete Routines
NR_LINBCG, see Obsolete Routines
NR_LUBKSB, see Obsolete Routines
NR_LUDCMP, see Obsolete Routines
NR_MACHAR, see Obsolete Routines
NR_MPROVE, see Obsolete Routines
NR_NEWT, see Obsolete Routines
NR_POWELL, see Obsolete Routines
NR_QROMB, see Obsolete Routines
NR_QROMO, see Obsolete Routines
NR_QSIMP, see Obsolete Routines
NR_RK4, see Obsolete Routines
NR_SPLINE, see Obsolete Routines
NR_SPLINT, see Obsolete Routines
NR_SPRSAB, see Obsolete Routines
NR_SPRSAX, see Obsolete Routines
NR_SPRSIN, see Obsolete Routines
NR_SVBKSB, see Obsolete Routines
NR_SVD, see Obsolete Routines
NR_TQLI, see Obsolete Routines
NR_TRED2, see Obsolete Routines
NR_TRIDAG, see Obsolete Routines
NR_WTN, see Obsolete Routines
NR_ZROOTS, see Obsolete Routines
NRIF
files, writing 1327R
standard file format I/O routines 228B
NROWS keyword 919R
Index O ... O
NSTEPS keyword 488R, 1182R
NSUM keyword 320O, 792R, 801R
NSUM system variable field 51R
NTERMS keyword 511R
NTOHL keyword 236R
NTOHS keyword 236R
Null display device (NULL) 154R
NUM_KEYPAD keyword 1001R
NUM_RECORDS keyword 899R
number of array elements 764R
numbers, random 886R, 890R
numeric keypads 1001R
numerical integration 449U, 866R
Numerical Recipes 426U
NVARIABLES keyword 797R
NVECS keyword 488R, 1182R
NX keyword 588R, 1130R, 1136R
NY keyword 588R, 1130R, 1136R
Nyquist frequency 409U
O
OBCELL keyword 1375R
OBJ keyword 536R, 706R
obj_axis.pro (example file) 75O
OBJ_CLASS function 259B, 771R
OBJ_DESTROY function 257B
OBJ_DESTROY procedure 772R
OBJ_ISA function 260B, 773R
obj_logaxis.pro (example file) 76O
OBJ_NEW function 256B, 774R
obj_plot.pro (example file) 100O
obj_tess.pro (example file) 71O
OBJ_VALID function 260B, 776R
obj_vol.pro (example file) 122O
OBJARR function 257B, 778R
object
class 250B
class structures 251B
encapsulation 250B
heap variables 250B
inheritance 251B, 253B
instances 250B
lifecycle 255B
method routines 261B
naming conventions 27O
persistence 251B
polymorphism 251B
Object Graphics 22O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
object graphics 148O
Expose Events 148O
Object Graphics 149O
object heap variables 254B
object oriented programming 250B
objects
creating 774R
arrays 778R
destroying 257B, 772R
determining
class names 771R
subclasses 773R
heap variables 230B, 254B
Object Graphics 268B, 23O
clipboard support
Macintosh 120U
Windows 88U
font use 66R
object-oriented
graphics 268B, 24O
references for heap variables 230B
testing existence 776R
OBJECTS keyword 539R
OBLIQUE keyword 337U, 128R, 1109R
obsolete routines and system variables 1391R
Obtaining Traceback Information 148B
OCCLUDED keyword 1202R
octal 14B
Oetli, Thomas 377U
OFAC keyword 683R
OFFSET keyword 362R
OMARGIN system variable field 53R
OMAX keyword 547R
OMIN keyword 547R
ON_ERROR procedure 142B, 145B, 745R, 779R
ON_IOERROR procedure 780R
OnButton draw area event 232U
OnButton Press event property 215U
ONCE keyword 230R
OnCellSelect table event 237U
OnChangeValue slider event 223U
OnColWidth table event 238U
OnDelete table event 238U
OnDelete text event 218U
OnDestroy property 200U
one-tailed hypothesis tests 447U
OnExpose draw area event 233U
OnFocus event property 210U
OnFocus table event 238U
Index-45
OnFocus text event 218U
ONGLASS keyword 385O
OnInsertCh text event 218U
OnInsertChar table event 239U
OnInsertString table event 239U
OnInsertString text event 219U
OnInvalidData table event 239U
OnKillRequest event property 210U
online help 242U, 440R, 751R
"Back" button 247U
annotate 244U
bookmark menu 244U
browse buttons 247U
button bar 247U
calling from programs 781R
contents button 247U
contents tab 248U
copying a topic 243U
edit menu 243U
extending 249U
File menu 243U
find tab 249U
help menu 246U
index tab 248U
menus 242U
Navigate menu 246U
Navigation dialog 248U
printing 243U
view menu 246U
ONLINE_HELP procedure 250U, 781R
ONLY_8BIT, see Obsolete Routines
OnMotion draw area event 233U
OnRealize event property 200U
OnSelectValue droplist event 225U
OnSelectValue listbox event 227U
OnSizeChange event property 210U
OnTextSelect table event 240U
OnTextSelect text event 219U
on-the-glass text 82O
OnTimer event property 200U
OnTracking event property 200U
OnViewportMoved draw area event 233U
opacities 1192R
OPACITY keyword 403O
opacity table 124O
OPACITY_TABLE0 keyword 410O
OPACITY_TABLE1 keyword 410O
OPAQUE keyword 851R
OPEN procedures 783R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index O ... O
Index-46
Index
OPEN_FUNC keyword 342R
opening files 160B, 783R
getting information on open files 537R
opening operation, in image processing 433R
OpenVMS see VMS
operating system
commands, issuing 31U
current version in use 45R
operations on objects 258B
operations on pointers 235B
operators 270U, 28B
addition 270U, 29B
AND 274U, 32B
array concatenation 273U, 31B
assignment 270U, 28B
Boolean 274U, 32B
division 271U, 29B
EQ 277U, 35B
exponentiation 271U, 29B
GE 277U, 35B
GT 277U, 36B
LE 277U, 36B
LT 278U, 36B
mathematical 270U, 28B
matrix multiplication 272U, 31B
maximum 272U, 30B
minimum 272U, 30B
modulo 271U, 30B
multiplication 271U, 29B
NE 278U, 36B
NOT 274U, 32B
OR 274U, 32B
parentheses 270U, 28B
precedence 268U, 26B
relational 275U, 34B
square brackets 270U, 28B
subtraction and negation 271U, 29B
XOR 274U, 33B
OPLOT procedure 287U, 292U, 792R
OPLOTERR procedure 794R
optimization 462U
AMOEBA function 193R
CONSTRAINED_MIN 294R
DFPMIN 420R
POWELL 838R
OPTIMIZE keyword 128R
optional parameters in user-written functions 765R
OR operator 274U, 32B
ORDER keyword 266O, 346R, 362R, 436R, 623R, 760R,
Index P ... P
848R, 908R, 923R, 1041R, 1151R, 1154R, 1162R,
1325R, 1333R, 1359R
ORDERED keyword 129R
ordinary differential equations
LSODE function 690R
ordinary differential equations, RK4 967R
ORIENTATION keyword 312O, 104R, 709R, 713R
orientation, 3-dimensional 276B
ORIGIN system variable field 47R
ORTHOGRAPHIC keyword 725R
orthographic map projection 362U, 725R
OUT executive command See commands
OUT_VAL keyword 470R
outer margins, setting 53R
outline fonts 65R
OUTLINE keyword 211R
OUTLINE_COLOR keyword 275O
OUTLINE_THICK keyword 275O
outlines of continents 708R
outlying data regression 598R
OUTP, see Obsolete Routines
output
BMP files 1320R
GIF files 1322R
JPEG files 1324R
NRIF files 1327R
PGM files 1331R
PICT files 1328R
PPM files 1331R
SRF files 1333R
TIFF files 1337R
wave files 1342R
OUTPUT keyword 129R, 539R, 846R
Output Log
IDLDE for Macintosh 118U
IDLDE for Motif 41U
IDLDE for Windows 85U
OUTPUT_SIZE keyword 1197R
OUTPUTS keyword 441R
overflow, integer 154B, 703R
overlaying images and contour plots 324U
OVERPLOT keyword 211R, 305R
overplotting 792R
OVERWRITE keyword 444R, 476R, 945R, 1348R
P
P_CORRELATE function 435U, 476U, 795R
P0 keyword 194R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
P0LAT keyword 359U
P0LON keyword 359U
P1 - P5 keywords 742R
PACKED keyword 204R
page break 451R
PAIRED keyword 1121R
PALATINO keyword 129R
PALETTE keyword 205O, 223O, 234O, 243O, 247O,
266O, 315O, 329O, 349O, 359O, 380O, 420O,
433O
palette object 31O, 302O
palette objects 60O, 66O
PALETTE, see Obsolete Routines
palettes 116O
pan offset 47R
parallel projection 44O
parallels, drawing 359U, 711R, 727R
parameters
actual 110B, 111B
copying 112B
finding number of 765R
formal 110B, 111B, 181O, 185R
passing mechanism 110B, 120B
PARAMETERS keyword 975R
parametric hypothesis tests 447U
PARENT keyword 208O, 240O, 250O, 263O, 272O,
281O, 290O, 318O, 327O, 337O, 362O, 383O,
391O, 399O, 405O, 1275R
PARENT_BASE keyword 614R, 627R, 651R, 667R
parentheses 270U, 28B
parents, of widgets 1275R
partial correlation coefficient 433U, 795R
PARTIAL_COR, see Obsolete Routines
PARTIAL2_COR, see Obsolete Routines
passing parameters 120B
path
definition string 462R
IDLDE for Macintosh 132U, 133U
IDLDE for Motif 65U
IDLDE for Windows 109U
on a Macintosh 134U, 44R
PATH environment variable 20U
PATH keyword 207O, 222O, 225O, 233O, 236O, 240O,
249O, 262O, 271O, 280O, 289O, 317O, 326O,
336O, 347O, 352O, 361O, 382O, 404O, 413O,
419O, 422O, 430O, 435O, 427R, 441R
PATH_DATA_COORDS keyword 305R
PATH_FILENAME keyword 320U, 305R
PATH_INFO keyword 306R
Index-47
PATH_XY keyword 306R
PATTERN keyword 312O, 827R
pattern object 31O, 310O
pattern objects 66O
PCL
driver 154R
files 146R
PCOMP function 476U, 796R
Pearson correlation coefficient 315R
penta.pro (example file) 69O
performance
analyzing 141U
optimizing with memory
IDLDE for Macintosh 133U
IDLDE for Windows 58U, 103U
performance tuning with object graphics 145O
period (character) 59R
permutation 473R
persistence 251B
PERSP keyword 323R
perspective 1109R
PERSPECTIVE keyword 337U, 1109R
perspective projection 44O
PGM files 913R, 1331R
phase 206R
of spectra 404U
PHASER, see Obsolete Routines
Pickdata method 224O, 235O, 351O, 421O, 434O
PICKFILE, see Obsolete Routines
PickVoxel method 412O
PICT files
reading 910R
standard file format I/O routines 228B
writing 1328R
PID keyword 1048R
PIVOT keyword 971R
pixels 380U
depth 121R
fixed 326U
reading value of 894R
scalable 325U, 383U
PIXELS keyword 129R, 1005R
PIXMAP keyword 1318R
pixmap objects
using 136O
PIXMAPS keyword 342R
PLANAR keyword 254O
PLANARCONFIG keyword 924R, 1340R
plane of vector-drawn text 1380R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index P ... P
Index-48
Index
PLIST keyword 1009R
plot object 29O, 315O
plot objects 93O
averaging points 96O
creating 93O
minimum and maximum values 95O
plotting symbols 95O
using 94O
PLOT procedure 287U, 312U, 343U, 800R
PLOT_3DBOX procedure 803R
PLOT_FIELD procedure 806R
PLOT_IO, See YLOG keyword to PLOT
PLOT_OI, See XLOG keyword to PLOT
PLOT_OO, See (XY)LOG keywords to PLOT
PLOT_TO keyword 129R
PLOTERR procedure 808R
plots 86O
contour 318U
filled contour 330U
logarithmic 305U, 76O
margins 53R
outer margins 53R
overplotting 292U
shaded surface 349U
surface 331U
X versus Y 287U
PLOTS procedure 809R
PLOTTER_ON_OFF keyword 129R
plotting 284U, 800R
2D fields 806R
3D fields 488R
3D transformations 107R, 314R, 350R, 380R,
984R, 985R, 1095R, 1109R, 1186R
annotation 293U
axes 310U
scaling 288U
thickness 107R
titles 109R
bar plots 210R
closing files (CLOSE_FILE keyword) 117R
combining images with graphics 347U
contour plots 300R, 559R
drawing axes (AXIS procedure) 207R
error bars 456R, 794R, 808R
filename for output (FILENAME keyword) 123R
flow field 488R
font selection 294U
functions of 2 variables 803R
height of output 143R
Index P ... P
histogram 105R
histogram style 297U
keyword parameters 284U
landscape orientation 127R
line thickness 52R, 107R
lines 809R
linestyles 49R, 102R
location on page 307U
logarithmic axes
linear-log 801R
log-linear 208R, 307R, 801R, 1006R, 1093R
missing data 309U
MAX_VALUE keyword 792R, 800R
multi-dimensional arrays 318U
multiple plots on a page 306U, 50R, 162R
output, positioning 148R
overplotting 292U, 559R, 792R
points 809R
polar 312U, 793R, 801R
portrait orientation 130R
position of window 51R, 104R
region 51R
selecting a plotting device 992R
shaded surfaces 1004R
subtitles 51R, 106R
symbol size 106R
symbols 295U, 296U, 51R, 105R
text 1379R
three-dimensional lines 810R
titles 289U, 52R, 109R
two-dimensional arrays 318U
user-defined symbols 1177R
velocity field 488R
velocity fields 1184R
weather fronts 1201R
width of output 142R
wire-mesh surfaces 1090R
without data 104R
without erasing 51R, 104R
XY plots 800R
Z-coordinate for 110R
PM, see Obsolete Routines
PMF, see Obsolete Routines
PNG files
standard file format I/O routines 228B
PNT_LINE function 811R
POINT_LUN procedure 157B, 813R
pointer heap variables 254B
pointers 230B, 254B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
creating 857R
creating arrays 860R
destroying 856R
examples 242B
examples of using 242B
file positioning
Macintosh 136U
file positoning
Windows 114U
freeing 242B
heap variables 230B, 233B
testing existence 858R
validity 241B
POISSON keyword 887R, 891R
Poisson random deviates 887R, 891R
POLAR keyword 320O, 651R, 793R, 801R
polar plots 312U, 801R
contours 815R
coordinates 338R, 817R
POLAR_CONTOUR procedure 815R
POLAR_SURFACE function 445U, 817R
polishing of roots 502R
political boundaries 708R
POLY function 819R
POLY_2D function 820R
POLY_AREA function 823R
POLY_FIT function 438U, 824R
POLY_SHADES keyword 833R
POLYCONTOUR, see Obsolete Routines
POLYFILL keyword 130R
POLYFILL procedure 826R
POLYFILLV function 829R
POLYFITW function 438U, 831R
polygon filling 298U, 826R, 829R
with HP plotters 130R
Polygon mesh optimization 145O
polygon object 29O, 324O
polygon objects 88O
creating 88O
pattern fills 89O
rendering style 89O
shading 89O
texture mapping 90O
using 89O
POLYGONS keyword 254O, 330O, 376O
polyline object 29O, 334O
polyline objects 92O
creating 93O
shading and coloring 93O
Index-49
using 93O
using symbols 93O
POLYLINES keyword 339O
polymorphism
objects 251B
polynomial warping 820R
POLYSHADE function 832R
POLYWARP procedure 835R
POPD procedure 257R, 837R
PORTABLE keyword 247R
portable unformatted I/O 197B
PORTRAIT keyword 130R
portrait orientation 159R
for IDL output (PORTRAIT keyword) 130R
POSITION keyword 183O, 185O, 187O, 286O, 292O,
354O, 358O, 389O, 395O, 397O, 401O, 104R
position of graphics 42O
Position slider property 222U
POSITION system variable field 51R
positional parameters 111B, 180O, 184R
returning number of 765R
positioning
child widgets within a base 1218R
commands 81R
cursor 1157R
graphics cursor 332R
PostScript output 159R
top level base widgets 1247R
widget bases 1219R
windows (XPOS and YPOS keywords) 1318R
positioning objects 42O
PostCreation event property 201U
PostScript
color 158R
device 156R
encapsulated 122R, 160R
EPSI (Encapsulated PostScript Interchange)
files 130R
files 146R
files with preview headers 130R
font index 124R
fonts 158R, 853R
importing graphics into other programs 163R
importing into another document 122R
multiple plots on a single page 162R
pixel bit depth 116R
positioning output 159R
scaling entire plot (SCALE_FACTOR
keyword) 132R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index P ... P
Index-50
Index
true-color images 158R
writing 24-bit images 159R, 1155R
Powell minimization (POWELL procedure) 463U, 838R
POWELL procedure 463U
power spectrum 406U
PPM files 913R, 1331R
standard file format I/O routines 228B
preferences, setting
IDLDE for Macintosh 128U
IDLDE for Motif 57U
IDLDE for Windows 102U
PREFIX keyword 530R, 534R
PREMULTIPLY keyword 294O, 295O
PRESERVE keyword 1356R
PREVIEW keyword 130R
PREVIOUS_LINE keyword 404R
PRIMES function 840R
principal components analysis 472U, 796R
PRINT keyword 261R, 440R, 789R, 1077R
PRINT procedure 158B, 841R
PRINT_FILE keyword 131R
PRINT_QUALITY keyword 349O
PRINTD procedure 257R, 843R
Printer Control Language, see PCL
PRINTER device 156R
printer object 32O, 342O
starting a new page 141O
submitting print jobs 141O
printer objects 139O
color model 140O
creating 139O
dialogs 140O
drawing to 140O
PRINTF procedure 158B, 841R
printing 28U, 156R
closing files (CLOSE_FILE keyword) 117R
dialog 277B, 429R
filename for output (FILENAME keyword) 123R
graphics output files 146R
help topics 243U
IDLDE for Macintosh 121U
IDLDE for Motif 44U
IDLDE for Windows 90U
landscape orientation 127R
printer set up 147R
properties 277B, 430R
setup dialog 277B, 430R
to file units 841R
to standard output 841R
Index P ... P
printing dialogs 277B
PRINTNAMES example routine 244B
PRO_SET_VALUE keyword 1211R, 1225R, 1241R,
1255R, 1264R, 1282R, 1287R, 1293R, 1302R, 1312R
PROB keyword 604R
probability
bivariate distributions 544R
density distribution 546R
Gaussian distribution 513R
Histogram function 546R
probability functions
binomial distribution 221R
Chi-square distribution 265R, 266R
F distribution 471R, 472R
Gaussian distribution 506R, 507R
student’s T distribution 1107R, 1108R
PROBD keyword 883R
procedure methods
calling sequence for 180O
procedures 29U
call stack, returning 537R
call statement 104B
calling
mechanism 121B
sequence for 184R
compiled 975R
definition statements 110B
DEVICE 111R
DFPMIN 463U
displaying compiled 540R
POWELL 463U
SET_PLOT 111R
PROFILE function 844R
PROFILER procedure 846R
PROFILES procedure 848R
profiling 141U
program
files 29U
listings 34R
Program Control Routines 128B
programming
displaying traceback information 540R
format of program files 28U
identifying keywords as set 585R
main programs 29U
preparing and running programs 28U
routines 124B
stopping programs 1070R
suspending execution of programs 1196R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
traceback information 538R
PROGRESSIVE keyword 624R, 1325R
PROJECT_VOL function 850R
projection 43O
parallel 44O
perspective 44O
PROJECTION keyword 393O
projection matrix 455U
projections
2D from 3D datasets 850R
Aitoff 365U, 724R
Alber’s equal-area conic 372U
Albers 724R
azimuthal 362U
azimuthal equidistant 365U, 724R
backprojection 963R
cylindrical 368U
cylindrical equidistant 371U, 724R
gnomonic (central, gnomic) 363U, 724R
Hammer-Aitoff 366U, 724R
Lambert’s conformal conic 371U, 724R
Lambert’s equal area 365U, 724R
Mercator 369U, 724R
Miller 724R
Miller cylindrical 371U
Mollweide 374U, 725R
orthographic 362U, 725R
Robinson 373U
satellite 366U, 725R
sinusoidal 373U, 725R
stereographic 362U, 725R
Transverse Mercator (UTM) 369U, 725R
prompt
changing default 45R
reading from 896R
PROMPT keyword 896R
PROMPT, see Obsolete Routines
properties
draw area widget 229U
entering multiple strings 169U
label widget 221U
retrieving 33O
setting 33O
table widget 234U
text widget 216U
Properties dialog 166U
# of Rows/Columns base property 202U
Alignment base property 203U
Alignment button property 213U
Index-51
Alignment label property 221U
Alignment table property 234U
Allow Moving base property 204U
Allowing Closing base property 203U
Bitmap button property 213U
Color Model draw area property 229U
Colors draw area property 229U
Column Labels table property 234U
Component Sizing common property 197U
Display Headers table property 234U
draw area events 232U
draw area widget properties 229U
droplist events 224U
droplist widgets 224U
Editable table property 235U
Editable text property 216U
entering multiple strings 169U
Floating base property 204U
Frame common property 197U
Graphics Type draw area property 230U
Grid Layout base property 204U
Handle Events common event 199U
Height listbox property 226U
Height text property 216U
Initial Value droplist property 224U
Initial Value listbox property 226U
Initial Value text property 216U
Label button property 214U
Layout base property 205U
listbox events 227U
listbox properties 226U
Maximum Value slider property 222U
Minimize/Maximize base property 206U
Minimum Value slider property 222U
Modal base property 206U
Multiple listbox property 226U
Name common property 196U
No Release button property 214U
OnButton draw area event 232U
OnButtonPress button event 215U
OnCellSelect table event 237U
OnChangeValue slider event 223U
OnColWidth table event 238U
OnDelete table event 238U
OnDelete text event 218U
OnDestroy common event 200U
OnExpose draw area event 233U
OnFocus base event 210U
OnFocus table event 238U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index P ... P
Index-52
Index
OnFocus text event 218U
OnInsertCh text event 218U
OnInsertChar table event 239U
OnInsertString table event 239U
OnInsertString text event 219U
OnInvalidData table event 239U
OnKillRequest base event 210U
OnMotion draw area event 233U
OnRealize common event 200U
OnSelectValue droplist event 225U
OnSelectValue listbox event 227U
OnSizeChange base event 210U
OnTextSelect table event 240U
OnTextSelect text event 219U
OnTimer common event 200U
OnTracking common event 200U
OnViewportMoved draw area event 233U
opening 92U, 167U
Position slider property 222U
PostCreation common event 201U
Renderer draw area property 230U
Resize Columns table property 235U
Retain draw area property 231U
Row Labels table property 236U
Row/Column Major table property 235U
Scroll base property 206U
Scroll draw area property 231U
Scroll table property 236U
Scroll text property 217U
Sensitive common property 198U
setting label widget properties 221U
Space base property 207U
Suppress Value slider property 222U
System Menu base property 207U
table events 237U
table widget properties 234U
Text label property 221U
Title Bar base property 208U
Title base property 207U
Title droplist property 224U
Title slider property 223U
Type button property 214U
Viewport Columns table property 236U
Viewport Rows table property 237U
Visible base property 208U
Width listbox property 227U
Width text property 217U
Word Wrapping text property 217U
X Offset common property 198U
Index Q ... Q
X Pad base property 208U
X Scroll base property 209U
X Scroll draw area property 231U
X Size common property 198U
Y Offset common property 198U
Y Pad base property 209U
Y Scroll base property 209U
Y Scroll draw area property 231U
Y Size common property 199U
PROPERTIES keyword 620R, 630R
properties of objects 33O
PS_SHOW_FONTS procedure 853R
PSAFM procedure 854R
PSEUDO procedure 391U, 855R
PSEUDO_COLOR keyword 131R
pseudo-color images, converting from true-color 279R
pseudo-color PostScript images 158R
pseudocylindrical map projections 373U
PSYM keyword 295U, 105R, 808R, 1202R
PSYM system variable field 51R
PTR keyword 536R, 706R
PTR_FREE procedure 856R
PTR_NEW function 857R
PTR_VALID function 858R
PTRARR function 860R
pulldown menu 382R, 1224R
PUSHD procedure 257R, 861R
Put method 300O
PutEntity method 200O
PWIDGET, see Obsolete Routines
Q
QL algorithm 1140R
QL method (computing eigenvalues) 444R
QROMB function 453U, 862R
QROMO function 453U, 864R
QSIMP function 453U, 866R
Quad strips 146O
quadrature function 411U
QUALITY keyword 223O, 234O, 299O, 420O, 624R,
1325R
QUALITY keywprd 349O, 433O
quantizing colors 279R
QUERY_* routines 868R
QUERY_BMP routine 870R
QUERY_DICOM 177O, 871R
QUERY_GIF routine 873R
QUERY_JPEG routine 874R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
QUERY_PICT routine 875R
QUERY_PNG routine 876R
QUERY_PPM routine 878R
QUERY_SRF routine 879R
QUERY_TIFF routine 880R
QUESTION keyword 424R
question mark
character 61R
online help system 242U
QuickHelp 250U
QUIET keyword 379O, 952R
quintic interpolation 1136R
QUINTIC keyword 1136R, 1197R
QUIT keyword 782R
quitting IDL 21U, 459R
quotas 139B
quotation marks 258U, 17B, 59R
R
R keyword 884R
R_CORRELATE function 435U, 448U, 882R
R_TEST function 448U, 884R
RADIANS keyword 323R, 470R
radio button widgets
creating 212U
creating multiple 212U
laying out 213U
setting attributes 213U
setting properties 212U
using 165U
radix 703R
Radon transform 963R
random deviates
binomial 887R, 891R
exponential 887R, 891R
gamma 887R, 891R
normal 891R
Poisson 887R, 891R
random 891R
random numbers
normally-distributed 886R
uniformly-distributed 890R
RANDOMN function 886R
RANDOMU function 890R
RANGE keyword 211O, 654R
RANGE system variable field 54R
rank correlation coefficient 882R
RANKS function 892R
Index-53
rank-sum test 977R
raster images 380U
RDPIX procedure 894R
READ keyword 427R
Read method 201O, 225O, 435O
READ procedure 158B, 895R
READ_ASCII function 898R
READ_BMP function 901R
READ_DICOM 176O, 903R
READ_GIF procedure 904R
READ_INTERFILE procedure 906R
READ_JPEG procedure 907R
READ_KEY procedure 896R
READ_PICT procedure 910R
READ_PNG function 911R
READ_PPM procedure 913R
READ_SPR function 466U, 915R
READ_SRF procedure 916R
READ_SYLK function 918R
READ_TABLES keyword 329R
READ_TIFF function 921R
READ_WAVE procedure 926R
READ_X11_BITMAP procedure 928R
READ_XWD function 930R
READF procedure 158B, 895R
reading
ASCII files 898R
BMP files 901R
current color table 1160R
cursor position 894R
data from a string 931R
files (OPENR procedure) 783R
formatted data 895R
from a prompt 896R
from tapes 1114R
GIF files 904R
images from the display 385U, 1161R
Interfile files 906R
JPEG files 907R
mouse position 332R
PGM files 913R
PICT files 910R
pixel values 894R
PPM files 913R
SRF files 916R
TIFF files 921R
unformatted binary data 933R
wave files 926R
X11 bitmaps 928R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index R ... R
Index-54
Index
XWD files 930R
reading and writing files, Macintosh differences 136U
READNAMES example routine 242B
read-only system variables 409R
READS procedure 213B, 931R
READU procedure 158B, 933R
real part of complex numbers 486R
REALIZE keyword 1241R
REALIZED keyword 1275R
realizing widgets 300B, 1241R
REBIN function 935R
recall buffer
command 938R
IDLDE for Windows 58U, 103U
RECALL keyword 404R
RECALL_COMMANDS function 938R
RECALL_COMMANDS keyword 539R
recent files
in IDLDE for Macintosh 121U
in IDLDE for Motif 44U
in IDLDE for Windows 90U
RECOMPUTE_DIMENSIONS keyword 386O
RECON3 function 939R
reconstructions
3D from 2D images 939R
Tomographic 963R
RECORD_START keyword 899R
recording an interactive IDL session 582R
record-oriented files 219B
records
length of 495R
updating 1344R
rectangular
coordinates 338R, 817R
filter 417U
recursion 122B
RED keyword 627R
RED keyword, GREEN keyword, BLUE keyword 1340R
RED_VALUES keyword 243O, 306O
REDRAW keyword 404R
reduce operator 452R
REDUCE_COLORS procedure 944R
_REF_EXTRA keyword (keyword inheritance) 115B
reference, parameters passed by 120B
REFERENCE_OUT keyword 615R, 628R, 642R, 646R,
652R, 657R, 667R, 672R
REFORM function 945R
reformatting arrays 945R
region
Index R ... R
labeling 596R
of interest 362R, 407R
REGION system variable field 51R, 54R
Regis device 168R
REGISTER keyword 1041R
REGRESS function 438U, 947R
REGRESS1, see Obsolete Routines
regression analysis 947R
REGRESSION, see Obsolete Routines
REGULAR keyword 587R, 1129R
REJECT keyword 330O, 994R
relational operators 275U, 34B
relaxed structure assignment 55B, 956R, 1087R
RELAXED_STRUCTURE_ASSIGNMENT
keyword 955R
release, current version in use 45R
Remove method 187O, 292O, 357O, 394O, 400O
REMOVE_ALL keyword 77B, 1071R, 1074R
RemoveEntity method 202O
removing breakpoints 229R
RENDER_STEP keyword 410O
Renderer draw area property 230U
RENDERER keyword 135O, 433O, 615R, 628R, 652R,
668R, 1255R
rendering 135O
3D objects 740R
3D volumes as 2D images 850R
hardware vs. software 135O
voxel 1192R
Rendering Process
rendering 38O
rendering speed of volumes 127O
repeat statement 107B
REPEATS keyword 1133R
REPLACE keyword 615R, 628R, 646R, 652R, 668R
replacing text
IDLDE for Macintosh 123U
IDLDE for Motif 47U
IDLDE for Windows 93U
REPLICATE function 346U, 949R
REPLICATE_INPLACE procedure 950R
REPORT keyword 296R, 846R
reserved words 63R
reserving colors 67U
RESET keyword 337U, 404O, 746R, 846R, 1110R,
1241R
Reset method 202O, 293O, 378O, 443O
RESET_DATA keyword 267O, 321O, 330O, 339O, 365O
RESET_STRING keyword 131R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
resetting widgets 1241R
RESIDUAL keyword 331R, 444R, 446R, 1376R
Resize Columns table property 235U
RESIZEABLE_COLUMNS keyword 1302R
RESIZEABLE_ROWS keyword 1302R
resizing arrays 291R, 461R, 935R
RESOLUTION 429O
RESOLUTION keyword 223O, 235O, 346O, 421O,
429O, 131R, 132R, 517R, 624R
resolution, CIA World map database 377U
RESOLVE_ALL procedure 952R
RESOLVE_ROUTINE procedure 954R
resource files, editing 67U
resource names for IDL widgets 1211R, 1225R, 1256R,
1264R, 1282R, 1287R, 1293R, 1312R
RESOURCE_NAME keyword 424R, 429R, 430R,
1211R, 1225R, 1256R, 1264R, 1282R, 1287R,
1293R, 1302R, 1312R
resources, X Window 66U
RESTORE keyword 362R, 408R
RESTORE procedure 34U, 955R, 1404
RESTORED_OBJECTS keyword 956R
restoring IDL save files 955R
restoring structures 57B
RESULT keyword 438R
RESULT_ACMODE keyword 1146R
RESULT_TABLE keyword 1146R
Retain draw area property 231U
RETAIN keyword 433O, 132R, 351R, 391R, 1041R,
1256R, 1318R
Retained Graphics 148O
RETALL command 957R
RETALL procedure 30U
RETURN command 958R
RETURN executive command See commands
RETURN procedure 30U
RETURN_EVENTS keyword 369R
RETURN_FULL_NAME keyword 384R
RETURN_ID keyword 355R, 384R
RETURN_INDEX keyword 355R, 384R
RETURN_NAME keyword 356R, 384R
RETURN_TYPE keyword 247R
returning
subscripts of non-zero array elements 1203R
widget information 1271R
REVERSE function 960R
reverse index list (for histograms) 546R
REVERSE_INDICES keyword 547R
reversing array indices 960R
Index-55
REWIND procedure 962R
REWRITE keyword 842R, 1344R
RGB color model 58O, 59O
RGB color system 386U, 277R, 387R, 1159R
RGB keyword 388R, 901R
RGB_HLS keyword 277R
RGB_HSV keyword 277R
RGB_TABLE0 keyword 410O
RGB_TABLE1 keyword 410O
RGB_TO_HSV, see Obsolete Routines
Rich Text Format 249U
RIEMANN procedure 963R
RIGHT keyword 1385R
right-handed coordinate system 335U
rivers 708R
RIVERS keyword 709R
RK4 function 967R
RM, see Obsolete Routines
RMF, see Obsolete Routines
RMS block mode 788R
RNAME_MBAR keyword 1213R
Roberts edge enhancement 969R
ROBERTS function 969R
Robinson map projection 373U
Romberg integration 862R, 864R
ROOT_DIR keyword 478R
roots 500R, 502R
ROT function 970R, 972R
ROT keyword 359U
ROT_INT, see Obsolete Routines
rot_text.pro (example file) 84O
ROTATE function 972R
ROTATE keyword 337U, 211R, 1110R
Rotate method 293O
rotate method 49O
rotating
arrays 336U, 972R
images 336U, 350R
by arbitrary amounts 970R
the viewing matrix 1109R
views 343U
rotation 48O, 49O
ROUND function 974R
rounding 703R
ceiling function 259R
floor function 487R
to nearest integer 974R
ROUTINE_INFO function 975R
routines
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index R ... R
Index-56
Index
accessing 29U
obsolete 1391R
saving as binary files 982R
ROUTINES keyword 540R, 982R
row bases 1213R
ROW keyword 306B, 356R, 369R, 965R, 1213R
Row Labels table property 236U
Row/Column Major table property 235U
ROW_HEIGHTS keyword 1241R, 1275R, 1302R
ROW_LABELS keyword 1241R, 1303R
ROW_MAJOR keyword 1303R
row-indexed sparse storage method 464U
row-major format 429U
RS_TEST function 448U, 977R
RSI electronic mail address 16U, 9B, 20O, 30R
RSI postal address 16U, 9B, 20O, 29R
RSI telephone and fax numbers 16U, 9B, 20O, 29R
RSI_GAMMAI, see Obsolete Routines
RSTRPOS function 979R
RTF 249U
RTOL keyword 692R
RUN executive command See commands
Runge-Kutta method 967R
run-length encoding 829R
running IDL 20U
runs test for randomness 884R
RUNS_TEST, see Obsolete Routines
runtime IDL 2B
RUNTIME keyword 681R
S
S system variable field 54R
S_TEST function 448U, 980R
S_VALUE keyword 247R
SAMPLE keyword 391R, 470R, 935R
sampled data analysis, aliasing 409U
SAT_P keyword 729R
SATELLITE keyword 725R
satellite map projection 366U, 725R
SAVE keyword 207R, 663R, 1006R, 1092R
Save method 300O
SAVE procedure 34U, 982R, 1404
save/restore
binary files 982R
files 955R
Macintosh differences 136U
Windows differences 114U
heap variables 232B
Index S ... S
SAVE_DIVIDE keyword 1186R
SAVE_HOURGLASS keyword 1269R
saved commands, displaying 539R
saving
files
IDLDE for Macintosh 121U
IDLDE for Motif 44U
IDLDE for Windows 89U
IDL routines as binary files 982R
IDL variables 982R
system variables 983R
variables 983R
saving and restoring heap variables 232B
saving and restoring windows 137O
scalable pixels 325U, 383U, 149R
SCALE keyword 337U, 360U, 299O, 194R, 391R, 716R,
730R, 1110R
Scale method 294O
scale method 50O
SCALE_FACTOR keyword 132R
SCALE3 procedure 338U, 984R
SCALE3D procedure 985R
scaling 335U, 48O, 50O, 1109R
axes 288U
factors 54R
images 384U
values into range of bytes 238R
SCATTER keyword 653R
scene object 28O, 353O
scene objects 36O
SCHOOLBOOK keyword 133R
SCR_XSIZE keyword 306B, 1213R, 1225R, 1242R,
1256R, 1264R, 1282R, 1287R, 1293R, 1303R, 1312R
SCR_YSIZE keyword 306B, 1214R, 1225R, 1242R,
1256R, 1264R, 1282R, 1288R, 1294R, 1303R, 1312R
screen size, finding 308B
SCREEN_DIMENSIONS keyword 221O, 232O, 429O
scripts, AppleScript 438R
scroll bars
for draw widgets 1256R
for text widgets 1309R, 1312R
Scroll base property 206U
Scroll draw area property 231U
SCROLL keyword 356R, 378R, 1214R, 1256R, 1294R,
1303R, 1312R
scroll offset 47R
Scroll table property 236U
Scroll text property 217U
SDEV keyword 604R, 756R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
search path
IDLDE for Macintosh 132U, 133U
IDLDE for Motif 66U
IDLDE for Windows 109U
SEARCH2D function 986R
SEARCH3D function 989R
searching, within strings 1084R
seasonal effect 467U
segmentation 596R
SEGMENTED keyword 789R
sel_obj.pro (example file) 131O
Select method 226O, 436O
SELECT_TARGET keyword 291O
selection 130O
example 131O
graphic atoms 131O
IDLgrWindow object 130O
model objects 131O
views 130O
self argument (objects) 262B
semicolon 85B, 59R
semi-logarithmic plots 208R, 307R, 801R, 1006R,
1093R
SEND_EVENT keyword 1242R
Sensitive common property 198U
SENSITIVE keyword 1214R, 1225R, 1242R, 1256R,
1264R, 1282R, 1288R, 1294R, 1303R, 1312R
sensitizing widgets 301B, 1242R
SEPARATOR keyword 1225R
SET keyword 230R, 1358R
SET_BUTTON keyword 1242R
SET_CHARACTER_SIZE keyword 133R
SET_COLORMAP keyword 133R
SET_DRAW_VIEW keyword 1243R
SET_DROPLIST_SELECT keyword 1243R
SET_FONT keyword 134R
SET_GRAPHICS_FUNCTION keyword 137R
SET_LIST_SELECT keyword 1243R
SET_LIST_TOP keyword 1243R
SET_NATIVE_PLOT, see Obsolete Routines
SET_PLOT procedure 111R, 992R
SET_RESOLUTION keyword 138R
SET_SCREEN, see Obsolete Routines
SET_SHADING procedure 350U, 832R, 994R
SET_SLIDER_MAX keyword 1243R
SET_SLIDER_MIN keyword 1244R
SET_STRING keyword 138R
SET_SYMBOL procedure 996R
SET_TABLE_SELECT keyword 1244R
Index-57
SET_TABLE_VIEW keyword 1244R
SET_TEXT_SELECT keyword 1244R
SET_TEXT_TOP_LINE keyword 1244R
SET_TRANSLATION keyword 138R
SET_UNAME keyword 1245R
SET_UVALUE keyword 1245R
SET_VALUE keyword 356R, 1245R
SET_VIEW.PRO 48O
SET_VIEWPORT, see Obsolete Routines
SET_WRITE_MASK keyword 139R
SET_XY, see Obsolete Routines
SetCurrentCursor method 437O
SETENV procedure 520R, 997R
setjmp, C language 255R
SETLOG procedure 998R
SetPalette method 202O
SetProperty method 214O, 227O, 245O, 255O, 259O,
268O, 276O, 284O, 294O, 301O, 308O, 313O,
322O, 333O, 341O, 352O, 358O, 368O, 373O,
387O, 395O, 401O, 413O, 422O, 438O, 439O
SetRGB method 308O
setting
breakpoints 230R
keywords 111B, 181O, 185R, 585R
properties 33O
properties at initialization 33O
properties of existing objects 33O
the current window 1346R
values 1245R
setting the cursor in a window object 137O
SETUP keyword 655R
SETUP_KEYS procedure 399R, 1000R
SFIT function 438U, 1002R
SGI keyword 1001R
SGML 250U
SH keyword 1049R
SHADE_RANGE keyword 330O, 365O
SHADE_SURF procedure 1004R
SHADE_SURF_IRR procedure 1008R
SHADE_VOLUME procedure 351U, 834R, 1010R
shaded surfaces 1004R
changing position of light source 994R
from polygons 832R
plotting 349U
The SHADE_SURF Procedure 349U
SHADES keyword 352U, 833R, 1006R, 1011R, 1092R
shading 349U, 994R
changing position of light source 994R
parameters 350U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index S ... S
Index-58
Index
volumes 832R
SHADING keyword 330O, 339O, 365O
SHARE_DATA keyword 267O, 321O, 331O, 340O,
365O
shared colormap 138R, 140R
Motif IDLDE 67U
SHARED keyword 789R
sheet feeder 122R
shells, spawning 1047R
SHIFT function 1013R
shifting
array elements 1013R
bit 581R
SHORT keyword 1340R
short word swap 236R
shortcuts, keyboard
IDLDE for Motif 55U
IDLDE for Windows 100U
SHOW keyword 1246R
SHOW_AXIS keyword 243O
SHOW_FILL keyword 275O
SHOW_FULL keyword 1041R
SHOW_OUTLINE keyword 243O, 275O
SHOW_SKIRT keyword 366O
SHOW3 procedure 1015R
SHOWFONT procedure 1017R
showing
images 1153R
windows 1347R
SHOWLOAD keyword 1358R
shrink operator 452R
shrinking
arrays 935R
windows 1347R
SIBLING keyword 1275R
SIG_AB keyword 605R
SIGMA keyword 283R, 678R, 1099R
SIGMA, see Obsolete Routines
sign test 980R
SIGN_TEST, see Obsolete Routines
signal
analysis transforms 400U
filtering 225R
processing 398U
CONVOL function 311R
SIGNED keyword 823R
significant bits 121R
SILENT keyword 685R, 1362R
simple polygons 71O, 375O
Index S ... S
SIMPLEX keyword 194R
SIMPSON, see Obsolete Routines
Simpson’s rule 866R
simultaneous linear equations, solving 453U
SIN function 1019R
SINDGEN function 1020R
sine 1019R
hyperbolic 1021R
inverse 203R
single-precision
arrays 482R, 490R
converting values to 486R
SINGULAR keyword 1099R
Singular Value Decomposition 438U, 454U, 1096R,
1103R
SINH function 1021R
SINKSORT example routine 245B
SINUSOIDAL keyword 725R
sinusoidal map projection 373U, 725R
SIZ keyword 436R
size
of arrays 1022R
of widgets 306B
SIZE executive command 1393R
SIZE function 124B, 127B, 1022R
SIZE keyword 259O, 373O, 351R, 706R
sizing widgets 304B
sizing windows
graphics
IDLDE for Windows 106U
IDLDEfor Macintosh 130U
IDLDEfor Motif 61U
skeletons of bi-level images 1118R
skewness 755R, 1025R
SKEWNESS function 1025R
SKIP executive command See commands
SKIPF procedure 1026R
SKIRT keyword 366O, 1093R
skirts (surface objects) 106O
slash character 181O, 185R
SLICER procedure 354U, 522R
SLICER, see Obsolete Routines
SLICER3 procedure 1027R
SLIDE_IMAGE procedure 1040R
SLIDE_WINDOW keyword 1041R
slider widgets 223U, 274B, 1291R
changing maximum value 1243R
changing minimum value 1244R
displayed values 222U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
drag events 1296R
draggable 1291R
events returned by 1296R
floating-point 377R
initial position 222U
maximum value 222U, 1293R
minimum value 222U, 1293R
properties 222U
returning minimum and maximum values 1276R
setting attributes 222U
setting events 223U
title 223U
using 165U
SLIDER_MIN_MAX keyword 1276R
smearing (in frequency plots) 405U
SMOOTH function 423U, 469U, 1043R
smoothing 1043R
contours 329U
CONVOL function 311R
example 161U
median 738R
MIN_CURVE_SURF function 300R
SOBEL function 1045R
SOLID keyword 200R
SOLID_WALLS keyword 804R
SORT function 1046R
sorting
arrays 1046R
SINKSORT example 245B
SOURCE keyword 976R
SOURCE_FILES keyword 540R
Space base property 207U
SPACE keyword 356R, 1214R
spaces, removing from a string 77B
SPACING keyword 313O, 709R, 827R
sparse arrays 464U
FULSTR 496R
LINBCG 601R
READ_SPR 915R
SPRSAB 1061R
SPRSAX 1063R
SPRSIN 1064R
WRITE_SPR 1332R
SPARSE keyword 694R
spawining a shell process 1047R
SPAWN procedure 31U, 1047R
SPEARMAN, see Obsolete Routines
Spearman’s rho rank correlation 882R
special characters 26U
Index-59
displaying in plots 68R
special functions
BETA 216R
IBETA 554R
Specifying the Location of a Plot 307U
SPH_4PNT procedure 1051R
SPH_SCAT function 1052R
SPHERE keyword 1133R, 1136R
spherical coordinates 338R
spherical gridding 1052R, 1131R, 1134R
spherical interpolation 1052R
SPHERICAL keyword 587R
spherical triangulation 1131R
SPL_INIT function 445U, 1054R
SPL_INTERP function 445U, 1056R
spline
cubic interpolation 1054R, 1058R, 1059R
thin-plate surface 748R
SPLINE function 445U, 1058R
SPLINE keyword 320U
SPLINE_P procedure 446U, 1059R
spreadsheet data files 918R, 1335R
SPRSAB function 466U, 1061R
SPRSAX function 466U, 1063R
SPRSIN function 466U, 1064R
SQRT function 1066R
square brackets 270U, 28B
See arrays, concatenation
square root 1066R
SRF files
reading 916R
standard file format I/O routines 228B
writing 1333R
SSCALE keyword 1016R
SSWAP keyword 236R
stacked histogram plots (LEGO keyword) 1091R
standard
deviation 755R
image file formats 227B
input 514R
standard deviation 1069R
Standard Generalized Markup Language, SGML 250U
STANDARD keyword 438O
STANDARD_PARALLELS keyword 730R
STANDARDIZE function 476U, 1067R
STANDARDIZE keyword 797R
standardized variables 472U, 1067R
START_COLOR keyword 358R
START_OF_LINE keyword 404R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index S ... S
Index-60
Index
STARTCOL keyword 919R, 1335R
starting IDL 20U
STARTROW keyword 919R, 1335R
startup
file 33U
IDLDE for Macintosh 132U
IDLDE for Motif 64U
IDLDE for Windows 108U
preferences
IDLDE for Macintosh 132U
IDLDE for Motif 64U
IDLDE for Windows 107U
switches 20U
statement labels 84B
statements 84B
STATIC_COLOR keyword 139R
STATIC_GRAY keyword 139R
stationarity 467U
STATIONARY keyword 1202R
statistics 426U
approximating models 282R
fitting data
growth trends 282R
least absolute deviation regression 598R
moving averages 1043R
multiple linear regression 947R
nonlinear least-squares regression 335R
outlying data regression 598R
kurtosis 590R
testing 446U
tools
absolute deviation 755R
Chi-square error, minimizing 604R
combinations 473R
contingency table 330R
cumulative sum 1123R
factorial 473R
frequency tables 546R
histogram 546R
kurtosis 590R, 755R
Lomb normalized periodogram 683R
magnitude-based ranking 892R
maximum 731R
mean 735R, 755R
mean absolute deviation 736R
median 755R
minimum 747R
number generators 840R, 886R, 890R
permutations 473R
Index S ... S
skewness 755R, 1025R
sort 1046R
standard deviation 755R, 1069R
T-statistic, Student’s 1121R
variance 755R, 1179R
STATISTICS keyword 299O
Status Bar
IDLDE for Motif 42U
IDLDE for Windows 86U
STDDEV function 1069R
STDEV, see Obsolete Routines
STEP executive command See commands
STEP keyword 1193R
step plot 399U
STEPMAX keyword 232R, 421R, 768R
STEPOVER executive command See commands
stepping through, debugging 139U
STEPWISE, see Obsolete Routines
STEREOGRAPHIC keyword 725R
stereographic map projection 362U, 725R
STIRLING keyword 473R
STOP keyword 348R
STOP procedure 130B, 1070R
stopping program execution 30U, 229R, 1070R
STR_SEP function 1071R
STRARR function 1073R
STRCOMPRESS function 77B, 78B, 1074R
STREAM keyword 789R
streamlines 1182R
STRETCH procedure 391U, 1075R
string data type 13B
STRING function 74B, 75B, 212B, 1077R
STRING keyword 369R, 561R, 706R
strings 258U, 259U, 17B
calling
IDL functions from 252R
IDL methods from 253R
IDL procedures from 254R
case folding 76B
concatenation 74B
converting to lowercase 1081R
converting to uppercase 1089R
creating arrays 1020R
creating string arrays 1073R
data type, converting to 1077R
executing contents of 458R
extracting substrings from 1083R
finding substrings within 979R, 1084R
formatting data 74B
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
inserting strings into 1085R
length of 79B, 1080R
nonstring arguments to routines 73B
operations 72B, 979R, 1071R
reading data from 931R
removing whitespace from 1074R, 1086R
separating into parts 1071R
substrings 79B
whitespace 77B
STRINGS keyword 386O
STRLEN function 79B, 1080R
STRLOWCASE function 76B, 1081R
STRMESSAGE function 1082R
STRMID function 79B, 81B, 1083R
STRPOS function 79B, 1084R
STRPUT procedure 79B, 80B, 1085R
STRTRIM function 77B, 78B, 1086R
STRUCT_ASSIGN procedure 55B, 1087R
STRUCTURE keyword 1023R
Structure objects 28O
structure of subarrays 65B
STRUCTURE_NAME keyword 1111R
structures
advanced 53B
arrays of 49B
arrays stored in structure form 464U
automatic definition 54B, 252B
concatenating 321R
creating and defining 262U, 42B, 54B, 321R
creating arrays of 949R
definition 55B, 1087R
displaying information on currently-defined 540R
FSTAT 494R
input/output 51B
introduction to 262U, 42B
number of fields in 53B
parameter passing 264U, 47B
references 263U, 45B
relaxed definition 956R, 1087R
relaxed defintion 55B
restoring 57B
returned by widgets 1270R
returning length of 766R
returning number of tags 766R
tag names 321R, 1111R
using help with 264U, 47B
zeroed 43B, 252B
STRUCTURES keyword 540R
structuring element 432R
Index-61
STRUPCASE function 76B, 1089R
STUDENT keyword 681R
STUDENT_T, see Obsolete Routines
Student’s t distribution 1107R, 1108R
Student’s T-statistic 1121R
STUDENT1_T, see Obsolete Routines
STUDRANGE, see Obsolete Routines
STYLE keyword 313O, 331O, 366O, 616R, 629R, 653R,
669R
STYLE system variable field 54R
STYLES keyword 220O, 231O, 345O, 417O, 428O
SUB_RECT keyword 924R
SUBDIRECTORY keyword 478R
SUBMIT keyword 790R
submitting a print job 141O
subscripts 60B
array valued 66B
arrays 261U
examples 61B
of scalars 63B
ranges 64B
ranges, combined with arrays 67B
subscript arrays 87B, 89B
SUBSTITUTE keyword 259O
substrings 79B
SUBTICKLEN 211O
SUBTICKLEN keyword 211O, 243O
SUBTITLE keyword 106R
SUBTITLE system variable field 51R
subtraction operator 271U, 29B
SUBTYPE keyword 647R
summation, array elements 1123R
SUN keyword 1001R
Sun raster files
reading 916R
writing 1333R
SUPERCLASS keyword 771R
SUPERSEDE keyword 790R
Suppress Value slider property 222U
SUPPRESS_ERROR keyword 579R
SUPPRESS_VALUE keyword 378R, 1294R
suppressing information messages 45R
surf_track.pro (example file) 110O, 441O
surface fitting 436U
SFIT 1002R
surface object 30O, 359O
surface objects 104O
creating 104O
example 110O
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index S ... S
Index-62
Index
hidden line removal 106O
rendering style 105O
shading 105O
skirts 106O
texture mapping 107O
using 105O
surface plots 331U, 1377R
with images and contours 1015R
SURFACE procedure 331U, 1090R
duplicating tranformations 1095R
SURFACE_FIT, see Obsolete Routines
surfaces, shaded 740R, 1004R, 1008R
SURFR procedure 1095R
suspending execution 140U
SVBKSB, see Obsolete Routines
SVD, see Obsolete Routines
SVDC procedure 460U, 1096R
SVDFIT function 438U, 1098R
SVSOL function 460U, 1102R
SWAP_ENDIAN function 1104R
SWAP_ENDIAN keyword 786R
SWAP_IF_BIG_ENDIAN keyword 236R, 786R
SWAP_IF_LITTLE_ENDIAN keyword 236R, 786R
swapping the order of bytes 235R
switches, command-line 20U
SX keyword 488R, 848R
SY keyword 488R, 848R
SYLK files 918R, 1335R
SYM_HT keyword 1202R
SYM_LEN keyword 1202R
SYMBOL keyword 321O, 340O, 139R
symbol object 31O, 370O
symbol objects 67O
symbolic link files 918R, 1335R
symbols, plotting 295U, 296U, 51R, 105R, 1177R
symmetric
array or matrix 1140R, 1142R
arrays 430U
SYMSIZE keyword 106R
system
clock 1105R
files 139B
SYSTEM keyword 846R, 976R
System Menu base property 207U
system variable fields
BACKGROUND 49R
BLOCK 39R
CHANNEL 49R
CHARSIZE 49R, 52R
Index S ... S
CHARTHICK 49R
CLIP 49R
CODE 39R
COLOR 49R
CRANGE 52R
FILL_DIST 46R
FLAGS 46R
FONT 49R
GRIDSTYLE 53R
LINESTYLE 49R
MARGIN 53R
MINOR 53R
MSG 39R
MSG_PREFIX 39R
MULTI 50R
N_COLORS 46R
NAME 39R, 46R
NOCLIP 51R
NOERASE 51R
NSUM 51R
OMARGIN 53R
ORIGIN 47R
POSITION 51R
PSYM 51R
RANGE 54R
REGION 51R, 54R
S 54R
STYLE 54R
SUBTITLE 51R
SYS_CODE 39R
SYS_MSG 39R
T 51R
T3D 51R
TABLE_SIZE 47R
THICK 52R, 55R
TICKFORMAT 55R
TICKLEN 52R, 55R
TICKNAME 55R
TICKS 56R
TICKV 56R
TITLE 52R, 56R
TYPE 56R
UNIT 47R
WINDOW 48R, 56R
X_CH_SIZE 48R
X_PX_CM 48R
X_SIZE 48R
X_VSIZE 48R
Y_CH_SIZE 48R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
Y_PX_CM 48R
Y_SIZE 48R
Y_VSIZE 48R
ZOOM 48R
system variables 266U, 22B, 37R
!C 46R
!D 46R
!D.TABLE_SIZE 1164R
!D.WINDOW 1199R, 1317R, 1346R
!EDIT_INPUT 24U
!ERR 1114R, 1203R
!ERROR_STATE 149B, 745R, 1082R
!JOURNAL 582R
!MAP 359U
!MAP1 723R
!MOUSE 332R
!ORDER 382U, 48R, 1154R, 1162R
!P 49R
!P.MULTI 162R
!P.T 107R
!QUIET 745R
!X 52R
!Y 52R
!Z 52R
creating 409R
displaying information on currently-defined 540R
for axes 52R
for errors 149B
for graphics 46R
obsolete 1391R
read-only 409R
saving 983R
SYSTEM_VARIABLES keyword 540R, 983R
SYSTIME function 1105R
SZ keyword 488R
T
T system variable field 51R
T_CVF function 1107R
T_PDF function 1108R
T3D keyword 107R, 310R, 833R, 1009R
T3D procedure 336U, 1109R
T3D system variable field 51R
TABLE keyword 998R, 1146R
table widgets 237U, 275B, 1298R
alignment of text 234U
attributes 234U
cell select events 237U
Index-63
column labels 234U
column width change events 238U
data invalid events 239U
data transfer to 235U
editing cells 235U
events 237U
focus events 238U
heading display 234U
height 235U
insert character events 239U
insert string events 239U
keyboard focus events 1301R
row labels 236U
scroll height 237U
scroll width 236U
scrolling 236U
sizing columns 235U
text delete events 238U
text selection events 240U
using 166U
width 235U
TABLE_ALL_EVENTS keyword 1276R
TABLE_EDIT_CELL keyword 1276R
TABLE_EDITABLE keyword 1276R
TABLE_SELECT keyword 1276R
TABLE_SIZE system variable field 47R
TABLE_VIEW keyword 1276R
TABLE_XSIZE keyword 1246R
TABLE_YSIZE keyword 1246R
tabs, removing from a string 77B
tabulated data 444U
TAG_NAMES function 1111R
tags, number in a structure 766R
TAN function 1112R
TAN0 keyword 1059R
TAN1 keyword 1060R
tangent 1112R
hyperbolic 1113R
inverse 206R
TANH function 1113R
tapes
reading from 1114R
rewiding 962R
skipping records 1026R
writing data to 1115R
writing EOF mark 1200R
TAPRD procedure 1114R
TAPWRT procedure 1115R
TEK_COLOR procedure 1116R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index T ... T
Index-64
Index
TEK_COLORS keyword 197R
TEK4014 keyword 139R
TEK4100 keyword 140R
Tektronix device 169R
telephone and fax numbers for RSI 16U, 9B, 20O, 29R
TEMP_DIRECTORY keyword 299O
TEMPLATE keyword 533R, 899R
TEMPORARY function 137B, 1117R
temporary variables 1117R
TERM environment variable 23U
TERMINAL keyword 478R, 998R
TERMINATE keyword 402R
ternary operator, ?: 36B
tesselation 1131R
Tessellate method 378O
tessellator object 31O, 375O
tessellator objects 71O
test functions 683R
CTI_TEST 330R
FV_TEST 498R
KW_TEST 591R
LNP_TEST 683R
MD_TEST 733R
R_TEST 884R
RS_TEST 977R
S_TEST 980R
TM_TEST 1121R
XSQ_TEST 1375R
test mode, IDL GUIBuilder 158U
test_surface.pro (example file) 53O
TESTCONTRAST, see Obsolete Routines
text
aligning 1379R
character
height 48R
size 49R
thickness 49R, 1380R
width 48R
displaying 1354R
font index 102R
font selection 49R
plane of 1380R
plotting in graphics windows 1379R
positioning 81R
replacing
IDLDE for Macintosh 123U
IDLDE for Motif 47U
IDLDE for Windows 93U
searching for
Index T ... T
IDLDE for Macintosh 122U
IDLDE for Motif 46U
IDLDE for Windows 92U
selecting, IDLDE for Windows 111U
size 100R
size of characters 1380R
widgets, See text widgets
width of 1380R
TEXT keyword 1354R
Text label property 221U
text object 30O, 380O
text objects 80O
3D 82O
alignment 82O
baseline and upward direction 82O
creating 81O
font 84O
location 81O
on the glass 82O
using 81O
text widgets 275B, 1309R
appending text to 1232R
changing selected text 1249R
converting
character offsets to column/line form 1277R
line/column positions to character
offsets 1277R
delete events 218U
determining
if all events are being returned 1276R
if text widget is editable 1276R
editable 1310R
making editable after creation 1235R
events returned by 1231R, 1309R, 1314R
focus events 218U
keyboard focus events 1311R
properties 216U
returning
line number of top line in viewport 1277R
number of characters 1277R
offsets of text selection 1277R
selected text 1249R
selection events 219U
setting
text selection 1244R
top line 1244R
setting attributes 216U
setting editable state 216U
setting height 216U
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
setting initial displays 216U
setting keyboard focus to 1238R
setting scrolling 217U
setting width 217U
setting word wrapping 217U
string insert events 219U
suppressing newline characters 1240R
text insert events 218U
using 165U
TEXT_ALL_EVENTS keyword 1276R
TEXT_AXES keyword 1380R
TEXT_COLOR keyword 275O
TEXT_EDITABLE keyword 1276R
TEXT_NUMBER keyword 1277R
TEXT_OFFSET_TO_XY keyword 1277R
TEXT_SELECT keyword 1277R
TEXT_TOP_LINE keyword 1277R
TEXT_XY_TO_OFFSET keyword 1277R
TEXTANGLE keyword 673R
TEXTPOS keyword 211O
texture mapping 107O
TEXTURE_COORD keyword 331O, 366O
TEXTURE_INTERP keyword 331O, 366O
TEXTURE_MAP keyword 331O, 367O
THICK keyword 212O, 243O, 313O, 321O, 332O,
340O, 367O, 373O, 107R, 201R, 642R, 646R, 652R,
657R, 658R, 793R, 801R, 1202R
THICK system variable field 52R, 55R
THICKNESS field 192O
THICKNESS keyword 259O
thickness of characters 1380R
THIN function 1118R
thinning images 1118R
thin-plate-spline surface 748R
THREED keyword 244O
THREED procedure 1119R
three-dimensional
graphics 334U
transformations
array transforms 1186R
coordinates 314R, 380R
duplicating SURFACE transforms 1095R
implementing transforms 1109R
matrices 335U
PLOT and CONTOUR 343U
plotting 314R, 380R
scaling 984R, 985R
specifying orientation 350R
T3D keyword 51R
Index-65
THRESH keyword 1061R, 1064R
THRESHOLD keyword 140R, 340R
throw, C++ language 255R
tick labels 80O
tick marks 302U
annotation 55R, 109R
data values for 56R, 109R
getting values of 109R
intervals 56R, 109R
length 52R, 108R
length on individual axes 55R, 108R
linestyles 302U, 102R
minor 53R, 103R
string labels for 55R
styles 53R
suppressing 56R, 109R
TICKDIR keyword 212O
TICKFORMAT keyword 212O, 244O
TICKFORMAT system variable field 55R
TICKFRMTDATA keyword 212O, 244O
TICKINTERVAL keyword 254O
TICKLEN keyword 302U, 213O, 244O, 254O, 108R
TICKLEN system variable field 52R, 55R
TICKNAME system variable field 55R
TICKS system variable field 56R
TICKTEXT keyword 213O, 244O
TICKV system variable field 56R
TICKVALUES keyword 213O, 244O
TIFF files
reading 921R
standard file format I/O routines 228B
writing 1337R
TIFF_DUMP, see Obsolete Routines
TIFF_READ, see Obsolete Routines
TIFF_WRITE, see Obsolete Routines
TILT keyword 509R
time
converting from string to binary 219R
returning current 1105R
TIME_TEST procedure 1120R
timed demo mode 414R
timer events (for widgets) 302B
TIMER keyword 302B, 1247R
TIMES keyword 140R
time-series analysis 466U
autocorrelation 187R
autocovariance 187R
autoregressive modeling 1147R, 1149R
cross correlation 240R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index T ... T
Index-66
Index
cross covariance 240R
forward differencing 1148R
Title Bar base property 208U
Title base property 207U
Title droplist property 224U
TITLE keyword 213O, 244O, 275O, 434O, 109R, 211R,
296R, 369R, 374R, 378R, 380R, 424R, 427R, 429R,
430R, 616R, 629R, 653R, 669R, 728R, 806R, 1041R,
1119R, 1182R, 1214R, 1264R, 1294R, 1318R,
1355R, 1358R
Title slider property 223U
TITLE system variable field 52R, 56R
titles 74O
titles, multiline 289U
TLB_FRAME_ATTR keyword 1215R
TLB_GET_OFFSET keyword 1247R
TLB_GET_SIZE keyword 1248R
TLB_KILL_REQUEST_EVENTS keyword 1215R,
1248R, 1277R
TLB_LOCATION keyword 616R, 629R, 653R, 669R
TLB_SET_TITLE keyword 1248R
TLB_SET_XOFFSET keyword 1248R
TLB_SET_YOFFSET keyword 1248R
TLB_SIZE_EVENTS keyword 1216R
TM_TEST function 448U, 1121R
t-means test 1121R
TMP keyword 478R
TNAME keyword 1023R
TO_CYLIN keyword 338R
TO_DATA keyword 310R
TO_DEVICE keyword 310R
TO_NORMAL keyword 310R
TO_POLAR keyword 339R
TO_RECT keyword 339R
TO_SPHERE keyword 339R
toggle buttons 1227R
TOL keyword 602R, 679R
TOLF keyword 232R, 768R
TOLMIN keyword 232R, 768R
TOLX keyword 232R, 421R, 768R
Tomographic reconstructions 963R
toolbars
IDL GUIBuilder 164U
IDLDE for Motif 41U, 72U
IDLDE for Windows 85U
TOP keyword 207O, 249O, 262O, 280O, 289O, 317O,
326O, 336O, 361O, 382O, 405O, 238R, 544R, 833R,
1165R
top margin, setting 53R
Index T ... T
TOP_ID keyword 1041R
TOP_STRETCH keyword 304O, 306O
top-level base 1205R
TOTAL function 1123R
TQLI, see Obsolete Routines
TRACE executive command See commands
TRACE function 460U, 1125R
traceback information 148B
displaying 540R
returning 538R
TRACEBACK keyword 540R, 746R
TRACK keyword 342R, 391R, 1358R
TrackBall
class 31O
Trackball
Init method 442O
Reset method 443O
Update method 444O
TrackBall object 440O
trackball_define.pro (example file) 55O
TRACKING_EVENTS keyword 1216R, 1225R, 1248R,
1257R, 1264R, 1277R, 1283R, 1288R, 1294R,
1303R, 1312R
tranformations
rotation 49O
TRANS keyword 851R
TRANSFER_COUNT keyword 933R, 1344R
TRANSFORM keyword 292O
transformation matrices 335U, 51R
transformations 50O, 51O
coordinate 51O
example 53O
model objects 48O
rotation 48O
scaling 48O
translation 48O, 49O
transforms
Fourier 400U, 474R
Hilbert 411U
wavelet 413U
TRANSLATE keyword 337U, 1110R
Translate method 295O
translate method 49O
translation 335U, 48O, 49O, 1109R
TRANSLATION keyword 140R, 281R
translation tables, bypassing 117R
transparency of voxels 124O
TRANSPARENT keyword 357O, 393O, 828R, 911R,
1329R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
TRANSPOSE function 430U, 1126R
transposing arrays 1126R
Transverse Mercator map (UTM) projection 369U,
725R
TRANSVERSE_MERCATOR keyword 725R
TRED2, see Obsolete Routines
tree 36O
TREE_EXAMPLE example routine 248B
trees 242B
binary 248B
trend analysis 467U
TRI_SURF function 1128R
TRIAL keyword 681R
Triangle Fans 146O
Triangle strips 147O
TRIANGULATE keyword 719R
TRIANGULATE procedure 446U, 1131R
triangulation 1131R, 1134R
spherical 1131R
TRIANGULATION keyword 307R
TRIDAG, see Obsolete Routines
tridiagonal array or matrix 1140R, 1142R, 1143R
TRIGRID function 446U, 1134R
trilinear interpolation 573R
TRIM keyword 1071R
trimming strings 1086R
TRIQL procedure 444U, 1140R
TRIRED procedure 444U, 1142R
TRISOL function 460U, 1143R
TRNLOG function 1145R
TRUE keyword 908R, 1154R, 1162R, 1325R
true map scale, setting 360U
true, definition of 103B
TRUE_COLOR keyword 141R
true-color
displays 392U
images
converting to pseudo-color 279R
displaying 1154R
PostScript 158R
reading 1162R
visuals 120R
TrueType 74R, 136R
TrueType fonts 64O, 65R, 86R
TRUNCATE_ON_CLOSE keyword 790R
TS_COEF function 469U, 1147R
TS_DIFF function 469U, 1148R
TS_FCAST function 469U, 1149R
TS_SMOOTH function 469U, 1151R
Index-67
TT_FONT keyword 141R, 1017R
TTY keyword 141R
TUMBLE_CNT keyword 366R
TUMBLE_PERIOD keyword 366R
TV procedure 381U, 1153R
TVCRS procedure 395U, 1157R
TVDELETE, see Obsolete Routines
TVLCT procedure 388U, 1159R
TVRD function 385U, 395U, 1161R
TVRDC, see Obsolete Routines
TVSCL procedure 381U, 1164R
TVSET, see Obsolete Routines
TVSHOW, see Obsolete Routines
TVWINDOW, see Obsolete Routines
TWO_PASS_QUANTIZE keyword 908R
TWO_SIDED keyword 410O
two-dimensional Gaussian fit 508R
two-tailed hypothesis tests 447U
Type button property 214U
type conversion
to 64-bit integer 689R
to byte 234R
to complex 285R, 396R
to double-precision 442R
to integer 484R
to longword 688R
to single-precision, floating-point 486R
to string 1077R
to unsigned 64-bit integer 1174R
to unsigned integer 1167R
to unsigned longword 1173R
TYPE keyword 282O, 411R, 518R, 561R, 624R, 706R,
808R, 1024R, 1278R
TYPE system variable field 56R
type-ahead buffer 514R
typestyle 84O
typographical conventions 27O
U
UDF_BLOCK keyword 790R
UI_VALUE keyword 247R
UINDGEN function 1166R
UINT function 1167R
UINT keyword 562R
UINTARR function 1168R
UL_VALUE keyword 247R
UL64 keyword 562R
UL64_VALUE keyword 247R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index U ... U
Index-68
Index
UL64INDGEN function 1169R
ULINDGEN function 1170R
ULON64ARR function 1171R
ULONARR function 1172R
ULONG function 1173R
ULONG keyword 562R
ULONG64 function 1174R
UNAME keyword 1216R, 1226R, 1257R, 1265R, 1278R,
1283R, 1288R, 1294R, 1304R, 1313R
unconstrained minimizer 462U
underflow errors 151B
UNEQUAL keyword 1122R
unformatted binary data 933R, 1344R
unformatted I/O 158B, 191B
uniform random deviates 891R
uniformly-distributed random numbers 890R
UNIQ function 1175R
UNIT keyword 909R, 1049R, 1325R
unit number, logical 785R
UNIT system variable field 47R
UNITS keyword 224O, 226O, 235O, 349O, 393O,
421O, 434O, 437O, 624R, 1216R, 1226R, 1248R,
1257R, 1265R, 1278R, 1283R, 1288R, 1295R,
1304R, 1313R
Unix
environment variables 519R
UNIX, OS-specific file I/O information 213B
unmapping widgets 1209R
UNRESOLVED keyword 976R
unsharp masking 384U
unsigned 64-bit integer
arrays 1169R
data type, converting to 1174R
unsigned arrays
longword 1170R
unsigned data type
integer 12B
long 12B
unsigned integer
arrays 1166R
data type, converting to 1167R
UNSIGNED keyword 924R
unsigned longword
arrays 1172R
data type, converting to 1173R
UP keyword 333R
UPDATE keyword 309B, 351R, 1249R, 1279R
Update method 444O
UPDATE_DATA keyword 620R
Index V ... V
updating files (OPENU procedure) 783R
UPDIR kwyword 386O
upper margin, setting 53R
UPPER_ONLY keyword 1093R
uppercase, converting strings to 1089R
USA keyword 709R, 728R
USE_CURRENT keyword 1362R
USE_TABLE_SELECT keyword 1249R, 1279R
USE_TEXT_COLOR keyword 213O
USE_TEXT_SELECT keyword 1249R
USE_TRIANGLES keyword 367O
USE_ZVALUE keyword 321O
USEDOUBLES keyword 919R
USELONGS keyword 919R
user interface compound widgets 276B
user values
for widgets 286B
setting 1245R
USER_FONT keyword 141R
user-defined plotting symbols 1177R
USERSYM procedure 296U, 1177R
using external modules 245R
UTM (Transverse Mercator) map projection 369U,
725R
UVALUE keyword 213O, 224O, 235O, 244O, 254O,
259O, 267O, 275O, 283O, 292O, 306O, 313O,
321O, 340O, 350O, 357O, 367O, 373O, 386O,
394O, 400O, 411O, 421O, 434O, 342R, 351R, 356R,
358R, 361R, 366R, 369R, 374R, 378R, 380R, 384R,
388R, 391R, 1216R, 1226R, 1257R, 1265R, 1283R,
1288R, 1295R, 1304R, 1313R
UX keyword 977R
UY keyword 978R
V
VALID_DATA keyword 406O
VALID_ID keyword 1279R
value
parameters passed by 120B
widgets 284B
VALUE keyword 247R, 351R, 369R, 378R, 706R, 1226R,
1257R, 1265R, 1283R, 1289R, 1295R, 1304R, 1313R
VALUES keyword 434R, 453R, 994R
VARIABLE keyword 790R
Variable Watch Window 145U
VARIABLE_WTS keyword 274R
variables 264U, 21B
associated 204R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
attributes of 264U, 21B
deleting 413R
derived 472U
disappearing 142B
displaying current 145U
interactive editing tool (XVAREDIT
procedure) 1378R
named 181O, 184R, 185R
names of 265U, 21B
reading display images into (TVRD
function) 1161R
returning information on 537R
saving 983R
standardized 472U
system 266U, 22B
temporary 1117R
VARIABLES keyword 976R, 983R
variance 498R, 755R
VARIANCE function 1179R
VARIANCE keyword 1099R
VARIANCES keyword 797R
VAX_CALL_EXT routine 1406
VAX_FLOAT function 1180R
VAX_FLOAT keyword 247R, 786R, 1406
VAXTOD keyword 236R
VAXTOF keyword 236R
VECTOR keyword 1342R
vector-drawn fonts 65R, 89R
! character 81R
displaying 1017R
editing (EFONT procedure) 443R
special characters 68R
vectors
drawing arrowheads 200R
subscripting 64B
VEL procedure 1182R
velocity field, plotting 488R, 1182R, 1184R
VELOVECT procedure 1184R
VERBOSE keyword 536R, 899R, 911R, 924R, 956R,
983R, 1011R, 1088R, 1329R, 1340R
VERSION keyword 1279R
VERT_COLORS keyword 321O, 332O, 340O, 367O
VERT_T3D function 1186R
VERTICAL keyword 378R, 388R, 1295R
vertical slider, See slider widgets
VERTICAL_ALIGNMENT keyword 386O
view area 42O
view menu (online help viewer) 246U
view object 28O, 388O
Index-69
view objects 37O
view volume 46O
finding an appropriate 47O
viewgroup object 28O, 396O
viewgroup objects 37O
viewplane rectangle 46O
VIEWPLANE_RECT 46O
routine for determining 47O
viewport 42O
Viewport Columns table property 236U
Viewport Rows table property 237U
VIEWPORT_EVENTS keyword 1258R
virtual memory 124B, 135B
minimizing 137B
running out of 136B
system parameters 138B
Visible base property 208U
Visible property 208U
VISUALIZATION_IN keyword 624R, 642R, 647R,
658R, 673R
VISUALIZATION_PROPERTIES keyword 663R
VMS
Open VMS
virtual memory performance
VMS file I/O information 217B
VMS logical name 412R
VMS logical name tables 1145R
VMS logical tables 1146R
VMS text libraries 462R
VMSCODE, see Obsolete Routines
VOIGT function 1188R
volume object 30O, 402O
volume objects 122O
attributes 124O
color values 125O
compositing 126O
creating 122O
interpolating values 127O
lighting 126O
opacity table 124O
rendering speed 127O
using 122O
zbuffering 126O
volume slices 1027R
VOLUME_SELECT keyword 411O
volumes
extracting slices 469R
rendering 850R
searching for objects 989R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index V ... V
Index-70
Index
visualizing 351U, 832R, 850R, 1010R, 1192R
VOLUMES keyword 404O
volumetric reconstruction 939R
VORONOI procedure 446U, 1190R
voxel rendering 1192R
voxel values (volume object) 122O
VOXEL_PROJ function 1192R
VRML object 32O, 414O
VRML objects 141O
creating 141O
VT200 keyword 1001R
VT240 keyword 141R
VT240 terminal 168R
VT330 terminal 168R
VT340 keyword 141R
VT340 terminal 168R
W
WAIT keyword 333R
WAIT procedure 130B, 1196R
WARM keyword 1202R
WARP_TRI function 1197R
warping
images 820R
to maps 715R, 718R
polynomial 820R
using the Z-buffer 828R
Wavefront Advanced Data Visualizer 926R, 1342R
Wavefront files
reading 926R
writing 1342R
wavelet transform 413U, 1348R
WDELETE procedure 144R, 1199R
weather fronts, plotting 1201R
WEIGHT keyword 1099R
WEIGHTS keyword 283R, 679R
WEOF procedure 1200R
WF_DRAW procedure 1201R
WHERE function 1203R
while statement 108B
whitespace, removing from strings 77B, 1074R, 1086R
WIDED, see Obsolete Routines
Widget Browser 169U, 191U
WIDGET_BASE function 306B, 1205R
WIDGET_BUTTON function 1222R
WIDGET_CONTROL procedure 300B, 301B, 1230R
WIDGET_DRAW function 1252R
WIDGET_DROPLIST function 1262R
Index W ... W
WIDGET_EVENT function 1268R
WIDGET_INFO function 1271R
WIDGET_KILL_REQUEST event 1215R
WIDGET_LABEL function 1280R
WIDGET_LIST function 1285R
WIDGET_MESSAGE, see Obsolete Routines
WIDGET_SLIDER function 1291R
WIDGET_TABLE function 1298R
WIDGET_TEXT function 1309R
widgets 202U, 210U, 272B
3D orientation 276B
aligning (ALIGN_XXX keywords) 1205R
animation 341R
annotation 196R
application
errors 282B
tips 315B
background tasks (TIMER keyword) 1247R
base 273B, 1205R
base focus events 210U
base, alignment 203U
base, allow moving 204U
base, allowing closing 203U
base, displaying titlebars 208U
base, floating 204U
base, grid layouts 204U
base, kill request events 210U
base, layouts 205U
base, menus, using system 207U
base, modal 206U
base, resizing 206U
base, rows and columns 202U
base, scroll area size 209U
base, scrolling 206U
base, setting properties 202U
base, spacing of contained widgets 207U
base, spacing of widgets in 208U, 209U
base, titles 207U
base, visibility 208U
bases, using 165U
blocking (MODAL keyword) 1365R
Browser 169U
button, press events 215U
button, release events 214U
button, setting properties 212U
buttons 273B, 1222R
bitmap labels 928R
groups 354R
release events 1224R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
buttons, adding menus 173U
buttons, displaying bitmaps 213U
buttons, labels 214U
buttons, using 165U
callbacks 1209R, 1211R
changing appearance of 1211R, 1225R, 1256R,
1264R, 1282R, 1287R, 1293R, 1312R
changing values 301B
checkboxes, using 165U
color
index 358R, 387R
resources 1213R
selection 360R
common blocks and 312B
common events 199U
compound 276B, 314B, 316B, 341R, 350R, 354R,
358R, 360R, 362R, 366R, 368R, 377R, 380R,
382R, 387R, 390R
template for creating 389R
compound, adding 188U
compound, example 188U
compound, handling events for 199U
controlling 300B
controlling visibility 191U
creating in IDL GUIBuilder 164U
creating with IDL GUIBuilder 150U
default font for 1233R
destroy events 200U
destroying 1234R
determining if widgets are realized
(ACTIVE keyword) 1271R
(REALIZED keyword) 1275R
disabling and enabling screen updates (UPDATE
keyword) 1249R
displaying 191U
draw 273B, 294B, 1252R
draw area properties 229U
draw area, color model 229U
draw events 232U
draw, attributes 229U
draw, backing store 231U
draw, changing view events 233U
draw, colors used in 229U
draw, graphic type 230U
draw, mouse events 232U
draw, mouse motion events 233U
draw, render type 230U
draw, scrolling 231U
draw, scrolling area 231U
Index-71
draw, using 166U
draw, viewport move events 233U
droplist 274B, 1262R
droplist attributes 224U
droplist events 224U
droplist properties 224U
droplist, select events 225U
droplist, title 224U
droplists, initial value 224U
droplists, using 165U
dynamic resizing 306B
enabled or disabled state 198U
events 287B, 1268R
CLEAR_EVENTS keyword 1232R
examples 278B
exclusive buttons 1208R
explicit size 305B
field 368R
finding screen size 308B
form 371R
frames, using 197U
geometry 305B
getting user values 1236R
height 199U
help buttons 1223R
hiding and showing 1246R
hierarchies 300B
horizontal size, changing 1242R, 1250R
hourglass cursor 301B
iconifying 1238R
interrupting the event loop 311B
invalid IDs 1232R, 1268R
killing hierarchies 300B
label 274B, 1280R
label, setting properties 221U
labels, using 165U
lifecycle 281B
list 274B, 1285R
listbox attributes 226U
listbox events 227U
listbox properties 226U
listbox, height 226U
listbox, initial value 226U
listbox, multiple selections 226U
listbox, selection events 227U
listbox, using 165U
listbox, width 227U
location 306B
main event loop for 1363R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index W ... W
Index-72
Index
managing the state of applications 312B
mapping 1209R
mapping and unmapping 1239R
menu bars 1206R, 1209R
menus 295B
message 274B
message dialog box 423R
modal 423R
modal dialogs 206U
naming 196U
natural size 305B
non-exclusive buttons 1211R
portability 316B
positioning 198U, 1218R, 1219R
post creation events 201U
preventing layout flicker 308B
properties for IDL GUIBuilder 166U
pulldown menu 382R
pulldown menus 298B
separators 1225R
radio buttons, using 165U
realize events 200U
realizing 1241R
hierarchies 300B
region of interest 362R
registered 1374R
registering with XMANAGER 1363R
resetting all widgets 1241R
resizing (DYNAMIC_RESIZE keyword) 1222R,
1262R, 1280R
restarting after an error 282B
retreiving values 301B
returning
children of 1271R
information about 1271R
name of event handler procedure 1273R
parent of 1275R
siblings of 1275R
size of (GEOMETRY keyword) 1273R
tracking event status 1278R
type of 1275R, 1278R
validity of 1279R
sending event to (SEND_EVENT keyword) 1242R
sensitizing 301B
sensitizing and de-sensitizing 1214R, 1225R,
1242R, 1256R, 1264R, 1282R, 1288R, 1294R,
1303R, 1312R
setting button events 215U
setting buttons 1242R
Index W ... W
setting label attributes 221U
showing and hiding 1246R
size 306B
changing
horizontal 1242R, 1250R
vertical 1242R, 1250R
dynamic resizing 306B
explicit 305B
natural 305B
sizing 304B
sizing, default or explicit 197U
slider 274B, 377R, 1291R
slider attributes 222U
slider properties 222U
slider, change value events 223U
slider, displayed values 222U
slider, initial position 222U
slider, maximum value 222U
slider, minimum value 222U
slider, setting events 223U
slider, title 223U
slider, using 165U
space between children 1214R
table 275B, 1298R
table attributes 234U
table events 237U
table properties 234U
table, alignment 234U
table, cell select events 237U
table, column labels 234U
table, column width events 238U
table, data transfer to 235U
table, editing 235U
table, focus events 238U
table, heading display 234U
table, height 235U
table, insert character events 239U
table, insert string events 239U
table, invalid data events 239U
table, row labels 236U
table, scroll height 237U
table, scroll width 236U
table, scrolling 236U
table, sizing columns 235U
table, text delete events 238U
table, text selection events 240U
table, using 166U
table, width 235U
template for creating 1369R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
text 275B, 1309R
text, character inserts 218U
text, delete event 218U
text, editable 216U
text, events 218U
text, focus events 218U
text, height 216U
text, initial display 216U
text, scrolling 217U
text, selection events 219U
text, string inserts 219U
text, using 165U
text, width 217U
text, word wrapping 217U
timer events 200U, 302B
tracking events 200U, 1216R
types 273B
unmapping 1209R, 1239R
user values 286B
values 284B, 1237R
user 286B
version of implementation 1279R
vertical size, changing 1242R, 1250R
viewing widgets managed by XMANAGER 1370R
width 198U
XMANAGER procedure 1268R
zoom 390R
WIDTH keyword 456R, 786R, 1355R, 1380R
Width listbox property 227U
width of text 1380R
Width text property 217U
Wilcoxon Rank-Sum Test 977R
WILCOXON, see Obsolete Routines
WINDOW keyword 197R, 347R, 760R, 1359R
window object 32O, 424O
window objects 137O
color model 135O
creating 134O
erasing 136O
exposing or hiding 136O
iconifying 137O
in draw widgets 135O
maximum size 136O, 424O
saving and restoring 137O
setting the cursor 137O
using 134O, 136O
WINDOW procedure 144R, 1317R
WINDOW system variable field 48R, 56R
WINDOW_IN keyword 616R, 621R, 624R, 629R, 630R,
Index-73
642R, 648R, 653R, 655R, 658R, 669R, 673R
WINDOW_SCALE keyword 559R
WINDOW_STATE keyword 141R
windowing
Hamming windowed signal 408U
HANNING function 407U
windows
backing store 132R, 144R, 1318R
clipboard support for graphics 88U, 120U
copying areas 118R
copying pixels from 118R
creating 1317R
deleting 1199R
display size 48R
draw widgets 1252R
erasing 451R
exposing 1347R
finding screen size 308B
height 1319R
hiding 1347R
iconifying 1347R
ID for draw widgets 1257R
index of currently open 48R
number of colors 46R
pixmaps 1318R
position of 51R, 126R
positioning 1318R
selecting current 1346R
systems 143R
visible area of display 48R
width 1319R
Windows display device (WIN) 112R
WinHelp 249U
WINX keyword 324R
WINY keyword 324R
wire-mesh surface plots 1090R
WK1 keyword 683R
WK2 keyword 684R
WMENU, see Obsolete Routines
WOLRDTITLE keyword 421O
Word Wrapping text property 217U
WORDS keyword 1155R, 1162R
working directory, changing, Macintosh 135U
World Wide Web 751R
WORLDINFO keyword 421O
WRAP keyword 1313R
wrapper routines 114B
WRITE keyword 427R
write mask 126R, 139R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index W ... W
Index-74
Index
Write method 203O
WRITE_32 keyword 1333R
WRITE_BMP procedure 1320R
WRITE_GIF procedure 1322R
WRITE_JPEG procedure 1324R
WRITE_NRIF procedure 1327R
WRITE_PICT procedure 1328R
WRITE_PNG function 1329R
WRITE_PPM procedure 1331R
WRITE_SPR procedure 466U, 1332R
WRITE_SRF procedure 1333R
WRITE_SYLK function 1335R
WRITE_TIFF procedure 1337R
WRITE_WAVE procedure 1342R
WRITEU procedure 158B, 1344R
writing
a compound widget 316B
BMP files 1320R
files (OPENW procedure) 783R
GIF files 1322R
JPEG files 1324R
NRIF files 1327R
PGM files 1331R
PICT files 1328R
PPM files 1331R
SRF files 1333R
TIFF files 1337R
wave files 1342R
WSET procedure 144R, 1346R
WSHOW procedure 144R, 1347R
WSIZE keyword 848R
WTN function 423U, 1348R
X
X keyword 300R
X Offset common property 198U
X Pad base property 208U
X resources 66U
widget colors 1213R
X Scroll base property 209U
X Scroll draw area property 231U
X Size common property 198U
X vs. Y Plots 287U
X Windows
bitmap files, reading 928R
Dump files, reading 930R
fonts 1356R
resource names 1211R, 1225R, 1256R, 1264R,
Index X ... X
1282R, 1287R, 1293R, 1312R
X Windows device 171R
DirectColor visual 121R
PseudoColor visual 131R
StaticColor visual 139R
StaticGray visual 139R
TrueColor visual 141R
visuals 171R
X_BITMAP_EXTRA keyword 1226R, 1250R
X_CH_SIZE system variable field 48R
X_PX_CM system variable field 48R
X_SCROLL_SIZE keyword 356R, 391R, 1217R, 1258R,
1305R, 1378R
X_SIZE system variable field 48R
X_TICKNAME keyword 617R, 648R, 654R, 670R
X_VSIZE system variable field 48R
X_ZSIZE keyword 391R
X0 keyword 408R, 436R
X11 Bitmap, standard file format I/O routines 228B
XANIMATE, see Obsolete Routines
XAXIS keyword 207R
XAXIS_IN keyword 648R
XAXIS_PROPERTIES keyword 664R
XBACKREGISTER, see Obsolete Routines
XBM_EDIT procedure 1228R, 1352R
XCHARSIZE keyword 100R
XCOORD_CONV keyword 213O, 245O, 254O, 267O,
275O, 283O, 321O, 332O, 340O, 367O, 386O,
411O
XDICE procedure 323B
XDISPLAYFILE procedure 1354R
XDL, see Obsolete Routines
XDR 197B
XDR files 160B, 983R
XDR format (floating point values) 235R
XDR keyword 786R, 983R
XDRTOD keyword 237R
XDRTOF keyword 237R
XFONT function 1356R
XGRID keyword 587R, 1129R, 1136R
XGRIDSTYLE keyword 102R
XINDEPENDENT keyword 616R, 669R
XINTERANIMATE procedure 1357R
XLOADCT procedure 390U, 1361R
XLOG keyword 208R, 307R, 617R, 653R, 669R, 801R,
1006R, 1093R
XMANAGER procedure 289B, 292B, 315B, 1268R,
1363R
XMANAGERTOOL, see Obsolete Routines
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index
XMARGIN keyword 103R, 728R
XMAX keyword 324R, 1182R
XMAX machine-specific parameter 703R
XMENU, see Obsolete Routines
XMIN keyword 324R
XMIN machine-specific parameter 703R
XMINOR keyword 302U, 103R
XMNG_TMPL procedure 1369R
XMTOOL procedure 1370R
XOFFSET keyword 306B, 142R, 159R, 347R, 356R,
361R, 384R, 1216R, 1226R, 1250R, 1258R, 1265R,
1283R, 1289R, 1295R, 1304R, 1313R, 1360R
XON_XOFF keyword 142R
XOR operator 274U, 33B
XPAD keyword 356R, 1217R
XPALETTE procedure 391U, 1371R
XPDMENU, see Obsolete Routines
XPOS keyword 1318R
XRANGE keyword 290U, 208O, 241O, 250O, 263O,
272O, 322O, 327O, 337O, 362O, 383O, 406O,
106R, 617R, 669R, 984R, 1011R
XREGISTERED function 292B, 1374R
XRESOL keyword 1340R
XSIZE keyword 306B, 142R, 356R, 359R, 369R, 378R,
380R, 391R, 719R, 833R, 1042R, 1155R, 1193R,
1217R, 1227R, 1250R, 1258R, 1265R, 1283R,
1289R, 1295R, 1305R, 1314R, 1319R, 1352R,
1383R, 1385R
XSQ_TEST function 448U, 1375R
XSTART keyword 719R, 844R
XSTYLE keyword 106R
XSURFACE procedure 1377R
XTHICK keyword 302U, 107R
XTICK_GET keyword 109R
XTICKFORMAT keyword 107R
XTICKFORMAT keyword, YTICKFORMAT keyword,
ZTICKFORMAT keyword 302U
XTICKLEN keyword 108R
XTICKNAME keyword 303U, 109R
XTICKS keyword 303U, 109R
XTICKV keyword 303U, 109R
XTITLE keyword 109R, 211R, 1119R
XVALUES keyword 588R, 1129R
XVAREDIT procedure 1378R
XVISIBLE keyword 1042R
xwd files
reading 930R
standard file format I/O routines 228B
654R
Index-75
XY_PLANE keyword 804R
XYEXCH keyword 337U, 1110R
XYOUTS procedure 293U, 1379R
See also positioning
XYSTYLE keyword 804R
XZ_PLANE keyword 804R
XZEXCH keyword 337U, 1110R
XZSTYLE keyword 804R
Y
Y keyword 301R
Y Offset common property 198U
Y Pad base property 209U
Y Scroll base property 209U
Y Scroll draw area property 231U
Y Size common property 199U
Y_CH_SIZE system variable field 48R
Y_PX_CM system variable field 48R
Y_SCROLL_SIZE keyword 357R, 391R, 1217R, 1259R,
1305R, 1378R
Y_SIZE system variable field 48R
Y_TICKNAME 617R, 654R
Y_TICKNAME keyword 648R, 670R
Y_VSIZE system variable field 48R
Y_ZSIZE keyword 392R
Y0 keyword 408R, 436R
YAXIS keyword 207R
YAXIS_IN keyword 648R
YAXIS_PROPERTIES keyword 664R
YCHARSIZE keyword 100R
YCOORD_CONV keyword 214O, 245O, 255O, 267O,
276O, 283O, 322O, 332O, 340O, 368O, 387O,
411O
YFIT keyword 283R, 679R, 1100R
YGRID keyword 588R, 1129R, 1136R
YGRIDSTYLE keyword 102R
YIELD_TO_TTY keyword 1269R
YINDEPENDENT keyword 616R, 669R
YLOG keyword 208R, 307R, 617R, 653R, 669R, 801R,
1006R, 1093R
YMARGIN keyword 103R, 728R
YMAX keyword 324R
YMIN keyword 324R
YMINOR keyword 302U, 103R
YNOZERO keyword 208R, 801R
YOFFSET keyword 306B, 142R, 159R, 347R, 356R,
361R, 384R, 1217R, 1227R, 1250R, 1258R, 1266R,
1284R, 1289R, 1295R, 1305R, 1314R, 1360R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Index Y ... Y
Index-76
Index
YP0 keyword 1054R
YPAD keyword 356R, 1217R
YPN_1 keyword 1054R
YPOS keyword 1318R
YRANGE keyword 290U, 208O, 241O, 250O, 263O,
272O, 322O, 327O, 337O, 362O, 383O, 406O,
106R, 617R, 669R, 984R, 1011R
YRESOL keyword 1340R
YSIZE keyword 306B, 143R, 356R, 359R, 370R, 378R,
380R, 391R, 719R, 834R, 1042R, 1155R, 1194R,
1217R, 1227R, 1250R, 1258R, 1266R, 1284R,
1289R, 1296R, 1305R, 1314R, 1319R, 1352R,
1383R, 1385R
YSTART keyword 719R, 844R
YSTYLE keyword 106R
YTHICK keyword 302U, 107R
YTICK_GET keyword 109R
YTICKFORMAT keyword 107R
YTICKLEN keyword 108R
YTICKNAME keyword 303U, 109R
YTICKS keyword 303U, 109R
YTICKV keyword 303U, 109R
YTITLE keyword 109R, 211R, 1119R
YVALUES keyword 588R, 1129R
YVISIBLE keyword 1042R
YZ_PLANE keyword 804R
YZEXCH keyword 338U, 1110R
YZSTYLE keyword 804R
Z
Z keyword 110R, 300R
ZAPFCHANCERY keyword 143R
ZAPFDINGBATS keyword 143R
ZAXIS keyword 207R, 307R, 1093R
ZAXIS_PROPERTIES keyword 664R
Z-buffer
closing 117R
using with POLYFILL 827R
using with POLYSHADE 832R
warping images to polygons 828R
Z-buffer device 178R
ZBUFFER keyword 412O, 1194R
ZBUFFER_DATA keyword 221O
zbuffering, volume objects 126O
ZCHARSIZE keyword 100R
ZCLIP keyword 394O
ZCOORD_CONV keyword 214O, 245O, 255O, 267O,
276O, 283O, 322O, 332O, 341O, 368O, 387O,
Index Z ... Z
412O
ZD keyword 883R
ZDIFF keyword 980R
ZERO keyword 417R
ZERO_OPACITY_SKIP keyword 412O
zeroed structures 43B, 252B
zeroing byte arrays 233R
ZFAC keyword 324R
ZGRIDSTYLE keyword 102R
ZLOG keyword 1093R
ZMARGIN keyword 103R
ZMAX keyword 324R
ZMIN keyword 324R
ZMINOR keyword 302U, 103R
ZOOM keyword 324R, 363R, 408R
ZOOM procedure 1382R
ZOOM system variable field 48R
zoom widget 390R
ZOOM_24 procedure 1384R
ZOOM_WINDOW keyword 1383R
ZPIXELS keywords 1194R
ZRANGE keyword 290U, 208O, 241O, 250O, 263O,
272O, 318O, 327O, 337O, 362O, 383O, 406O,
106R, 984R, 1011R
ZROOTS, see Obsolete Routines
ZSTYLE keyword 106R
ZTHICK keyword 302U, 107R
ZTICK_GET keyword 109R
ZTICKFORMAT keyword 107R
ZTICKLEN keyword 108R
ZTICKNAME keyword 303U, 109R
ZTICKS keyword 303U, 109R
ZTICKV keyword 303U, 109R
ZTITLE keyword 109R
ZVALUE keyword 344U, 322O, 110R
Using IDL, Building IDL Applications, Object Graphics, Reference Guide Index
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement