You can create custom IDL routines that interact with the ENVI application and perform specialized tasks. An example is processing an input dataset with your own algorithm and writing it to an output file. You can make these routines (called extensions) available from the ENVI application's Toolbox. See Example for instructions.

You can also create extensions with the ENVI Extension Wizard, which is accessed from the IDL Workbench. See the IDL Help topic "ENVI Extension Wizard" for more information.

This topic contains the following sections:

Best Practices


When writing a Toolbox extension, keep the following practices in mind:

  • The extension must be a procedure and should be the last routine in a .pro file of the same name.
  • Insert COMPILE_OPT IDL2 after the PRO statement.
  • Follow error-handling procedures to catch any errors in your code.
  • The extension can accept an event argument that contains the UVALUE set during the call to ENVI::AddExtension.
  • To get the current ENVI instance, use the following command:
  e = ENVI(/CURRENT)
  • For initialization tasks while starting ENVI, or to customize the layout of your extension in the Toolbox, create a procedure named filename_extensions_init inside the filename.pro file. See Configure the Toolbox Structure.

Build SAVE Files


If you are going to provide extensions to other users who have only an ENVI runtime license or who will run the ENVI application in IDL runtime mode, you must deploy them as IDL SAVE files. See the SAVE routine in the IDL Help for more details.

SAVE files allow you to:

  • Distribute a Toolbox extension to an end user who does not have an ENVI+IDL license.
  • Hide the source code from the end user.

When building SAVE files, keep the following practices in mind:

  • Issue .RESET_SESSION in your IDL session to ensure you only build the SAVE file with the routines that are part of the Toolbox extension.
  • After issuing .RESET_SESSION, compile the routines that are used in the Toolbox extension.
  • Issue RESOLVE_ALL after compilation to resolve all dependencies, but exclude ENVI itself.
  • To ensure cross-platform compatibility, name SAVE files with all lower-case characters.

Here is an example of building a SAVE file:

.RESET_SESSION
.COMPILE emboss_band1.pro
RESOLVE_ALL, /CONTINUE_ON_ERROR, SKIP_ROUTINES='ENVI'
SAVE, FILENAME='emboss_band1.sav', /ROUTINES

Deploy Extensions


When ENVI starts, it searches three locations (and their subfolders) to find .pro and .sav extensions that should be added to the Toolbox:

Name Location Search Order Access

Description

ENVI_EXTENSIONS User-defined 1 User

An optional user-accessible location defined by an environment variable. It is useful for installing shared extensions in environments where the installation directory is not accessible.

Install directory Install_Dir/ENVIxx/extensions 2 Admin This is the preferred location for deploying extensions accessible by all users. However, administrator (admin) privileges are required to deploy here.
Preferences directory user_home/.idl/envi/extensionsx_x 3 User

An extensions folder under the application user directory. Extensions deployed here are only accessible by the user account under which they were installed.

You can change this directory using the Extensions File Directory entry in the ENVI Preferences dialog.

This folder should not contain any .pro or .sav files that are not Toolbox extensions.

IDL package directory

Defined by the IDL_PACKAGE_PATH preference in IDL

4

User

If an IDL package that contains an ENVI toolbox extension has been installed, its directory will contain an additional envi_extensions subfolder. See the IPM topic in IDL Help for details.

If multiple definitions of the same extension are discovered in different locations, the first one discovered following the search order previously described will be used.

If a routine called by a Toolbox extension resides in a directory defined by !PATH, that file will be used first before ENVI searches any other location.

Note: Issue the .RESET_SESSION command if you add an extension to one of the previous directories and want the Toolbox to display the new extension in the current session.

Configure the Toolbox Structure


You can specify a folder structure where the extension will reside inside of the Toolbox. Write a custom routine filename_extensions_init (where filename is the name of the extension file) above the extension routine in your extension file. See the sample code under Example.

If ENVI discovers the filename and filename_extensions_init routines, the latter routine will be called upon application startup instead of adding the extension automatically to the Toolbox Extensions folder. If this routine does not add the extension to the Toolbox, the extension will not be automatically added.

The filename_extensions_init routine consists of two lines of code:

PRO myroutine_extensions_init
  e = ENVI(/CURRENT)
  e.AddExtension, 'My Routine', 'myroutine', PATH='My Routines'
END

See ENVI::AddExtension for more information.

Example


The following example shows how to create and deploy a Toolbox extension called emboss_band1 as a SAVE file. The example also shows how to rename the extension inside the Toolbox Extensions folder by adding a emboss_band1_extension_init routine to the extension file.

  1. Create a file named emboss_band1.pro with the following contents:
  PRO emboss_band1_extensions_init
  COMPILE_OPT IDL2
   
  ; Get ENVI session
  e = ENVI(/CURRENT)
   
  ; Add the extension to a subfolder
  e.AddExtension, 'Emboss Band 1', 'emboss_band1'
   
  END
   
  PRO emboss_band1
  COMPILE_OPT IDL2
   
  ; General error handler
  CATCH, err
  IF err NE 0 THEN BEGIN
    CATCH, /CANCEL
    IF OBJ_VALID(e) THEN $
      e.ReportError,'ERROR: ' + !error_state.msg
    MESSAGE,/RESET
    RETURN
  ENDIF
   
  ; Get ENVI session
  e = ENVI(/CURRENT)
   
  ; Prompt for the input file
  inFile = DIALOG_PICKFILE(DIALOG_PARENT = e.WIDGET_ID, $
    TITLE='Please select input file', $
    /MUST_EXIST)
  ; Prompt for the output file
  outFile = DIALOG_PICKFILE(DIALOG_PARENT = e.WIDGET_ID, $
    TITLE = 'Please select output file')
   
  ; Open the input file and display it
  raster = e.OpenRaster(inFile)
  view = e.GetView()
  layer1 = view.CreateLayer(raster, BANDS = [0])
   
  ; Create the output
  rasterNew = ENVIRaster(URI=outFile, INHERITS_FROM=raster)
   
  ; Iterate through the tiles of the original data set
  ; for the first band
  tiles = raster.CreateTileIterator(BANDS = [0])
  FOREACH tile, Tiles DO BEGIN
    data = EMBOSS(tile, /EDGE_WRAP)
    rasterNew.SetTile, Data, Tiles
  ENDFOREACH
   
  ; Save the data and display
  rasterNew.Save
  layer2 = view.CreateLayer(rasterNew)
   
  ; Create a portal and flicker
  portal = view.CreatePortal()
  portal.Animate
   
  END
  1. Issue the following commands to generate a SAVE file. If emboss_band1.pro is not in the current directory of the IDL path, provide the full path in the .COMPILE command. The SAVE file will be saved to the current directory unless you specify a full path in which to save.
  .RESET_SESSION
  .COMPILE emboss_band1.pro
  RESOLVE_ALL, /CONTINUE_ON_ERROR, SKIP_ROUTINES='ENVI'
   SAVE, FILENAME = 'emboss_band1.sav', /ROUTINES
  1. Close IDL.
  2. Move the file emboss_band1.sav into install_dir\ENVIxx\extensions. If you do not have write permission to that directory, you can define an ENVI_EXTENSIONS environment variable that points to the directory that contains the SAVE file.
  3. Launch ENVI from the Start menu.
  4. In the Toolbox Extensions folder, notice that the extension Emboss Band 1 is now listed. Double-click this entry.
  5. When prompted for the input file, select install_dir\ENVIxx\data\qb_boulder_msi.
  6. When prompted for the output file, enter a valid filename and path.
  7. When the script finishes executing, the original file and the new file will appear in the layer manager and a portal will flicker between the layers.