X
9640 Rate this article:
No rating

The Benefits of Using Include Files in IDL

Anonym

In IDL code, you can include the contents of another file by using the @ symbol followed by the filename. See Using Include Files in Routines for the syntax.

When this is used, the entire contents of the included file are literally dropped into place by the compiler. There are many uses for this, including error handling and logging, debugging, version tracking, and setting predefined variables. You can even use this technique to change COMPILE_OPT options for multiple routines at once.

Keep in mind that the content of an include file does not need to contain a full procedure or function, and it can be as short as a single line. Here are a few examples:

Error Handling and Logging

One of the most common uses of include files is for error handling; the file contains a catch block that handles and recovers from an error. Perhaps the error will also be logged to a file. Here is an example of a file called my_error_handler.pro, which can be placed at the beginning of any routine.

Catch, error
if error ne 0 then begin
  Catch, /CANCEL
  log_file = 'C:\algorithm_results\errors.txt'
  traceback = Scope_Traceback(/STRUCTURE)
  OpenW, unit, log_file, /GET_LUN
  Printf, unit, 'Error caught in ' + traceback[-1].ROUTINE + ', scope level ' + StrTrim(traceback[-1].LEVEL, 2)
  Printf, unit, !ERROR_STATE.msg
  Free_Lun, unit
  Message, /RESET
  result = Execute('Return', 1, 1)
  if ~result then begin
    result = Execute('Return, 0', 1, 1)
  endif
endif

The purpose of the execute calls is so that this file can be included in either a procedure or a function without worrying about compile errors based on whether a value needs to be returned.

Debugging

An include file can be useful for adding debugging statements. For instance, if you want the name of a function printed as IDL enters a routine, you could put this into an include file and include it at the beginning of all of your routines:

traceback = Scope_Traceback(/STRUCTURE)
pro_or_func = traceback[-1].IS_FUNCTION ? 'function' : 'procedure'
Print, 'Entering ' + pro_or_func + ': ' + traceback[-1].ROUTINE

The great thing about this is that when you are finished debugging, you don't need to edit every routine you've written to remove the debug statements; instead you can simply update the included file to be a blank file, and nothing will be compiled into your final code.

Version Tracking

If you publish multiple versions of code, and there are times that the code needs to know the version used, an include file provides an excellent way to store the version. This way, you will only ever need to update the version in a single place.

Here is an include file called my_code_version.pro that defines a version

version = 1.0
version_str = '1.0'

Here is an example of code that makes use of it:

@my_code_version
if version eq 1 then begin
  ; Code
endif else if version eq 1.1 then begin
  ; Different code
endif else if version eq 2 then begin
  ; Completely different code
endif else begin
  Message, 'Version ' +  version_str + ' is not supported.'
endelse

Predefined Variables

An include file is a good way to set predefined variables, such as constants, which may be used in many different routines. This may be preferable to using a common block.

Keep in mind that you may not need to do this for all of your desired constants because IDL offers many physical constants with the !CONST variable.
 

Setting COMPILE_OPT

I have also made use of include files to set the COMPILE_OPT options in many routines so that they are changeable. For example, when writing, debugging, and testing code, I often like to see the printouts of what routines are compiled at the time they are first called. However, when I am done writing code and start using it for processing real data, these printouts can be a bit of an annoyance. Therefore, I want to be able to add "hidden" to all of my compile opt statements. The easy way to do this is to write a one-line include file with the COMPILE_OPT statement, which can then be changed. The routines that I want to make use of this can use the include file instead of using COMPILE_OPT directly.

Note

A small word of caution with include files is that it might take slightly longer for code to compile because IDL needs to look for the include file in the path. However, as long as I don't get carried away with including too many separate files, I have never worried about this because the difference is extremely small. Additionally, if the final code is published in the form of savefiles rather than pro code, it doesn't matter because the savefiles are pre-compiled.