Professional Documents
Culture Documents
&
Coding Guidelines
TRAD Philips’ proprietary, 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 2 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
1. Introduction
The main purpose of this document and the guidelines is to simplify the development, review and re-use of
PRIDE based IDL applications by promoting a form of unity in the code. This will greatly simplify the
exchange of PRIDE software.
The guidelines stated in this document are not mandatory and the first concerns of any application should
clinical relevance and proper functioning. However, be aware that adherence to the guidelines and some form of
structure within the application will make help during development and follow-up of the application much
easier.
The PRIDE intranet contains the latest up-to-date version of this document as well as some more advanced tips
and tricks on using IDL and the PRIDE library objects.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 3 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
2. Guidelines
2.1. Code outline guidelines
1. Use 4 spaces or a TAB to indent to the next level (e.g., BEGIN). The END-statement is not indented.
and not
3. When possible, use BEGIN and END statements in stead of multiline commands separated by a ‘$’.
and not
and not
5. Differentiate between accessing array indices and passing parameters to function calls.
Address array elements with square brackets, pass parameters to function calls using round brackets.
my_array = INTARR(100)
my_array[10] = 123
result = my_function(my_array)
and not
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 4 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
perform_registration(images)
and not
do_my_thing_now_and_return_from_routine(my_array_of_image_objects)
or
pr(x)
2. Use all lower cases to identify variables and user created functions/procedures. Use all uppercases for IDL
routines and commands.
my_array = INTARR(10)
FOR i = 0, 10 DO BEGIN
FOR j = 0, 10 DO BEGIN
PRINT, ‘something interesting’
do_something_interesting(i, j, my_array)
END
END
and not
My_Array = intarr(10)
for I = 0, 10 do begin
For j = 0, 10 do begin
print, ‘something interesting’
DO_SOMETHING_INTERESTING(I, j, My_Array)
End
end
3. Use a prefix (about 2 to 4 letters in length) when naming external functions and procedures. This prevents
naming conflicts within IDL and it indicates which package the function originates from.
E.g. rw_common or ex_subtraction or pflh_viewport_put_image. Also use these prefixes when naming the
files containing the procedures/functions.
When using a slightly altered function or routine from IDL or public domain, keep the original name (and
credit), but add a prefix to the function name.
4. To avoid problems with name clashes, ensure functions have unique names. This can be done by adding the
same prefix described above to all a module’s local functions as well. An example of this can be seen in the
zoom_pan example in the ex_sample project. The local functions in the module have the prefix “zp_”.
This is especially important when several different programs are contained in a single IDL project, or when
not using IDL projects, just modules.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 5 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
5. Use a single blank line to separate between blocks of code belonging together
dim_x = 256
dim_y = 256
nr_masks = 5
an_image = INTARR(dim_x, dim_y)
mask = INTARR(dim_x, dim_y, nr_masks)
and not
dim_x = 256
dim_y = 256
nr_masks = 5
an_image = INTARR(dim_x, dim_y)
mask = INTARR(dim_x, dim_y, nr_masks)
FOR i = 0, nr_masks-1 THEN BEGIN
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 6 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
;+
; NAME:
; Project Name
;
; PURPOSE/DESCRIPTION:
; A description describing the purpose and use of the module.
;
; GENERAL DESIGN:
; A description of the general design decisions used in the file.
;
; LIST OF ROUTINES:
; Exported routines - Short description of each function/procedure.
;
; MODIFICATION HISTORY:
; Written: Author Name Creation Date
; Update : Author Name Update Date: Short Description
;-
3. Comments should precede the line(s) for which they are intended and should be indented at the same level.
long_axis = 15.0
and not
long_axis = 15.0
FOR i = 1, 10 DO BEGIN
; Display 10 of ellipses with different short axes.
short_axis = long_axis/i
draw_ellipse(long_axis, short_axis)
END
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 7 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
4. Do not leave source lines which are commented out in your code, unless specific comments have been
added as to why it’s still there. Without any additional comments, the commented out code can be very
confusing. (e.g. Did someone forget to remove these comments?)
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 8 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
pr_some_project.prj
Source
pr_my_file_1.pro
pr_my_file_2.pro
pr_my_GUI.pro
…
GUI
pr_my_GUI_builder.prc (GUI Builder Resource File)
…
Data (Any data other required/generated)
Bitmaps
pr_splash_screen.bmp
pr_intera_open.bmp
Other (Used by PRIDE library)
2. Event handlers should be viewport independent. When a mouse button is pressed, the resulting event
contains the widget id of the widget which triggered the event.
(See the example of bullet number 3.)
3. Any generic events such as mouse movements, clicks on draw widgets, etc. are caught in the event handler
assigned in the XMANAGER call in the GUI creation routine. The name of that function can be set using the
EVENT_HANDLER keyword in the XMANAGER procedure.
; The generic GUI event handler for my_zoom_program as set below in the
; XMANAGER call.
PRO mz_event_handler, event
; Retrieve the info structure from the top widget.
WIDGET_CONTROL, event.top, GET_UVALUE=info, /NO_COPY
PRO, mz_my_zoom_program
; Create GUI
; Initialise parameters including the info structure.
…
; Create the GUI, assigning mz_event_handler as the generic GUI callback.
XMANAGER, 'my_zoom', top_wid, EVENT_HANDLER = ‘mz_event_handler’, $
/NO_BLOCK
END
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 9 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
4. Avoid routines that change the currently active viewport. In general this can be done by first storing the
active viewport, displaying the relevant items in the proper viewport(s), and finally resetting the original
viewport. (This is only applicable for direct graphics programming.)
Here is such an example of a display_image routine:
WSET, some_window
TVSCL, my_image, /ORDER
WSET, current_wid
END
5. Avoid GOTO’s.
6. When possible, avoid hard coded (magical) numbers. Whenever they are used, add a simple comment
stating what the number represents and why it is used.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 10 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
For an example on interactive zooming, panning and windowing according to these mouse-button
combinations, see the ex_zoom_pan module in the ex_sample project.
2. Use data size independent viewports: do not let the size of your viewports depend on the data size of the
images displayed inside. It does not matter if the data being displayed is 1024x1024 or 64x64, re-scaling
the bulk to the size of the viewport(s) when displaying it results in a much more predictable GUI.
3. When displaying multiple images, use smaller viewports, for example 256x256. If only a single image is
displayed the viewport can be larger, for example 512x512. Note that having viewports that are easy to
resize in the code is very nice to have as it allows the program to run well on displays using other
resolutions than your own.
4. Avoid over-use of pop-up windows. It’s much clearer to use a panel in the main window to display relevant
information. Use pop-up windows only in exceptional cases such as error windows or file selection or if
there simply is not enough screen space.
5. In order to maximize available space on the GUI, e.g. for viewports, it is easily possible to build a
Windows style menu bar for common actions such as opening of data and exiting the application.
Examples for this can be found in the standard IDL demos and examples.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 11 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
2. Avoid common blocks by using an event control “info” structure. Use the /NO_COPY option to avoid
copying large chunks of data. (See pg. 263 of IDL programming techniques by D. Fanning for a
comprehensive explanation of this /NO_COPY mechanism.)
In general only one info-structure is used in your file to store all the global data. The info-structure is
generally stored as the user defined value of the top level widget. This allows access to the structure from
anywhere in the file.
A routine where the info structure is needed, such as during event control, grabs it by a GET_UVALUE
with the /NO_COPY keyword parameter. Be sure to put the structure back using a SET_UVALUE call
with the /NO_COPY keyword parameter so other procedures can access it afterwards. Only during
termination of the program is it not required to put the info structure back after grabbing it.
Below is an example consisting of two procedures. The first procedure defines the event control info
structure and stores it in the top level widget. The second procedure is a typical event procedure which
updates information in the structure.
PRO my_main_routine
…… Create UI ……
…… Perform initializion ……
; Retrieve the pixel size value and store it in the INFO struct.
WIDGET_CONTROL, event.id, GET_VALUE = p_size
info.pixel_size = FLOAT(p_size[0])
3. In the IDL ‘examples\widgets’ directory, an example demonstrating the different GUI controls and their
related callbacks can be found: xnothing.pro. Many examples are given here, but be aware that some, such
as the radio buttons, use obsolete functions and procedures!
(Note that depending on what version of IDL is used, the example might be in a different directory.)
The various PRIDE examples such as ex_zoom_pan.pro and ex_subtraction.pro are also good examples on
building GUI’s.
4. To get a unique unit number to open or close files, use the keyword /GET_LUN
OPENW, unit_number, file_name, /GET_LUN
…Do something with the file…
CLOSE, unit_number
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 12 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
6. Care must be taken in IDL when converting to double or long integers. One conversion in an expression
does not necessarily mean that the whole expression is converted .
To properly force the result of a calculation to type long integer, convert the integer to type long integer
before multiplication. This can be done by adding ‘L’ after the value, or using the LONG(value) function.
E.g.: 256 * 256 + 1 = 1
256 * 256 + 1L = 1L
256 * 256L + 1 = 65537L
LONG(256 * 256 + 1) = 1L
LONG(256) * 256 + 1 = 65537L
7. Arguments in routines can only be updated when these are not passed to the routine as expressions (e.g.
structure fields or array elements.
info.my_value = 1
add_one(info.my_value)
PRINT, info.my_value
IDL> 1
and
my_array[2] = 1
add_one(my_array[2])
PRINT, my_array[2]
IDL> 1
but
my_value = 1
add_one(my_value)
PRINT, my_value
IDL> 2
8. Compile options, such as "save before compiling", only work when compiling individual files and not
when building or running a whole project. This can be extremely confusing since the file you are looking at
is not necessarily the file compiled, thus the code which is currently running. Be careful of this especially
when debugging an application.
This has gotten somewhat better in the later versions of IDL (5.4+), but can still cause for confusing
situations.
9. Especially when creating a new IDL project by copying an existing one, be aware that the open code
windows when first starting your new project do not necessarily show the code of the new project. IDL uses
hard-coded paths and you might be looking at (and changing) the code of the original project!
The safe workaround is to copy only the source files and the directories, but create a new project file from
scratch. This way, the files must be manually added to the project, ensuring the correct files are displayed.
The quick workaround this is to close all open code windows when first opening the project.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved
PRIDE: CAUTION: Investigation Device Page 13 of 13
Tips & Coding Guidelines Limited by Federal Law to investigational use 02-07-2001
10.When in the IDL editor, the keyboard combination ‘CTRL-D’ can be used to jump to declaration of the
function/procedure the cursor is currently at.
11.It is important to keep the following tips handy whenever performance is a main issue in an IDL project.
Avoid IF statements wherever possible.
e.g. in stead of: IF(a EQ x) THEN b = 1 you can use: b = (a EQ x)
Avoid (nested) loops wherever possible. It is usually possible through the use of modulo and division to avoid a
nested FOR loop. One way to avoid FOR loops is by using IDL's array indexes such as '*' and '0:5'.
Avoid declaring arrays that are larger than the amount of RAM in the PC.
(Though this is hard to check for, try to manage your memory as best as possible…)
Especially when you are incrementing sizable arrays, use the TEMPORARY function to limit memory usage.
So in stead of: large_array = large_array + 1 use
large_array = TEMPORARY(large_array) + 1
To truly optimize array access put the fastest changing indexes last (unlike other languages such as C!) and keep
the number of array dimensions as small as possible, e.g. using the REFORM command.
When accessing the bulk of an array of image slices, the array would be set up as follows:
array[slices][x][y]
with slices being the slowest changing index first.
Note that in fact the x, y should be reversed as well, but this severely hampers the readability and
maintainability of the code.
12.When continuously updating the display (e.g. display a moving crosshair or a fast movie display) look into
the use of pixmaps. One important note is that the amount of memory in the PC is a severely limiting factor
as in how many images can be displayed smoothly!
More information on pixmaps can be found in the IDL help (WINDOW and DEVICE procedures) as well
as on the internet. (The PRIDE intranet contains links to IDL links on the internet.)
13. Use the Help provided in IDL. It contains a comprehensive reference guide for the available
functions/procedures as well as several guides. Some interesting generic information on IDL can be found
in “ContentsBuilding IDL ApplicationsProgramming in IDL”. This section contains some of the
things to be avoided (and how to avoid them) as well as some IDL’s global principles.
TRAD Philips’ proprietary, © 2001 Philips Electronics N.V. All rights reserved