This page contains an introduction to programming in IDL, in the style that is embodied by Spamalize. There are also several tutorials available for IDL programming in general. Most of the Spamalize routines involve (1) a Graphical User Interface (GUI) that displays parameters, options, and images, and (2) some programs that actually do the work. The GUI helps to set up parameters, but most of the programs can be called without the GUI, e.g. in a data processing pipeline.
The bulk of this page is devoted to the nuts and bolts of Spamalize, so you can figure out how to steal pieces of Spamalize code to include in your own IDL application. Alternately, you could also plug your code into Spamalize's framework (it's easy!) and save a lot of work. If you make a nifty addition, please tell me about it (troakes - at - wisc.edu) so I can include it for others to use.
There are seperate pages devoted to:
There are two main types of programs in Spamalize:
1) Mature programs that perform an image analysis or display task, like BrainMaker or BrainSpinner;
2) All the others, that let you take a more modular approach to image processing.
This section concentrates on the latter, since there are already web-pages devoted to most of the more mature self-standing programs. All of the programs are accessed through the main menu, which looks like this:
The first five buttons are pull-down menus. (For more information on the menu features and how to use them, see the Spamalize MainMenu page.) If you add a new program, edit SPW_MAINMENU.PRO to add the program to the menu. You will need to add a new label to the menu, and also make sure to add a new call for your program in the event-handler.
The basic idea behind Spamalize is that you can read image data into a single array, store it in memory, and do things to it. Things like display, drawing, scaling, flipping, writing, etc. This may be routine now, but back when Spamalize was first developed (early 1990's) the ability to combine multiple image sets in the same environment was pretty cool. Some of the programs in the older part of Spamalize are becoming obsolete, but a few of them still have some dedicated users, so this page is a sort of reference manual for them.
The image data are stored in an array called (drum roll, please) "img_arr". Whenever you read in a new image file, it gets stored there. When you write an image file, it is the contents of "img_arr" that get written.When you flip your data left/write... well, you get the idea. All of the Spamalize programs can access "img_arr" through a common variable structure. (For non-IDL'ers, this is a type of global environment variable.)
There are a number of image-read programs, all of which funnel the image data into "img_arr". The general read process can be seen in a diagram. Most of these steps are transparent or at least ignorable to the user. The top-level read program looks like:
You may select an alternate file type from the dropdown menu in the upper left. Context-sensitive options will appear. For instance, the GE/Advance PET menu looks like:
Clicking on "Continue, Load Image(s)" pops up a browser that lets you select an image file. Depending on the type of image, a menu may pop up to let you select which images you want to load. The menu for PET multi-plane, multi-frame image set will look like:
Every image in the data set is represented by a check-box. You can select (or unselect) any combination of images. The sliders in the center of the menu let you quickly select a range of images. When yo select one or more images, their check-boxes get filled in. To load all of the images, simply click "Read All Images in Data Set". If you move the check-box-window-sliders, you can see all of the check-boxes, as well as boxes that let you select a single plane or frame, as shown in the following menu:
Here, I selected "P33", which then selected all of the images in plane 33, and "Frame 11, All Planes" which selected all the images in Frame 11. Unselecting works the same way. If you do several iterations, eventually the GUI will get confused and you will have to start over... Click "Continue, Load Selected Images" to load in the desired images. When you want to display, write, print, etc. the images, you will get a menu that looks similar to the Read menu above, but only the images you loaded will be sensitive, i.e. you will not be allowed to do anything with unloaded images.
Image data storage
There are associated common variables that contain main-header information for the entire image array (X,Y,Z dimensions, pixel dimensions, etc.) and also information for each image slice in a sub-header structure, such as time of acquisition, number of counts, etc. These common variables are cleverly called "main_header" and "sub_header".
Since Spamalize was originally written for PET, "img_arr" is oriented toward storing multi-time-frame or dynamic data. On earlier PET systems there would not infrequently be planes or frames that were garbage, so "img_arr" is designed as a collection of 2D slices rather than as a 3D or 4D array. To access a particular slice, you need to interogate "sub_header" to figure out which slice-number in "img_arr" corresponds to the desired plane and frame. One nice result of this scheme is that missing slices do not interfere with the display or storage of images.
A big downfall of this scheme is that it is difficult to extract orthogonal views. There are two ways to get around this in Spamalize. The first is to just declare "img_arr" to be a 3D array, and take your lumps. Because of the way IDL stores arrays and how the image data get read in, frequently you will never notice a problem. Problems will show up first as an inability to display an image using the general "Display" tools if you take this approach. A second technique is just to shift the data to another array that is designed to be 3D (or 4D) from the get-go. In Spamalize, this array is called "anlz_img_arr". Spamalize internally keeps track of whether "img_arr" or "anlz_img_arr" is active, and for the most part knows how to display, write, etc. the appropriate one. However, I should mention that keeping track of this has caused more hair to be pulled out than any other aspect of Spamalize. For most modern applications using "good" data with no missing planes, I would advise using a 3D array such as "anlz_img_arr", which is how most of my recent programs work. Notable exceptions are the FDG Quantitation tool and the Patlak/Logan-plot Tool, both of which are oriented toward PET and continue to use "img_arr".
There are a number of programs that funnel the image data and header-values into the correct place. The program "SPAM_READ_ANLZ" is a good example that uses all of these programs, most of which are related to making sure the data are scaled properly, header values go to the right place, and missing header values get reasonable estimates.
A more-or-less comprehensive index of Spamalize programs is in the file .../spamalize/install_spam/catalogue_of_spam. The programs are organized by functionality (read, write, utilities, etc.) with a one or two-line description of each program. When I vaguely remember that I may have written a program similar to the one that I am about to embark on, I search in this catalogue to see if there is a good template there.
Most of the Spamalize "worker" programs can be called outside of the context of their GUI. In particular, programs that perform a particular task like file reading, image filtering, etc. are designed to be called from within many programs. To avoid the complexity introduced by IDL's common variables, most of these programs have the necessary parameters passed via KEYWORDS. This is an IDL technique for passing parameters where the order of the parameter does not matter. The syntax is simple: include a statement in the program call like "FILENAME='C:\myfile.img'". You need to know what the name of the keyword is, and what its appropriate values are. This is usually contained in the top comment-section of a program. (See the IDL documentation for more details on Keywords.) Furthermore, most of worker programs that you would want to run in batch mode avoid asking the user for any information which would interupt the flow of the program. This means that there must be a lot of parameter and error checking, and some way to make good guesses for missing data...
As I mentioned earlier, the two main types of Spamalize programs are GUIs and workers. There is a third type, an "auxiliary" program, that are not as Spamalize-specific as the others. These are usualy small programs that do a particular task, and are amenable to being used outside of the Spamalize environment. They live in .../spamalize/src/aux_progs/.
A partial list of some of the more useful programs includes:
if (N_TAGS(event) LE 5) then begin
;* event was a button press- show the menu: *
res=CW_COLOR_CHOOSER(event, COLOR_VECTOR=br3d.p.col.surf, /RAMPED, /THREE_D, $
TITLE='Color Chooser: BrainSpinner Surface')
endif else begin
;* event was sent from CW_COLOR_CHOOSER- update the color: *
if (event.update EQ 2) then begin
br3d.p.col.surf = [event.r, event.g, event.b]
endif else RETURN
Back to top.