Don't be daunted by using callable IDL. It might look complex at first glance but you only need to remember 2 rules:
INTRO: IDL was written as a language to write code from
scratch. Using Fortran to call IDL's capabilites to plot graphs is
a little klugy, but it can be done without too much trouble if you use
this example as a template. The Fortran code, align2.f
calls a C wrapper called callable_wraps.c
This short C program will not need to be changed or even opened.
Just keep a copy of it in the directory where you have your program.
Then you will add an IDL program file to the directory, as well.
This will be where the plot is actually generated. This IDL example
program is called align.pro (remember all
IDL program files must end in .pro). You will also need a Makefile
and shell script to compile and execute the programs. For further
information on compiling, go to Compiling
Callable IDL. Remember, all you have to do is copy much of this
without worrying. If you click on the links to the code, you'll see
complete versions of the code. Below, the code has been commented
on with colored text.
C This program demonstrates how to use Callable IDL from a FORTRAN program.
C Data for five functions are generated; the data are imported into
IDL,
C and a companion IDL program (align.pro) is invoked to plot the
data.
C The companion program brings up a widget application. Included
are a
C button to exit the application and a draw widget where the imported
data
C are plotted.
C All of the arguments and keywords which are passed to the companion
C progrsam (and, subsequently, to the IDL PLOT procedure), are
defined in
C this FORTRAN program.
C The use of companion IDL programs for Callable IDL applications
is very
C desirable. If designed carefully, they can simplify both "sides"
of
C the Callable IDL environment.
C In addition to the companion IDL program, a set of "wrapper" functions,
C written in C, are used to "step" from FORTRAN into the actual
IDL
C internal functions that are called. These "wrapper" functions
are located
C in the file callable_wraps.c .
C Written by Doug Loucks
C Research Systems, Inc., Oct, 1998
C Function data generation and plot annotation are taken from a
program by
C Bill Gadzuk and Barbara am Ende, NIST, October, 1998
C Define a few IDL parameters based upon those found in export.h
PARAMETER
(IDL_FALSE = 0)
PARAMETER
(IDL_TRUE = 1)
PARAMETER
(IDL_TYP_FLOAT = 4)
C This eases changes to the size of the function arrays.
PARAMETER (NUMPOINTS = 80)
C Declare the arrays for the function data.
DIMENSION XP(NUMPOINTS),
*
Y1(NUMPOINTS),
*
Y2(NUMPOINTS),
*
Y3(NUMPOINTS),
*
Y4(NUMPOINTS),
*
Y5(NUMPOINTS)
INTEGER*4 options,
just_cleanup, status
INTEGER*4
ndim, dim(1),
type
INTEGER*4
callback /0/
INTEGER*4
zero /0/
CHARACTER*1
null
C Initialize local variables.
null = char(0)
C Initialize Callable IDL.
options =
0
status = IDL_Init(
options )
C Check for problems. Exit if Callable IDL can't be initialized.
if (status
.eq. IDL_FALSE) then
print *, 'Failure to Initialize Callable IDL. Status: ', status
call exit
endif
C Generate the function data to be plotted (From Barbara am Ende).
EX = 0.0
DEX = 0.1
DO 15 J=1, NUMPOINTS
X1 = EX
X2 = EX / 2.0
X3 = EX / 3.0
X4 = EX / 4.0
X5 = EX / 5.0
Y1(J) = X1 * (2.+X1)
/ (1.+X1)**2
Y2(J) = X2 * (2.+X2)
/ (1.+X2)**2
Y3(J) = X3 * (2.+X3)
/ (1.+X3)**2
Y4(J) = X4 * (2.+X4)
/ (1.+X4)**2
Y5(J) = X5 * (2.+X5)
/ (1.+X5)**2
XP(J) = EX
EX = EX + DEX
15 CONTINUE
C Prepare to import these data into the IDL environment. First,
define
C the arguments to the IDL function that imports data.
ndim = 1
dim(1)
= NUMPOINTS
type = IDL_TYP_FLOAT
callback =
0
zero = 0
C Import each of the function arrays. For your code, use one function
call for each C array you need to import.
call IDL_ImportNamedArray(
'xp' // null,
ndim, dim,
*
type, xp, callback,
zero )
call IDL_ImportNamedArray(
'y1' // null,
ndim, dim,
*
type, y1, callback,
zero )
call IDL_ImportNamedArray(
'y2' // null,
ndim, dim,
*
type, y2, callback,
zero )
call IDL_ImportNamedArray(
'y3' // null,
ndim, dim,
*
type, y3, callback,
zero )
call IDL_ImportNamedArray(
'y4' // null,
ndim, dim,
*
type, y4, callback,
zero )
call IDL_ImportNamedArray(
'y5' // null,
ndim, dim,
*
type, y5, callback,
zero )
C Execute the IDL command that runs the companion IDL program. The
C companion program is passed the data which have been imported
into IDL.
C Here you are calling the name of the procedure contained within
align.pro and
C passing arguments that contain the array names and the keywords
needed for the
C plot command.
call IDL_ExecuteStr(
* 'align,
xp, y1,y2,y3,y4,y5,
* xtitle =
''INCIDENT ENERGY (EV)'',
* xstyle =
1, xticks=4, xminor=10, xrange = [0,8], xsize=500,
* ytitle =
''T TO V EFFICIENCY'',
* ystyle =
1, yrange = [0,1], ysize=500,
* yticks =
1, yminor = 10,
* charsize
= 1, psym=0,
* title=''ALIGN
-- Callable IDL Example''' // null )
C Do the IDL cleanup stuff. With just_cleanup set to one, the IDL_Cleanup
C function returns to this program.
just_cleanup
= 1
status = IDL_Cleanup(
just_cleanup )
print *, 'FORTRAN program TESTPLOT -- Done -- status:', status
CALL EXIT
END
/* Nothing in this program should ever need
to be modified, so instead of
color coding it, the text is
black. The program should simply reside in
the directory with the directory
containing the Fortran and IDL programs
using it. */
/* callable_wraps.c
These wrapper routines are written to be called
from FORTRAN programs
that utilize Callable IDL functions.
Two assumptions about the FORTRAN compiler
used to compile Callable IDL
FORTRAN programs:
1) FORTRAN routine names are generated
in all lower case letters.
2) FORTRAN routine names are appended
with the underscore (_) character.
Future enhancements planned:
1) Generalize for all platforms, including
FORTRAN underscore
differences.
Written by Doug Loucks
Research Systems Incorporated, October, 1998
------------------------------------------------------------------------*/
#include <stdio.h>
/* HINT: export.h is in the external directory
of the IDL installation
tree. */
#include "export.h"
/*-----------------------------------------------------------------------
Function idl_init_
-----------------------------------------------------------------------*/
int idl_init_(int *options) {
int argc = 0;
char *argv[] = {NULL};
return IDL_Init(*options, &argc,
argv);
}
/*-----------------------------------------------------------------------
Function idl_executestr_
-----------------------------------------------------------------------*/
void idl_executestr_( char *cmd ) {
IDL_ExecuteStr( cmd );
}
/*-----------------------------------------------------------------------
Function idl_importnamedarray_
-----------------------------------------------------------------------*/
void idl_importnamedarray_(
char *name,
int *n_dim,
IDL_LONG dim[],
int *type,
UCHAR *data,
void *callback,
void *s ) {
IDL_VPTR v;
v = IDL_ImportNamedArray( name, *n_dim,
dim, *type, data, callback, s);
}
/*-----------------------------------------------------------------------
Function idl_cleanup_
-----------------------------------------------------------------------*/
int idl_cleanup_(int *just_cleanup) {
printf("IDL is cleaning up...\n");
return IDL_Cleanup(*just_cleanup);
}
; This program was written as a companion to the Callable IDL example
; align.f
;
; Written by Doug Loucks
; Research Systems Incorporated, October, 1998.
;-------------------------------------------------------------------------
; Procedure testplot_event
; Event handler for testplot
;-------------------------------------------------------------------------
; The event handler is used to handle the
event of a user clicking on the
; exit button (the button is a widget) in
the window of the plot
PRO testplot_event, event
; Get the user value of the widget that generated the event.
widget_control, event.id, get_uvalue=uvalue
; Handle events.
case uvalue of
'exit' : begin
widget_control, event.top,
/destroy
end
default: begin
print, 'Event
received, no action:'
help, event,
/struct
end
endcase
END
;-------------------------------------------------------------------------
; Procedure align
; This procedure plots 5 functions on the same set of axes.
;
; Input Arguments:
; xp Vector of independent values
; y1 Vector of first set of dependent values.
; y2 Vector of second set of dependent values.
; y3 Vector of third set of dependent values.
; y4 Vector of fourth set of dependent values.
; y5 Vector of fifth set of dependent values.
;
; The input Keywords coincide with those passed to the PLOT procedure
; and the WIDGET_DRAW procedure.
;-------------------------------------------------------------------------
PRO align, xp,
y1, y2, y3, y4, y5,$
xtitle=xtitle, xstyle=xstyle,
xticks=xticks, xminor=xminor,$
xrange=xrange, xsize=xsize,$
ytitle=ytitle, ystyle=ystyle,
yticks=yticks, yminor=yminor,$
yrange=yrange, ysize=ysize,$
charsize=charsize, psym=psym,
title=title
;-------------------------------------------------------------------------
; The purpose of the widget is to force the graph to display on
the monitor
; until the user is done viewing the graph. Without the widget,
the program
; automatically returns back to Fortran and destroys the graph
in microseconds.
; Define the Top Level Base widget.
tlb = widget_base( title=title, /column
)
; Define an Exit button.
b = widget_button( tlb, value='Exit',
uvalue='exit' )
; Define a Draw widget.
d = widget_draw( tlb, xsize=xsize,
ysize=ysize )
widget_control, tlb, /realize
; Get the window number of the draw widget.
widget_control, d, get_value=winnum
; Set the Draw widget as the current graphics window.
wset, winnum
; Plot the first function graph.
plot, xp, y1,$
xtitle=xtitle, xstyle=xstyle, xticks=xticks, xminor=xminor,$
xrange=xrange,$
ytitle=ytitle, ystyle=ystyle, yticks=yticks, yminor=yminor,$
yrange=yrange,$
charsize=charsize, psym=psym, title=title
; Overplot the remaining four functions.
oplot, xp, y2
oplot, xp, y3
oplot, xp, y4
oplot, xp, y5
; Enter the Xmanager procedure, so that events can be managed.
xmanager, 'testplot', tlb
END