# IDL Example Programs

This page was created by the IDL library routine `mk_html_help`. For more information on this routine, refer to the IDL Online Help Navigator or type:

         ? mk_html_help

at the IDL command line prompt.

Last modified: Mon Jan 27 18:31:36 2014.

# List of Routines

- ADJUSTPOSITION
- ANSI_VALUE
- ARCSAMPLE
- ASINHSCL
- ASPECT
- BINARY
- BITGET
- BLOB_ANALYZER__DEFINE
- CAPFIRSTLETTER
- CHECKERBOARD
- CINDEX
- CLIPBOARD
- CLIPSCL
- COLORBUTTONBITMAP
- COLORSAREIDENTICAL
- CONTRASTZOOM
- CONVERT_TO_TYPE
- CW_DRAWCOLOR
- DIRPATH
- ERRORLOGGER__DEFINE
- FIND_BOUNDARY
- FIT_ELLIPSE
- FIXED_MAP_GRID
- FLOATS_EQUAL
- FPUFIX
- FSCCLEANUP7
- FSCCLEANUP8
- FSC_COLORBAR__DEFINE
- FSC_COLORSELECT
- FSC_DROPLIST
- FSC_FIELD
- FSC_FILESELECT
- FSC_INPUTFIELD
- FSC_PLOTWINDOW
- FSC_PSCONFIG__DEFINE
- GAUSSSCL
- GETIMAGE
- GETPRIMARYSCREENSIZE
- GET_OBJECT_ID
- GMASCL
- HCOLORBAR
- HELP_VAR
- HISTOMATCH
- IMAGESELECT
- IMAGE_BLEND
- IMAGE_DIMENSIONS
- INSIDE
- JD2TIME
- LEFTJUSTIFY
- LINKEDLIST
- LIST_SELECTOR
- LOGSCL
- MAXMIN
- MAXWINDOWSIZE
- NAME_SELECTOR
- NCDF_ATTRIBUTE
- NCDF_BROWSER
- NCDF_CASTDATATYPE
- NCDF_CONTAINER
- NCDF_DATA__DEFINE
- NCDF_DIMENSION
- NCDF_FILE
- NCDF_FILE_EXAMPLES
- NCDF_ISVALIDFILE
- NCDF_VARIABLE
- PICKCOLOR
- PRECIPMAP
- PRINTWINDOW
- PSWINDOW
- PS_BACKGROUND
- RANDOMNUMBERGENERATOR
- RANGEOF
- REPMAT
- RESOLVE_OBJECT
- REVERSE_AXES
- SAVETOMAIN
- SCALEMODIS
- SCROLLWINDOW
- SDEVSCL
- SELECT_OBJECTS
- SETDEFAULTVALUE
- SHARPEN
- SORT_ND
- STATIONPLOT
- STR_SIZE
- TEXTBOX
- TEXTLINEFORMAT
- TEXTURE_SURFACE
- TRANSFORM_VOLUME
- UNDEFINE
- VCOLORBAR
- WINDBARB
- WINDOWAVAILABLE
- WINDOWIMAGE

# Routine Descriptions

## ADJUSTPOSITION

[Next Routine] [List of Routines]

     NAME:
           AdjustPosition

     PURPOSE:

           This is a program for interactively adjusting the plot position
           coordinates. The result of the function is a four-element floating
           point array of normalized coordinates, suitable for passing to the
           POSITION keyword of most IDL graphics commands.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics

     CALLING SEQUENCE:

           position = AdjustPosition(startingPosition)

     OPTIONAL INPUTS:

           startingPosition - A four-element array of normalized coordinates
                of the form [x0, y0, x1, y1].

     OUTPUTS:

           position - The adjusted plot position. A four-element array of normalized coordinates.

     INPUT KEYWORDS:

           GROUP_LEADER - The group leader of this program. This keyword
                is required to ensure modal operation when calling from
                another widget program.

           TITLE - The title of the window. "Adjust Plot Position in Window..." by default.

           XOFFSET - The X offset of the program on the display. Calculated from the
                upper left-hand corner of the display.

           YOFFSET - The Y offset of the program on the display. Calculated from the
                upper left-hand corner of the display.

     OUTPUT KEYWORDS:

           CANCEL - Returns a 1 if the user selects the Cancel button. Returns 0 otherwise.
                Note that if the use cancels, the "position" parameter is set to the value of
                the "startingPosition" parameter.

     DEPENDENCIES:

           Reqires FSC_FIELD and FSC_PLOTWINDOW from the Coyote Library:

                         http://www.idlcoyote.com/programs/fsc_field.pro
                         http://www.idlcoyote.com/programs/fsc_plotwindow.pro

     MODIFICATION HISTORY:

           Written by David Fanning, March 2001.

(See adjustposition.pro)

## ANSI_VALUE

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
       Provides a way to display non-printable characters in widget elements.

     :Categories:
        Widgets

     :Params:
        str_in: in, required, type=string
             The input string that you wish to render on a widget element.

     :Keywords:
         example: in, optional, type=boolean, default=0
             Set this keyword to see an example of non-printable characters
             rendered in a Dialog_Pickfile widget.

     :Examples:
        Call the built-in example::
           IDL> void = ANSI_Value(/EXAMPLE)

     :Author:
           Bernat Puigdomenech

     :History:
         Change History::
            Written, 2 September 2011. Bernat Puigdomenech.

     :Copyright:
         Copyright (c) 2011, Bernat Puigdomenech.

(See ansi_value.pro)

## ARCSAMPLE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           ARCSAMPLE

     PURPOSE:

           Given X and Y points that describe a closed curve in 2D space,
           this function returns an output curve that is sampled a specified
           number of times at approximately equal arc distances.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           ArcSample, x_in, y_in, x_out, y_out

     INPUT_PARAMETERS:

           x_in:          The input X vector of points.
           y_in:          The input Y vector of points.

     OUTPUT_PARAMETERS:

          x_out:          The output X vector of points.
          y_out:          The output Y vector of points.

     KEYWORDS:

         POINTS:         The number of points in the output vectors. Default: 50.

         PHASE:          A scalar between 0.0 and 1.0, for fine control of where interpolates
                         are sampled. Default: 0.0.

     MODIFICATION HISTORY:

           Written by David W. Fanning, 1 December 2003, based on code supplied
              to me by Craig Markwardt.

(See arcsample.pro)

## ASINHSCL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           ASINHSCL

     PURPOSE:

           This is a utility routine to perform an inverse hyperbolic sine
           function intensity transformation on an image. I think of this
           as a sort of "tuned" gamma or power-law function. The algorithm,
           and notion of "asinh magnitudes", comes from a paper by Lupton,
           et. al, in The Astronomical Journal, 118:1406-1410, 1999 September.
           I've relied on the implementation of Erin Sheldon, found here:

               http://cheops1.uchicago.edu/idlhelp/sdssidl/plotting/tvasinh.html

           I'm also grateful of discussions with Marshall Perrin on the IDL
           newsgroup with respect to the meaning of the "softening parameter", beta,
           and for finding (and fixing!) small problems with the code.

           Essentially this transformation allow linear scaling of noise values,
           and logarithmic scaling of signal values, since there is a small
           linear portion of the curve and a much large logarithmic portion of
           the curve. (See the EXAMPLE section for some tips on how to view this
           transformation curve.)

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           outputImage = ASINHSCL(image)

     ARGUMENTS:

           image:         The image or signal to be scaled. Written for 2D images, but arrays
                          of any size are treated alike.

     KEYWORDS:

           BETA:          This keyword corresponds to the "softening parameter" in the Lupon et. al paper.
                          This factor determines the input level at which linear behavior sets in. Beta
                          should be set approximately equal to the amount of "noise" in the input signal.
                          IF BETA=0 there is a very small linear portion of the curve; if BETA=200 the
                          curve is essentially all linear. The default value of BETA is set to 3, which
                          is appropriate for a small amount of noise in your signal. The value is always
                          positive.

           NEGATIVE:      If set, the "negative" of the result is returned.

           MAX:           Any value in the input image greater than this value is
                          set to this value before scaling.

           MIN:           Any value in the input image less than this value is
                          set to this value before scaling.

           OMAX:          The output image is scaled between OMIN and OMAX. The
                          default value is 255.

           OMIN:          The output image is scaled between OMIN and OMAX. The
                          default value is 0.
     RETURN VALUE:

           outputImage:   The output, scaled into the range OMIN to OMAX. A byte array.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           Plot,  ASinhScl(Indgen(256), Beta=0.0), LineStyle=0
           OPlot, ASinhScl(Indgen(256), Beta=0.1), LineStyle=1
           OPlot, ASinhScl(Indgen(256), Beta=1.0), LineStyle=2
           OPlot, ASinhScl(Indgen(256), Beta=10.), LineStyle=3
           OPlot, ASinhScl(Indgen(256), Beta=100), LineStyle=4

     RESTRICTIONS:

         Requires cgScaleVector from the Coyote Library:

            http://www.idlcoyote.com/programs/cgScaleVector.pro

         Incorporates ASINH from the NASA Astronomy Library and renamed ASINHSCL_ASINH.

           http://idlastro.gsfc.nasa.gov/homepage.html

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 24 February 2006.
           Removed ALPHA keyword and redefined the BETA keyword to correspond
             to the "softening parameter" of Lupton et. al., following the
             suggestions of Marshall Perrin. 25 April 2006. DWF.

(See asinhscl.pro)

## ASPECT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      ASPECT

     PURPOSE:

      This function calculates and returns the normalized position
      coordinates necessary to put a plot with a specified aspect ratio
      into the currently active graphics window. It works on the display
      output window as well as in a PostScript output window.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Graphics

     CALLING SEQUENCE:

      position = ASPECT(aspectRatio)

     INPUTS:

      aspectRatio: A floating point value that is the desired aspect
         ratio (ratio of heigth to width) of the plot in the current
         graphics output window. If this parameter is missing, an aspect
         ratio of 1.0 (a square plot) is assumed.

     KEYWORD PARAMETERS:

      MARGIN:  The margin around the edges of the plot. The value must be
         a floating point value between 0.0 and 0.5. It is expressed in
         normalized coordinate units. The default margin is 0.15.

      WINDOWASPECT: The aspect ratio of the target window. If not provided,
         the value is obtained from the current graphics window.

     OUTPUTS:

      position: A four-element floating array of normalized coordinates.
         The order of the elements is [x0, y0, x1, y1], similar to the
         !P.POSITION system variable or the POSITION keyword on any IDL
         graphic command.

     EXAMPLE:

      To create a plot with an aspect ratio of 1:2 and a margin of
      0.10 around the edge of the output window, do this:

         plotPosition = ASPECT(0.5, Margin=0.10)
         PLOT, Findgen(11), POSITION=plotPosition

      Notice this can be done in a single IDL command, like this:

         PLOT, Findgen(11), POSITION=ASPECT(0.5, Margin=0.10)

     MODIFICATION HISTORY:

      Written by: David Fanning, November 1996.
           Added better error checking, 18 Feb 1997, DWF.
           Added WindowAspect keyword. 10 Feb 2000. DWF
           Added double precision tolerance for aspectRatio. 9 NOV 2001 BT
           Officially retired in favor of cgAspect. 11 February 2013. DWF.

(See aspect.pro)

## BINARY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      BINARY

     PURPOSE:

       This function is used to display a binary representation of byte,
       integer, and long integer values.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       Utilities

     CALLING SEQUENCE:

       output = Binary(theNumber)

     RETURN VALUE:

       output:        A string array of 0s and 1s to be printed (normally), in a
                      binary representation of the number. The number is represented with
                      the highest bits on the left and the lowest bits on the right,
                      when printed with the PRINT command.

     ARGUMENTS:

      theNumber:      The number for which the user wants a binary representation.
                      It must be BYTE, INT, or LONG.

     KEYWORDRS:

      COLOR:          If this keyword is set, the binary representation always
                      contains 24 bits of output.

      SEPARATE:       If this keyword is set, the output is separated with space
                      between each group of eight bits.

     EXAMPLE:

      IDL> Print, Binary(24B)
              0 0 0 1 1 0 0 0
      IDL> Print, Binary(24L)
              0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
      IDL> Print, Binary(24L, /COLOR)
              0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
      IDL> Print, Binary(24L, /COLOR, /SEPARATE)
              0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0    0 0 0 1 1 0 0 0

     MODIFICATION HISTORY:

      Written by: David W. Fanning, November 10, 2007.
      Fixed a problem with error handling. 13 March 2008. DWF.

(See binary.pro)

## BITGET

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           BITGET

     PURPOSE:

           Returns the bit value (0 or 1) of a specified bit in a supplied number.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           bitValue = BitGet(number, bit)

     INPUT_PARAMETERS:

           number:          The input number. Should be a scalar integer. If not, it is converted to
                            one by rounding.

           bit:             The number of the bit you are interested in. A value between 0 and 63.
                            If not supplied, all 64 bit values of the number are returned. May be
                            an array of bit numbers.

     OUTPUT_PARAMETERS:

          bitValue:        The value, 0 or 1, of the specified bit in the number.

     KEYWORDS:

         SILENT:           If set, suppresses informational messages regarding rounding operations.

     MODIFICATION HISTORY:

           Written by David W. Fanning, 14 June 2006.

(See bitget.pro)

## BLOB_ANALYZER__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           BLOB_ANALYZER__DEFINE

     PURPOSE:

           The purpose of this routine is to create a system for analyzing
           regions of interest (ROIs) or (more commonly) "blobs" inside images.
           In particular, given a suitable image (this will require judgement on
           your part), the program will automatically select "blobs" or connected
           regions in the image and make it possible for you to analyze these
           blobs. An example program is provided to show you one way the program
           can be used.

           The code is a wrapper, essentially, for LABEL_REGION and HISTOGRAM, with
           a couple of my other image processing routines (FIND_BOUNDARY and FIT_ELLIPSE)
           used in a supporting role.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Analysis, Image Processing

     CALLING SEQUENCE:

           analyzer = Obj_New("BLOB_ANALYZER", image)

     INPUTS:

       image:           A two-dimensional image array. To make this program memory efficient,
                        a copy of the image is *not* stored in the object. You will be responsible
                        for image operations outside this program.

     KEYWORDS:

       ALL_NEIGHBORS:    Set this keyword to look at all eight neighbors when searching
                         for connectivity. The default is to look for four neighbors on
                         each side of the starting pixel. Passed directly to LABEL_REGION.

       MASK:             A two-dimensional array, the same size as image, that identifies the
                         foreground and background pixels in the image. Applying the mask
                         should result in a bi-level image of 0s and 1s, where 1 identifies the
                         blobs you wish to analyze. If a mask is not provided, the mask is created
                         like this:

                         mask = image > 0

       SCALE:            A one- or two-dimensional given the pixel scaling parameters. By default [1.0, 1.0].
                         If passed a scalar, the scale parameter is applied to both the X and Y directions of
                         each pixel. Statistical output is reported with scaling unless the NOSCALE keyword
                         is set. Scaling also effects the data that is output from the various methods.

     OBJECT METHODS:

       The following methods are provided. Please see the documentation header for each method for
       information on arguments and keywords that can be used with the method.

       FitEllipse:       This method fits an ellipse to the blob. It returns information about the fitted
                         ellipse, including the points that all the ellipse to be drawn.

       GetIndices:       This method returns the indices for a particular blob in the image.

       GetStats:         This method returns a structure containing statistics for a particular blob in the image.
                         The structure is defined as follows:

                         stats = {INDEX: indexNumber, $                  ; The index number of this blob.
                                  COUNT: N_Elements(indices), $          ; The number of indices in this blob.
                                  PERIMETER_PTS: boundaryPts, $          ; A [2,n] array of points that describe the blob perimeter.
                                  PIXEL_AREA: pixelArea, $               ; The area as calculated by pixels in the blob.
                                  PERIMETER_AREA: perimeterArea, $       ; The area as calculated by the blob perimeter. (Smaller than pixel area.)
                                  CENTER: centroid[0:1], $               ; The [x,y] array that identifies the centroid of the blob.
                                  PERIMETER_LENGTH: perimeter_length, $  ; The perimenter length (scaled unless the NOSCALE keyword is set).
                                  SCALE: scale, $                        ; The [xscale, yscale] array used in scaling.
                                  MINCOL: Min(xyindices[0,*]), $         ; The minimum column index in the blob.
                                  MAXCOL: Max(xyindices[0,*]), $         ; The maximum column index in the blob.
                                  MINROW: Min(xyindices[1,*]), $         ; The minimum row index in the blob.
                                  MAXROW: Max(xyindices[1,*])}           ; The maximum row index in the blob.

       NumberOfBlobs:     The number of blobs identified in the image.

       ReportStats:       This methods reports statistics on every identified blob in the image. The
                          report can be sent to the display (the default) or to a file. The format for
                          the report works for most images, but you may have to change the format or override
                          this method for your particular image. The reported statistics are basically the
                          output of the GetStats and FitEllipse methods.

        Here is an example of statistical output from the example program below.

      INDEX   NUM_PIXELS   CENTER_X    CENTER_Y   PIXEL_AREA   PERIMETER_AREA   PERIMETER_LENGTH  MAJOR_AXIS   MINOR_AXIS    ANGLE
         0        426        107.89       9.78       106.50          98.00            37.56          12.15        11.29       -8.05
         1        580        151.97      10.22       145.00         134.25            49.21          17.49        11.77       -0.99
         2        812        266.29      15.36       203.00         190.75            52.56          17.88        14.65     -107.48
         3       1438        204.53      43.29       359.50         344.13            70.23          21.68        21.12      -76.47

     RESTRICTIONS:

           Requires programs from the Coyote Library. At the very least, those below are required.
           It is *highly* recommended that you install the entire library. FIT_ELLIPSE has been
           changed specifically for this release, so by sure you get a copy of that with this
           source code.

           The program currently works only with 2D bi-level images.

     EXAMPLE:

           To run an example program. Compile the file and type "example" at the IDL command line.

           IDL> .compile blob_analyzer__define
           IDL> example

     MODIFICATION HISTORY:

           Written by David W. Fanning, Fanning Software Consulting, 17 August 2008.
           Ideas taken from discussion with Ben Tupper and Ben's program HBB_ANALYZER.

(See blob_analyzer__define.pro)

## CAPFIRSTLETTER

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CAPFIRSTLETTER

     PURPOSE:

           Given a string, separates the parts by white space, commas,
           semi-colons, or colons. Each part has the first letter capitalized.
           The returned string has the capitalized parts separated by a space.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           capitalizedString = CatFirstLetter(theString)

     AUGUMENTS:

           theString:         The input string.

     RETURN_VALUE:

          capitalizedString:  The capitalized output string. There is a space between parts
                              (words) of the input string.

     KEYWORDS:

         None.

     MODIFICATION HISTORY:

           Written by David W. Fanning, 29 July 2005.

(See capfirstletter.pro)

## CHECKERBOARD

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           Checkerboard

     PURPOSE:
           This function returns a 2D image, with boxes of alternating colors.
           Checkerboard images are useful in certain types of image processing
           procedures and for making blended image masks.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Image Processing

     CALLING SEQUENCE:

            board = Checkerboard()

     RETURN VALUE:

            board:      A 2D long array of alternating colored boxes.

     ARGUMENTS:

            boxes:      The number of boxes of alternating colors on each side
                        of the resulting image. Must be an even integer greater
                        than or equal to two. Optional. Default is 8 (normal
                        checkerboard).

     INPUT KEYWORDS:

       BLACK:           The value of the "black" boxes. By default, 0.

       WHITE:           The value of the "white" boxes. By default, 255.

       XSIZE:           The X size of the returned image. By default, 400.

       YSIZE:           The Y size of the returned image. By default, 400.

     COMMON BLOCKS:

       None.

     EXAMPLE:

            IDL> cgImage, Checkerboard()

     MODIFICATION HISTORY:

      Written by David W. Fanning, 26 September 2007, based on suggestions
      of JD Smith on IDL newsgroup 25-26 Septermber 2007.

(See checkerboard.pro)

## CINDEX

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CIndex

     PURPOSE:
           This is a program for viewing the current colors in the
           colortable with their index numbers overlayed on each color.
           On 24-bit systems you must click the cursor in the graphics window
           to see the colors in the current color table.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY: Graphics

     CALLING SEQUENCE:  CIndex

     INPUTS:   None.

     INPUT KEYWORDS:

      BREWER:     If this keyword is set, the BREWER colors will be loaded with the
                  Change Colors button. (Assuming the brewer color table file, fsc_brewer.tbl,
                  has been installed.

     OUTPUTS:  None

     OPTIONAL OUTPUTS:  None

     OUTPUT KEYWORDS:

       NOTIFYID:   A two-element array containing the Change Colors button widget
                   identifier and the identifier of the top-level base widget. This
                   array is meant to be sent to an XCOLORS routine via its NOTIFYID
                   keyword. This will allow instant updating of the CINDEX interface.

     COMMON BLOCKS:  None

     SIDE EFFECTS:   None

     RESTRICTIONS:   Reqires XCOLORS and cgImage from the Coyote Library:

                         http://www.idlcoyote.com/programs/xcolors.pro
                         http://www.idlcoyote.com/programs/cgImage.pro

     PROCEDURE:

      Draws a 31x25 set of small rectangles in 256 different colors.
      Writes the color index number on top of each rectangle.

     MODIFICATION HISTORY:  Written by David Fanning, May 1995

      Widgetized and made it work in 24-bit color. Colors are
         updated by clicking in window. 22 Oct 98. DWF
      Replace POLYFILL with TV command to avoid underflow error in
         Z-buffer. 8 March 99. DWF
      Fixed a problem with 24-bit devices with color decomposition ON. 15 Feb 2000. DWF.
      Added the NOTIFYID keyword, 15 Dec 2005. DWF.
      Added BREWER keyword, 19 May 2008. DWF.
      Replaced TV commands with cgImage, 12 June 2013. DWF.

(See cindex.pro)

## CLIPBOARD

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CLIPBOARD

     PURPOSE:

           The purpose of this program is to copy the contents of a
           graphics window to the clipboard for subsequent pasting into
           applications such as Photoshop or Powerpoint.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

          Graphics.

     CALLING SEQUENCE:

          CLIPBOARD, window_index

     OPTIONAL INPUTS:

           window_index:    The window index number of the graphics window to
                            copy. If absent, the current graphics window is used
                            by default.

     KEYWORDS:

           All COLOR_QUAN keywords are allowed. In particular, if you are
           taking snapshots of line plots with few colors in them, you may
           get better results by calling the program with the CUBE=6 keyword
           set. Otherwise, white colors can sometimes be a bit gray.

     OUTPUTS:
           None.

     COMMON BLOCKS:
           None.

     DEPENDENCIES:

           Uses the IDLgrClipboard object introduced in IDL 5.2(?).

     PROCEDURE:

           Copies the window contents to a clipboard object.

     EXAMPLE:

            IDL> Window
            IDL> Plot, Findgen(11)
            IDL> CLIPBOARD

     RESTRICTIONS:

           May not work for all applications. Applications tested successfully
           include: Framemaker, Powerpoint, Photoshop, Excel, Microsoft Word.
           Converts 24-bit images to 2D images with color tables.

     MODIFICATION HISTORY:

           Written by: David W. Fanning, 24 October 2001.
           Added _EXTRA keyword to pass COLOR_QUAN keywords along. 28 Oct 2002. DWF.

(See clipboard.pro)

## CLIPSCL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CLIPSCL

     PURPOSE:

           This is a utility routine to perform linear scaling (similar to BYTSCL)
           on image arrays. If differs from BYTSCL only in that a user-specified
           percentage of pixels can be clipped from the image histogram, prior to
           scaling. By default, two percent of the pixels are clipped. Clipping
           occurs at both ends of the image histogram.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           scaledImage = CLIPSCL(image, clipPercent)

     ARGUMENTS:

           image:         The image to be scaled. Written for 2D images, but arrays
                          of any size are treated alike.

           clipPercent:   The percent of image clipping. Optional argument is set
                          to 2 by default. Must be value between 0 and 49. Clipping
                          occurs from both ends of image histogram, so a clip of 2
                          linearly scales approximately 96% of the image histogram.
                          Clipping percents are approximations only, and depend
                          entirely on the distribution of pixels in the image. For
                          interactive scaling, see cgStretch.

     INPUT KEYWORDS:

           NEGATIVE:      If set, the "negative" of the result is returned.

           OMAX:          The output image is scaled between OMIN and OMAX. The
                          default value is 255.

           OMIN:          The output image is scaled between OMIN and OMAX. The
                          default value is 0.
     OUTPUT KEYWORDS:

           THRESHOLD:     A two-element array containing the image thresholds for clipping.

     RETURN VALUE:

           scaledImage:   The output, scaled into the range OMIN to OMAX. A byte array.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           LoadCT, 0                                            ; Gray-scale colors.
           image = cgDemoData(22)                                 ; Load image.
           TV, ClipScl(image, 4)

     RESTRICTIONS:

         Requires cgScaleVector from the Coyote Library:

            http://www.idlcoyote.com/programs/cgScaleVector.pro

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 6 September 2007.
           Not sure what this program was doing, but not what I thought. I've reworked
              the algorithm to scale the data appropriately. 25 Oct 2011. DWF.

(See clipscl.pro)

## COLORBUTTONBITMAP

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           ColorButtonBitmap

     PURPOSE:

           The purpose of this program is to create a 24-bit bitmap that can be used to
           create a colored widget button.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Widget Programming

     CALLING SEQUENCE:

           bitmap = ColorButtonBitmap(theText)
           button = Widget_Button(tlb, Value=bitmap)

     REQUIRED INPUTS:

           theText - The text you wish to have on the button.

     OUTPUTS:

           bitmap - A 3xMxN byte array, representing a 24-bit image that is used
                    as a button value.

     OPTIONAL KEYWORDS:

           BGCOLOR - The name of the background color. For example, 'Yellow', 'Tan', etc.
                     The name must be compatible with names appropriate for cgColor.

           FGCOLOR - The name of the foreground color. For example, 'Navy', 'Black', etc.
                     The name must be compatible with names appropriate for cgColor.

     DEPENDENCIES:

           Reqires cgColor from the Coyote Library:

                         http://www.idlcoyote.com/programs/cgColor.pro

     EXAMPLE:

           tlb = Widget_Base(/Row, /Exclusive)
           button1 = Widget_Button(tlb, Value=ColorButtonBitmap('Button 1')) ; Normal button.
           button2 = Widget_Button(tlb, Value=ColorButtonBitmap('Button 2', FGCOLOR='YELLOW', BGCOLOR='NAVY'))
           button3 = Widget_Button(tlb, Value=ColorButtonBitmap('Button 3', BGCOLOR='YELLOW', FGCOLOR='NAVY'))
           Widget_Control, tlb, /Realize

     MODIFICATION HISTORY:

           Written by David Fanning, May 25, 2007 based on code named BitmapForButtonText supplied to the IDL
           newsgroup by Dick Jackson: http://www.idlcoyote.com/tip_examples/bitmapforbuttontext.pro.
           Fixed a problem with foreground and background colors that caused them to work correctly only
               when color decomposition is on--as it should be :-). 6 May 2009.

(See colorbuttonbitmap.pro)

## COLORSAREIDENTICAL

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
       Returns a 1 if the two input colors refer to the same color, otherwise returns a 0.

     :Categories:
        Graphics Utility

     :Params:
        color_1: in, required, type=string/integer/long
             The first color to compare for "equality".
        color_2: in, required, type=string/integer/long
             The second color to compare for "equality".

     :Keywords:
         None.

     :Examples:
        Used to compare if two different colors are the same color::
           IDL> Print, ColorsAreIdentical('white', cgColor('white'))
           IDL> Print, ColorsAreIdentical(252, !P.Color)
           IDL> Print, ColorsAreIdentical('white', '255')

     :Author:
           FANNING SOFTWARE CONSULTING::
               David W. Fanning
               1645 Sheely Drive
               Fort Collins, CO 80526 USA
               Phone: 970-221-0438
               E-mail: david@idlcoyote.com
               Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written, 24 December 2010. DWF.
            Fixed a typo when first color is INTEGER and second color is STRING. 3 Jan 2011. DWF.
            Added error handling for out of bounds color values. 25 May 2011. DWF.

     :Copyright:
         Copyright (c) 2010, Fanning Software Consulting, Inc.

(See colorsareidentical.pro)

## CONTRASTZOOM

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CONTRASTZOOM

     PURPOSE:

           The purpose of this program is to demonstrate how to
           zoom an image "in place" and how to window and level
           (set "contrast and brightness") an image using object
           graphics functionality. The exercise involves using
           multiple views in an object graphics scene, and being
           able to interact with different views in different ways.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Widgets, Object Graphics.

     CALLING SEQUENCE:

           ContrastZoom, image

     REQUIRED INPUTS:

           None. The image "mr_knee.dcm" from the examples/data directory
           is used if no data is supplied in call.

     OPTIONAL INPUTS

           image: A 2D image array of any data type.

     OPTIONAL KEYWORD PARAMETERS:

           COLORTABLE: The number of a color table to use as the image palette.
           Color table 0 (grayscale) is used as a default.

           GROUP_LEADER: The group leader for this program. When the group leader
           is destroyed, this program will be destroyed.

     COMMON BLOCKS:

           None.

     SIDE EFFECTS:

           None.

     RESTRICTIONS:

           None. The Coyote Library program VCOLORBAR is included.

     EXAMPLE:

           To use this program with your 8-bit image data and a red-temperature
           color scale, type:

              IDL> ContrastZoom, image, Colortable=3

     NOTES:

           The left image is used to "zoom" into a portion of the image.
           The aspect ratio of the sub-image is always preserved. To see
           the entire image, click and release the mouse button in this
           window.

           The center image is used to adjust the contrast and brightness
           (sometimes called the "window" and "level" of the image. Click and
           drag the mouse vertically to set contrast. Click and drag the mouse
           horizontally to set brightness. To return to original values (25%
           contrast and 75% brightness), click and release in the center image.

           The color bars shows the image values of the image.

     MODIFICATION HISTORY:

           Written by David Fanning, 18 November 2001.
           Added second colorbar to show the relationship of the clamped
              colors to the overall image values. 19 November 2001. DWF.
           Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See contrastzoom.pro)

## CONVERT_TO_TYPE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CONVERT_TO_TYPE

     PURPOSE:

           Converts its input argument to a specified data type.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           result = Convert_To_Type(input, type)

     INPUT_PARAMETERS:

           input:          The input data to be converted.
           type:           The data type. Accepts values as given by Size(var, /TNAME) or Size(var, /TYPE).
                           If converting to integer types, values are truncated (similar to FLOOR keyword below),
                           unless keywords are set.

     OUTPUT_PARAMETERS:

          result:          The input data is converted to specified data type.

     KEYWORDS:

         CEILING:          If set and converting to an integer type, the CEIL function is applied before conversion.

         FLOOR:            If set and converting to an integer type, the FLOOR function is applied before conversion.

         ROUND:            If set and converting to an integer type, the ROUND function is applied before conversion.

     RESTRICTIONS:

         Data types STRUCT, POINTER, and OBJREF are not allowed.

     MODIFICATION HISTORY:

         Written by David W. Fanning, 19 February 2006.
         Typo had "UNIT" instead of "UINT". 23 February 2009. DWF.
         Added CEILING, FLOOR, and ROUND keywords. 1 April 2009. DWF.
         Modified so that the "type" variable is not changed by the program. 5 May 2009. DWF.

(See convert_to_type.pro)

## CW_DRAWCOLOR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           CW_DRAWCOLOR

     PURPOSE:

           This compound widget is used to place a label or color name next
           to a color patch. Clicking on the color patch allows the user
           to select another color

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics

     CALLING SEQUENCE:

           colorpatchID = CW_DrawColor(parent)

     REQUIRED INPUTS:

           parent - The identifier of a parent base widget.

     OUTPUTS:

           colorpatchID - The widget identifier of the top-level base of this compound widget

     INPUT KEYWORDS:

       COLOR - The name of the color to be displayed. Color names come from cgPickColorName.
       COLUMN - Set this keyword to stack widgets in a column. Default is in a row.
       EVENT_FUNC - The name of an event handler function for this compound widget.
       EVENT_PRO -The name of an event handler procedure for this compound widget.
       INDEX - An index number where the color should be loaded. !D.Table_Size-2, by default.
       FILENAME - An optional input to cgPickColorName specifying different
                  colors.  See the cgPickColorName documenation for the file format.
       LABEL_LEFT - Set this keyword to have the label text aligned on the left of the label. Default is to center.
       LABEL_RIGHT - Set this keyword to have the label text aligned on the right of the label. Default is to center.
       LABELSIZE - This is the X size of the label widget (containing the label) in device coordinates. Default is natural size.
       LABELTEXT - This is the text on the label. Example, "Background Color", etc.
       TITLE - This is the title on the cgPickColorName program that allows the user to select another color.
       UVALUE - A user value for the widget.
       XSIZE - The xsize (in pixel units) of the color patch. By default, 20.
       YSIZE - The xsize (in pixel units) of the color patch. By default, 20.

     OUTPUT KEYWORDS:

       OBJECT - The object reference. Use this to call methods, etc.

     OBJECT PROCEDURE METHODS:

       Set_Value -- this method takes one argument, the new color name.
                   It will change the color of the widget if it has
                   already been realized.

       Get_Value -- this method returns the color name the widget is displaying

     DEPENDENCIES:

           Reqires cgColor and cgPickColorName from the Coyote Library:

                         http://www.idlcoyote.com/programs/cgColor.pro
                         http://www.idlcoyote.com/programs/cgPickColorName.pro

     MODIFICATION HISTORY:

           Written by David W. Fanning, March 2001.
           Fixed a problem with self object cleanup. 7 March 2006. DWF.
           Allow addition to already realized widget hierarchies, October 2007. L. Anderson.
           Added set_value and get_value methods to the widget can be
                updated after being realized. October 2007. L. Anderson.
           Added option to pass filename on to cgPickColorName. October
                2007. L. Anderson

(See cw_drawcolor.pro)

## DIRPATH

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
        DIRPATH

     PURPOSE:

        The purpose of this function is to return a device-independent
        name of a directory. It is similar to the IDL-supplied FILEPATH
        routine, except that a file name is not required.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

        Utility.

     CALLING SEQUENCE:

        IDL> theDirectory = DIRPATH('examples')
        IDL> Print, theDirectory
                 C:\IDL\IDL56\examples

     INPUTS:

        subDirectory:    This is a string argument containing the name of the
                         sub-directory you wish to use. It can be a string
                         array of sub-directory names. By default, the subDirectory
                         is set to ['examples', 'data']. To only return the Root_Directory,
                         set the subDirectory to a null string ("").

     KEYWORDS:

        ROOT_DIRECTORY: The name of the root directory to use. By default,
                        the root directory is set to !DIR.

     OUTPUTS:

        The machine-independent directory path.

     MODIFICATION HISTORY:

        Written by: David W. Fanning, 28 April 2003.

(See dirpath.pro)

## ERRORLOGGER__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           ErrorLogger__Define

     PURPOSE:

           The purpose of this program is to log program errors or text messages during
           program execution as an aid to debugging such a program at a later date. The
           ErrorLogger program is written as an object so that it will persist in the IDL
           session until it is destroyed.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           errorLogger = Obj_New("ErrorLogger")

     ARGUMENTS:

           filename:    The name of the error log file. If not provided, a default name
                        will be created, based on the current system time. (Optional)

     KEYWORDS:

           ALERT:       The default behavior of the error logger is simply to write text to a file.
                        But if the ALERT keyword is set, the program will alert the user via a
                        message dialog that an error has occurred when using the AddError method.
                        Default is 0. (Input)

          DELETE_ON_DESTROY: If this keyword is set, the error log file will be deleted when the
                        ErrorLogger object is destroyed, but only if the ErrorLogger object is not
                        in an error state at that time (error status = 2). Default is 0. (Input)

           NOCLUTTER:   Believe it or not, some people who use an ErrorLogger prefer that an error log
                        file is never left behind. (They prefer that the program act like cgErrorMsg.)
                        For those people, the NOCLUTTER keyword provides a way for them to automatically
                        set the ALERT and DESTROY_ON_DELETE keywords to 1. It also prevents the error
                        logger from ever setting the error status to 2. Thus, when the ErrorLogger is
                        destroyed, the file is always deleted. Default is 0. When set, overrides ALERT
                        and DELETE_ON_DESTROY settings. (Input)

           NOTRACEBACK: Set this keyword to suppress traceback information in the error log output
                        and in any alerts issued by the program. Default is 0. (Input)

           TIMESTAMP:   Set this keyword if you wish a time stamp to be appended to the provided
                        filename. Otherwise, the filename is used as defined. Default filenames
                        always have a timestamp appended to the file name. (Input)

     METHODS:

            AddError:   Adds an error text string or array to the error log file. By default,
                        it will add the HELP, LAST_MESSAGE=1, /TRACEBACE traceback
                        information to the file. (Procedure)

            AddText:    Adds a text string or array to the error log file. (Procedure)

            ClearLog:   Erases all the text currently in the error log file. (Procedure)

            CloseFile:  Closes the currently open error log file. (Procedure)

            Flush:      Forces a write of any current information to the disk (Procedure)

            GetProperty: Gets properties of the object. (Procedure)

            LastMessage: Returns the last message text written into the error log file. (Function)

            OpenFile:   Opens the error log file for writing. (Function)

            PrintLastMessage: Writes the last message text written into the error log file to
                        standard output. (Procedure)

            Status:     Returns the current status of the error logger. (0 - waiting for input,
                        1 - normal operation, 2 - error operation.) (Function)

            SetProperty: Sets properties of the object. (Procedure)

            SetStatus:  Sets the current status of the error logger. Normally not used by the
                        user, but used internally. (Procedure)

     MODIFICATION HISTORY:

           Written by David W. Fanning, November 2009.
           Modified and expanded the way errors are written into the log file and displayed.
              Also made it possible to automatically delete the log file when the object is
              destroyed, if the error logger is not in an error state at the time. Added
              DELETE_ON_DESTROY and NOTRACEBACK keywords to the INIT and SetProperty
              methods. 28 Jan 2010. DWF.
            Modified default filenames so that I am now guaranteed to get unique file names
               by using cgTimestamp program from the Coyote Library. 8 Feb 2010. DWF.
            Added NOCLUTTER keyword. 15 February 2010. DWF.
            Added PRINT keyword to AddText method to allow users to log statements that should
               also be printed easily to a file. 17 February 2010. DWF.
            Small documentation changes to the program. 22 June 2010. DWF.
            Made a change so that the file is not opened until something needs to be written
                to it. 22 June 2010. DWF.
            Added FLUSH method and keyword IMMEDIATE to the INIT method (defaults to 1) which
                will immediately flush the log information to disk when log information is
                added to the object. This will prevent missing information that is buffered
                when a program crashes. Matt Savoie suggestion. DWF, 10 Sept 2010.
            Now calling cgTimeStamp rather than TimeStamp to avoid problems with IDL code. 6 Feb 2013. DWF.

(See errorlogger__define.pro)

## FIND_BOUNDARY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           FIND_BOUNDARY

     PURPOSE:

           This program finds the boundary points about a region of interest (ROI)
           represented by pixel indices. It uses a "chain-code" algorithm for finding
           the boundary pixels.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics, math.

     CALLING SEQUENCE:

           boundaryPts = Find_Boundary(indices, XSize=xsize, YSize=ysize)

     OPTIONAL INPUTS:

           indices - A 1D vector of pixel indices that describe the ROI. For example,
                the indices may be returned as a result of the WHERE function.

     OUTPUTS:

           boundaryPts - A 2-by-n points array of the X and Y points that describe the
                boundary. The points are scaled if the SCALE keyword is used.

     INPUT KEYWORDS:

           SCALE - A one-element or two-element array of the pixel scale factors, [xscale, yscale],
                used to calculate the perimeter length or area of the ROI. The SCALE keyword is
                NOT applied to the boundary points. By default, SCALE=[1,1].

           XSIZE - The X size of the window or array from which the ROI indices are taken.
                Set to !D.X_Size by default.

           YSIZE - The Y size of the window or array from which the ROI indices are taken.
                Set to !D.Y_Size by default.

     OUTPUT KEYWORDS:

           AREA - A named variable that contains the pixel area represented by the input pixel indices,
                scaled by the SCALE factors.

           CENTER - A named variable that contains a two-element array containing the center point or
                centroid of the ROI. The centroid is the position in the ROI that the ROI would
                balance on if all the index pixels were equally weighted. The output is a two-element
                floating-point array in device coordinate system, unless the SCALE keyword is used,
                in which case the values will be in the scaled coordinate system.

           PERIM_AREA - A named variable that contains the (scaled) area represented by the perimeter
                points, as indicated by John Russ in _The Image Processing Handbook, 2nd Edition_ on
                page 490. This is the same "perimeter" that is returned by IDLanROI in its
                ComputeGeometry method, for example. In general, the perimeter area will be
                smaller than the pixel area.

           PERIMETER - A named variable that will contain the perimeter length of the boundary
                upon returning from the function, scaled by the SCALE factors.

      EXAMPLE:

           LoadCT, 0, /Silent
           image = BytArr(400, 300)+125
           image[125:175, 180:245] = 255B
           indices = Where(image EQ 255)
           Window, XSize=400, YSize=300
           TV, image
           PLOTS, Find_Boundary(indices, XSize=400, YSize=300, Perimeter=length), $
               /Device, Color=cgColor('red')
           Print, length
               230.0

     MODIFICATION HISTORY:

           Written by David W. Fanning, April 2002. Based on an algorithm written by Guy
           Blanchard and provided by Richard Adams.
           Fixed a problem with distinction between solitary points and
              isolated points (a single point connected on a diagonal to
              the rest of the mask) in which the program can't get back to
              the starting pixel. 2 Nov 2002. DWF
           Added the ability to return the perimeter length with PERIMETER and
               SCALE keywords. 2 Nov 2002. DWF.
           Added AREA keyword to return area enclosed by boundary. 2 Nov 2002. DWF.
           Fixed a problem with POLYFILLV under-reporting the area by removing
               POLYFILLV and using a pixel counting method. 10 Dec 2002. DWF.
           Added the PERIM_AREA and CENTER keywords. 15 December 2002. DWF.
           Replaced the cgErrorMsg routine with the latest version. 15 December 2002. DWF.
           Fixed a problem in which XSIZE and YSIZE have to be specified as integers to work. 6 March 2006. DWF.
           Fixed a small problem with very small ROIs that caused the program to crash. 1 October 2008. DWF.
           Modified the algorithm that determines the number of boundary points for small ROIs. 28 Sept 2010. DWF.

(See find_boundary.pro)

## FIT_ELLIPSE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           Fit_Ellipse

     PURPOSE:

           This program fits an ellipse to an ROI given by a vector of ROI indices.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics, math.

     CALLING SEQUENCE:

           ellipsePts = Fit_Ellipse(indices)

     OPTIONAL INPUTS:

           indices - A 1D vector of pixel indices that describe the ROI. For example,
                the indices may be returned as a result of the WHERE function.

     OUTPUTS:

           ellipsePts - A 2-by-npoints array of the X and Y points that describe the
                fitted ellipse. The points are in the device coodinate system.

     INPUT KEYWORDS:

           NPOINTS - The number of points in the fitted ellipse. Set to 120 by default.

           SCALE - A two-element array that gives the scaling parameters for each X and Y pixel, respectively.
                Set to [1.0,1.0] by default.

           XSIZE - The X size of the window or array from which the ROI indices are taken.
                Set to !D.X_Size by default.

           YSIZE - The Y size of the window or array from which the ROI indices are taken.
                Set to !D.Y_Size by default.

     OUTPUT KEYWORDS:

           CENTER -- Set to a named variable that contains the X and Y location of the center
                of the fitted ellipse in device coordinates.

           ORIENTATION - Set to a named variable that contains the orientation of the major
                axis of the fitted ellipse. The direction is calculated in degrees
                counter-clockwise from the X axis.

           AXES - A two element array that contains the length of the major and minor
                axes of the fitted ellipse, respectively.

           SEMIAXES - A two element array that contains the length of the semi-major and semi-minor
                axes of the fitted ellipse, respectively. (This is simple AXES/2.)

      EXAMPLE:

           LoadCT, 0, /Silent
           image = BytArr(400, 300)+125
           image[180:245, 125:175] = 255B
           indices = Where(image EQ 255)
           Window, XSize=400, YSize=300
           TV, image
           PLOTS, Fit_Ellipse(indices, XSize=400, YSize=300), /Device, Color=cgColor('red')

     MODIFICATION HISTORY:

           Written by David W. Fanning, April 2002. Based on algorithms provided by Craig Markwardt
                and Wayne Landsman in his TVEllipse program.
           Added SCALE keyword and modified the algorithm to use memory more efficiently.
                I no longer have to make huge arrays. The arrays are only as big as the blob
                being fitted. 17 AUG 2008. DWF.
           Fixed small typo that caused blobs of indices with a longer X axis than Y axis
                to misrepresent the center of the ellipse. 23 February 2009.

(See fit_ellipse.pro)

## FIXED_MAP_GRID

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FIXED_MAP_GRID

     PURPOSE:
           The MAP_GRID procedure draws the graticule of parallels and meridians,
     according to the specifications established by MAP_SET. MAP_SET must be called
     before MAP_GRID to establish the projection type, the center of the
     projection, polar rotation and geographical limits.

     CATEGORY:
       Mapping.

     CALLING SEQUENCE:
           MAP_GRID

     INPUTS:
       NONE

     OPTIONAL INPUTS:
       NONE

     KEYWORD PARAMETERS:

     BOX_AXES: Surround the map window with a "box" style axes with
             annotations, outside the box, where the parallels intersect the
             sides, and the meridians intersect the bottom and top edges of the
             box.  The border of the box is drawn in alternating foreground and
             background colors, with color changes at each intersection with
             a parallel or meridian.  This keyword determines the thickness of
             the box's border, in millimeters.  If LABEL is not explicitly
             specified, it defaults to 1 when this keyword is present.  If this
             feature is selected, be sure to leave enough room around the map
             window for the annotation, usually by specifying the XMARGIN and
             YMARGIN keywords to MAP_SET.  See the example below.
       CHARSIZE: The size of the characters used for the labels. The default is 1.
          COLOR: The color index for the grid lines.
    FILL_HORIZON: Fills the current map_horizon.
        HORIZON: Draws the current map horizon.
      INCREMENT: Determines the spacing between graticle points.
     GLINESTYLE: If set, the line style used to draw the grid of parallels and
                 meridians. See the IDL User's Guide for options. The default is
                 dotted.
     GLINETHICK: The thickness of the grid lines. Default is 1.
          LABEL: Set this keyword to label the parallels and meridians with their
                 corresponding latitudes and longitudes. Setting this keyword to
                 an integer will cause every LABEL gridline to be labeled (i.e,
                 if LABEL=3 then every third gridline will be labeled). The
                 starting point for determining which gridlines are labeled is the
                 minimum latitude or longitude (-180 to 180), unless the LATS or
                 LONS keyword is set to a single value. In this case, the starting
                 point is the value of LATS or LONS.
       LATALIGN: This keyword controls the alignment of the text baseline for
                 latitude labels. A value of 0.0 left justifies the label,
                 1.0 right justifies it, and 0.5 centers it.
         LATDEL: The spacing in degrees between parallels of latitude in the grid.
                 If not set, a suitable value is determined from the current map
                 projection.
           LATS: The desired latitudes to be drawn (and optionally labeled). If
                 this keyword is omitted, appropriate latitudes will be generated
                 with consideration of the optional LATDEL keyword. If this
                 keyword is set to a single value, drawn (and optionally labeled)
                 latitudes will be automatically generated  as
                 [...,LATS-LATDEL,LATS,LATS+LATDEL,...] over the extent of the
                 map.  The single valued LATS is taken to be the starting point
                 for labelling (See the LABEL keyword).
         LATLAB: The longitude at which to place latitude labels. The default is
                 the center longitude on the map.
       LATNAMES: An array specifing the names to be used for the latitude labels.
                 By default, this array is automatically generated in units of
                 degrees. This array can be a string array or numeric, but should
                 not be of mixed type. When LATNAMES is specified, LATS must also
                 be specified, but the number of elments in the two arrays need not
                 be equal. Extra LATNAMES are ignored, while LATNAMES not supplied
                 are automatically reported in degrees. LATNAMES can be used when
                 LATS is set to a single value. It this case, the LATS used will
                 start at the specified latitude and progress northward, wrapping
                 around the globe if appropriate. Caution should be used when
                 using LATNAMES in conjunction with a single LATS, since the
                 number of visible latitude gridlines is dependent on many factors.
       LONALIGN: This keyword controls the alignment of the text baseline for
                 longitude labels. A value of 0.0 left justifies the label,
                 1.0 right justifies it, and 0.5 centers it.
         LONDEL: The spacing in degrees between meridians of longitude in the grid.
                 If not set, a suitable value is determined from the current map
                 projection.
         LONLAB: The latitude at which to place longitude labels. The default is
                 the center latitude on the map.
           LONS: The desired longitudes to be drawn (and optionally labeled). If
                 this keyword is omitted, appropriate longitudes will be generated
                 with consideration of the optional LONDEL keyword. If this
                 keyword is set to a single value, drawn (and optionally labeled)
                 longitudes will be automatically generated as
                 [...,LONS-LONDEL,LONS,LONS+LONDEL,...] over the extent of the map.
                 The single valued LONS is taken to be the starting point for
                 labeling (See the LABEL keyword).
       LONNAMES: An array specifing the names to be used for the longitude labels.
                 By default, this array is automatically generated in units of
                 degrees. This array can be a string array or numeric, but should
                 not be of mixed type. When LONNAMES is specified, LATS must also
                 be specified, but the number of elments in the two arrays need not
                 be equal. Extra LONNAMES are ignored, while LATNAMES not supplied
                 are automatically reported in degrees. LONNAMES can be used when
                 LONS is set to a single value. It this case, the LONS used will
                 start at the specified longitude and progress eastward, wrapping
                 around the globe if appropriate. Caution should be used when
                 using LONNAMES in conjunction with a single LONS, since the number
                 of visible longitude gridlines is dependent on many factors.

     MAP_STRUCTURE: Set this keyword to a !MAP structure, as returned from
           MAP_PROJ_INIT. If this keyword is set then the gridlines are passed
           through MAP_PROJ_FORWARD and the resulting lines are drawn using
           Cartesian coordinates. If this keyword is not set then it is assumed
           that MAP_SET has been called to set up a map projection.

     NO_GRID: Set this keyword if you only want labels but not gridlines.

    ORIENTATION: Specifies the clockwise angle in degrees from horizontal
                 of the text baseline that the labels should be rotated. Note,
                 that the rotation used in MAP_SET is also clockwise, but XYOUTS
                 is normally counterclockwise.

     T3D: Set this keyword to indicate that the generalized transformation
          matrix in !P.T is to be used. If not present, the user-supplied
          coordinates are simply scaled to screen coordinates.

     ZVALUE: Sets the Z coordinate, in normalized coordinates in the
             range of 0 to 1, at which to output the continents.

          Note - This keyword has effect only if keyword T3D is set and the
             transformation is stored in !P.T

    OUTPUTS:
             Draws gridlines and labels on the current map.

     EXAMPLE:
         map_set,10,20,23.5,/cont,/ortho,/horizon     ; establish a projection
             lats=[-65,-52,-35,-20,-2.59,15,27.6,35,45,55,75,89]
                         ; choose the parallels to draw
             map_grid,lats=lats,londel=20,lons=-13,label=2,lonlab=-2.5,latlab=7
                         ;draw the grid
       Make a map with a grid surrounded by a box style axis:
       map_set, /STEREO, 40, -90,scale=50e6,/CONTINENTS, XMARGIN=3, YMARGIN=3
       map_grid, /BOX_AXES, COLOR=3, CHARSIZE=1.5  ;

     MODIFICATION HISTORY:
       Written by: SVP, May, 23 1996.
       DMS, Feb, 1996 Note that this version plots all gridlines
               unless a 4 element LIMIT was specified to MAP_SET.
           SVP, Nov 1996   Changed over !map1 (new IDL5 maps)
       SVP, May 1996   Map_Grid used to live inside of map_set.pro, now
                           it lives here.
           SVP, May 1996   Changed LABEL to determine the skip between labelled
                           gridlines.
                           Also, added the LATS and LONS keywords to give complete
                           control over where the labels go.
           SVP, Sept 1996  Added LATNAMS,LONAMES, and ORIENTATION keywords
       DMS, Nov, 1996  Rev 2 of maps.
       DMS, Jul, 1997  Added Box Axes
       CT, Jan 2004: Added MAP_STRUCTURE keyword.
       Renamed the function FIXED_MAP_GRID with fixed at lines 555-556 and
          664-665 as described here: http://www.dfanning.com/map_tips/missinggrid.html.
          This is required to get proper grid output in some applications, but
          it breaks other code.

(See fixed_map_grid.pro)

## FLOATS_EQUAL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           FLOATS_EQUAL

     PURPOSE:

           The purpose of this function is to compare two floating-point values or
           arrays to determine if the values or arrays are equal. Arrays are equal
           if they have the same number of elements, and each element is equal.

           To learn why determing if floats are equal is hard (and probably not done
           correctly in this program), please read the following article::

              http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           result = FLOATS_EQUAL(array_1, array_2)

     ARGUMENTS:

           array_1        Any single or double precision value or array. Required parameter.

           array_2        Any single or double precision value or array. Required parameter.

     KEYWORDS:

           ULP            UNIT in the LAST PLACE. It is the gap or difference between two
                          floating point numbers in the last digit that can distinguish the
                          two numbers. Must be a positive integer. Set to 1 by default. Set
                          to a larger value if you suspect accumulative round-off errors
                          in your arrays.

     RETURN VALUE:

           result         Set to 1 if the arrays are equal, which means that the arrays have
                          the same number of elements and each element is equal to the same
                          element in the other array. Set to 0 if the arrays are not equal.
     COMMON BLOCKS:
           None.

     EXAMPLE:

           IDL> a = Findgen(11)
           IDL> b = Findgen(11)
           IDL> Print, Floats_Equal(a,b)
                 1
           IDL> b[4] = b[4] + 0.0001
           IDL> Print, Floats_Equal(a,b)
                 0

     RESTRICTIONS:

           None.

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 29 August 2007.
           Fixed a problem when using large numbers with the TOTAL command
              by setting the INTEGER keyword. 22 June 2011. DWF.

(See floats_equal.pro)

## FPUFIX

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           FPUFIX

     PURPOSE:

           This is a utility routine to examine a variable and fix problems
           that will create floating point underflow errors.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           fixedData = FPUFIX(data)

     ARGUMENTS:

           data :         A numerical variable to be checked for values that will cause
                          floating point underflow errors. Suspect values are set to 0.

     KEYWORDS:

           None.

     RETURN VALUE:

           fixedData:    The output is the same as the input, except that any values that
                         will cause subsequent floating point underflow errors are set to 0.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           data = FPTFIX(data)

     RESTRICTIONS:

         None.

     MODIFICATION HISTORY:

           Written by David W. Fanning, from Mati Meron's example FPU_FIX. Mati's
              program is more robust that this (ftp://cars3.uchicago.edu/midl/),
              but this serves my needs and doesn't require other programs from
              Mati's library.  24 February 2006.

(See fpufix.pro)

## FSCCLEANUP7

[Previous Routine] [Next Routine] [List of Routines]

     This procedure cleans up any open graphics windows and widget windows for
     versions of IDL prior to IDL 8.

     :Categories:
        Utility

     :Keywords:
         all: in, optional, type=boolean, default=1
           Set this keyword if you wish to clean up windows of all types.
         cg: in, optional, type=boolean, default=0
           Set this keyword if you wish to clean up only Coyote Graphics windows.
         dg: in, optional, type=boolean, default=0
           Set this keyword if you wish to clean up only Direct Graphics windows.

     :Examples:
        For example, to destroy all windows on the display::
           IDL> FSCCleanup7

     :Author:
        FANNING SOFTWARE CONSULTING::
           David W. Fanning
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Written, 6 October 2012.

     :Copyright:
         Copyright (c) 2012, Fanning Software Consulting, Inc.

(See fsccleanup7.pro)

## FSCCLEANUP8

[Previous Routine] [Next Routine] [List of Routines]

     This procedure cleans up any open graphics windows and widget windows for
     versions of IDL from IDL 8 onward.

     :Categories:
        Utility

     :Keywords:
         all: in, optional, type=boolean, default=1
           Set this keyword if you wish to clean up windows of all types.
         cg: in, optional, type=boolean, default=0
           Set this keyword if you wish to clean up only Coyote Graphics windows.
         dg: in, optional, type=boolean, default=0
           Set this keyword if you wish to clean up only Direct Graphics windows.
         fg: in, optional, type=boolean, default=0
           Set this keyword if you wish to clean up only Function Graphics windows.

     :Examples:
        For example, to destroy all windows on the display::
           IDL> FSCCleanup8

     :Author:
        FANNING SOFTWARE CONSULTING::
           David W. Fanning
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Written, 6 October 2012.

     :Copyright:
         Copyright (c) 2012, Fanning Software Consulting, Inc.

(See fsccleanup8.pro)

## FSC_COLORBAR__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           FSC_COLORBAR__DEFINE
           Note: The name of the routine has been changed from COLORBAR__DEFINE
           on 25 Sept 2010 to avoid conflicts with an IDL 8.0 routine of the
           same name. See the article "IDL 8 Name Conflicts" here:

               http://www.idlcoyote.com/ng_tips/idl8_name_conflicts.html

     PURPOSE:
           The purpose of this routine is to implement a FSC_COLORBAR object
           class. The ColorBar is rendered in the direct graphics system.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           Graphics.

     CALLING SEQUENCE:
           colorbar = Obj_New("FSC_COLORBAR")

     INPUTS:
           All inputs to the program are via keyword parameters.

     KEYWORD PARAMETERS:

       Background: Background color. This is the color with which the colorbar is
                   erased. The default color is !P.Background.
       Bottom: Bottom color index of colors allocated to colorbar.
       Charsize: Character size of annotation. Default is 1.0.
       Color: Color of annotation and outline. Default is !P.Color.
       Font: Font to use for annotation. Default is -1, Hershey fonts.
       Format: Format of annotation. Default is "(F8.2)".
       Major: The number of major tick intervals. Default is 5.
       Minor: The number of minor tick intervals. Default is 2.
       MinusOne: Set this keyword to choose MinusOne keyword on the Congrid command
                   that resizes the colorbar into the window.
       NColors: The number of colors allocated to colorbar. Default is (256 <
                !D.N_Colors).
       Neighbor: Set to indicate Nearest Neighbor sampling for Congrid. Default is
                 0 (Bilinear).
       Position: The position of colorbar in normalized coordinates. Default for a
                 horizontal colorbar is [0.15, 0.88, 0.85, 0.95]. Default for a
                 vertical colorbar is [0.88, 0.15, 0.95, 0.85]. These defaults are
                 designed for a 400 by 400 window.
       Range: The data range on colorbar. Default is [0, 255].
       TickLen: The length of tick marks. Default is -0.1
       TickV:   Locations for the tick marks in data units. This is the same as
                the [XY]TickV keyword. Default is to do what IDL would do
                normally.
       Vertical: Set this keyword if you want a vertical colorbar. Default is
                 horizontal.
       XEraseBox: A five-element vector of X points (normalized) for erasing the
                  colorbar plot. Normally this keyword will not have to be used.
                  The program uses the plot REGION for erasing. But larger
                  character sizes can result in annotation going outside the
                  region enclosed by the plot. If that is the case, then use this
                  keyword along with YEraseBox to specify a larger-than-normal
                  erasure area. The points are sent to the POLYFILL command for
                  erasing.

                     POLYFILL, xEraseBox, yEraseBox, /Normal, Color=background

       YEraseBox: A five-element vector of Y points (normalized) for erasing the
                  colorbar plot.

     OBJECT METHODS:

       Clamp: This procedure method allows the color bar range to be "clamped"
              to a particular data range.

       Draw: This procedure method draws the colorbar in the display window. The
             ERASE keyword to this method will erase the current colorbar (by
             calling the ERASE method) before drawing the colorbar in the display
             window.

                   colorbar->Draw

       Erase: This procedure method erases the colorbar object in the window. It
              accomplishes this by performing a POLYFILL in the background color.
              This method is primarily useful for interactive graphics display
              devices.
                   colorbar->Erase

       GetProperty: This procedure method allows one to obtain the current state
                    of the object via the keyword parameters listed above.

                   colorbar->GetProperty, Range=currentRange, Title=currentTitle
                   Print, currentRange, currentTitle

       SetProperty: This procedure method allows one to set the properties of the
                    colorbar object via the keywords described above. In addition,
                    a DRAW and ERASE keyword are provided so that the colorbar can
                    be immediately drawn when the new property is set.

                   colorbar->SetProperty, Range=[500, 15000], /Erase, /Draw

     COMMON BLOCKS:
           None.

     SIDE EFFECTS:
           The display window is not erased first.

     RESTRICTIONS:
           None.

     EXAMPLE:
           To create a colorbar, use it, then destroy it, type:

           colorbar = Obj_New("FSC_COLORBAR", Title='Colorbar Values', Range=[0,1000],$
                      Format='(I4)')
           Window
           LoadCT, 5
           colorbar->Draw
           colorbar->SetProperty, Range=[0,500], /Erase, /Draw
           Obj_Destroy, colorbar

     MODIFICATION HISTORY:
           Written by: David Fanning, Fanning Software Consulting,
                       26 November 1998.
           Added Horizontal keyword to SetProperty method and fixed problem in
           going from Vertical to Horizontal color bars. 29 Nov 1998. DWF.
           Added LoadCT method and current color table index to object.
                 6 December 1998.
           Fixed a bug dealing with nearest neighbor resampling. 30 Mar 1999. DWF.
           Fixed a bug with how NCOLORS and BOTTOM keywords interacted.
                 29 Aug 1999. DWF.
           10 Oct 99. Modified the program so that current plot and map coordinates
                    are saved and restored after the colorbar is drawn. DWF.
           26 May 2000 Added {XY}TICKV capability to the draw method. This
                    required adding TickV to the object data structure, and to the
                    INIT, GetProperty and SetProperty methods.
                    Changed default tick length to -0.1. DWF (and Jack Saba)
           18 Nov 2001. Added Clamp method. DWF.
           25 September 2010. Renamed to FSC_Colorbar__Define to avoid conflict with a
                    Colorbar__Define program introduced with IDL 8.0. DWF.

(See fsc_colorbar__define.pro)

## FSC_COLORSELECT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_COLORSELECT

     PURPOSE:

       The purpose of this compound widget is to provide a means for selecting
       a new color or color table in a widget program. The program consists of
       a label, a non-editable text widget, and a button to make a color or
       color table selection interactively. (See the example program.)

     AUTHOR:
       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       objectRef = FSC_COLORSELECT(parent, Title='Annotate Color ", Color='red')

     INPUT PARAMETERS:

       parent -- The parent widget ID of the compound widget. Required.

     INPUT KEYWORDS:

       BREWER:        Set if you want Brewer color tables, rather than the normal IDL color tables.
                      This requires the file fsc_brewer.tbl to be in your IDL path.

       CFONT:         Set to the name of a font to display the color name in.

       COLOR:         The name of the color to be displayed in the widget. If color
                      is not used, or if it is set to a null string, then the widget
                      will allow selection of a color table, instead of a color name.

       CT_INDEX:      The color table index number you wish to use. The actual name of the
                      color table will be displayed in the widget.

       EVENT_FUNC:   Set this keyword to the name of an Event Function. If this
                     keyword is undefined and the Event_Pro keyword is undefined,
                     all compound widget events are handled internally and not
                     passed on to the parent widget.

       EVENT_PRO:    Set this keyword to the name of an Event Procedure. If this
                     keyword is undefined and the Event_Func keyword is undefined,
                     all compound widget events are handled internally and not
                     passed on to the parent widget.

       FRAME:        Set this keyword to put a frame around the compound widget.

       LABELALIGN:  Set this keyword to align label text. [0-center (default), 1-left, 2-right].

       LABELFONT:   The font name for the text in the Label Widget.

       LABELSIZE:   The X screen size of the Label Widget.

       NAME:        A scalar string name of the object. (Default = ''.)

       SCR_XSIZE:   The X screen size of the compound widget.

       SCR_YSIZE:   The Y screen size of the compound widget.

       STYLE:       The "style" of the text in the Text Widget. A value of 0 (the default)
                    capitalizes the first letter in the name. A style of 1 uses all lowercase.
                    A style of 2 uses all uppercase.

       TITLE:       The text to go on the Label Widget.

       UVALUE:      A user value for any purpose.

       XSIZE:       The X size of the Text Widget.

       In addition, any keyword defined for WIDGET_TEXT, but not defined here (e.g., SENSITIVE), is
       passed along without inspection to the text widget. Use of "extra" keywords is discouraged.

     COMMON BLOCKS:

       None.

     RESTRICTIONS:

       None.

     EVENT STRUCTURE:

       All events are handled internally unless either the Event_Pro or Event_Func
       keywords are used to assign an event handler to the compound widget.

       event = { FSC_ColorSelect_Event, $; The name of the event structure.
                 ID: 0L, $              ; The ID of the compound widget's top-level base.
                 TOP: 0L, $             ; The widget ID of the top-level base of the hierarchy.
                 HANDLER: 0L, $         ; The event handler ID. Filled out by IDL.
                 Color: "", $           ; The name of the current color or color table.
                 Index: 0L, $           ; The color table index selected if color tables are used.
                 Brewer: 0L, $          ; A flag that indicated Brewer color tables are being used.
                 NColors: 0L, $         ; The number of colors used for the color table.
                 ObjRef:Obj_New()}      ; The "self" object.

     GETTING and SETTING VALUES:

       Almost all the properties of the widget can be obtained or set via
       the object's GetProperty and SetProperty methods (described below).
       But since traditional compound widgets have the ability to get and
       set the value of the compound widget, this capability is implemented
       as special methods: Get_Color/Set_Color and Get_Color_Index/Set_Color_Index.

       To get the color of the widget, do this: color = objectRef->Get_Color()
       To set the color of the widget, do this: objectRef->Set_Color, 'blue'.
       Valid colors are those returned by FSC_Color. Getting and setting the
       color table index number works similarly.

     EXAMPLE:

       An example program is provided at the end of the FSC_COLORSELECT code. To run it,
       type these commands:

          IDL> .Compile FSC_COLORSELECT
          IDL> Example

     DEPENDENCIES:

       Requires the Coyote Library:
         http://www.idlcoyote.com/programs/coyoteprograms.zip

     MODIFICATION HISTORY:

       Written by: David W. Fanning, 26 JULY 2010.

(See fsc_colorselect.pro)

## FSC_DROPLIST

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_DROPLIST

     PURPOSE:

       The purpose of this compound widget is to provide an alternative
       to the DROPLIST widget offered in the IDL distribution. What has
       always annoyed me about a droplist is that you can't get the current
       "value" of a droplist easily. This compound widget makes this and
       other tasks much easier.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       droplistObj = FSC_Droplist(parent, Title='Animals: ", Value=['Dog'. 'Cat', 'Coyote'], Index=2)

       The return value of the FSC_Droplist (droplistObj in this example) is
       an object reference. Interaction with the droplist will occur through
       object methods.

     INPUT PARAMETERS:

       parent -- The parent widget ID of the compound widget. Required.

     INPUT KEYWORDS:

     Any keyword that is appropriate for the Widget_Droplist function can be used.
     In addition, these keywords are explicitly defined.

       EVENT_FUNC -- Set this keyword to the name of an Event Handler Function.
       EVENT_PRO -- Set this keyword to the name of an Event Handler Procedure.
       FORMAT -- A format specifier for the "format" of the values in the droplist.
       INDEX -- The index number of the current selection.
       SPACES -- A two-element array that indicates the number of blank spaces to be added
                 to the the beginning and end of the formatted values. If a single number
                 is provided, this number of blank spaces is added to both the beginning
                 and the end of the value.
       TITLE -- The title of the droplist widget.
       UNAME -- The user name of the droplist widget. (Only available in IDL 5.2 and higher.)
       UVALUE -- The normal "user value" of the droplist.
       VALUE -- An array of the droplist "selections". May be any data type.

     COMMON BLOCKS:

       None.

     EVENT STRUCTURE:

       An event is returned each time the droplist value is changed. The event structure
       is defined like this:

       event = { FSC_DROPLIST_EVENT, $ ; The name of the event structure.
                 ID: 0L, $             ; The ID of the compound widget's top-level base.
                 TOP: 0L, $            ; The widget ID of the top-level base of the hierarchy.
                 HANDLER: 0L, $        ; The event handler ID. Filled out by IDL.
                 INDEX: 0L, $          ; The index number of the current selection.
                 SELECTION:Ptr_New() $ ; A pointer to the current selection "value".
                 SELF:Obj_New() }      ; The object reference of the compound widget.

     PUBLIC OBJECT METHODS:

       GetID -- A function with no arguments that returns the widget identifier
          of the droplist widget.

          droplistID = droplistObj->GetID()

       GetIndex -- A function with no arguments that returns the index
          number of the current droplist selection.

          currentIndex = droplistObj->GetIndex()

       GetSelection -- A function with no arguments that returns the current
          droplist selection.

          currentSelection = droplistObj->GetSelection()

       GetUValue -- A function with no arguments that returns the "user value"
          of the compound widget i.e., the value set with the UVALUE keyword).

          myUValue = droplistObj->GetUValue()

       GetValues -- A function with no arguments that returns the "values" or
          "selections" for the droplist.

          possibleSelections = droplistObj->GetValues()

       Resize -- A procedure that sets the X screen size of the droplist. It is
          defined like this:

          PRO Resize, newSize, ParentSize=parentSize

          The "newSize" keyword is the new X screen size. If this argument is
          missing, the screen X size of the compound widget's parent is used.
          The parentSize keyword is an output keyword that returns the X screen
          size of the compound widget's parent.

          droplistObj->Resize, 400

          Note that not all devices (e.g., X Windows devices) support droplist resizing.

       SetIndex -- A procedure that sets the current droplist selection based on
          the given index. This is equivalent to Widget_Control, droplistID, Set_Droplist_Select=newIndex

          droplistObj->SetIndex, newIndex

       SetSelection -- Whereas a regular droplist widget can only be set by index
          number, this compound widget can also be set by a "selection". The new selection
          can be any data type and corresponds to one of the "values" of the droplist.

          droplistObj->SetSelection, newSelection

       SetValues -- Sets the possible selections of the droplist widget. The CurrentIndex keyword
          will allow the current index of the selection to be changed to:

          newChoices = ['dog', 'cat', 'coyote']
          droplistObj->SetValues, newChoices, CurrentIndex=2

     EXAMPLE:

       An example program is provided at the end of the FSC_DROPLIST code. To run it,
       type these commands:

          IDL> .Compile FSC_DROPLIST
          IDL> Example

     MODIFICATION HISTORY:

       Written by: David W Fanning, 17 Jan 2000. DWF.
       Added FORMAT and SPACES keywords 28 April 2000. DWF.
       Fixed a small problem with event processing when the EVENT_FUNC keyword
          was used. 29 Dec 2000. DWF.
       Attached the UNAME value to the TLB of the compound widget instead
          of to the droplist widget itself. 11 Jan 2001. DWF.
       Fixed a problem when the droplist was part of a modal widget and used the
          EVENT_PRO keyword. 27 Oct 2003. DWF.
       Added a SetValue method for setting all the values in the droplist at once. 12 Nov 2004. DWF.
       Fixed type on line 346/ 6 Feb 2008. DWF.

(See fsc_droplist.pro)

## FSC_FIELD

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_FIELD

     PURPOSE:

       The purpose of this compound widget is to provide an alternative
       to the CW_FIELD widget offered in the IDL distribution. One weakness
       of the CW_FIELD compound widget is that the text widgets do not
       look editable to the users on Windows platforms. This program
       corrects that deficiency and adds some features that I think
       will be helpful. For example, you can now assign an event handler
       to the compound widget, ask for positive numbers only, and limit
       the number of digits in a number, or the number of digits to the
       right of a decimal point. The program is written as a widget object,
       which allows the user to call object methods directly, affording
       even more flexibility in use. This program replaces the earlier
       programs FSC_INPUTFIELD and COYOTE_FIELD.

       The program consists of a label widget next to a one-line text widget.
       The "value" of the compound widget is shown in the text widget. If the
       value is a number, it will not be possible (generally) to type
       alphanumeric values in the text widget. String values behave like
       strings in any one-line text widget.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     TYPICAL CALLING SEQUENCE:

       fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)

     INPUT PARAMETERS:

       parent -- The parent widget ID of the compound widget. Required.

     INPUT KEYWORDS:

       COLUMN        Set this keyword to have the Label widget above the Text widget.
                     The default is to have the Label widget in a row with the Text widget.

       CR_ONLY       Set this keyword if you only want Carriage Return events returned to
                     your event handler. If this keyword is not set, all events are returned.
                     Setting this keyword has no effect unless either the EVENT_PRO or
                     EVENT_FUNC keyword is used.

       DECIMAL       Set this keyword to the number of digits to the right of the decimal
                     point in floating point or double precision numbers. Ignored for STRING values.

       DIGITS        Set this keyword to the number of digits permitted in integer numbers.

       EVENT_FUNC    Set this keyword to the name of an event handler function. If this
                     keyword is undefined and the Event_Pro keyword is undefined,
                     all compound widget events are handled internally and not
                     passed on to the parent widget.

       EVENT_PRO     Set this keyword to the name of an event handler procedure. If this
                     keyword is undefined and the Event_Func keyword is undefined,
                     all compound widget events are handled internally and not
                     passed on to the parent widget.

       FIELDFONT     The font name for the text in the text widget.

       FRAME         Set this keyword to put a frame around the compound widget.

       FOCUS_EVENTS  Set this keyword to enable event generation for keyboard focus
                     events. Ignored unless EVENT_FUNC or EVENT_PRO keywords are specified.

       HIGHLIGHT     Set this keyword to highlight the existing text if the widget gain
                     the keyboard focus. This keyword MUST be set for tabbing to work naturally
                     in IDL 6.2 and higher.

       LABEL_LEFT    Set this keyword to align the text on the label to the left.

       LABEL_RIGHT   Set this keyword to align the text on the label to the right.

       LABELFONT     The font name for the text in the label widget.

       LABELSIZE     The X screen size of the label widget.

       NAME          A string containing the name of the object. The default is ''.

       NOEDIT        Set this keyword to allow no user editing of the input text widget.

       NONSENSITIVE  Set this keyword to make the input text widget non-sensitive.

       POSITIVE      Set this keyword if you want only positive numbers allowed.

       SCR_XSIZE     The X screen size of the compound widget.

       SCR_YSIZE     The Y screen size of the compound widget.

       TITLE         The string text placed on the label widget.

       UNDEFINED     Set this keyword to the value to use for "undefined" values. If
                     not set, then !Value.F_NAN is used for numerical fields and a
                     NULL string is used for string fields. This applies to values
                     obtained with the GET_VALUE method or the GET_VALUE function.

       UVALUE        A user value for any purpose.

       VALUE         The "value" of the compound widget. Any type of integer, floating, or string
                     variable is allowed. The data "type" is determined automatically from the
                     value supplied with this keyword. Be sure you set the type appropriately for
                     your intended use of the value.

       XSIZE         The X size of the text widget in the usual character units.

     OUTPUT KEYWORDS:

       OBJECT        Set this keyword to a named variable to receive the compound widget's
                     object reference. This is required if you wish to call methods on the object.
                     Note that the object reference is also available in the event structure
                     generated by the widget object. Note that the object reference will be
                     necessary if you want to get or set values in the compound widget.

     COMMON BLOCKS:

       None.

     RESTRICTIONS:

       Requires cgDblToStr from the Coyote Library:
          http://www.idlcoyote.com/programs/cgdbltostr.pro

     EVENT STRUCTURE:

       All events are handled internally unless either the Event_Pro or Event_Func
       keywords are used to assign an event handler to the compound widget. By
       default all events generated by the text widget are passed to the assigned
       event handler. If you wish to receive only Carriage Return events, set the
       CR_Only keyword.

       event = { FSC_FIELD_EVENT, $   ; The name of the event structure.
                 ID: 0L, $            ; The ID of the compound widget's top-level base.
                 TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
                 HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
                 OBJECT: Obj_New(), $ ; The "self" object reference. Provided so you can call methods.
                 VALUE: Ptr_New(), $  ; A pointer to the widget value.
                 TYPE:""              ; A string indicating the type of data in the VALUE field.
               }

       Note that if the field is "empty", the VALUE will be a pointer
       to an undefined variable. You should check this value before you
       use it. You code will look something like this:

         IF N_Elements(*event.value) EQ 0 THEN $
             Print, 'Current Value UNDEFINED.' ELSE $
             Print, 'Current Value: ', *event.value

     GETTING and SETTING VALUES:

       Almost all the properties of the widget can be obtained or set via
       the object's GetProperty and SetProperty methods (described below).
       Traditional compound widgets have the ability to get and set the "value"
       of the compound widget identifier (e.g., fieldID in the calling
       sequence above). Unfortunately, it is impossible to retreive a variable
       in this way when the variable is undefined. In practical terms, this
       means that the undefined variable must be set to *something*. You can
       determine what that something is with the UNDEFINED keyword, or I will set
       it to !VALUES.F_NAN for numerical fields and to the null string for string
       fields. In any case, you will have to check for undefined variables before
       you try to do something with the value. For a numerical field, the code
       might look something like this:

          fieldID = FSC_FIELD(parent, Title="X Size:", Value=256, Object=fieldObject, Digits=3)
          currentValue = fieldObject->Get_Value()
          IF Finite(currentValue) EQ 0 THEN Print, 'Value is Undefined' ELSE Print, currentValue

       Additional examples are provided in the numerical example fields in Example Program below.

       Setting the value of the compound widget is the same as calling the Set_Value
       method on the object reference. In other words, these two statements are equivalent.

            fieldObject->Set_Value, 45.4
            Widget_Control, fieldID, Set_Value=45.4

       The data type of the value is determined from the value itself. Be sure you set it appropriately.

     OBJECT PROCEDURE METHODS:

       GetProperty -- This method allows various properties of the widget to be
           returned via output keywords. The keywords that are available are:

           CR_Only -- A flag, if set, means only report carriage return events.
           DataType -- The data type of the field variable.
           Decimal -- Set this keyword to the number of digits to the right of the decimal
                  point in FLOATVALUE and DOUBLEVALUE numbers.
           Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
           Event_Func -- The name of the event handler function.
           Event_Pro -- The name of the event handler function.
           Has_Focus -- Set to 1 if the text widget currently has the keyboard focus.
           Highlight -- The highlight flag.
           NoEdit -- The NoEdit flag.
           NonSensitive -- The NonSensitive flag.
           Undefined -- The "value" of any undefined value.
           UValue -- The user value assigned to the compound widget.
           Value -- The "value" of the compound widget.
         Name -- A scalar string name of the object.

       Resize -- This method allows you to resize the compound widget's text field.
            The value parameter is an X screen size for the entire widget. The text
            widget is sized by using the value obtained from this value minus the
            X screen size of the label widget.

              objectRef->Resize, screen_xsize_value

       Set_Value -- This method allows you to set the "value" of the field. It takes
           one positional parameter, which is the value.

              objectRef->Set_Value, 5

       SetProperty -- This method allows various properties of the widget to be
           set via input keywords. The keywords that are available are:

           CR_Only -- Set this keyword if you only want Carriage Return events.
           Decimal -- Set this keyword to the number of digits to the right of the decimal
                  point in FLOAT and DOUBLE numbers.
           Digits -- Set this keyword to the number of digits permitted in INTERGER and LONG numbers.
           Event_Func -- Set this keyword to the name of an Event Function.
           Event_Pro -- Set this keyword to the name of an Event Procedure.
           Highlight -- Set this keyword to highlight the existing text
                        when the widget gets the keyboard focus
           LabelSize --  The X screen size of the Label Widget.
           Name -- A scalar string name of the object. (default = '')
           NoEdit -- Set this keyword to make the text widget uneditable
           NonSensitive -- Set this keyword to make the widget nonsensitive
           Scr_XSize -- The X screen size of the text widget.
           Scr_YSize -- The Y screen size of the text widget.
           Title -- The text to go on the Label Widget.
           UValue -- A user value for any purpose.
           Value -- The "value" of the compound widget.
           XSize -- The X size of the Text Widget.

       SetTabNext -- This method allows you to specify which field to go to when a TAB character
          is typed in the text widget. See the Example program below for an example of how to
          use this method.

     OBJECT FUNCTIONS METHODS:

          Get_Value -- Returns the "value" of the field. No parameters. Will be undefined
              if a "number" field is blank. Should be checked before using:

              IF N_Elements(objectRef->Get_Value()) NE 0 THEN Print, Value is: ', objectRef->Get_Value()

          GetID -- Returns the widget identifier of the compound widget's top-level base.
             (The first child of the parent widget.) No parameters.

          GetLabelSize -- Returns the X screen size of the label widget. No parameters.

          GetTextID -- Returns the widget identifier of the compound widget's text widget.
             No parameters.

          GetTextSize -- Returns the X screen size of the text widget. No parameters.

     PRIVATE OBJECT METHODS:

       Although there is really no such thing as a "private" method in IDL's
       object implementation, some methods are used internally and not meant to
       be acessed publicly. Here are a few of those methods. I list them because
       it may be these private methods are ones you wish to override in subclassed
       objects.

          MoveTab -- This method moves the focus to the widget identified in the "next" field,
            which must be set with the SetTabNext method. No parameters. Called automatically
            when a TAB character is typed in the text widget.

          Text_Events -- The main event handler method for the compound widget. All
            text widget events are processed here.

          ReturnValue -- This function method accepts a string input value and converts
            it to the type of data requested by the user.

          Validate -- This function method examines all text input and removes unwanted
            characters, depending upon the requested data type for the field. It makes it
            impossible, for example, to type alphanumeric characters in an INTEGER field.

     EXAMPLE:

       An example program is provided at the end of the FSC_FIELD code. To run it,
       type these commands:

          IDL> .Compile FSC_Field
          IDL> Example

     MODIFICATION HISTORY:

       Written by: David W. Fanning, 18 October 2000. Based heavily on an earlier
          FSC_INPUTFIELD program and new ideas about the best way to write
          widget objects.
       Added LABEL_LEFT, LABEL_RIGHT, and UNDEFINED keywords. 29 Dec 2000. DWF.
       Modified the way the value is returned in the GET_VALUE method and the
          GET_VALUE function. Modified Example program to demonstrate. 30 Dec 2000. DWF.
       Added NOEDIT and NONSENSITIVE keywords, with corresponding SETEDIT and SETSENNSITIVE
          methods. 19 Jan 2001. DWF.
       Actually followed through with the changes I _said_" I made 29 Dec 2000. (Don't ask....) 13 June 2001. DWF.
       Added GetTextSize and GetLabelSize methods for obtaining the X screen
          size of the text and label widgets, respectively. 21 July 2001. DWF.
       Fixed a problem in SetProperty method where I was setting self.xsize, which doesn't exist. 24 April 2002. DWF.
       Small modification to the SetEdit method. 6 August 2003. DWF.
       Added Highlight keyword. Ported Focus_Events keyword from
          fsc_inputfield.pro. Updated documentation. 17 November
          2004. DWF and Benjamin Hornberger
       Added Has_Focus keyword to the GetProperty method. 18 November
          2004. Benjamin Hornberger
       Fixed bug in GetProperty method (set value to *self.undefined if
          *self.value is undefined. 24 Feb 2004. Benjamin Hornberger
       Modified FOCUS_EVENTS keyword handling so that *all* focus events are now
          passed to specified event handlers. Check event.select to see if the
          widget is gaining or losing focus. 10 August 2005. DWF.
       Added new tabbing functionality, introduced in IDL 6.2. To use tabbing
          functionality natually, the HIGHTLIGHT keywords must be set.
          See included EXAMPLE program for details. 10 August 2005. DWF.
       Added functionality to covert double precision values to strings properly. 30 Nov 2005. DWF.
       Set the default fonts to be the current widget font, rather than the default widget font. 4 Oct 2008. DWF.
       Fixed a problem with validating a float or double value when it was written with
          exponential notation. 2 April 2010. DWF.

(See fsc_field.pro)

## FSC_FILESELECT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_FILESELECT

     PURPOSE:

       The purpose of this compound widget is to provide a means
       by which the user can type or select a file name. The
       program is written as an "object widget", meaning that
       the guts of the program is an object of class FSC_FILESELECT.
       This is meant to be an example of the obvious advantages of
       writing compound widget programs as objects.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       filenameID = FSC_FileSelect(parent)

     INPUT PARAMETERS:

       parent -- The parent widget ID of the compound widget. Required.

     INPUT KEYWORDS:

       Event_Pro -- The event handler procedure for this compound widget.By default: "".
       Event_Func -- The event handler function for this compound widget. By default: "".

          If neither EVENT_PRO or EVENT_FUNC is defined, program events are handled internally by the compound widget.

       DirectoryName -- The initial name of the directory. By defaut: current directory.
       Filename -- The initial file name in the filename text widget.
       Filter -- The file filter. By default: "*".
       Frame -- Set this keyword for a frame around the compound widget.
       LabelFont -- The font for the label widget. By default: "".
       LabelName -- The text on the label widgt. By default: "Filename: ".
       LabelSize -- The X screen size of the label widget. By default: 0.
       MustExist -- A flag that indicates selected files must exist. By default: 0.
       NoMaxSize -- A flag to prohibit automatic text widget sizing. By default: 0.

         If this keyword is not set, the compound widget will automatically resize itself to
         the largest widget in its parent base widget. It will do this by changing the size of
         the text widgets holding the file and directory names.

       Read -- Set this keyword to have file selection for reading a file. By default: 1.
       SelectDirectory -- The default directory for file selection. In other words, this is the
         default directory for DIALOG_PICKFILE, which is accessed via the BROWSE buttons.
       SelectFont -- The font for the "Browse" button. By default: "".
       SelectTitle -- The title bar text on the file selection dialog. By default: "Select a File...".
       TextFont -- The font for the filename text widget. By default: "".
       UValue -- User value for any purpose.
       Write -- Set this keyword to open a file for writing. By default: 0.
       XSize -- The X size of the text widget holding the filename. By default: StrLen(filename) * 1.5 > 40.

     OUTPUT KEYWORDS:

       ObjectRef -- Assign this keyword to an output variable that will hold the internal object reference.
                    With the object reference you can call object methods to easily change many properties of
                    the compound widget.

     COMMON BLOCKS:

       None.

     EVENT STRUCTURE:

       All events are handled internally unless either the Event_Pro or Event_Func
       keywords are used to assign an event handler to the compound widget. All events
       generated by the text widgets are passed to the assigned event handler.

       event = { CW_FILESELECT, $     ; The name of the event structure.
                 ID: 0L, $            ; The ID of the compound widget's top-level base.
                 TOP: 0L, $           ; The widget ID of the top-level base of the hierarchy.
                 HANDLER: 0L, $       ; The event handler ID. Filled out by IDL.
                 Basename: "", $      ; The base filename without directory specifiers.
                 Filename: "", $      ; The fully qualified filename.
                 Directory: "", $     ; The name of the current file directory.
               }

     EXAMPLE:

       An example program is provided at the end of the FSC_FILESELECT code. To run it,
       type these commands:

          IDL> .Compile fsc_fileselect
          IDL> Example

       Or, if you want to obtain the object reference, type this:

          IDL> Example, theObject

       Now you can call the object's methods. For example:

          IDL theObject->SetProperty, XSize=150

     GETTING and SETTING VALUES:

       So as not to disrupt the accepted paradigm in using compound widgets, you
       can use the return value of the FSC_FILESELECT function with WIDGET_CONTROL to
       get and set the "value" of the widget.

           Widget_Control, filenameID, Set_Value='C:\RSI\IDL52\DATA\cyclone.dat'

       The program will automatically separate the file name portion of the value
       from the directory portion and put things in the correct text widgets.

       Similarly, you can get the "value" of the widget:

           Widget_Control, filenameID, Get_Value=theValue
           Print, theValue

               C:\RSI\IDL52\DATA\cyclone.dat

       The return value is the fully qualified file path to the file.

     USING OBJECT METHODS to CHANGE PROGRAM PROPERTIES:

       If you obtain the object reference, you have a great deal more control
       over the properties of the compound widget. You obtain the object reference
       by calling the function like this:

          filenameID = FSC_FILESELECT(parent, ObjectRef=theObject)

     OBJECT PROCEDURE METHODS:

       GetProperty -- This method allows various properties of the widget to be
           returned via output keywords. The keywords that are available are:

          DirectoryName -- The current directory.
          Event_Func -- The name of the event handler function for this compound widget.
          Event_Pro -- The name of the event handler procedure for this compound widget.
          Filename -- The current base filename.
          Filter -- The current file filter.
          LabelName -- The text on the label widget.
          LabelSize -- The X screen size of the label widget.
          MustExist -- A flag that indicates selected files must exist to be selected.
          Parent -- The parent widget of the compound widget.
          Read=read -- The file selection for reading flag.
          SelectTitle -- The title bar text on the file selection dialog.
          TLB -- The top-level base of the compound widget.
          UValue -- The user value of the compound widget.
          Write -- The file selection for writing flag.
          XSize -- The X size of the text widget holding the filename.

       LabelSize -- This method makes sure that the directory name and file name labels
          are the same size. Normally, this procedure is called internally. No parameters.

       MatchSize -- This method resizes the compound widget so that it is as long as the
          the longest widget in the parent base widget. This is done automatically upon
          realization unless the NOMAXSIZE keyword is set. The method aids in writing
          resizeable widget programs.

       SetProperty -- This method allows various properties of the widget to be
           set via input keywords. The keywords that are available are:

          DirectoryName -- The current directory.
          Event_Func -- The name of the event handler function for this compound widget.
          Event_Pro -- The name of the event handler procedure for this compound widget.
          Filename -- The current base filename.
          Filter -- The current file filter.
          LabelName -- The text on the label widget.
          LabelSize -- The X screen size of the label widget.
          MustExist -- A flag that indicates selected files must exist to be selected.
          Read -- The file selection for reading flag.
          SelectTitle -- The title bar text on the file selection dialog.
          UValue -- The user value of the compound widget.
          Write -- The file selection for writing flag.
          XSize -- The X size of the text widget holding the filename.

       TextSelect - Allows you to create a selection in filename text widget. See the
                    documentation for the SET_TEXT_SELECT keyword to Widget_Control.

          selection -- A two-element array containing the starting position and selection length.

     OBJECT FUNCTION METHODS:

          GetFileName -- Returns the fully qualified filename. No parameters.

          GetTLB -- Returns the top-level base ID of the compound widget. No Parameters.

          Inspect_DirectoryName -- Inspects the directory name for correctness. Requires one positional parameter.

            directoryName -- The name of the directory from the directory text widget.
            textSelection -- The current text selection position.

            At the moment all this does is remove any blank characters from either
            end of the directory name and makes sure the last character of the directory
            name does not end in a subdirectory specifier (except for VMS).

         Inspect_Filename -- Inspects the file name for correctness. Requires one positional parameter.

            filename -- The name of the file from the filename text widget.
            textSelection -- The current text selection position.

            At the moment all this does is remove any blank characters from either
            end of the file name

     MODIFICATION HISTORY:

       Written by: David W. Fanning, 21 NOV 1999.
       Fixed bug in File Name selection button. 18 MAR 2000. DWF.
       Fixed an error in which directory the Browse buttons should start
           searching. 29 SEP 2000. DWF.
       Previously returned events only for typing in text widgets. Now
           Browse button events are also returned. 29 SEP 2000. DWF.
       Fixed a bug in setting the file filter. 29 SEP 2000. DWF.
       Removed the Directory Browse button 10 AUG 2002. DWF.
       Added cgErrorMsg to error handling. 10 AUG 2002. DWF.
       Changed the ability to specify a file filter as a string array, instead
           of just as a scalar string. This required the use of a pointer, which
           meant that I had to remove the FILTER field from the CW_FILESELECT
           event structure to avoid likely memory leakage. This is a dangerous
           change because it means programs that relied on this (I expect there
           are very, very few) will break and it goes against my philosopy of
           keeping my programs backward compatible. Let me know if you have
           problems. In testing, I discoved no problems in my own code. 31 OCT 2002. DWF.
       Fixed a problem with DIALOG_PICKFILE that sometimes allowed users to change
           directories without selecting a file. 3 Nov 2002. DWF.
       Fixed a problem with widget resizing with the help of Bob Portman that had plagued
           me from the beginning. Thanks, Bob! 5 August 2003. DWF
       Added TEXTSELECT method. 5 Aug 2003. DWF.
       Had to add FORWARD_FUNCTION statement to get error handler compiled when using
           DIRECTORY keyword. 24 Nov 2003. DWF.
       Fixed a problem with too many events going to an event handler specified with
           the EVENT_PRO or EVENT_FUNC keyword from the text widget. Now only Carriage
           Return events are passed on to the user-specified event handler. 8 July 2004. DWF.
       Replace all "\" characters with "/" characters in directory names. 8 Januay 2006. DWF.
       Set the default fonts to be the current widget font, rather than the default widget font. 4 Oct 2008. DWF.

(See fsc_fileselect.pro)

## FSC_INPUTFIELD

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_INPUTFIELD

     PURPOSE:

       The purpose of this compound widget is to provide an alternative
       to the CW_FIELD widget offered in the IDL distribution. What has
       always bothered me about CW_FIELD is that the text widgets do not
       look editable to the users on Windows platforms. This program
       corrects that deficiency and adds some features that I think
       would be helpful. For example, you can now assign an event handler
       to the compound widget. The program is written entirely as an object.
       A companion program, COYOTE_FIELD, has much the same functionality,
       but is written as a traditional compound widget. The point of writing
       the same program in two different ways is to give you the opportunity
       to compare and contrast the two methods. I personally think there
       is no substitute for the power of object programs. :-)

     AUTHOR:
       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       objectRef = FSC_INPUTFIELD(parent, Title='X Size: ", Value=256, /IntegerValue)

     INPUT PARAMETERS:

       parent -- The parent widget ID of the compound widget. Required.

     INPUT KEYWORDS:

       Column -- Set this keyword to have the Label Widget above the Text Widget.
       CR_Only -- Set this keyword if you only want Carriage Return events. Note that no
                  events are returned unless the EVENT_PRO or EVENT_FUNC keywords are also used.
       Decimal -- Set this keyword to the number of digits to the right of the decimal
                  point in FLOATVALUE and DOUBLEVALUE numbers.
       Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
       DoubleValue -- Set this keyword if you want DOUBLE values returned.
       Event_Func -- Set this keyword to the name of an Event Function. If this
                    keyword is undefined and the Event_Pro keyword is undefined,
                    all compound widget events are handled internally and not
                    passed on to the parent widget.
       Event_Pro -- Set this keyword to the name of an Event Procedure. If this
                    keyword is undefined and the Event_Func keyword is undefined,
                    all compound widget events are handled internally and not
                    passed on to the parent widget.
       FieldFont -- The font name for the text in the Text Widget.
       FloatValue -- Set this keyword for FLOAT values.
       Focus_Events -- Set this keyword if you only want text events when the keyboard focus is
                    moved out of the text widget. Note that no events are returned unless the
                    EVENT_PRO or EVENT_FUNC keywords are also used.
       Frame -- Set this keyword to put a frame around the compound widget.
       IntegerValue -- Set this keyword for INTEGER values.
       LabelAlign -- Set this keyword to align label text. [0-center (default), 1-left, 2-right].
       LabelFont -- The font name for the text in the Label Widget.
       LabelSize -- The X screen size of the Label Widget.
       LongValue -- Set this keyword for LONG values.
       Name -- A scalar string name of the object. (default = '')
       Positive -- Set this keyword if you want only positive numbers allowed.
       Row=row -- Set this keyword to have the Label beside the Text Widget. (The default.)
       Scr_XSize -- The X screen size of the compound widget.
       Scr_YSize -- The Y screen size of the compound widget.
       StringValue -- Set this keyword for STRING values. (The default.)
       Title -- The text to go on the Label Widget.
       UValue -- A user value for any purpose.
       Value -- The "value" of the compound widget.
       XSize -- The X size of the Text Widget.

       In addition, any keyword defined for WIDGET_TEXT, but not defined here (e.g., SENSITIVE), is
       passed along without inspection to the text widget. Use of "extra" keywords is discouraged.

     COMMON BLOCKS:

       None.

     RESTRICTIONS:

       None.

     EVENT STRUCTURE:

       All events are handled internally unless either the Event_Pro or Event_Func
       keywords are used to assign an event handler to the compound widget. By
       default all events generated by the text widget are passed to the assigned
       event handler. If you wish to receive only Carriage Return events, set the
       CR_Only keyword.

       event = { FSC_INPUTFIELD_EVENTS, $  ; The name of the event structure.
                 ID: 0L, $                 ; The ID of the compound widget's top-level base.
                 TOP: 0L, $                ; The widget ID of the top-level base of the hierarchy.
                 HANDLER: 0L, $            ; The event handler ID. Filled out by IDL.
                 ObjRef: Obj_New(), $      ; The "self" object reference. Provided so you can call methods.
                 Value: Ptr_New(), $       ; A pointer to the widget value.
                 Type:""                   ; A string indicating the type of data in the VALUE field.
               }                           ; Values are "INT", "LONG", "FLOAT", "DOUBLE", or "STRING".

     GETTING and SETTING VALUES:

       Almost all the properties of the widget can be obtained or set via
       the object's GetProperty and SetProperty methods (described below).
       But since traditional compound widgets have the ability to get and
       set the value of the compound widget, this capability is implemented
       as special methods.

       To get the value of the field, do this: value = objectRef->Get_Value()
       To set the value of the field, so this: objectRef->Set_Value, value, /IntegerValue

       The proper keyword should be used to set the data type of the value. If a keyword
       is not used, the data type is determined from the value itself.

     OBJECT PROCEDURE METHODS:

       GetProperty -- This method allows various properties of the widget to be
           returned via output keywords. The keywords that are available are:

           CR_Only -- A flag, if set, means only report carriage return events.
           DataType -- The data type of the field variable.
           Decimal -- Set this keyword to the number of digits to the right of the decimal
                  point in FLOATVALUE and DOUBLEVALUE numbers.
           Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
           Event_Func -- The name of the event handler function.
           Event_Pro -- The name of the event handler function.
           Positive -- Indicates if the Positive number flag is set (1) or not (0).
           UValue -- The user value assigned to the compound widget.
           Value -- The "value" of the compound widget.
         Name -- A scalar string name of the object.

       Resize -- This method allows you to resize the compound widget's text field.
            The value parameter is an X screen size for the entire widget. The text
            widget is sized by using the value obtained from this value minus the
            X screen size of the label widget.

              objectRef->Resize, screen_xsize_value

       Set_Value -- This method allows you to set the "value" of the field. It takes
           one positional parameter, which is the value.

              objectRef->Set_Value, 5

           Keywords available are these to set the type of the data. If keywords
           are not used, the data type is determined from the value.

           DoubleValue -- Set this keyword if you want DOUBLE values returned.
           FloatValue -- Set this keyword for FLOAT values.
           IntegerValue --  Set this keyword for INTEGER values.
           LongValue -- Set this keyword for LONG values.
           StringValue -- Set this keyword for STRING values. (The default.)

       SetProperty -- This method allows various properties of the widget to be
           set via input keywords. The keywords that are available are:

           CR_Only -- Set this keyword if you only want Carriage Return events.
           Decimal -- Set this keyword to the number of digits to the right of the decimal
                  point in FLOATVALUE and DOUBLEVALUE numbers.
           Digits -- Set this keyword to the number of digits permitted in INTERGERVALUE and LONGVALUE numbers.
           DoubleValue -- Set this keyword if you want DOUBLE values returned.
           Event_Func -- Set this keyword to the name of an Event Function.
           Event_Pro -- Set this keyword to the name of an Event Procedure.
           FloatValue -- Set this keyword for FLOAT values.
           IntegerValue --  Set this keyword for INTEGER values.
           LabelSize --  The X screen size of the Label Widget.
           LongValue -- Set this keyword for LONG values.
           Name -- A scalar string name of the object. (default = '')
           Positive -- Set this keyword to indicate only positive numbers are allowed.
           Scr_XSize -- The X screen size of the text widget.
           Scr_YSize -- The Y screen size of the text widget.
           Sensitive -- Set to 1 to make the widget sensitive, and to 0 to make it insensitive.
           StringValue -- Set this keyword for STRING values. (The default.)
           Title -- The text to go on the Label Widget.
           UValue -- A user value for any purpose.
           Value -- The "value" of the compound widget.
           XSize -- The X size of the Text Widget.

       SetTabNext -- This method allows you to specify which field to go to when a TAB character
          is typed in the text widget. See the Example program below for an example of how to
          use this method.

     OBJECT FUNCTIONS METHODS:

          Get_Value -- Returns the "value" of the field. No parameters. Will be undefined
              if a "number" field is blank. Should be checked before using:

              IF N_Elements(objectRef->Get_Value()) NE 0 THEN Print, Value is: ', objectRef->Get_Value()

          GetID -- Returns the widget identifier of the compound widget's top-level base.
             (The first child of the parent widget.) No parameters.

          GetLabelSize -- Returns the X screen size of the label widget. No parameters.

          GetTextID -- Returns the widget identifier of the compound widget's text widget.
             No parameters.

          GetTextSize -- Returns the X screen size of the text widget. No parameters.

     PRIVATE OBJECT METHODS:

       Although there is really no such thing as a "private" method in IDL's
       object implementation, some methods are used internally and not meant to
       be acessed publicly. Here are a few of those methods. I list them because
       it may be these private methods are ones you wish to override in subclassed
       objects.

          MoveTab -- This method moves the focus to the widget identified in the "next" field,
            which must be set with the SetTabNext method. No parameters. Called automatically
            when a TAB character is typed in the text widget.

          Text_Events -- The main event handler method for the compound widget. All
            text widget events are processed here.

          ReturnValue -- This function method accepts a string input value and converts
            it to the type of data requested by the user.

          Validate -- This function method examines all text input and removes unwanted
            characters, depending upon the requested data type for the field. It makes it
            impossible, for example, to type alphanumeric characters in an INTEGER field.

     EXAMPLE:

       An example program is provided at the end of the FSC_INPUTFIELD code. To run it,
       type these commands:

          IDL> .Compile FSC_InputField
          IDL> Example

     NOTES:

       IDL 6.2 introduced new TAB behavior, which broke the previous TAB behavior. New TAB behavior
       is now supported, but FOCUS_EVENTS *must* be set on the widget for the new TAB events to
       behave properly. See the EXAMPLE program for examples.

     DEPENDENCIES:

       Requires cgDblToStr from the Coyote Library:
         http://www.idlcoyote.com/programs/cgdbltostr.pro

     MODIFICATION HISTORY:

       Written by: David W. Fanning, 23 NOV 1999.
       Added DECIMAL and DIGITS keywords, 2 Jan 2000, DWF.
       Changed the calling sequence to that of a function rather than an object
          creation call. This is more familiar to users of compound widgets. 4 Jan 00. DWF.
       Added GetID and Resize methods. 7 Jan 00. DWF.
       Added the Positive keyword and functionality. 12 Jan 00. DWF
       Modified (slightly) the behavior on deleting characters. 12 Jan 00. DWF.
       If a number field is blank, the Get_Value method will now return an undefined variable.
          Be sure you check this value before you use it for something! 17 Jan 00. DWF.
       Fixed a small typo: "aveDecimal" to "haveDecimal". 10 March 2000. DWF.
       Added the ability to tab between FSC_INPUTFIELD widgets with the SetTabNext,
          MoveTab, and GetTextID methods. 31 July 2000. DWF.
       Added NAME field property, a scalar string name for the object 2 AUG 2000 BT
       Added ObjRef field to the FSC_FIELD event structure and added field selection
          for the TAB events added 31 July. 7 AUG 2000. DWF
       Added GetTextSize and GetLabelSize methods for obtaining the X screen
          size of the text and label widgets, respectively. 30 Jan 2001. DWF.
       Added FOCUS_EVENTS keyword and fixed a problem with the event structure.
          Also added better error handling. 5 January 2003. DWF.
       Fixed a small problem in which input values were cast to strings inadvertently. 9 January 2004. DWF.
       Fixed a small problem with error messages and using EVENT_FUNC. 14 January 2004. DWF.
       Fixed a problem when setting ROW keyword. 23 February 2004. DWF.
       IDL 6.2 introduced new TAB behavior, which broke the previous TAB behavior. New TAB behavior
          is now supported, but FOCUS_EVENTS *must* be set for the new TAB events to behave properly.
          10 August 2005. DWF.
       Modified to covert double precision values to strings properly. 30 November 2005. DWF.
       Added POSITIVE keyword to SETPROPERTY and GETPROPERTY methods. 25 February 2006. DWF.
       Set the DYNAMIC_RESIZE keyword on the label widget. 25 February 2006. DWF.
       Added SENSITIVE keyword to SetProperty documentation. 10 November 2006. DWF.
       Fixed a small problem in which doubles were not being initialized correctly due
          to an inadvertant extra line of code. 3 July 2007. DWF.
       Fixed a small problem with input validation when the input is of BYTE type. 1 Oct 2008. DWF.
       Set the default fonts to be the current widget font, rather than the default widget font. 4 Oct 2008. DWF.
       Fixed a problem with validating a float or double value when it was written with
          exponential notation. 2 April 2010. DWF.

(See fsc_inputfield.pro)

## FSC_PLOTWINDOW

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_PLOTWINDOW

     PURPOSE:

       The purpose of this compound widget is to create a resizeable
       "plot window" inside a larger "page window". I'm not sure it
       has any value except as a utility routine for the PostScript
       configuration object FSC_PSCONFIG__DEFINE, but it's a neat
       program anyway. :-)

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       Utility routine for FSC_PSCONFIG__DEFINE.

     CALLING SEQUENCE:

       plotwindowObject = CW_PlotWindow(parent)

     REQUIRED INPUT PARAMETERS:

       parent - The parent base widget of this compound widget.

     RETURN VALUE:

       plotwindowObject - The object reference of the compound widget.

     KEYWORDS:

       COLOR - If set, display the window in "color". This is the default on 24-bit devices.
       DEBUG - Set this keyword to turn traceback error handling on in the error handling code.
       EVENT_PRO - The event procedure for the widget. Required for events to be generated. Otherwise, all events are handled internally.
       LANDSCAPE - If set, display the page in landscape mode. Otherwise the page is display in portrait mode.
       PAGESIZE - The "pagesize" of the widget. Possible values are: "LETTER", "LEDGER", "LEGAL", "A4", and "DISPLAY".
       UNITS - A string indicating INCHES or CENTIMETER units. DEVICE units represented by a null string, "".
       UVALUE - A user value for the caller of this program.
       WINDOWCOLOR - A three-element array specifying the background window color (RGB).
       WINDOWSIZE - The size of the "window" on the page. A four-element array of normalized coordinates in the form [x0, y0, x1, y1].

     EVENT STRUCTURE:

       The event structure that is returned from this compound widget is defined like this,
       where the sizes and offsets locate the target "window" on the page in normalized units:

          event = {ID:0L, TOP:0L, HANDLER:0L, XSize:0.0, YSize:0.0, XOffset:0.0, YOffset:0.0}

     MODIFICATIONS:

       Written by David Fanning, 31 January 2000.
       Fixed a small bug that prevented it working on Macintosh computers. 26 Sept 2000. DWF.
       Added a "DISPLAY" page size, so the program can be used to position
          plots and other graphics in a display window. The "page area" will
          have the same aspect ratio is the current graphics window. 17 March 2001. DWF.
       Changed some of the tolerances for "closeness" from 0.1 to 0.025 to allow smaller
          sizing for colorbars and other small objects. 6 July 2005. DWF.

(See fsc_plotwindow.pro)

## FSC_PSCONFIG__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       FSC_PSCONFIG__DEFINE

     PURPOSE:

       The purpose of this program is to implement an object that
       can keep track of--and allow the user to change--the current
       configuration of the PostScript device.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     DOCUMENTATION:

       Complete documentation for the FSC_PSCONFIG object, including
       keyword and method descriptions, and example programs using the object
       can be found on the Coyote's Guide to IDL Programming web page:

         http://www.idlcoyote.com/programs/docs/fsc_psconfig.html

       Or, if you would prefer, you can download a self-contained PDF file:

         http://www.idlcoyote.com/programs/docs/fsc_psconfig.pdf

     KEYWORDS:

       Any keyword accepted by the FSC_PSCONFIG object can be used with
       this program. Here are a few of the most popular keywords.

       Bits_per_Pixel - The number of image bits saved for each image pixel: 2, 4, or 8. The default is 8.
       Color - Set this keyword to select Color PostScript output. Turned on by default.
       Decomposed - Set this keyword to 0 to select indexed color and to 1 to select decomposed color.
       DefaultSetup - Set this keyword to the "name" of a default style. Current styles (you can easily
         create and add your own to the source code) are the following:

           "System (Portrait)" - The normal "default" system set-up. Also, "System".
           "System (Landscape)" - The normal "default" landscape system set-up.
           "Centered (Portrait)" - The window centered on the page. Also, "Center" or "Centered".
           "Centered (Landscape)" - The window centered on the landscape page. Also, "Landscape".
           "Square (Portrait)" - A square plot, centered on the page.
           "Square (Landscape)" - A square plot, centered on the landscape page.
           "Figure (Small)" - A small encapsulated figure size, centered on page. Also, "Encapsulated" or "Encapsulate".
           "Figure (Large)" - A larger encapsulated figure size, centered on page. Also, "Figure".
           "Color (Portrait)" - A "centered" plot, with color turned on. Also, "Color".
           "Color (Landscape)" - A "centered" landscape plot, with color turned on.

       Directory - Set this keyword to the name of the starting directory. The current directory is used by default.
       Encapsulated - Set this keyword to select Encapsulated PostScript output. Turned off by default.
       European - This keyword has been depreciated in favor of METRIC.
       Filename - Set thie keyword to the name of the PostScript file. The default is "idl.ps".
       Inches - Set this keyword to indicate sizes and offsets are in inches as opposed to centimeters. Set by Metric keyword by default.
       Landscape - Set this keyword to select Landscape page output. Portrait page output is the default.
       Language_Level - Set this keyword to select the Language Level interpreter. Default is 1.
       Metric - Set this keyword to indicate metric mode (i.e., A4 page and centimeter units). Turned off by default.
       PageType - Set this keyword to the "type" of page. Possible values are:
           "Letter" - 8.5 by 11 inches. (Default, unless the Metric keyword is set.)
           "Legal" - 8.5 by 14 inches.
           "Ledger" - 11 by 17 inches.
           "A4" - 21.0 by 29.7 centimeters. (Default, if the Metric keyword is set.)
       XOffset - Set this keyword to the X Offset. Uses "System (Portrait)" defaults. (Note: offset calculated from lower-left corner of page.)
       XSize - Set this keyword to the X size of the PostScript "window". Uses "System (Portrait)" defaults.
       YOffset - Set this keyword to the Y Offset. Uses "System (Portrait)" defaults. (Note: offset calculated from lower-left corner of page.)
       YSize - Set this keyword to the Y size of the PostScript "window". Uses "System (Portrait)" defaults.

       In addition, the following keywords can be used:

       CANCEL -- An output keyword that will be set to 1 if the user
       chooses the Cancel button on the form. It will be 0 otherwise.

       FONTINFO -- Set this keyword is you wish to have font information
       appear on the form. The default is to not include font information.

       FONTTYPE -- Set this keyword to a named variable that will indicate
       the user's preference for font type. Values will be -1 (Hershey fonts),
       0 (hardware fonts), and 1 (true-type fonts). This keyword will always
       return -1 unless the FONTINFO keyword has also been set.

       GROUP_LEADER -- Set this keyword to a widget identifier of the widget
       you wish to be a group leader for this program.

     EXAMPLE:

       A simple sequence of using the object would look something like this:

         psObject = Obj_New("FSC_PSCONFIG")
         psObject->GUI
         psKeywords = psObject->GetKeywords()
         thisDevice = !D.Name
         Set_Plot, 'PS'
         Device, _Extra=psKeywords
         cgImage, image
         Device, /Close_File
         Set_Plot, thisDevice
         Obj_Destroy, psObject

      Note that the object can also be called from the cgPS_Config interface:

         psKeywords = cgPS_Config()

     OTHER PROGRAMS NEEDED:

       The following programs are required to run this one:

         fsc_droplist.pro
         fsc_fileselect.pro
         fsc_field.pro
         fsc_plotwindow

     MODIFICATIONS:

       Written by David W. Fanning, 31 January 2000.
       Added capability to call GUI methods when the current graphics device
          doesn't support windows. Device is restored when the GUI exits. 11 May 2000. DWF.
       Changed the default value for the Color keyword to 1. 16 May 2000. DWF.
       Fixed a bug where filename changed when switching Setups. 8 AUG 2000. DWF.
       Fixed a bug when saving setup in Landscape mode. 8 AUG 2000. DWF.
       Added the ability to Get and Set the object's name via the SetProperty
          and a very abbreviated GetProperty method. Also added a GetName method. 26 SEP 2000. DWF.
       Fixed a problem in which the proper configuration was not restored if in Landscape mode. 20 Nov 2000. DWF.
       Made a number of modifications at the request of Martin Schultz. 4 Dec 2000. DWF.
       Fixed a bug when setting file  and directory names with the SetProperty method. 18 Dec 2000. DWF.
       Fixed a small problem in initializing the page size properly. 3 Jan 2001. DWF.
       Corrected a problem that resulted from a change to FSC_DROPLIST. 6 Jan 2001. DWF.
       Added the ability to restore the font type instead of always reverting to !P.Font. 7 Jan 2001. DWF.
       Increased the length of the file/directory name fields. 7 Jan 2001. DWF.
       Fixed another problem with Landscape mode interacting with A4 paper size. 7 Jan 2001. DWF.
       Seems I only half fixed the previous problem. :-( 26 April 2001. DWF.
       Forgot to update program to reflect change in FSC_FIELD. Fixed 26 April 2001. DWF.
       Changed BOOKMAN keyword to BKMAN to avoid conflict with BOOKSTYLE keyword. 26 April 2001. DWF.
       Modified the System Defaults to say "None" if none is used. Improved documentation. 10 September 2001. DWF.
       Added the ability to specify a filename at the same time as a Default Setup. 10 September 2001. DWF.
       Fixed a small problem in not setting new page sizes appropriately. 22 May 2002. DWF.
       Fixed a problem that occurred when the Accept button was not named "Accept". 6 May 2003.DWF.
       Whoops! I was a bit overly agressive on that last fix. :-( 17 July 2003. DWF.
       Fixed a problem with setting page types when using the DEFAULTSETUP keyword. 31 July 2003. DWF.
       Fixed a problem with turning encapsulation on in the GUI. Renamed ENCAPSULATE keyword ENCAPSULATED
          to avoid obvious errors. 31 July 2003. DWF.
       Removed obsolete STR_SEP and replaced with STRSPLIT. 27 Oct 2004. DWF.
       Now honoring EUROPEAN keyword when setting system default setups in the INIT method. 12 Nov 2004. DWF.
       Added CMYK output option 24 August 2007. Assumes LANGUAGE_LEVEL=2 printer. L. Anderson.
       Fixed a problem with the filename on WINDOWS computers coming back with forward slashes instead of
           backward slashes. 20 May 2008. DWF.
       Modified the program to return as the default, ISOLATIN1=1. 18 July 2008. DWF.
       Fixed a problem with filenames when a DEFAULTSETUP was used with it. 12 Nov 2008. DWF.
       Changed default window size when LANDSCAPE keyword is set. 10 April 2009. DWF.
       Changed the default window size for PORTRAIT mode to be a bit larger. 10 April 2009. DWF.
       Updated for IDL 7.1 and 24-bit color PostScript support. 24 May 2009. DWF.
       Added PAGETYPE field to returned structure to allow PostScript page type to be determined. 8 August 2009. DWF.
       Fixed a problem with 24-bit color support that allowed only IDL 7 versions to work correctly. 20 Sept 2009. DWF.
       Added a LANGUAGE_LEVEL keyword. 13 Dec 2010. DWF.
       Added the FONTYPE value to the keyword return structure. 14 Dec 2010. DWF.
       Modified the return structure to turn landscape mode off and set offsets to zero if in
            encapsulated mode. 19 Feb 2011. DWF.
       Changes to handle inability to create raster files from PS encapsulated files in
            landscape mode. Also removed changes of 19 Feb 2011 as no longer needed. 26 Aug 2011. DWF.
       The PAGETYPE was not getting set properly in the return keywords when the Metric
            option was selected on the GUI. 12 October 2011. DWF.
       The program now remembers the last directory you used and will start in that
           directory, unless told otherwise. 26 Oct 2011. DWF.
       Parsing of full filename failing. Fixed 27 Oct 2011. DWF.

(See fsc_psconfig__define.pro)

## GAUSSSCL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           GAUSSSCL

     PURPOSE:

           This is a utility routine to perform a gaussian gray-level pixel
           transformation stretch on a image.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           scaledImage = GAUSSSCL(image)

     ARGUMENTS:

           image:         The image to be scaled. Written for 2D images, but arrays
                          of any size are treated alike.

     KEYWORDS:

           SIGMA:         The sigma value or width of the Gaussian
                          function. Set to 1 by default.

           MAX:           Any value in the input image greater than this value is
                          set to this value before scaling.

           MIN:           Any value in the input image less than this value is
                          set to this value before scaling.

           NEGATIVE:      If set, the "negative" of the result is returned.

           OMAX:          The output image is scaled between OMIN and OMAX. The
                          default value is 255.

           OMIN:          The output image is scaled between OMIN and OMAX. The
                          default value is 0.
     RETURN VALUE:

           scaledImage:   The output, scaled into the range OMIN to OMAX. A byte array.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           LoadCT, 0                                            ; Gray-scale colors.
           image = cgDemoData(11)                                 ; Load image.
           TV, GaussScl(image)

     RESTRICTIONS:

         Requires cgScaleVector from the Coyote Library:

            http://www.idlcoyote.com/programs/cgScaleVector.pro

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 5 September 2007.
           Now setting NAN keyword on all MIN and MAX functions. 2 Dec 2011. DWF.

(See gaussscl.pro)

## GETIMAGE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           GETIMAGE

     PURPOSE:

           The purpose of this function is to allow the user to open either
           unformmated or XDR binary image files of up to eight dimensions.

     CATEGORY:

           Widgets, File I/O.

     CALLING SEQUENCE:

           image = GETIMAGE(filename)

     OPTIONAL INPUTS:

           filename: The name of the file to open for reading.

     OPTIONAL KEYWORD PARAMETERS:

           CANCEL: An output variable that can be set to a named variable.
           The value of the return variable will be 1 if the user clicked
           the "Cancel" button or if there was a problem reading the file.

           DATATYPE: The "type" of data you wish to read out of the file.
           The data type corresponds to the Size(image, /TYPE) value. Here
           are the types supported:

           BYTE                   1 (default)
           INTEGER                2
           LONG INTEGER           3
           FLOAT                  4
           DOUBLE                 5
           UNSIGNED INTEGER      12
           UNSIGNED LONG INTEGER 13
           64-bit LONG           14
           64-bit UNSIGNED LONG  15

           DIMENSIONS: A vector of image dimensions. The default value is [256, 256].

           DIRECTORY: The name of the directory the file is located in. By
           default the program looks in the "coyote" directory under the
           main IDL directory, if one exists. Otherwise, it defaults to the
           current directory.

           ENDIAN: Set this keyword to an integer that indicates the byte
           ordering of the data file. If you don't know what byte order means,
           or you don't know anything about the byte order of the data, or
           if you are sure the data was created on the same type of machine
           you are now running IDL on, then just accept the default of 0 or
           "native" ordering. If you are wrong, you will soon know it and you
           can set the keyword to another value on your next try. :-)

           If you know the machine was created on a big endian machine (such
           as a Sun or HP workstation), set this value to 1 (Big Endian). If e
           you are sur the image data was create on a little endian machine (such
           as a Windows PC or laptop running LINUX), set the value to 2 (Little Endian).

           HEADER: The size of any header information in the file in BYTES.
           Default is 0.

           HEADDATA: An optional output keyword that will contain the header
           information read from the file.

           PARENT: The group leader for this widget program. The PARENT is
           required if GETIMAGE is called from another widget program in order
           to make this program a MODAL widget program.

           XDR: Set this keyword if the binary file is of XDR type. The default
           type is "Unformatted".

           XOFFSET: This is the X offset of the program on the display. The
           program will be placed approximately in the middle of the display
           by default.

           YOFFSET: This is the Y offset of the program on the display. The
           program will be placed approximately in the middle of the display
           by default.

     COMMON BLOCKS:

           None.

     SIDE EFFECTS:

           A "CANCEL" operation is indicated by a 0 return value.
           Any error in reading the file results in a 0 return value.

     EXAMPLE:
           To load the image "galaxy.dat" in the $IDL/examples/data
           directory, type:

           image = GETIMAGE('galaxy.dat', DIRECTORY=!DIR + '/examples/data', $
              DIMENSIONS=[256,256], Cancel=cancelled, Parent=event.top)
           IF NOT cancelled THEN TV, image

     MODIFICATION HISTORY:
           Written by: David Fanning, 3 February 96.
           Fixed bug that prevented reading INTEGER data. 19 Dec 96.
           Modifed program for IDL 5 MODAL operation. 19 Oct 97.
           Added CANCEL keyword. 27 Oct 97. DWF.
           Fixed CANCLE keyword spelling. Sigh... 29 JUN 98. DWF.
           Added COYOTE_FIELD, improved appearance. 19 NOV 99. DWF.
           Updated with latest version of COYOTE_FIELD. 18 FEB 2000. DWF.
           Added CATCH keyword so the program will break when I want
           it to. :-) 18 MAR 2000. DWF.
           Added GROUP_LEADER keyword, which is synonymous with PARENT. 31 MAR 2000. DWF.
           Updated obsolete PICKFILE call to DIALOG_PICKFILE. 17 JAN 2001. DWF.
           Extensive update for IDL Programming Techniques, 3rd Edition. 1 November 2006. DWF.
              XSIZE, YSIZE, CATCH, and FRAMES keyword made obsolete.
              HEADDATA, ENDIAN, DATATYPE, DIMENSIONS keywords added.
           Added ability to parse fully qualified file names passed from Dialog_Pickfile. 30 Oct 2010. DWF.
           IF a file name is not passed into the program, it asks the user to select one now. 10 Jan 2011. DWF.
           Problem with SWAP_ENDIAN keywords fixed. 7 March 2011. DWF.

(See getimage.pro)

## GETPRIMARYSCREENSIZE

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
       Provides a way to get the screen size of the primary monitor, especially when
       there are several being used.

     :Categories:
        Graphics

     :Params:
        none

     :Keywords:
         exclude_taskbar: in, optional, boolean, default=0
             Set this keyword to exclude the taskbar from the monitor size.
             This keyword is ignored on all but Windows machines.

     :Author:
           Dick Jackson, www.dick-jackson.com

     :History:
         Change History::
            Written, 8 March 2011. DJ
            Modified to only use IDLsysMonitorInfo for IDL 6.3 and higher. 23 Feb 2012. DWF.

     :Copyright:
         Copyright (c) 2011, Fanning Software Consulting, Inc.

(See getprimaryscreensize.pro)

## GET_OBJECT_ID

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
        GET_OBJECT_ID

     PURPOSE:

        The purpose of this function is to be able to obtain a unique
        object identifier string for a heap variable (object or pointer).

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

        Utility.

     CALLING SEQUENCE:

        objectID = Get_Object_ID(theObject)

     INPUTS:

        theObject:    The object or pointer for which an identifier is requested. If
                      this is a null object, the function returns the string
                      "NullObject". If it is a null pointer, "NullPointer".

     OUTPUTS:

        objectID:     The unique object or pointer identifier.

     KEYWORDS:

        NUMBER:       If this keyword is set, the function returns the unique
                      number identifier associated with a valid pointer or object.
                      The number is returned as a STRING variable. The string
                      "-999" is returned if the pointer or object is invalid and
                      this keyword is set.

     EXAMPLE:

        Create a trackball object and obtain its unique object ID.

           IDL> theObject = Obj_New('TRACKBALL', [100,100], 50)
           IDL> objectID = Get_Object_ID(theObject, NUMBER=number)
           IDL> Print, objectID
                   ObjHeapVar71(TRACKBALL)
           IDL> Print, number
                   71

     MODIFICATION HISTORY:

        Written by: David W. Fanning, 4 September 2003.
        Added NUMBER keyword. DWF, 22 September 2008.

(See get_object_id.pro)

## GMASCL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           GMASCL

     PURPOSE:

           This is a utility routine to perform basic gray-level pixel
           transformations of images. I think of it as BYTSCL on steroids.
           It is similar to IMADJUST in _Digital Image Processing with MATLAB_
           by Gonzales, Wood, and Eddins. It performs a log scaling of the
           image array.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           scaledImage = GMASCL(image)

     ARGUMENTS:

           image:         The image to be scaled. Written for 2D images, but arrays
                          of any size are treated alike.

     KEYWORDS:

           GAMMA:         The exponent in a power-law transformation (image^gamma). A gamma
                          value of 1 results in a linear distribution of values between
                          OMIN and OMAX. Gamma values less than 1 map darker image values
                          into a wider range of output values, and Gamma values
                          greater than 1 maps lighter image values into a wider
                          range of output values. The gamma value is constrained to
                          be greater than 1.0e-6.

           MAX:           Any value in the input image greater than this value is
                          set to this value before scaling.

           MIN:           Any value in the input image less than this value is
                          set to this value before scaling.

           NEGATIVE:      If set, the "negative" of the result is returned.

           OMAX:          The output image is scaled between OMIN and OMAX. The
                          default value is 255.

           OMIN:          The output image is scaled between OMIN and OMAX. The
                          default value is 0.
     RETURN VALUE:

           scaledImage:   The output, scaled into the range OMIN to OMAX. A byte array.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           LoadCT, 0                                            ; Gray-scale colors.
           image = cgDemoData(11)                                 ; Load image.
           TV, GmaScl(image, Min=30, Max=100)                   ; Similar to BytScl.
           TV, GmaScl(image, /Negative)                         ; Produce negative image.
           power = Shift(ALog(Abs(FFT(image,-1))), 124, 124)    ; Create power spectrum.
           TV, GmaScl(power, Gamma=2.5)                         ; View power specturm with gamma correction.
           TV, GmaScl(power, Gamma=2.5, /Negative)              ; Reverse power spectrum.

     RESTRICTIONS:

         Requires cgScaleVector from the Coyote Library:

            http://www.idlcoyote.com/programs/cgScaleVector.pro

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 17 February 2006.
           Fixed a problem with output scaling. 1 July 2009. DWF (with input from Bo Milvang-Jensen).
           Now setting NAN keyword on all MIN and MAX functions. 2 Dec 2011. DWF.

(See gmascl.pro)

## HCOLORBAR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           HCOLORBAR

     FILENAME:

           hcolorbar__define.pro
    ;
     PURPOSE:

           The purpose of this program is to create a horizontal
           colorbar object to be used in conjunction with other
           IDL 5 graphics objects.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

           Object Graphics.

     CALLING SEQUENCE:

           thisColorBar = Obj_New('HColorBar')

     REQUIRED INPUTS:

           None.

     INIT METHOD KEYWORD PARAMETERS:

           COLOR: A three-element array representing the RGB values of a color
              for the colorbar axes and annotation. The default value is
              white: [255,255,255].

           FONTSIZE: A floating value that is the point size of the font
               used for the axis and title annotations. Set to 8 point by default.

           NAME: The name associated with this object.

           NCOLORS: The number of colors associated with the colorbar. The
              default is 256.

           MAJOR: The number of major tick divisions on the colorbar axes.
              The default is 5.

           MINOR: The number of minor tick marks on the colorbar axes.
              The default is 4.

           PALETTE: A palette object for the colorbar. The default palette
               is a gray-scale palette object.

           POSITION: A four-element array specifying the position of the
               colorbar in normalized coordinate space. The default position
               is [0.10, 0.90, 0.90, 0.95].

           RANGE: The range associated with the colorbar axis. The default
               is [0, NCOLORS].

           TITLE: A string containing a title for the colorbar axis
               annotation. The default is a null string.

     OTHER METHODS:

           Clamp (Procedure): Given a two-element array in the data range of
              the colorbar, the colorbar image is clamped to this range. In
              other words, the range of colors is clamped to the specified
              range. Values above or below the range in the colorbar are set to
              the minimum and maximum range values, respectively.

           GetProperty (Procedure): Returns colorbar properties in keyword
              parameters as defined for the INIT method. Keywords allowed are:

                   COLOR
                   MAJOR
                   MINOR
                   NAME
                   PALETTE
                   POSITION
                   RANGE
                   TEXT
                   TITLE
                   TRANSFORM

           SetProperty (Procedure): Sets colorbar properties in keyword
              parameters as defined for the INIT method. Keywords allowed are:

                   COLOR
                   MAJOR
                   MINOR
                   NAME
                   PALETTE
                   POSITION
                   RANGE
                   TEXT
                   TITLE
                   TRANSFORM

     SIDE EFFECTS:

           A HColorBar structure is created. The colorbar INHERITS IDLgrMODEL.
           Thus, all IDLgrMODEL methods and keywords can also be used. It is
           the model that is selected in a selection event, since the SELECT_TARGET
           keyword is set for the model.

     EXAMPLE:

           To create a colorbar object and add it to a plot view object, type:

           thisColorBarObject = Obj_New('HColorBar')
           plotView->Add, thisColorBarObject
           plotWindow->Draw, plotView

     MODIFICATION HISTORY:

           Written by David Fanning, from VColorBar code, 20 Sept 98. DWF.
           Changed a reference to _Ref_Extra to _Extra. 27 Sept 98. DWF.
           Fixed bug when adding a text object via the TEXT keyword. 9 May 99. DWF.
           Fixed the same bug when getting the text using the TEXT keyword. :-( 16 Aug 2000. DWF.
           Fixed a bug with getting the text object via the TEXT keyword. 16 Aug 2000. DWF.
           Added the TRANSFORM keyword to GetProperty and SetProperty methods. 16 Aug 2000. DWF.
           Added RECOMPUTE_DIMENSIONS=2 to text objects. 16 Aug 2000. DWF.
           Added a polygon object around the image object. This allows rotation in 3D space. 16 Aug 2000. DWF.
           Removed TEXT keyword (which was never used) and improved documentation. 15 AUG 2001. DWF.
           Added ENABLE_FORMATTING keyword to title objects. 22 October 2001. DWF.
           Added a CLAMP method. 18 November 2001. DWF.
           Forgot to pass extra keywords along to the text widget. As a result, you couldn't
              format tick labels, etc. Fixed this. Any keywords appropriate for IDLgrTick objects
              are now available. 26 June 2002. DWF.
           Fixed a problem with POSITION keyword in SetProperty method. 23 May 2003. DWF.
           Fixed a problem with setting RANGE keyword in SetProperty method. 6 Sept 2003. DWF.
           Removed NORMALIZE from source code. 19 November 2005. DWF.
           Font sizes have changed. Now using a 12 point font. 6 May 2011. DWF.
           Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See hcolorbar__define.pro)

## HELP_VAR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           HELP_VAR

     PURPOSE:

           The purpose of this program is to display HELP on just
           the variables at the level in which HELP_VAR is called.
           It is similar to the HELP command, except that compiled
           functions and procedures are not displayed.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities.

     CALLING SEQUENCE:

           HELP_VAR

     REQUIRED INPUTS:

           None.

     SIDE EFFECTS:

           Memory is allocated for each variable, in turn, then deleted.
           Uses undefined and unsupported ROUTINE_NAMES function. May not
           work in all versions of IDL, including future versions.

     EXAMPLE:

           PRO HELP_VAR_TEST
              a = 4.0
              b = Lindgen(11)
              HELP_VAR
           END

           IDL> help_var
                A          FLOAT     =       4.00000
                B          LONG      = Array[11]

     MODIFICATION HISTORY:

           Written by David W. Fanning, 8 August 2003.

(See help_var.pro)

## HISTOMATCH

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           HistoMatch

     PURPOSE:

           This is a function for Histogram Matching, in which an image
           is manipulated in such a way that it's final histogram approximates
           the histogram of an input image or histogram. Histogram matching
           allows the user to specify the shape of the histogram of the final
           product.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Image Processing

     CALLING SEQUENCE:

           output_image = HistoMatch(image, histogram_to_match)

     INPUTS:

           image - The input image to be manipulated. Assumed to be a 2D byte array.

           histogram_to_match - Can be either a 1D long vector of 256 elements specifying
               the histogram to match, or a 2D byte array from which the histogram to
               match is calculated.

     OUTPUTS:

           output_image - The manipulated image adjusted to the histogram specifications.

     INPUT KEYWORDS:

           None.

     OUTPUT KEYWORDS:

           None.

     DEPENDENCIES:

           None.

     METHOD:

           Based on the Histogram Matching method on pages 94-102 of Digital
           Image Processing, 2nd Edition, Rafael C. Gonzalez and Richard E. Woods,
           ISBN 0-20-118075-8.

     EXAMPLE:

           There is an example program at the end of this file. It will require cgImage
           from the Coyote Library to run. You can also find an explanation of this program
           at http://www.idlcoyote.com/ip_tips/histomatch.html.

     MODIFICATION HISTORY:

           Written by David W. Fanning, January 2003.

(See histomatch.pro)

## IMAGESELECT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       IMAGESELECT

     PURPOSE:

       The purpose of this program is to allow the user to select a formatted
       image file for reading. The image data is returned as the result of the
       function. The program allows the user to see a thumbnail version of the
       image, along with information about the image, before selection. The
       program uses the file extention to determine what kind of image is to
       be read. The following image types are supported:

          TYPE      FILE EXTENSION
          BMP       *.bmp
          DICOM     *.dcm
          FITS      *.fits, *.fts (requires NASA ASTRO library on IDL Path)
          GIF       *.gif (IDL 6.2 and higher)
          JPEG      *.jpg, *.jpeg, *.jpe
          JPEG2000  *.jpf, *.jpx, *.jp2, *.j2c, *.j2k
          PICT      *.pict
          PNG       *.png
          TIFF      *.tif, *tiff

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       image = ImageSelect()

     INPUT PARAMETERS:

       None. All input is via keywords.

     INPUT KEYWORDS:

       BMP -- Set this keyword to select BMP files.

       DEMO -- If this keyword is set, the program changes directory to !DIR/examples/data.

       DICOM -- Set this keyword to select DICOM files.

       DIRECTORY -- The initial input directory name. The current directory by default.

       EXCLUDE -- A list of filenames that should excluded from the file selection list.

       FILENAME -- The initial filename. If the initial directory has image files of the
                   correct type, the default is to display the first of these files. Otherwise, blank.

       FILTER -- A string, representing the file filter. For example, '*.jpg'.

       FITS -- Set the keyword to select FITS files. (Must have NASA Astro Library on path.)

       FLIPIMAGE -- Set this keyword if you wish to flip the image from its current orientation. Setting
                    this keyword reverses the Y dimension of the image.

       GIF -- Set this keyword to select GIF files. (IDL versions before 5.4 and after 6.0, only.)

       GROUP_LEADER -- Set this keyword to a widget identifier group leader. This keyword MUST be
                       set when calling this program from another widget program to guarantee modal operation.

       J2000 -- Set this keyword to select JPEG2000 files. (May also be set as J2K.) (IDL 6.1 or above.)

       J2K -- Set this keyword to select JPEG2000 files. (May also be set as J2000.) (IDL 6.1 or above.)

       JPEG -- Set this keyword to select JPEG files.

       LISTXSIZE -- Set this keyword to the XSIZE of the list widget. Default is 30 or MAX(StrLen(filenames)), whichever is larger.

       OFFSETS -- A two-element array containing the X and Y offsets of the program, from the upper left
                  corner of the display. On dismissal of the program, if this is a named variable (passed into
                  the program by reference), then it will contain the last offsets of the program. This is
                  useful if you want to call ImageSelect again and have it positioned in exactly the same
                  location it was before.

       ONLY2D -- Set this keyword if you only want the user to be able to select 2D images. Note
                 that the user will be able to browse all images, but the Accept button will only
                 be sensitive for 2D images.

       ONLY3D -- Set this keyword if you only want the user to be able to select 3D or true-color images.
                 Note that the user will be able to browse all images, but the Accept button will only
                 be sensitive for 3D or true-color images.

       PICT -- Set this keyword to select PICT files.

       PGM -- Set this keyword to select PGM files.

       PPM -- Set this keyword to select PPM files.

       PNG -- Set this keyword to select PNG files.

       PREVIEWSIZE -- Set this keyword to the maximum size (in pixels) of the preview window. Default is 150.

       SILENT -- Set this keyword to turn off Group_Leader educational message. Use only if you
                 are sure you know what you are doing. :-)

       TIFF -- Set this keyword to select TIFF files. (This is the default filter selection.)

       TITLE -- Set this keyword to the text to display as the title of the main image selection window.

       NOTE: Any extra keywords passed into the program will collected and passed along to the READ_XXX routines
       that actually do the image file reading. Using this keyword inheritance mechanism makes it impossible
       to trap misspelled or misused keywords. Please take care when using ANY keyword for this routine!

     OUTPUT KEYWORDS:

       CANCEL -- This keyword is set to 1 if the user exits the program in any way except hitting the ACCEPT button.
                 The ACCEPT button will set this keyword to 0.

       FHEADER -- Set this keyword to a named variable that will return the FITS header information for a FITS file.

       FILEINFO -- This keyword returns information about the selected file. Obtained from the QUERY_**** functions.

       GEOTIFF --  If the file is a GeoTIFF file, this keyword will return the GeoTIFF structure containing
                   the files GeoTags.

       OUTDIRECTORY -- The directory where the selected file is found.

       OUTFILENAME -- The short filename of the selected file.

       PALETTE -- The current color table palette returned as a 256-by-3 byte array.

     COMMON BLOCKS:

       None.

     RESTRICTIONS:

       Requires other programs from the Coyote Library.

      Note: Keyword inheritance to collect undefined keywords that may be passed into the
      program for use in READ_XXX routines, make it impossible to trap keyword useage errors.
      Please take care when using keywords.

     EXAMPLE:

       To read JPEG files from the directory:

          IDL> image = ImageSelect(/JPEG)

     MODIFICATION HISTORY:

       Written by: David W. Fanning, 18 Jan 2001.
       Added modification to read both 8-bit and 24-bit BMP files. 27 Jan 2001. DWF.
       Fixed a problem with calculating the new size of the draw widget. 5 April 2002. DWF.
       Fixed a problem with List Widgets not sizing correctly on UNIX machines. 10 Aug 2002. DWF.
       Fixed a problem with the initial file not being selected correctly when you changed
         the file type. 10 Aug 2002. DWF.
       Added a FLIPIMAGE keyword 10 Aug 2002. DWF.
       When user chooses to Flip Image, I now reverse the Y dimension of the image,
         rather than set the !Order system variable. 10 Aug 2002. DWF.
       Added OUTDIRECTORY and OUTFILENAME keywords. 18 Aug 2002. DWF.
       Fairly extensive changes in the way this program works and selects images.
         A new version of FSC_FileSelect is also required. Because of interactions
         with the operating system with image filters, the program has probably
         become more Windows-centric. The default is now to display all image
         files the program is capable of reading. 31 October 2002. DWF.
       Added ONLY2D keyword to allow the acceptance of 2D images only. 3 Nov 2002. DWF.
       Added ability to center itself on the display. 8 Nov 2002. DWF.
       Fixed a problem caused by reading old images with short color table vectors. 26 Nov 2002. DWF.
       Fixed a problem with specifying a fully-qualified filename. 26 Nov 2002. DWF.
       Now highlights the selected file in the directory. 26 Nov 2002. DWF.
       Improved error handling. 9 Dec 2002. DWF.
       Added PALETTE keyword and improved color operation on 8-bit displays. If the image file
         contains a color palette, that palette is now loaded when the image is read from the file.
         The current color palette can be obtained with the PALETTE keyword. 4 April 2003. DWF.
       Added ONLY3D keyword. 19 April 2003. DWF.
       Added ability to read PPM and PGM files. 24 November 2003. DWF.
       Added TITLE keyword. 1 December 2003. DWF.
       Added EXAMPLES keyword. 22 December 2005. DWF.
       Added GIF and JPEG2000 file types. Rearranged and cleaned up code. 3 January 2006. DWF.
       Added LISTXSIZE keyword. 3 January 2006. DWF.
       Added file type checkmark buttons. Program now compatible with IDL 5.6 and higher. 3 January 2006. DWF.
       Improved error handling with invalid file types. 5 January 2006. DWF.
       Added OFFSETS and EXCLUDE keywords. 3 March 2006 DWF.
       Modified the program to check for FITS unsigned integer data. 3 March 2006. DWF.
       Added ability to double-click image name in list to Accept. 10 March 2006. DWF.
       Added FHEADER keyword to return FITS header information. 3 April 2006. DWF.
       Fixed a problem in which the file type was not set if the user cancelled. 10 July 2006. DWF.
       Added a "fit" file extension for FITS images. 1 April 2008. DWF.
       Added a FILTER keyword. 1 April 2008. DWF.
       Updated for reading transparent images. 13 May 2009. DWF.
       Provided check for PNG images with more than 8 bits per channel. 5 August 2009. DWF.
       Fixed a problem in which the starting directory was changed on exit. 20 Nov 2010. DWF.
       Change EXAMPLES to more easily remembered DEMO keyword. 29 Nov 2010. DWF.
       Removed NOINTERPOLATION keywords in going from TVIMAGE to cgImage. 22 Feb 2011. DWF.
       Fixed a problem reading 2D Tiff files. 20 Sept 2012. DWF.

(See imageselect.pro)

## IMAGE_BLEND

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           IMAGE_BLEND

     PURPOSE:
           The purpose of this program is to demonstrate how to
           use the alpha channel to blend one image into another.
           The specific purpose is to see a color image on top of
           a gray-scale image, with the gray-scale image showing
           through behind the color image.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Widgets, Object Graphics.

     CALLING SEQUENCE:

           Image_Blend

     REQUIRED INPUTS:

           None. The images "worldelv.dat" and "ctscan.dat" from the
           examples/data directory are used.

     OPTIONAL INPUTS:

           backgroundImage::  A 2D image variable that will be used for the background image.
           foregroundImage:   A 2D image variable that will be used for the foreground image.

     OPTIONAL KEYWORD PARAMETERS:

           COLORTABLE: The number of a color table to use for the foreground image.
           Color table 3 (red temperature) is used as a default.

     COMMON BLOCKS:

           None.

     SIDE EFFECTS:

           None.

     RESTRICTIONS:

           None. The program XCOLORS is required from the Coyote library.

     EXAMPLE:

           Image_Blend, Colortable=5

     MODIFICATION HISTORY:

           Written by David Fanning, 30 March 99.
           Fixed bug where I redefined the image parameter. Duh... 1 April 99. DWF.
           Moved the program into the 21st century. :-) 21 March 2003. DWF.
           Added TIFF, GIF (if version supports it), and PS output. 27 December 2006. DWF.

(See image_blend.pro)

## IMAGE_DIMENSIONS

[Previous Routine] [Next Routine] [List of Routines]

     The purpose of this function is to return the various dimensions of the image,
     and also to extract relevant image information via output keywords. The
     function works only with 2D and 3D (24-bit) images, with or without alpha
     channels.

     :Categories:
        Utilities

     :Returns:
         A vector containing the size of each dimension of the image. It is equivalent
         to calling the SIZE function with the DIMENSIONS keyword set.

     :Params:
        image:  in, optional, type=various
            The image variable from which information is to be obtained.

     :Keywords:
         alphachannel: out, optional, type=boolean
            This keyword is set to 1 if there is an alpha channel in the image. Otherwise,
            the keyword is set to 0.
         trueindex: out, optional, type=integer
            The position of the "true color" index in the return value. Is -1 for 2D images.
         xindex: out, optional, type=integer
            The index (position) of the X dimension in the return value.
         xsize: out, optional, type=integer
            The X size of the image.
         yindex: out, optional, type=integer
            The index (position) of the Y dimension in the return value.
         ysize: out, optional, type=integer
            The Y size of the image.

     :Examples:
        To load open a window of the appropriate size and display a 24-bit image::

           dims = Image_Dimensions(image24, XSize=xsize, YSize=ysize, TrueIndex=trueindex)
           Window, XSIZE=xsize, YSIZE=ysize
           TV, image24, TRUE=trueindex

     :Author:
        FANNING SOFTWARE CONSULTING::
            David W. Fanning
            1645 Sheely Drive
            Fort Collins, CO 80526 USA
            Phone: 970-221-0438
            E-mail: david@idlcoyote.com
            Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     :History:
        Modification History::
           Written by:  David W. Fanning, 5 March 2003.
           Added support for alpha channel images, include ALPHACHANNEL keyword. 13 May 2009. DWF.

     :Copyright:
         Copyright (c) 2003-2011, Fanning Software Consulting, Inc.

(See image_dimensions.pro)

## INSIDE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
        INSIDE

     PURPOSE:

        The purpose of this function is to indicate whether a specified
        2D point is inside (returns a 1) a specified 2D polygon or outside
        (returns a 0).

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

        Utility.

     CALLING SEQUENCE:

        result = INSIDE(x, y, xpts, ypts)

     INPUTS:

        x:        A scalar or vector of the x coordinates of the 2D point(s) to check.
        y:        A scalar or vector of the y coordinates of the 2D point(s) to check.
        xpts:     The x coordinates of the 2D polygon.
        ypts:     The y coordinates of the 2D polygon.

     OUTPUTS:

        result:  A scalar or vector set to 1 if the point is inside the polygon and to
                 0 if the point is outside the polygon.

     KEYWORDS:

        INDEX:   An output keyword. If set to a named variable, will return the indices
                 of the X and Y points that are inside the polygon.

     ALGORITHM:

        Based on discussions on the IDL newsgroup (comp.lang.idl-pvwave) and
        discussed here:

          http://www.idlcoyote.com/tips/point_in_polygon.html

        Primarily the work of B�rd Krane and William Connelly.

     MODIFICATION HISTORY:

        Written by: David W. Fanning, 4 September 2003.
        Vectorized the function in accord with William Connelly's suggestions 24 July 2005. DWF.

(See inside.pro)

## JD2TIME

[Previous Routine] [Next Routine] [List of Routines]

     The purpose of this function is to convert a Julian day number into
     a time string of the form "16 Mar 2009".

     :Categories:
        Utilities

     :Returns:
        A scalar or vector of time strings of the form "16 Mar 2009 15:34:26".

     :Params:
        jdnumber: in, optional, type=integer
           A Julian day number or array of Julian day numbers. If absent,
           today's current Julian day number.
        jdyear: in, optional, type=integer
           The year for which the Julian day number applies. If absent, the current year.

     :Keywords:
         day: out, optional, type=integer
            The day of the month as an integer.
         month: out, optional, type=integer
            The month as an integer.
         year: out, optional, type=integer
            The year as an integer.

     :Examples:
        Used like the IDL AXIS command::
           IDL> cgPlot, cgDemoData(1), YStyle=8, Position=[0.1, 0.1, 0.85, 0.9], /Window
           IDL> cgAxis, /YAxis, Color='red', YRange=[-500, 500], /Save, /Window

     :Author:
        FANNING SOFTWARE CONSULTING::
           David W. Fanning
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written by: David W. Fanning, 25 June 2009.
            Added DAY, MONTH, and YEAR keywords. 18 Sept 2012. DWF.

     :Copyright:
         Copyright (c) 2009-2012, Fanning Software Consulting, Inc.

(See jd2time.pro)

## LEFTJUSTIFY

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           LEFTJUSTIFY

     PURPOSE:

           This is a utility routine to create a string that is left-justified with
           respect to a string width.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           justifiedString = LeftJustify(string, width)

     AUGUMENTS:

           string:      The string that is to be left-justified. If not supplied, a null
                        string is returned and no error is issued.

           width:       The final width of the left-justified string. The width must be
                        longer than the length of the string or an error results. Default: 50.

     KEYWORDS:

           None.

     RETURN VALUE:

           justifiedString: A string of WIDTH, with the string left-justified and the rest of the string
                         filled with blank characters.

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 26 January 2009.

(See leftjustify.pro)

## LINKEDLIST

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       LINKEDLIST

     FILENAME:
       linkedlist__define.pro

     PURPOSE:

       The purpose of this program is to implement a list that
       is linked in both the forward and backward directions. There
       is no restriction as to what can be stored in a linked list
       node. The linked list is implemented as an object.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       General programming.

     CALLING SEQUENCE:

       mylist = Obj_New('LINKEDLIST', item)

     OPTIONAL INPUTS:

       item: The first item added to the list. Items can be any
         valid IDL variable type.

     COMMON BLOCKS:

       Are you kidding?!

     RESTRICTIONS:

       Be sure to destroy the LINKEDLIST object when you are finished
       with it: Obj_Destroy, mylist

       Node index numbers start at 0 and go to n-1, where n is the
       number of items in the list.

     PUBLIC METHODS:

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     PRO LINKEDLIST::ADD, item, index, $
         AFTER=after, $
         BEFORE=before, $
         ERROR=error, $
         NO_COPY=no_copy, $
         REPLACE=replace

       The ADD method adds a data item to the list.

       Parameters:

       item: The data item to be added to the list. Required.

       index: The location in the list where the data item is
         to be added. If neither the AFTER or BEFORE keyword is
         set, the item is added AFTER the item at the index location.
         If index is missing, the index points to the last item in
         the list. Optional.

       Keywords:

       AFTER: If this keyword is set, the item is added after the
         item at the current index.

       BEFORE: If this keyword is set, the item is added before the
         item at the current index.

       ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

       NO_COPY: If set, the item is transferred to the internal pointer using
          a no copy method. This will cause the item variable to become undefined.

       REPLACE: If this keyword is set, the item will replace the current item at
          the index location.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     PRO LINKEDLIST::DELETE, index, ALL=all, DESTROY=destroy, ERROR=error

       The DELETE method deletes an item from the list.

       Parameters:

       index: The location in the list where the data item is
         to be delete. If index is missing, the index points to
         the last item in the list. Optional.

       Keywords:

       ALL: If this keyword is set, all items in the list are deleted.

       DESTROY: If the item at the node is an object or pointer, the
         item will be destroyed before the node is deleted. This keyword
         is turned on (set to 1) by default. Set to 0 to prevent destruction.

        ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     FUNCTION LINKEDLIST::GET_COUNT

       The GET_COUNT method returns the number of items in the list.

       Return Value: The number of items stored in the linked list.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     FUNCTION LINKEDLIST::GET_ITEM, index, $
        ALL=all, $                 ; This ASSUMES all items stored are the same type!!!
        Dereference=dereference, $ ; Obsolete. Ignored. Always returns item.
        ItemPtr=itemPtr, $         ; The pointer to the item, if needed. Output.
        NO_COPY=no_copy, $         ; Copy from location with NO_COPY.
        ERROR=errorMsg             ; The error message. Null string if no error.

       Parameters:

       index: The location in the list from which the data item is
         to be retrieved. If not present, the last item in the list
         is retrieved. Optional.

       Keywords:

       DEREFERENCE: This keyword obsolete and only provided for backward compatibility.

       ALL: Set this keyword to return an n-element array containing all the list
          items.  This requires that all list items be of the same type, and
          if they are arrays, they have 7 dimensions or fewer. If index is passed,
          it is ignored.

       ITEMPTR: The pointer to the data item.

       NO_COPY: If this keyword is set, the item is transferred from the data
          pointer using a NO_COPY method. This will undefine the item at that
          indexed locaton.

        ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

       Return Value: The data item at this index on the list.
         If ALL is set, then an array containing all the data items is returned.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     FUNCTION LINKEDLIST::GET_NODE, index, ERROR=error

       The GET_NODE method returns a pointer to the specified node
       from the list.

       Parameters:

       index: The location in the list from which the data node is
         to be retrieved. If not present, the last node in the list
         is retrieved. The node is a structure with three fields:
         Previous is a pointer to the previous node in the list.
         Next is a pointer to the next node in the list. A null pointer
         in the previous field indicates the first node on the list. A
         null pointer in the next field indicates the last node on the
         list. The item field is a pointer to the item stored in the
         node. Optional.

       ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

       Return Value: A pointer to the specified node structure in
         the linked list.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     PRO LINKEDLIST::HELP, PRINT=print

     The HELP method performs a HELP command on each item
     in the linked list.

       Keywords:

        PRINT: If this keyword is set, the PRINT command is used
          instead of the HELP command on the items in the list.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     PRO LINKEDLIST::MOVE_NODE, nodeIndex, location, BEFORE=before, ERROR=error

       The MOVE_NODE method moves a list node from one location to another.

       Parameters:

       nodeIndex: The location in the list of the node you are moving.
         Required.

       location: The location (index) you are moving the node to. If
         location is missing, the location points to the node at the
         end of the list.

       Keywords:

        BEFORE: If this keyword is set, the node is added to the
          list before the location node. Otherwise, it is added after
          the location node.

        ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     PRO LINKEDLIST::REPLACE_ITEM, newItem, index, ERROR=error

      Use this method to replace any item in the list with any other value.
      This allows the caller to change an item without stepping through the
      process of deleting an item then adding a new one.

      Parameters:
         index:  The location of the node you are replacing

         newItem:  Any value of any data type.

        ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     FUNCTION LINKEDLIST::HAVE_ITEM, index, ERROR=error

      Use this method to check to see if an item exits at a particular location
      on the list. Returns a 1 if the item is there, otherwise a 0.

      Parameters:
         index:  The location of the node you are replacing

        ERROR: On return, if this is not a null string, an error occurred
          and this value is set equal to the error message.

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

     EXAMPLE:

       mylist = Obj_New("LINKEDLIST", 5)
       mylist->Add, 10
       mylist->Add, 7, 1, /Before
       mylist->Add, 12
       print, mylist->Get_Item(/All)
       mylist->Add, 'Bob', 2, /Replace
       mylist->Help
       mylist->Delete, 0
       mylist->Help, /Print

     MODIFICATION HISTORY:
       Written by: David Fanning, 25 August 98.
       25 August 99. Fixed several errors in various methods dealing with
           moving nodes from one place to another. DWF.
       13 June 2001. DWF. Added DEREFERENCE to the GET_ITEM method to
           return the item itself, instead of the pointer to the item.
       27 June 2001 Added REPLACE_ITEM method.  Ben Tupper.
       7 April 2003. Added DESTROY keyword to DELETE method so that objects
          and pointers could be cleaned up properly when they are deleted
          from the linked list. DWF.
       9 April 2003. Fixed a problem that occurs when deleting the last node. DWF.
       3 Feb 2004. Make sure loop index vars are long.  Jeff Guerber
       30 Jun 2004.  Added /ALL to GET_ITEM function.  Henry Throop, SWRI.
       23 Nov 2004.  Fixed GET_ITEM, /ALL to accomodate structures and empty
          lists.  Henry Throop.
       21 February 2011. A complete refurbishing to incorporate changes and to fix bugs
          I found in the SolarSoft version of this code. I've tried to make this compatible
          with the version distributed with SolarSoft to reduce problems caused by two versions
          of the software with the same name.
        9 December 2011. Fixed a problem with the ALL keyword on the Get_Item method. DWF.

(See linkedlist__define.pro)

## LIST_SELECTOR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       LIST_SELECTOR

     PURPOSE:

       The purpose of this function is to implement a pop-up dialog widget
       for the purpose of selecting "names". Names can be names of variables,
       names of files, etc. Any string array can be used.

     CALLING SEQUENCE:

       selectedNames = List_Selector(theNames)

     ARGUMENTS:

       theNames:       A string array of potential "names" that can be selected.

     KEYWORDS:

       ALL:            Set this keyword if you wish all the names to be selected
                       initially.

       CANCEL:         An output keyword set to 1 if the user cancels or quits the
                       program without hitting the Accept button. Set to 0 if a proper
                       selection was made and the use hits the Accept button.

       COUNT:          An output keyword containing the number of elements in the return array.

       GROUP_LEADER:   The widget identifier of a widget who will be the group leader
                       for this dialog. Passing a group leader is the *only* way to
                       assure the dialog will be a MODAL dialog (as opposed to a blocking
                       dialog). A GROUP_LEADER is required if you will be using this
                       function in an IDL Virtual Machine application.

       LABEL:          A string that will be placed on a label above the selections.
                       If not used, no label is used in the program.

       LIST_COUNTER:   If this keyword is set, a number is associated and displayed with
                       each list item, starting with the number 1.

       TITLE:          A string that is used for the title of the dialog window. If
                       undefined, then "Selection Widget" is used.

       SELECTED_INDICES: An output vector of the selected indices from theNames array.

     RETURN VALUE:

       selectedNames:  Typically, an array of selected names. If there is only one item
                       in the selection, the variable will be a scalar string.

     EXAMPLE:

       See the List_Selector_Test procedure below. I use the program to allow the
       user to select the names of scientific data sets in an HDF file for further
       reading and processing.

     MODIFICATION HISTORY:

       Written by David W. Fanning, 11 January 2009, based on Name_Selector program.
       Added "Accept on Double-Click" functionality. 14 January 2009. DWF.
       Added LIST_COUNTER keyword. 25 May 2009. DWF.
       Well, basically a RE-DO of yesterday's work, although done correctly today. 26 May 2009. DWF.
       Fixed a problem when the user double-clicks an item in the list. 8 August 2009. DWF.
       Double clicks are a problem with UNIX machines because  sets event.clicks = 2
          prematurely. Removed double-click functionality from all but Windows machines. 9 Feb 2012. DWF.

(See list_selector.pro)

## LOGSCL

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           LOGSCL

     PURPOSE:

           This is a utility routine to perform a log intensity transformation
           on an image. For exponent values greater than 1.0, the upper and
           lower values of the image are compressed and centered on the mean.
           Larger exponent values provide steeper compression. For exponent values
           less than 1.0, the compression is similar to gamma compression. (See
           IMGSCL.) See pages 68-70 in _Digital Image Processing with MATLAB_
           by Gonzales, Wood, and Eddins. The function is used to improve contrast
           in images.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           outputImage = LOGSCL(image)

     ARGUMENTS:

           image:         The image to be scaled. Written for 2D images, but arrays
                          of any size are treated alike.

     KEYWORDS:

           EXPONENT:      The exponent in a log transformation. By default, 4.0.

           MEAN:          Values on either side of the mean will be compressed by the log.
                          The value is a normalized value between 0.0 and 1.0. By default, 0.5.

           NEGATIVE:      If set, the "negative" of the result is returned.

           MAX:           Any value in the input image greater than this value is
                          set to this value before scaling.

           MIN:           Any value in the input image less than this value is
                          set to this value before scaling.

           OMAX:          The output image is scaled between OMIN and OMAX. The
                          default value is 255.

           OMIN:          The output image is scaled between OMIN and OMAX. The
                          default value is 0.
     RETURN VALUE:

           outputImage:   The output, scaled into the range OMIN to OMAX. A byte array.

     COMMON BLOCKS:
           None.

     EXAMPLES:

           cgLoadCT, 0                                       ; Gray-scale colors.
           image = cgDemoData(22)                            ; Load image.
           cgImage, image                                    ; No contrast.
           cgImage, LogScl(image)                            ; Improved contrast.
           cgImage, LogScl(image, Exponent=10, Mean=0.65)    ; Even more contrast.
           cgImage, LogScl(image, /Negative, Exponent=5)     ; A negative image.

     RESTRICTIONS:

         Requires cgScaleVector from the Coyote Library:

            http://www.idlcoyote.com/programs/cgScaleVector.pro

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 20 February 2006.
           Fixed a problem with output scaling. 1 July 2009. DWF (with input from Bo Milvang-Jensen).

(See logscl.pro)

## MAXMIN

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
        Prints the maximum and minimum of an IDL variable.

     :Categories:
        Utility

     :Params:
        variable: in, required, type=any
           The variable whose minimum and maximum you wish to know.

     :Keywords:
         NAN: in, optional, type=boolean
           Set this keyword to ignore NANs in the variable. Default: 0.
         TEXT: in, optional, type=string
           Prepend this string to the output of MinMax. Default: "MinMax: ".

     :Examples:
       The MaxMin routine gives the range of the variable::
         IDL> a = Findgen(11)
         IDL> MaxMin, a, TEXT='Variable A:'
         Variable A:   11    0

     :Author:
           FANNING SOFTWARE CONSULTING::
               David W. Fanning
               1645 Sheely Drive
               Fort Collins, CO 80526 USA
               Phone: 970-221-0438
               E-mail: david@idlcoyote.com
               Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written, 20 Sept 2010.
            Changed name of program from MinMax to MaxMin to avoid conflict with
            MinMax program in NASA Astronomy Library. 1 Nov 2010. DWF.

     :Copyright:
         Copyright (c) 2010, Fanning Software Consulting, Inc.

(See maxmin.pro)

## MAXWINDOWSIZE

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
        Returns the resolution of the largest unobstructed graphics window that can be
        created on this particular graphics device. Works properly for Windows and UNIX
        computers, excluding Macintosh computers. There is no known way to find the resolution
        of the largest unobstructed graphics window on a Macintosh computer, so a fudge factor
        of 22 pixels is used to account for the Macintosh "dock".

     :Categories:
        Utility

     :Params:
        none:

     :Keywords:
         monitor_resolution: out, optional, type=long
            Set this keyword to a named variable to return the resolution of the
            primary display monitor.

     :Examples:
        To create a window of maximum size::
           maxsize = MaxWindowSize()
           Window, XSize=maxsize[0], YSize=maxsize[1], /Free

     :Author:
           FANNING SOFTWARE CONSULTING::
               David W. Fanning
               1645 Sheely Drive
               Fort Collins, CO 80526 USA
               Phone: 970-221-0438
               E-mail: david@idlcoyote.com
               Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written, 26 October 2010. DWF.
            Misunderstood Macintosh result. Now Mac treated like UNIX. 27 Oct 2010. DWF.
            No known method for Macintosh computers. Resorting to a fudge factor
               of 22 pixels to account for the Macintosh dock. 27 Oct 2010. DWF.
            Code is total reversed for UNIX and Macintosh computers! Fixed. 16 Dec 2011. DWF.
            Modified to only use IDLsysMonitorInfo for IDL 6.3 and higher. 23 Feb 2012. DWF.

     :Copyright:
         Copyright (c) 2010, Fanning Software Consulting, Inc.

(See maxwindowsize.pro)

## NAME_SELECTOR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       NAME_SELECTOR

     PURPOSE:

       The purpose of this function is to implement a pop-up dialog widget
       for the purpose of selecting "names". Names can be names of variables,
       names of files, etc. Any string array can be used.

     CALLING SEQUENCE:

       selectedNames = Name_Selector(theNames)

     ARGUMENTS:

       theNames:       A string array of potential "names" that can be selected.

     KEYWORDS:

       ALL:            Set this keyword if you wish all the names to be selected
                       initially.

       CANCEL:         An output keyword set to 1 if the user cancels or quits the
                       program without hitting the Accept button. Set to 0 if a proper
                       selection was made and the use hits the Accept button.

       COUNT:          An output keyword containing the number of elements in the return array.

       GROUP_LEADER:   The widget identifier of a widget who will be the group leader
                       for this dialog. Passing a group leader is the *only* way to
                       assure the dialog will be a MODAL dialog (as opposed to a blocking
                       dialog). A GROUP_LEADER is required if you will be using this
                       function in an IDL Virtual Machine application.

       LABEL:          A string that will be placed on a label above the selections.
                       If not used, no label is used in the program.

       NUMCOLS:        The number of columns to organize the string array in. The default
                       is to use one column per approximately 20 strings.

       TITLE:          A string that is used for the title of the dialog window. If
                       undefined, then "Selection Widget" is used.

     RETURN VALUE:

       selectedNames:  Typically, an array of selected names. If there is only one item
                       in the selection, the variable will be a scalar string.

     EXAMPLE:

       See the Name_Selector_Test procedure below. I use the program to allow the
       user to select the names of scientific data sets in an HDF file for further
       reading and processing.

     MODIFICATION HISTORY:

       Written by David W. Fanning, 21 December 2008.
       Added a COUNT keyword. DWF. 6 January 2009.

(See name_selector.pro)

## NCDF_ATTRIBUTE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_ATTRIBUTE

     PURPOSE:

           The pupose of this NCDF_Attribute object is to store information about
           a netCDF global or variable attribute. The object is principally used
           as a utility routine for the NCDF_FILE object. Given the attribute name,
           the object will acquire additional information about the attribute from
           the netCDF file containing the attribute.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           File I/O

     CALLING SEQUENCE:

           IDL> attrObj = Obj_New('NCDF_ATTRIBUTE', attrName, parent, VARNAME=varName)

     ARGUMENTS:

           attrName:  The case sensitive name of a netCDF attribute that is stored in the
                      netCDF file. (Input and required.)

           parent:    The object reference (NCDF_FILE object) of the netCDF file. In other words, the
                      object reference of the file that contains this attribute. (Input and required.)

     KEYWORD PARAMETERS:

           varName:   If this is a variable attribute, this is the case sensitive name of the
                      variable that the attribute is attached to. (Input and required for variable
                      attributes.) Note that a variable object reference may be used in place of the
                      variable name.

     METHODS:

         The following methods are available. Each is documented in front of the method.

         attrName = attrObject -> GetName()
         propertyValue = attrObject -> GetProperty(attrProperty)
         attrValue = attrObject -> GetValue()
         attrObject -> ParseAttribute

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 3 Feb 2010.

(See ncdf_attribute__define.pro)

## NCDF_BROWSER

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_BROWSER

     PURPOSE:

           This program is designed to make it easier to browse and read the
           data and metadata in netCDF and HDF files. The user can browse files,
           and read the data and metadata into main-level IDL variables. New netCDF
           and HDF files can be opened at any time. The user interacts with the
           program via a browser window (GUI). This program is a wrapper for the
           NCDF_DATA object (ncdf_data__define.pro), which must also be downloaded.

           Note that only HDF files with scientific datasets (SD) can be read currently.
           There is no support for VDATA objects or other objects sometimes found in HDF
           files. Also note that when variables are returned from HDF files, they are returned
           in a calibrated form, if calibration information about the variable is present in the
           file. Calibration information is presented as an extra variable attribute in the
           browser.

              calibratedData = calData.cal * (uncalibratedData - calData.offset)

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           File I/O

     CALLING SEQUENCE:

           IDL> NCDF_Browser, filename

     Arguments:

           filename: The name of a netCDF and HDF file to open and browse.

     KEYWORD PARAMETERS:

           EXTENSION: In general, netCDF and HDF files use *.nc, *.ncf, *.ncdf and *.hdf file extensions to
                      identify themselves as netCDF and HDF files. Some users have their own file extensions.
                      You can use this keyword to identify the file extension you wish to use. If
                      set here, it will be used as the file filter in place of the normal file
                      extensions in DIALOG_PICKFILE.

                          obj = ('NCDF_DATA', file, EXTENSION='*.bin')

           NO_NEW_FILE: If this keyword is set, then the button that allows a new file to be open
                      on the browser is not created.

           NO_READ_ON_PARSE: Normally, when a file is opened it is parsed for information.
                      One piece of information is the minimum and maximum values of the variables.
                      This requires actually reading the variables. This can slow things down
                      considerably is the variable is large. Setting this keyword will suppress
                      the reading of the variables during the parsing of the data file, with the
                      result that no minimum or maximum values will be reported.

           TITLE:     Set this keyword to a string that is on the title bar of the browser.

           XOFFSET:   Set this keyword to the X offset in pixels of the top-left corner of the browser.

           YOFFSET:   Set this keyword to the Y offset in pixels of the top-left corner of the browser.

     NOTES:

           This program is only a (useful) front-end for a more flexible
           object program of class NCDF_DATA. In this front end, the NCDF_DATA
           object is created and then destroyed when the GUI is destroyed.
           The NCDF_DATA object can be used to read netCDF data in a non-interactive
           way, if you prefer not to use a GUI to interact with the data file.

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 03 Feb 2008. Used ideas from many
               people, including Chris Torrence, Ken Bowman, Liam Gumely,
               Andrew Slater, and Paul van Delst.
           Added Extension keyword. DWF. 04 Feb 2008.
           Added error handling and protection for NCDF variables that have a dimension of length zero. 22 April 2009. DWF.
           Added NO_READ_ON_PARSE keyword. 22 April 2009. DWF.
           Now convert NCDF CHAR type variables to strings on output. 22 April 2009. DWF
           Made the default value of NO_READ_ON_PARSE set to 1. 25 June 2009. DWF.
           Added NO_NEW_FILE keyword to suppress the Open File button. 3 February 2010. DWF.
           Added TITLE, XOFFSET, and YOFFSET keywords. 5 February 2010. DWF.
           Fixed a problem with memory leakage when the input file cannot be read. 1 May 2010. DWF.

(See ncdf_browser.pro)

## NCDF_CASTDATATYPE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_CastDataType

     PURPOSE:

           This is a utility routine to turn IDL data types into the equivalent
           netCDF data type. In other words, change 'STRING' to 'CHAR' and so on.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           ncdf_datatype = NCDF_CastDataType(variable)

     ARGUMENTS:

           variable:      The IDL variable for which you want a netCDF data type.
                          Or, if the TYPE keyword is set, the variable type index you wish
                          to convert. Or, if the TNAME keyword is set, the variable type
                          name you wish to convert.

     KEYWORDS:

            TYPE:         If set, the positional argument is an IDL variable type of
                          the sort returned by the SIZE function with the TYPE keyword set.

                           type = Size(variable, /TYPE)

            TNAME:        If set, the positional argument is an IDL variable type of
                          the sort returned by the SIZE function with the TNAME keyword set.

                           type = Size(variable, /TNAME)

     RETURN VALUE:

           ncdf_datatype: The netCDF data type of the variable. Possible values are
                          'BYTE', 'CHAR', 'SHORT', 'LONG', 'FLOAT' and 'DOUBLE'.

     NOTES:

         The program is designed to work with the NCDF_FILE object and related programs.

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 3 February 2010.
           Made a UINT data type be cast to LONG, rather than SHORT. 29 April 2010. DWF.
           Added TYPE and TNAME keywords. 5 May 2010. DWF.

(See ncdf_castdatatype.pro)

## NCDF_CONTAINER

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_Container

     PURPOSE:

           This is a beefed-up IDL_CONTAINER object written as a utility object
           for the NCDF_FILE object and related objects. In particular, two new
           container methods have been added. The FindByID method searches container
           objects by object ID, and the FindByName method searches container object
           by object name. If found, the object reference is returned. This object
           is a subclassed IDL_CONTAINER object and uses the IDL_CONTAINER
           initialization routine.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           ncdf_container = NCDF_Container()

     ARGUMENTS:

           Those used in the IDL_CONTAINER method.

     RETURN VALUE:

           A sub-classed IDL_Container object.

     NOTES:

         The program is designed to work with the NCDF_FILE object and related programs.

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 3 February 2010.

(See ncdf_container__define.pro)

## NCDF_DATA__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_DATA__DEFINE

     PURPOSE:

           This program is designed to make it easier to browse and read the
           data and metadata in netCDF and HDF files. The user can browse files,
           and read the data and metadata into main-level IDL variables. New netCDF
           and HDF files can be opened at any time. The user interacts with the
           program via a browser window (GUI) or directly through the methods of
           the object. The program implements an IDL object.

           Note that only HDF files with scientific datasets (SD) can be read currently.
           There is no support for VDATA objects or other objects sometimes found in HDF
           files. Also note that when variables are returned from HDF files, they are returned
           in a calibrated form, if calibration information about the variable is present in the
           file. Calibration information is presented as an extra variable attribute in the
           browser.

              calibratedData = calData.cal * (uncalibratedData - calData.offset)

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           File I/O

     CALLING SEQUENCE:

           IDL> nCDFObject = Obj_New('NCDF_DATA', filename)

     ARGUMENTS:

           filename: The name of a netCDF or HDF file to open and browse.

     KEYWORD PARAMETERS:

           BROWSE:   If this keyword is set, the Browse Window is invoked as soon
                     as the object is initiated.

           DESTROY_FROM_BROWSER:  As with all objects, this object is persistent until
                      it is destroyed. However, with this keyword set, the object will
                      be destroyed when the user closes the Browse Window.

           EXTENSION: In general, netCDF and HDF files use *.nc, *.ncf, *.ncdf of *.hdf file extensions to
                      identify themselves as netCDF or HDF files. Some users have their own file extensions.
                      You can use this keyword to identify the file extension you wish to use. If
                      set here, it will be used as the file filter in place of the normal file
                      extensions in DIALOG_PICKFILE.

                          obj = ('NCDF_DATA', file, EXTENSION='*.bin')

           NO_READ_ON_PARSE: Normally, when a file is opened it is parsed for information.
                      One piece of information is the minimum and maximum values of the variables.
                      This requires actually reading the variables. This can slow things down
                      considerably is the variable is large. Setting this keyword will suppress
                      the reading of the variables during the parsing of the data file, with the
                      result that no minimum or maximum values will be reported.

     NOTES:

           This program is designed to be flexible in how it is used, so it
           can be used in both interactive and non-interactive (called directly)
           ways. A less flexible way of interacting with the program is via the
           NCDF_BROWSER program, which is a front-end to this object.

           The netCDF and HDF file formats are thought to be "standards". And to
           a large extent, they are. But files are not always created to standards,
           and both netCDF and HDF files can be quirky. If you look carefully at the
           code you will see places where I work around quirks in the files I typically
           use on a daily basis. If you find you can't read a particular file, let me know
           about it. I may be able to improve the program in such as way that it can be read.

           This program is not meant to be the be-all and end-all of programs. Rather, it is
           a tool I use, and improve upon whenever necessary, in my own work with netCDF and HDF
           files. It will get better for all of us if you report problems to me directly.

     METHODS:

         The following methods can be used directly.

         ncdfObject -> Browse                             ; Use GUI to browse file data and metadata.
         ncdfObject -> OpenFile, filename                 ; Opens a new netCDF or HDF file.
         globalAttr = ncdfObject -> ReadGlobalAttr()      ; Return a structure containing global attributes.
         attribute = ncdfObject -> ReadAttribute(attrname); Return an attribute, identified by name.
         dim = ncdfObject -> ReadDimension(dimName)        ; Return a dimension, identified by name.
         variable = ncdfObject -> ReadVariable(varname)   ; Return a variable, identified by name.
         varstruct = ncdfObject -> ReadVariableWithAttr(varname)   ; Return a variable, identified by
                                                                   ; name, along with its attributes.
         allData = ncdfObject -> ReadFile(filename)        ; Read all the data in the file, into structures.

     EXAMPLE:

           IDL> filename = 'example.nc'
           IDL> ncdfObj = Obj_New('NCDF_DATA', filename)
           IDL> ncdfObj -> Browse
           IDL> Obj_Destroy, ncdfObj

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 03 Feb 2008. Used ideas from many
               people, including Chris Torrence, Ken Bowman, Liam Gumely,
               Andrew Slater, and Paul van Delst.
           Added EXTENSION keyword, resizeable TLB, and ability to download
               individual global attibutes. DWF. 04 Feb 2008.
           Added ReadDimension and ReadVariableWithAttr methods. DWF. 05 Feb 2008.
           Ill-formed attribute names giving me fits. Now doing checks with IDL_VALIDNAME
                before creating structures. 06 February 2008. DWF.
           Same problem. Wide use of IDL_VALIDNAME everywhere it seems wise. 06 Feb 2008. DWF.
           Added functionality to read a variable with its attributes from the browser interface,
                and fixed a problem with reading CHAR values. 2 March 2008. DWF.
           Fixed a problem with changing variable name when reading variable plus attributes. 6 March 2008. DWF.
           Fixed a problem with not setting GLOBAL keyword when inquiring about global attribute. 6 March 2008. DWF.
           Made sure file was parsed before attempting to read variables and attributes to avoid errors. 7 March 2008. DWF.
           Small bug with variable attributes fixed. 18 Dec 2008. DWF.
           Added ability to read HDF files containing Scientific Datasets (SD). 21 February 2009. DWF.
           Added error handling and protection for NCDF variables that have a dimension of length zero. 22 April 2009. DWF.
           Added NO_READ_ON_PARSE keyword. 22 April 2009. DWF.
           Now convert NCDF CHAR type variables to strings on output. 22 April 2009. DWF
           Fixed a problem with the directory being correct when file name passed in. 11 May 2009. DWF.
           Added COUNT, OFFSET, and STRIDE keywords to ReadVariable method. 25 June 2009. DWF.
           When reading a netCDF variable by itself (without it's attributes), the program now looks for
              a SCALE_FACTOR and ADD_OFFSET attribute, and if found will apply this to the variable before
              it is returned to the user. 24 August 2009. DWF.
           Added the methods GetAttrNames, GetVarNames, GetVarAttrNames, and ReadVarAttr to retrieve specfic
              information from the data files. 16 November 2009. DWF.
           Modified the ReadVariableWithAttr method to include the number of dimensions (in the NDIMS field,
              and the dimensions (in the DIMS field) in the return structure. For HDF files, the DIMS field
              is a vector of the dimensions of the variable. For netCDF files, the DIMS field is a vector
              of dimension IDs for the dimensions of the variable. 27 Nov 2009. DWF.
           Andy Meigs alerted me to a problem creating a structure when the ncdf variable name
              is ill-formed according to IDL structure tag name rules. Fixed in the ReadFile method.
              30 November 2009. DWF.
           Added NO_NEW_FILE keyword to the BROWSE method. This keyword will suppress the OPEN FILE
              button on the browse interface. 3 Feb 2010. DWF.
           Made the default browser size a bit larger to accomodate longer variable names. 3 Feb 2010. DWF.
           Add a check for HDF/netCDF file type in the INIT method to better accommodate reading data
              from the file without first parsing the file. 16 March 2010. DWF.
           Changed the ReadVariable for netCDF files to now check for missing data, using either the
               depreciated missing_value attribute or the compliant _FillValue attribute. Missing data
               is now identified via new output keywords MISSINGINDICES and FILLVALUE, and missing data
               is not scaled or offset, if these operations are applied to the data prior to return.
               21 March 2010. DWF. Problem with these changes, fixed 23 March 2010. DWF.
           Fixed a problem with memory leakage when the input file cannot be read. 1 May 2010. DWF.
           Fixed a problem with memory leakage from created structures. 1 May 2010. DWF.
           Have done some work on parsing HDF-EOS swath files, but currently unused in code. 15 May 2010. DWF.
           Modified the ReadVariable method to check for 0 length dimensions when reading variables
               from HDF files. 21 July 2010. DWF.
           Modified the global attribute structure so that the "filename" field, which holds the
               name of the netCDF of HDF file is now named "ncdf_filename" or "hdf_filename". This
               will avoid conflicts with global attributes with "filename". 20 January 2011. DWF.
           Typo in the section reading calibration data fixed. 12 March 2013. DWF.

(See ncdf_data__define.pro)

## NCDF_DIMENSION

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_DIMENSION

     PURPOSE:

           The pupose of this NCDF_Dimension object is to store information about
           a netCDF dimension. The object is principally used as a utility routine
           for the NCDF_FILE object. Given the dimension name, the object will
           acquire additional information about the dimension from the netCDF file
           containing the dimension.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           File I/O

     CALLING SEQUENCE:

           IDL> dimObj = Obj_New('NCDF_DIMENSION', dimName, parent)

     ARGUMENTS:

           dimName:   The case sensitive name of a netCDF dimension that is stored in the
                      netCDF file. (Input and required.)

           parent:    The object reference (NCDF_FILE object) of the netCDF file. In other words, the
                      object reference of the file that contains this attribute. (Input and required.)

     KEYWORD PARAMETERS:

           None.

     METHODS:

         The following methods are available. Each is documented in front of the method.

         dimName = dimObject -> GetID()
         dimName = dimObject -> GetName()
         dimName = dimObject -> GetSize()
         propertyValue = dimObject -> GetProperty(dimProperty)
         dimValue = dimObject -> GetValue()
         dimName = dimObject -> GetUnlimited()
         dimObject -> ParseAttribute

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 3 Feb 2010.

(See ncdf_dimension__define.pro)

## NCDF_FILE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_FILE

     PURPOSE:

           The pupose of this NCDF_File object is three-fold. (1) Allow the user to easily
           determine what information is inside a netCDF file and allow easy access
           to such information. (2) Allow the user to easily create a netCDF file from
           scratch. (3) Allow the user to easily copy information from one netCDF
           file to another.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           File I/O

     CALLING SEQUENCE:

           IDL> nCDFObject = Obj_New('NCDF_FILE', filename)

     ARGUMENTS:

           filename:  The name of a netCDF file to read, write to, or browse.

     KEYWORD PARAMETERS:

           ALERT:     Set this keyword if you wish to have alert from the object's error logger.
                      Input. Default is 1.

           BROWSE:    If this keyword is set, the Browse Window is invoked as soon
                      as the object is initiated. Input. Default is 0.

           CLOBBER:   Set this keyword if you are opening a netCDF file that already exists and
                      you want to overwrite the existing file. Input. Default is 0.

           CREATE:    Set this keyword if you wish to create a new netCDF file to write
                      into. Input. Default is 0, which means the file will be opened as
                      "read-only".

           DELETE_ON_DESTROY:  Set this keyword if you wish to delete the error log file when
                      the ErrorLogger object is destroyed. This will only happen if the ErrorLogger
                      object is not in an error state. Input. Default is 1.

           MODIFY:    Set this keyword if you wish to modify (write to) a file you are opening.
                      If not set, the file will be opened as "read-only".

     METHODS:

         The following methods are available. Each is documented in front of the method.

         ncdfObject -> Browse
         ncdfObject -> CopyVarAttrTo, varName, attrName, destObj
         ncdfObject -> CopyVarDataTo, varName, destObj, COUNT=count, OFFSET=offset, STRIDE=stride
         ncdfObject -> CopyVarDefTo, varName, destObj
         ncdfObject -> CopyGlobalAttrTo, attrName, destObj
         ncdfObject -> CopyDimTo, dimName, destObj
         dimNames = ncdfObject -> GetDimNames(COUNT=dimCount)
         dimValue = ncdfObject -> GetDimValue(dimName)
         fileID = ncdfObject -> GetFileID()
         globalAttrNames = ncdfObject -> GetGlobalAttrNames(COUNT=attrCount)
         attrValue = ncdfObject -> GetGlobalAttrValue(attrName, DATATYPE=datatype)
         ncdfObject -> GetProperty, ....
         property = ncdfObject -> GetProperty(thisProperty)
         varAttrNames = ncdfObject -> GetVarAttrNames(varName, COUNT=attrCount)
         varAttrValue = ncdfObject -> GetVarAttrValue(varName, varAttrName, COUNT=attrCount)
         varNames = ncdfObject -> GetVarNames(COUNT=varCount)
         varData = ncdfObject -> GetVarData(varName, COUNT=count, OFFSET=offset, STRIDE=stride)
         answer = ncdfObject -> HasGlobalAttr(attrName, OBJECT=object)
         answer = ncdfObject -> HasDim(dimName, OBJECT=object)
         answer = ncdfObject -> HasVar(varName, OBJECT=object)
         answer = ncdfObject -> HasVarAttr(varName, attrName, OBJECT=object)
         ncdfObject -> PrintFileInfo
         ncdfObject -> ParseFile
         ncdfObject -> SetMode, DEFINE=define, DATA=data
         ncdfObject -> WriteVarData, varName, data, COUNT=count, OFFSET=offset, STRIDE=stride
         ncdfObject -> WriteVarDef, varName, dimNames, DATATYPE=datatype, VAROBJ=varObj
         ncdfObject -> WriteDim, dimName, dimSize, UNLIMITED=unlimited
         ncdfObject -> WriteGlobalAttr, attrName, attrValue, DATATYPE=datatype
         ncdfObject -> WriteVarAttr, attrName, attrValue, varObj, DATATYPE=datatype

     NOTES:

         Note that all variable, attribute, and dimension names in a netCDF file are CASE SENSITIIVE!!
         Thus, it is a good idea to use the methods provided in this object to obtain and examine
         information in the file, as these names are handled in a case sensitive manner.

         Whenever you are creating a new netCDF file, you should try to create the file in
         the following way.
            1. Create your global attributes.
            2. Create the dimensions you will be using to describe the variables.
            3. Define the variables. To do this correctly, dimensions MUST be defined.
            4. Define variable attributes.
            5. Load your variables with data.

            Note that the data type of the _FillValue variable attribute MUST match the
            data type of the variable data. Otherwise, you will have MANY problems! This
            is a common source of error.

            Note that in almost all cases where you see the names "varName", "dimName", or
            "attrName" used as input variables, you can substitute the proper object
            reference in place of the actual name. In other words, you could get the value
            of a variable attribute by doing something like this:

                check = ncdfObject -> HasAttr('history', OBJECT=attrObj)
                IF check THEN attrValue = ncdfObject -> GetGlobalAttrValue(attrObj)

             as opposed to this:

                IF check THEN attrValue = ncdfObject -> GetGlobalAttrValue('history')
     EXAMPLE:

           IDL> filename = 'example.nc'
           IDL> ncdfObj = Obj_New('NCDF_FILE', filename)
           IDL> ncdfObj -> Browse
           IDL> Obj_Destroy, ncdfObj

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 3 Feb 2010, using (stealing, really) plenty of ideas
              from Mark Hadfield's Motley Library. Mark's mghncfile object is terrific, but it
              had a number of limitations for my particular application, which I have attemped
              to correct in my version of the software. But I wouldn't have even attempted this
              had Mark not blazed the trail and Matt Savoie not insisted that I look at Mark's
              wonderful library.
           Changes in the way dimensions with a zero length are handled. 11 Feb 2010, DWF.
           Added GetVarInfo method. 20 March 2010. DWF.
           Added MISSINGINIDCES and FILLVALUE output keywords to GetVarData method. 20 March 2010. DWF.
           Added output keywords SCALE_FACTOR, ADD_OFFSET, and DATATYPE to GetVarData method
               so that these values can be obtained with the data. 29 Apr 2010. DWF.
           I changed "missingValue" to "fillValue" some time ago, but I missed one in
               the GetVarData method. Fixed. 7 June 2010. DWF.
           Used the undefine procedure OBJ_DELETE, rather than OBJ_DESTROY. Sheesh! 18 June 2010. DWF.
           Added NETCDF4_FORMAT keyword. 13 Feb 2012. DWF.
           Added a bunch of new IDL 8.0 and 8.1 keyword to the WriteVarDef method to allow
               access to these keywords in NCDF_VarDef. Also modified the NETCDF4_FORMAT keyword
               to apply only in IDL versions 8.0 and higher. 21 Feb 2012. DWF.
           Small typo fixed in setting CHAR datatype for IDL 8.1 and higher. 22 May 2013. DWF.
           Typo (CONTINUOUS->CONTIGUOUS) fixed in WriteDefVar method. 30 July 2013. DWF.
           Modified CopyVarDefTo method to allow new NCDF4 keywords. 30 July 2013. DWF.
           Added DelGlobalAttr method to allow deletion of global attributes. 11 Jan 2014. DWF.

(See ncdf_file__define.pro)

## NCDF_FILE_EXAMPLES

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_FILE_EXAMPLES

     PURPOSE:

           This is a utility routine demonstrates the several ways it is possible
           to use the NCDF_FILE object to create netCDF files, copy information
           from one netCDF file to another, and to read information from a netCDF
           file.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           NCDF_File_Examples

     ARGUMENTS:

           None.

     KEYWORDS:

           None.

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 3 February 2010.
           Updated to use a time variable for the frame number. 29 Oct 2011.

(See ncdf_file_examples.pro)

## NCDF_ISVALIDFILE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
        NCDF_ISVALIDFILE

     PURPOSE:

        Utility routine to determine if a file is a valid netCDF file or not.
        Returns a 1 if the file is valid and a 0 otherwise.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

        Utility.

     CALLING SEQUENCE:

        result = NCDF_IsValidFile(filename)

     INPUTS:

        filename:    The name of a filename to open to see if it is a valid netCDF file.

     RETURN VALUE:

        result:  A 1 if the file can be opened as a netCDF file. A 0 otherwise.

     KEYWORDS:

        None.

     ALGORITHM:

        Try to open the file. If you fail, it is not an netCDF file.

     MODIFICATION HISTORY:

        Written by: David W. Fanning, 21 February 2010.

(See ncdf_isvalidfile.pro)

## NCDF_VARIABLE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           NCDF_VARIABLE

     PURPOSE:

           The pupose of this NCDF_Variable object is to store information about
           a netCDF variable. The object is principally used as a utility routine
           for the NCDF_FILE object. Given the variable name, the object will acquire
           additional information about the variable from the netCDF file containing
           the variable.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           File I/O

     CALLING SEQUENCE:

           IDL> varObj = Obj_New('NCDF_VARIABLE', varName, parent)

     ARGUMENTS:

           varName:   The case sensitive name of a netCDF variable that is stored in the
                      netCDF file. (Input and required.)

           parent:    The object reference (NCDF_FILE object) of the netCDF file. In other words, the
                      object reference of the file that contains this attribute. (Input and required.)

     KEYWORD PARAMETERS:

           None.

     METHODS:

         The following methods are available. Each is documented in front of the method.

         varObject -> AddAttr
         varAttrNames = varObject -> GetAttrNames()
         dimIDs = varObject -> GetDimIDs()
         dimNames = varObject -> GetDimNames()
         varAttrValue = varObject -> GetAttrValue()
         varID = varObject -> GetID()
         varName = varObject -> GetName()
         propertyValue = varObject -> GetProperty(attrProperty)
         varValue = varObject -> GetValue()
         varObject -> ParseVariable

     MODIFICATION HISTORY:
           Written by:  David W. Fanning, 3 Feb 2010.
           Changes to the way dimensions of length 0 are handled. 11 Feb 2010. DWF.
           Added GetInfo method. 20 Mar 2010. DWF.
           Added MISSINGINDICES and FILLVALUE keywords to GetValue method to return the indices
               and the value of missing data. 20 Mar 2010. DWF.
           Modified the GetValue method so that if the data returned is scaled and/or offset
               then the "missing" data value is preserved, although its data type may change.
               In other words, the "missing" data is not scaled or offset. 20 Mar 2010. DWF.
           Added output keywords SCALE_FACTOR, ADD_OFFSET, and DATATYPE to the GetValue method
               so that these values can be returned to the caller at run-time. 29 April 2010. DWF.
           Modified AddAttr method to allow for additional data types in attributes, specifically
               INT data type. 3 June 2013. DWF.
           Had to modify AddAttr method again to allow compatibility with IDL versions below 8.1. 26 July 2013. DWF.

(See ncdf_variable__define.pro)

## PICKCOLOR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           PICKCOLOR

     PURPOSE:

           A modal dialog widget allowing the user to select
           the RGB color triple specifying a color. The return
           value of the function is the color triple specifying the
           color or the "name" of the color if the NAME keyword is set.

     AUTHOR:
           FANNING SOFTWARE CONSULTING:
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: davidf@dfanning.com
           Coyote's Guide to IDL Programming: http://www.dfanning.com

     CATEGORY:

           Graphics, Color Specification. See related program cgCOLOR.

     CALLING SEQUENCE:

           color = PickColor(colorindex)

     RETURN VALUE:

           The return value of the function is a 1-by-3 array containing
           the values of the color triple that specifies the selected color.
           The color can be loaded, for example, in any color index:

               color = PickColor(240)
               TVLCT, color, 240

           The return value is the original color triple if the user
           selects the CANCEL button.

           IF the NAMES keyword is set, the return value of the function is
           the "name" of the selected color. This would be appropriate for
           passing to the cgCOLOR program, for example.

     OPTIONAL INPUT POSITIONAL PARAMETERS:

           COLORINDEX: The color index of the color to be changed. If not
                  specified the color index !D.Table_Size - 2 is used.
                  The Current Color and the Color Sliders are set to the
                  values of the color at this color index.

     OPTIONAL INPUT KEYWORD PARAMETERS:

           GROUP_LEADER: The group leader for this widget program. This
                  keyword is required for MODAL operation. If not supplied
                  the program is a BLOCKING widget. Be adviced, however, that
                  the program will NOT work if called from a blocking widget
                  program, unless a GROUP_LEADER is supplied.

           NAMES: Set this keyword to return the "name" of the selected color
                  rather than its color triple.

           STARTINDEX: 88 pre-determined colors are loaded The STARTINDEX
                  is the index in the color table where these 88 colors will
                  be loaded. By default, it is !D.Table_Size - 89.

           TITLE: The title on the program's top-level base. By default the
                  title is "Pick a Color".

     OPTIONAL INPUT KEYWORD PARAMETERS:

           CANCEL: A keyword that is set to 1 if the CANCEL button is selected
                  and to 0 otherwise.

     COMMON BLOCKS:

           None.

     SIDE EFFECTS:

           88 pre-determined colors are loaded in the color table.
           In addition, the color index at COLORINDEX is modified while
           the program is on the display. When the program exits, the
           entry color table is restored. Thus, on 8-bit displays there
           might be some color effects in graphics windows while PICKCOLOR
           is on the display. Changes in the color table are not noticable
           on 16-bit and 24-bit displays.

     EXAMPLE:

           To specify a color for a plot in color decomposition OFF mode:

              Device, Decomposed=0
              !P.Color = !P.Color < (!D.Table_Size - 1)
              color = PickColor(!P.Color, Cancel=cancelled)
              IF NOT cancelled THEN BEGIN
                  TVLCT, color, !P.Color
                  Plot, data
              ENDIF

           To specify a color for a plot in color decomposition ON mode:

              Device, Decomposed=1
              color = PickColor(Cancel=cancelled)
              !P.Color = Color24(color)
              IF NOT cancelled THEN Plot, data

            To obtain the name of the selected color to pass to GetColor:

              selectedColor = PickColor(/Name)
              axisColor = cgColor(selectedColor, !D.Table_Size-4)

     MODIFICATION HISTORY:
           Written by: David Fanning, 28 Oct 99.
           Added NAME keyword. 18 March 2000, DWF.
           Fixed a small bug when choosing a colorindex less than !D.Table_Size-17. 20 April 2000. DWF.
           Added actual color names to label when NAMES keyword selected. 12 May 2000. DWF.
           Modified to use 88 colors and cgCOLOR instead of 16 colors and GETCOLOR. 4 Dec 2000. DWF.
           Changed FSC_Color to cgColor everywhere. 16 Jan 2013. DWF.

(See pickcolor.pro)

## PRECIPMAP

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           PrecipMap

     PURPOSE:

           This is a program that demonstrates how to place an IDL map projection
           onto an image that is already in a map projection space. It uses a NOAA
           precipitation image that is in a polar stereographic map projection, and
           for which the latitudes and longitudes of its four corners are known.

           For additional details, see http://www.idlcoyote.com/map_tips/precipmap.html.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

           Map Projection

     CALLING SEQUENCE:

           IDL> PrecipMap, filename

     INPUTS:

          filename:   The name of the precipitation file. For demo, download
                      ST4.2005010112.24h.bin from http://www.idlcoyote.com/data/ST4.2005010112.24h.bin.

     KEYWORDS:

          DATA:   Set this keyword to a named variable that on output will contain the scaled data.

          PALETTE:    Set this keyword to a named variable that on output will contain the color
                      palette used to display the data.

     RESTRICTIONS:

         Requires files from the Coyote Library:

         http://www.idlcoyote.com/documents/programs.html

     MODIFICATION HISTORY:

      Written by David W. Fanning, 28 April 2006 from code and discussion supplied
           by James Kuyper in the IDL newsgroup.
      Renamed Colorbar procedure to cgColorbar to avoid conflict with IDL 8 Colorbar function.
            26 September 2010. DWF.
      Got the polar stereo map projection correct. 5 September 2011. DWF.
      Added DATA, MAP, and PALETTE output keywords and updated to use more modern Coyote
            Library mapping routines. 2 November 2012. DWF.

(See precipmap.pro)

## PRINTWINDOW

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
       PRINTWINDOW

        This program sends the contents of the specified
        window to the default printer. The current window
        is used if a window index number is not provided.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Graphics

     CALLING SEQUENCE:

      IDL> PrintWindow, wid

     OPTIONAL POSITIONAL PARAMETERS:

       WID       The window index number of the window to send to the
                 printer. !D.Window used by default.

     KEYWORD PARAMETERS:

       LANDSCAPE  If this keyword is set, the output is in Landscape
                  mode. Otherwise, Portrait mode is used.

       PAGESIZE: Set this keyword to a string indicating the type
                 of PostScript page size you want. Current values are "LETTER",
                 "LEGAL", and "A4". Default is "LETTER".

       RGB_ERROR: Some printers (particularly attached to LINUX machines) cannot
                  load a 24-bit image. You get this error message:

                     %Can't set RGB color on an indexed destination.

                  If this happens to you, set this keyword and the 24-bit image will
                  be made into a 2D image with color table vectors. Colors are not
                  quaranteed to be accurate with this method, but in practice it is
                  not usually too bad.

                  IDL> PrintWindow, /RGB_Error

     MODIFICATION HISTORY:

     Written by David W. Fanning based on previous PRINT_IT program. 29 July 2000.
     Added RGB_Error keyword. 2 Nov 2004. DWF.

(See printwindow.pro)

## PSWINDOW

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
        PSWINDOW

     PURPOSE:

        This function is used to calculate the size of a PostScript
        window that has the same aspect ratio (ratio of height to
        width) as the current display graphics window. It creates
        the largest possible PostScript output window with the
        desired aspect ratio. This assures that PostScript output
        looks similar, if not identical, to normal graphics output
        on the display.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

        Graphics.

     CALLING SEQUENCE:

        pageInfo = PSWINDOW()

     INPUTS:

        None.

     KEYWORD PARAMETERS:

        ASPECTRATIO: Normally the aspect ratio is matched to the
        aspect ratio (ratio of height divided by width) of the current
        graphics window. However, this keyword can be used to select
        a particular aspect ratio for the PostScript window. This should
        be a floating point value.

        CM: Normally the structure value that is returned from this
        function reports its values in inches. Setting this keyword
        causes the return values to be in units of centimeters.

        EUROPEAN: This keyword is depreciated in favor of METRIC.

        FUDGE: A quick way to set symetrical XFUDGE and YFUDGE factors.
        If this keyword is set to a value, XFUDGE and YFUDGE keywords are
        set to the same value. Fudge factors are used only with some
        printers and generally only when output is being sent to the
        PRINTER device. (See the description of the XFUDGE and YFUDGE
        keywords for additional information.)

        LANDSCAPE: Normally, a landscape page is selected if the current
        graphics window is wider than it is tall. If you prefer a landscape
        aspect window on a Portrait page, set the LANDSCAPE keywword to 0.
        Setting  this keyword to 1 will result in a landscape page no
        matter the size of the current graphics window.

        MARGIN:  The margin around the edges of the plot. The value must be
        a floating point value between 0.0 and 0.35. It is expressed in
        normalized coordinate units. The default margin is 0.05.

        METRIC: If this keyword is set, the program defaults change
        so that the CM keyword is set to 1 and the PAGESIZE keyword is
        set to "A4".

        PAGESIZE: Set this keyword to a string indicating the type
        of PostScript page size you want. Current values are "LETTER",
        "LEGAL", and "A4". Default is "LETTER".

        PRINTER: Set this keyword if the output will be used to
        configure the PRINTER device, rather than the PS device.
        (In the PRINTER device, offsets are always calculated from
        the lower-left corner of the page and do not rotate in
        Landscape mode, as they do with the PS device.) Note that
        the PRINTER device is only able to accept these keywords
        in IDL 5.1 and higher.

        XFUDGE: Printers calculate the offset point from the printable
        edge of the paper (sometimes), rather from the corner of the paper.
        For example, on my Lexmark printer, both X and Y offsets are
        calculated from a point 0.25 inches in from the edge. This keyword
        allows you to set a "fudge" factor that will be subtracted from
        the XOFFSET that is returned to the user. This allows you to create
        output that is centered on the page. The fudge factor should be in
        the same units as the returned size and offset values.

        YFUDGE: Printers calculate the offset point from the printable
        edge of the paper (sometimes), rather from the corner of the paper.
        For example, on my Lexmark printer, both X and Y offsets are
        calculated from a point 0.25 inches in from the edge. This keyword
        allows you to set a "fudge" factor that will be subtracted from
        the YOFFSET that is returned to the user. This allows you to create
        output that is centered on the page. The fudge factor should be in
        the same units as the returned size and offset values.

     OUTPUTS:

        pageInfo: The output value is a named structure defined like
        this:

          pageInfo = {PSWINDOW_STRUCT, XSIZE:0.0, YSIZE:0.0, $
             XOFSET:0.0, YOFFSET:0.0, INCHES:0, PORTRAIT:0, LANDSCAPE:0}

        The units of the four size fields are inches unless the CM
        keyword is set.

        The output can be used to immediately configure the PostScript
        or Printer device, like this:

           Set_Plot, 'PS' ; or 'PRINTER'
           Device, _Extra=pageInfo

     RESTRICTIONS:

        The aspect ratio of the current graphics window is calculated
        like this:

           aspectRatio = FLOAT(!D.Y_VSIZE) / !D.X_VSIZE

     EXAMPLE:

        To create a PostScript output window with the same aspect
        ratio as the curently active display window, type:

         pageInfo = PSWINDOW()
         SET_PLOT, 'PS'
         DEVICE, _Extra=pageInfo

         To configure the PRINTER device:

         pageInfo = PSWINDOW(/Printer, Fudge=0.25)
         SET_PLOT, 'PRINTER'
         DEVICE, _Extra=pageInfo

     MODIFICATION HISTORY:

        Written by: David W. Fanning, November 1996.
           Fixed a bug in which the YOFFSET was calculated incorrectly
              in Landscape mode. 12 Feb 97.
           Took out a line of code that wasn't being used. 14 Mar 97.
           Added correct units keyword to return structure. 29 JUN 98. DWF
           Fixed a bug in how landscape offsets were calculated. 19 JUL 99. DWF.
           Fixed a bug in the way margins were used to conform to my
              original conception of the program. 19 JUL 99. DWF.
           Added Landscape and Portrait fields to the return structure. 19 JUL 99. DWF.
           Added PageSize keyword, changed MARGIN keyword, and completely
              rewrote most of the intenal code. 9 FEB 2000. DWF.
           Fixed a bug in how I calculated the aspect ratio. 1 MAR 2000. DWF.
           Added PRINTER keyword to return proper offset values for the
              PRINTER device, where the offset location is not rotated. 1 MAR 2000. DWF.
           Added PRINTER fudge factors to take into account that printer offsets are
              calculated from the printable area of the paper, rather than the corner
              of the paper. 8 AUG 2000. DWF.
           Changed the default margin to 0.05 from 0.15. 29 Nov 2004, DWF.
           Added EUROPEAN keyword and set LANDSCAPE mode if window wider than higher
               as the default if LANDSCAPE is not set. 13 Dec 2010. DWF.
           Added ASPECTRATIO keyword to allow user-specified window aspect ratio. 13 Dec 2010. DWF.
           Depreciated EUROPEAN keyword in favor of METRIC. 31 Jan 2011. DWF.
           Now setting LANDSCAPE=0 if aspect GT 1 and not set otherwise. 19 Feb 2013. DWF.

(See pswindow.pro)

## PS_BACKGROUND

[Previous Routine] [Next Routine] [List of Routines]

     :Description:
       Provides a device-independent way to set the background color in the PostScript device.

     :Categories:
        Graphics, Utilities

     :Params:
        color: in, required, type=string/integer, default='white'
             The color that is used for the PostScript background. A polygon of
             this color is written to the PostScript file and fills the PostScript
             "window".

     :Examples:
           IDL> PS_Background, 'rose'

     :Author:
           FANNING SOFTWARE CONSULTING::
               David W. Fanning
               1645 Sheely Drive
               Fort Collins, CO 80526 USA
               Phone: 970-221-0438
               E-mail: david@idlcoyote.com
               Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written, 17 November 2010. DWF.
            Modified to use gcColorFill so that color is done with decomposed color. 24 Dec 2010. DWF.

     :Copyright:
         Copyright (c) 2010, Fanning Software Consulting, Inc.

(See ps_background.pro)

## RANDOMNUMBERGENERATOR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           RANDOMNUMBERGENERATOR

     PURPOSE:

           Allows the user to obtain a sequence of pseudo-random numbers. The
           object maintains the random number generator seed in such a way that
           subsequent calls to GetRandomNumbers will guarentee that you don't
           get the same random numbers each time you ask for random numbers.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           Generate three random numbers.

           IDL> rng = Obj_New('RandomNumberGenerator', initialSeed)
           IDL> numberOfNumbersNeeded = 3
           IDL> randomNumbers = rng -> GetRandomNumbers(numberOfNumbersNeeded)
           IDL> Print, randomNumbers
                 0.80952855      0.35878432      0.52150406

           Generate a sequence of 8 random digits.
           IDL> Print, rng -> GetRandomDigits(8)
                 21855786

     INPUT PARAMETERS FOR INIT METHOD:

           initialSeed:    The initial seed for the random number generator. If undefined
                           or absent, the number of seconds after 1 January 1970 is used.

     METHODS:

           randomNumbers -> GetRandomNumbers(d1, d2, d3, d4 d5, d6, d7, d8)
           randomDigits = obj -> GetRandomDigits(numDigets)
           obj -> SetSeed, seed

     MODIFICATION HISTORY:

           Written by David W. Fanning, 13 November 2009.
           Added GetRandomDigits method. 7 February 2010. DWF.
           Incorrect cleanup of the seed pointer fixed in the CLEANUP procedure.
               25 February 2010, DWF.

(See randomnumbergenerator__define.pro)

## RANGEOF

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      RANGEOF

     PURPOSE:

      This function returns the range (i.e., the minimum and maximum value)
      of its argument.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Utilities

     CALLING SEQUENCE:

      range = RangeOf(variable)

     INPUTS:

      variable:     Any numeric IDL variable, except complex.

     KEYWORD PARAMETERS:

      None.

     OUTPUTS:

      range:        A two-element vector containing the minimum and maximum value
                    of the variable.

     EXAMPLE:

      x = RandomU(3L, 10) * 100
      Print, RangeOf(x)
            3.78892      98.4703

     MODIFICATION HISTORY:

      Written by: David W. Fanning, 15 February 2009.

(See rangeof.pro)

## REPMAT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           REPMAT

     PURPOSE:

           This program replicates a matrix or array in the style of
           the MATLAB RebMat command. The matrix or array is "tiled"
           in some integer number of columns and rows.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           tiledMatrix = RepMat(matrix, ncol, nrow)

     AUGUMENTS:

           matix:         The matrix or array to be tiled.

           ncol:          The number of columns in the tile.

           nrow:          The number of rows in the tile.

     RETURN_VALUE:

          tiledMatrix:    If (xdim,ydim) is the size of the original 2D matrix, then the
                          output matrix is sized (ncol*xdim, nrow*ydim).

     KEYWORDS:

         None.

     EXAMPLE:

            IDL> matrix = Reform(Indgen(6) + 1, 3, 2)
            IDL> Print, matrix, FORMAT='(3I3)'
                 1  2  3
                 4  5  6
            IDL> Print, RepMat(matrix, 3, 2), FORMAT='(9I3)'
                 1  2  3  1  2  3  1  2  3
                 4  5  6  4  5  6  4  5  6
                 1  2  3  1  2  3  1  2  3
                 4  5  6  4  5  6  4  5  6

     MODIFICATION HISTORY:

           Written by David W. Fanning, 8 May 2009.
           Algorithm significantly improved by Ronn Kling, 4 August 2009.
           Added line to handle an input matrix with a trailing 1 dimension correctly. DJ 8 March 2011.

(See repmat.pro)

## RESOLVE_OBJECT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      RESOLVE_OBJECT

     PURPOSE:

       The purpose of this function is to resolve object methods in files that have the object
       methods in the same file as the object class definition module (i.e., object__define.pro).
       It is particularly useful in restoring object methods for objects that have been saved and
       are being restored. Restored objects often do not know about their methods unless an object
       of the same object class has been previously compiled in that IDL session.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       Utilities

     CALLING SEQUENCE:

       Resolve_Object, obj_or_class

     ARGUMENTS:

      obj_or_class:   Either an IDL object or the class name of an IDL object. Required parameter.

     KEYWORDRS:

      ROUTINE_INFO:   Not strictly used by the user of the program, but this provides a mechanism by which
                      currently compiled routine names can be checked, so that object code is not being
                      recompiled unnecessarily. It is actually used internally in the code in a sort of
                      recursive approach to handling object superclasses.

     INFORMATION:

      A discussion of this routine, and of the problem the routine was written to address can
      be found here:

         http://www.idlcoyote.com/tips/saved_objects.html

     MODIFICATION HISTORY:

      Written by: David W. Fanning, August 20, 2009, and based on code written by JD Smith and
         discussed in the article above.

(See resolve_object.pro)

## REVERSE_AXES

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           REVERSE_AXES

     PURPOSE:

           The purpose of this program is to extend the SIMPLE_SURFACE
           program to demonstrate how to create reversible axes in
           object graphics.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Widgets, Object Graphics.

     CALLING SEQUENCE:

           REVERSE_AXES, data, x, y

     REQUIRED INPUTS:

           None. Fake data will be used if no data is supplied in call.

     OPTIONAL INPUTS

           data: A 2D array of surface data.

           x: A vector of X data values.

           y: A vector of Y data values.

     OPTIONAL KEYWORD PARAMETERS:

           EXACT:  Set this keyword to get exact axis scaling.

           _EXTRA: This keyword collects otherwise undefined keywords that are
            passed to the surface initialization routine.

           GROUP_LEADER: The group leader for this program. When the group leader
           is destroyed, this program will be destroyed.

           LANDSCAPE: Set this keyword if you are printing in landscape mode. The
           default is Portrait mode. The Landscape keyword on the PRINTER object
           is set, but not all printers will honor this keyword setting. If yours
           does not, set Landscape mode in the Printer Setup dialog.

           VECTOR: Set this keyword if you want vector printing (as opposed to
           the default bitmap printing).

           XTITLE: A string used as the X title of the plot.

           YTITLE: A string used as the Y title of the plot.

           ZTITLE: A string used as the Z title of the plot.

     COMMON BLOCKS:

           None.

     EXAMPLE:

           To use this program with your 2D data, type:

            IDL> Reverse_Axes, data

     MODIFICATION HISTORY:

      Written by: David Fanning, October 2001.
      Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See reverse_axes.pro)

## SAVETOMAIN

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      SAVETOMAIN

     PURPOSE:

       This is used primarily in debugging mode to save a variable to
       the main IDL level for later inspection.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

       Utilities

     CALLING SEQUENCE:

       SaveToMain, variable, nameOfVariable

     ARGUMENTS:

      variable:         The variable you wish to save at the main IDL level.

      nameOfVariable:   The name of the variable at the main IDL level. If undefined,
                        the variable will have the same name as the variable that was
                        used as the variable argument.

     KEYWORDRS:

      None.

     MODIFICATION HISTORY:

      Written by: David W. Fanning, 2 July 2009.

(See savetomain.pro)

## SCALEMODIS

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      SCALEMODIS

     PURPOSE:

      MODIS corrected reflectance images often appear drab when initially processed
      and displayed on a computer using BYTSCL. In fact, the resulting true-color
      images look nothing like the images you can find on the MODIS Rapid Response
      web page (http://rapidfire.sci.gsfc.nasa.gov/gallery/). After poking around on
      the Internet for awhile, I discovered that the Rapid Response Team doesn't use
      BYTSCL to prepare the images. Rather, they selectively scale portions of the
      reflectance image, using a piecewise scaling with different slopes. This program
      implements this Rapid Response Team algorithm.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Graphics

     CALLING SEQUENCE:

      scaledBand = ScaleModis(red, green, blue)

     ARGUMENTS:

      red:           A two-dimensional array representing the corrected reflectance
                     values of a MODIS image. This is a required parameter. If the
                     green and blue parameters are also used, this parameter will
                     represent the red band of a RGB 24-bit scaled image that is returned.

      green:         If the three parameters--red, green, and blue--are present, the returned
                     array is a 24-bit true-color image, scaled appropriately. This parameter
                     is used as the green band in such an image. The parameter is a two-dimensional
                     array of corrected reflectance values.

      blue:          If the three parameters--red, green, and blue--are present, the returned
                     array is a 24-bit true-color image, scaled appropriately. This parameter
                     is used as the blue band in such an image. The parameter is a two-dimensional
                     array of corrected reflectance values.

     KEYWORD PARAMETERS:

      RANGE:         A two-dimensional array that the input bands are first scaled into, prior to
                     the differential scaling using the MODIS Rapid Response algorithm. The default
                     input range is [-0.01, 1.10]. These values will be used to set the MIN and MAX
                     keywords for the BYTSCL command in the initial scaling of the input bands.

      CLOUD:         The MODIS Rapid Response team uses a slightly different scaling algorithm when
                     the idea is to emphasize clouds in a MODIS scene. Set this keyword to use the
                     alternate cloud scaling algorithm.

     OUTPUTS:

      scaledBand:    If a single 2D array is passed as the argument, then scaledBand is the scaled
                     2D output array. If all three arguments are passed to the program, then scaledBand
                     is a scaled 24-bit image that represents a true-color or false color representation
                     of the three input bands.

     MODIFICATION HISTORY:

      Written by: David W. Fanning, July 2009, using the IDL programs MODIS_FALSE_COLOR and
         and SCALE_IMAGE for inspiration. I found these programs on the Internet when poking
         around MODIS web pages. I suspect, but I am not sure, these programs were originally
         written by Liam Gumley.
      Minor changes to the ScaleIt function to be sure partitioning is done correctly. 5 Aug 2009. DWF.

(See scalemodis.pro)

## SCROLLWINDOW

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      SCROLLWINDOW

     PURPOSE:

      This procedure is more or less a drop-in replacement for the WINDOW
      command. The main difference is that if the requested window size
      is larger then the current display size, the window is created in a
      base widget with scroll bars so the user can scroll around
      the larger window. Use the WID keyword to pass in the window
      index number of the window you want to create (a small change
      from the WINDOW syntax). If the program can create a window with
      this window index number, it will. Otherwise, this keyword will
      return the window index number of the window that was actually
      created.

      I use ScrollWindow to create windows that I can view both on
      my large monitor at work and on my smaller laptop monitor when
      I travel.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Graphics

     CALLING SEQUENCE:

      ScrollWindow, xsize, ysize

     ARGUMENTS:

      xsize:       The x size of the graphics window. By default, 640.

      ysize:       The y size of the graphics window. By default, 512.

     KEYWORD PARAMETERS:

      FREE:        Get a window with a free or unused window index number.
                   This is *always* done with a scrollable window. The window
                   index number of the window is returned in the WID keyword.

      PIXMAP:      Set to create a pixmap window. In this case, no scrollable
                   window is possible. A normal IDL graphics window is
                   always created.

      SIZEFRAC:    Make the window this fraction of the screen dimensions.
                   A number between 0.0 and 1.0

      TITLE:       The title string that is displayed on the window.

      WID:         The window index number. If supplied as an IDL variable,
                   this can be both an input and an output keyword. If a
                   window with this window index number can be created, it
                   is. Otherwise, this varible upon exit from the program
                   contains the window index number of the graphics window
                   that was created.

      XPOS:        The x offset of the upper-left corner of the window.

      XSIZE:       The same as the xsize argument. Provided so ScrollWindow
                   can be a drop-in replacement for the Window command.

      YPOS:        The y offset of the upper-left corner of the window.

      YSIZE:       The same as the ysize argument. Provided so ScrollWindow
                   can be a drop-in replacement for the Window command.

     EXAMPLE:

      ScrollWindow, XSIZE=800, YSIZE=400   ; Produces normal IDL graphics window.
      ScrollWindow, XSIZE=1800, YSIZE=1200 ; Produces a scrollable graphics window.

     MODIFICATION HISTORY:

      Written by: David W. Fanning, 25 March 2009
      Added SIZEFRACTION keyword, Mats Löfdahl, 25 November 2012.

(See scrollwindow.pro)

## SDEVSCL

[Previous Routine] [Next Routine] [List of Routines]

     This is a utility routine to perform standard deviation scaling
     on image arrays. The user defines a multiple of the standard
     deviation and this is used with the standard deviation of the
     pixels in the image to create a threshold for linear scaling.
     Use the EXCLUDE keyword to exclude a particular value from
     the standard deviation calculation.

     :Categories:
        Utilities, Graphics

     :Params:
         image: in, required, type=numeric
            The image array that is to be scaled.

     :Keywords:
         exclude: in, optional, type=numeric
             Set this keyword to a value in the image array that is to be excluded from the
             standard deviation calculation. Normally, this would be the backgroud value of
             the image, if there is a background.
         multiplier: in, optional, type=float, default=2.0
            The standard deviation of the image pixels is computed and then
            multiplied by the multiplier factor to produce upper and lower
            thresholds for the linear scaling of the image by subtracting
            or adding this value to the mean value of the image. The image
            is linearly scaled between these two threshold values.
         negative: in, optional, type=boolean
              Set this keyword to return the "negative" or reverse of the image scaling.
         omax: in, optional, type=byte, default=255
              Normally, the image is scaled into the range of 0 to 255. Setting the
              OMIN and OMAX keywords can change this scaling.
         omin: in, optional, type=byte, default=0
              Normally, the image is scaled into the range of 0 to 255. Setting the
              OMIN and OMAX keywords can change this scaling.
         threshold: out, optional, type=float
              A two-element array that contains the minimum and maximum thresholds, respectively,
              that were calculated for the scaling.

     :Examples:
         To display an image with standard deviation scaling::
            image = cgDemoData(5)
            cgDisplay, 256*3, 256
            !P.Multi = [0,3,1]
            cgImage, image
            cgImage, SDevScl(image)
            cgImage, SDevScl(image, Exclude=0)
            !P.Multi = 0

     :Author:
         FANNING SOFTWARE CONSULTING::
            David W. Fanning
            1645 Sheely Drive
            Fort Collins, CO 80526 USA
            Phone: 970-221-0438
            E-mail: david@idlcoyote.com
            Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written by: David W. Fanning, 5 June 2012.

     :Copyright:
         Copyright (c) 2012, Fanning Software Consulting, Inc.

(See sdevscl.pro)

## SELECT_OBJECTS

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           SELECT_OBJECTS

     PURPOSE:
           The purpose of this program is to demonstrate how to select
           and move objects in an object graphics window. Once the objects
           appear in the window, use your mouse to select the objects and
           move them in the window. The window is resizeable.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           Object Graphics.

     CALLING SEQUENCE:
           SELECT_OBJECTS

     REQUIRED INPUTS:
           None.

     KEYWORD PARAMETERS:
           None.

     COMMON BLOCKS:
           None.

     SIDE EFFECTS:
           None.

     RESTRICTIONS:
           Requires VCOLORBAR from the Coyote Library:
               http://www.idlcoyote.com/programs/vcolorbar__define.pro.

     EXAMPLE:
           Select_Objects

     MODIFICATION HISTORY:
           Written by David Fanning, 21 September 98.
           Added the ability to shrink and expand the objects. 27 Sept 98. DWF.
           Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See select_objects.pro)

## SETDEFAULTVALUE

[Previous Routine] [Next Routine] [List of Routines]

     This procedure sets default values for positional and keyword arguments to
     IDL procedures and functions.

     :Categories:
        Utilities

     :Params:
        argument: in, required
             The augument variable you are setting the default value of. If this variable
             is undefined, the `defaultValue` will be assigned to it. Otherwise, the argument
             variable will not change.
        defaultvalue: in, required
             The default value that will be assigned to the argument variable ONLY if the argument
             variable is undefined. If this variable is undefined, the argument variable will
             be treated as if the BOOLEAN keyword had been set.

     :Keywords:
        boolean: in, optional, type=integer
             If this keyword is set, the argument value will always be forced to return with a
             value of 0 or 1.

     :Examples:
        Here is how to use this program::

          FUNCTION Action, arg1, arg2, MULTIPLY=multiply

             SetDefaultValue, arg1, 1
             SetDefaultValue, arg2, 2
             SetDefaultValue, multiply, 1, /BOOLEAN

             IF multiply THEN RETURN, arg1 * arg2 ELSE RETURN, arg1 + arg2

          END

     :Author:
        FANNING SOFTWARE CONSULTING::
           David W. Fanning
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written by: David W. Fanning, November 26, 2008, from suggestion by Carsten Lechte on
               IDL newsgroup on this date.
            Made a change to the way the BOOLEAN keyword works. Now argument is set to BOOLEAN before
               return, if required. 3 Dec 2008. DWF.

     :Copyright:
         Copyright (c) 2008-2014, Fanning Software Consulting, Inc.

(See setdefaultvalue.pro)

## SHARPEN

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           Sharpen

     PURPOSE:

            This function sharpens an image using a Laplacian kernel.
            The final result is color adjusted to match the histogram
            of the input image.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Image Processing

     CALLING SEQUENCE:

           sharp_image = Sharpen(image)

     INPUTS:

           image - The input image to be sharpened. Assumed to be a 2D byte array.

     OUTPUTS:

           sharp_image - The sharpened image.

     INPUT KEYWORDS:

           KERNEL -- By default the image is convolved with this 3-by-3 Laplacian kernel:
               [ [-1, -1, -1], [-1, +8, -1], [-1, -1, -1] ].  You can pass in any  kernel
               of odd width. The filtered image is added back to the original image to provide
               the sharpening effect.

           DISPLAY -- If this keyword is set a window is opened and the details of the sharpening
               process are displayed.

     OUTPUT KEYWORDS:

           None.

     DEPENDENCIES:

           None.

     METHOD:

           This function is based on the Laplacian kernel sharpening method on pages 128-131
           of Digital Image Processing, 2nd Edition, Rafael C. Gonzalez and Richard E. Woods,
           ISBN 0-20-118075-8.

     EXAMPLE:

           There is an example program at the end of this file.

     MODIFICATION HISTORY:

           Written by David W. Fanning, January 2003.
           Updated slightly to use Coyote Library routines. 3 Dec. 2010. DWF.
           Modified the example to work with cgImage. 29 March 2011. DWF.

(See sharpen.pro)

## SORT_ND

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           SORT_ND

     PURPOSE:

           Efficiently perform an N-dimensional sort along any dimension
           of an array.

     CALLING SEQUENCE:

           inds=sort_nd(array,dimension)

     INPUTS:

           array: An array of at least 2 dimensions to sort.

           dimension: The dimension along which to sort, starting at 1
              (1:rows, 2:columns, ...).

     OUTPUTS:

           inds: An index array with the same dimensions as the input
              array, containing the (1D) sorted indices.  Can be used
              directly to index the arary (ala SORT).

     EXAMPLE:

           a=randomu(sd,5,4,3,2)
           sorted=a[sort_nd(a,2)]

     SEE ALSO:

           HISTOGRAM

     MODIFICATION HISTORY:

           Tue Aug 22 15:51:12 2006, J.D. Smith

       Written, based on discussion on c.l.i-p, 08/2006.

(See sort_nd.pro)

## STATIONPLOT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           STATIONPLOT

     PURPOSE:

           This is routine for drawing station plots on a map or other display.
           Normally, this routine is used in conjunction with WINDBARB.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics.

     CALLING SEQUENCE:

           StationPlot, x, y

     REQUIRED INPUTS:

           x:            The X location of the center of the station plot, expressed in data coordinates.

           y:            The Y location of the center of the station plot, expressed in data coordinates.

     KEYWORDS:

          COLOR:         The name of the color to draw the station plot in. May be a vector
                         the same length as X. Colors are those available in cgColor.

          RADIUS:        The radius of the station plot circle in normalized coordinates.

     RESTRICTIONS:

           Requires cgColor from the Coyote Library:

               http://www.idlcoyote.com/programs/cgColor.pro

     EXAMPLE:

       seed = -3L
       lon = Randomu(seed, 20) * 360 - 180
       lat = Randomu(seed, 20) * 180 - 90
       speed = Randomu(seed, 20) * 100
       direction = Randomu(seed, 20) * 180 + 90
       Erase, cgColor('Ivory', !P.Background)
       Map_Set, /Cylindrical,Position=[0.1, 0.1, 0.9, 0.9], Color=cgColor('Steel Blue'), /NoErase
       Map_Grid, Color=cgColor('Charcoal', !D.Table_Size-2)
       Map_Continents, Color=cgColor('Sea Green', !D.Table_Size-3)
       StationPlot, lon, lat, Color='Indian Red'

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 20 May 2003, based on TVCircle from the
           NASA Astonomy Library.
           Added THICK keyword. 23 February 2005. DWF.

(See stationplot.pro)

## STR_SIZE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      STR_SIZE

     PURPOSE:

      The purpose of this function is to return the proper
      character size to make a specified string a specifed
      width in a window. The width is specified in normalized
      coordinates. The function is extremely useful for sizing
      strings and labels in resizeable graphics windows.

     AUTHOR:

       FANNING SOFTWARE CONSULTING
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: david@idlcoyote.com
       Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

      Graphics Programs, Widgets.

     CALLING SEQUENCE:

      thisCharSize = STR_SIZE(thisSting, targetWidth)

     INPUTS:

      thisString:  This is the string that you want to make a specifed
         target size or width.

     OPTIONAL INPUTS:

      targetWidth:  This is the target width of the string in normalized
         coordinates in the current graphics window. The character
         size of the string (returned as thisCharSize) will be
         calculated to get the string width as close as possible to
         the target width. The default is 0.25.

     KEYWORD PARAMETERS:

      INITSIZE:  This is the initial size of the string. Default is 1.0.

      STEP:   This is the amount the string size will change in each step
         of the interative process of calculating the string size.
         The default value is 0.05.

      XPOS:   X position of the output test string. This can be
         used on the Postscript device, where no pixmap windows are
         available and where therefore the test strings would appear on
         the printable area. Default is 0.5 on most devices. If !D.NAME
         is PS, the default is 2.0 to draw the test string out of the
         drawable window area.

      YPOS:   Y position of the output test string. This can be
         used on the Postscript device, where no pixmap windows are
         available and where therefore the test strings would appear on
         the printable area. Default is 0.5 on most devices. If !D.NAME
         is PS, the default is 2.0 to draw the test string out of the
         drawable window area.

     OUTPUTS:

      thisCharSize:  This is the size the specified string should be set
         to if you want to produce output of the specified target
         width. The value is in standard character size units where
         1.0 is the standard character size.

     EXAMPLE:

      To make the string "Happy Holidays" take up 30% of the width of
      the current graphics window, type this:

          XYOUTS, 0.5, 0.5, ALIGN=0.5, "Happy Holidays", $
            CHARSIZE=STR_SIZE("Happy Holidays", 0.3)

     MODIFICATION HISTORY:

      Written by: David Fanning, 17 DEC 96.
      Added a scaling factor to take into account the aspect ratio
         of the window in determing the character size. 28 Oct 97. DWF
      Added check to be sure hardware fonts are not selected. 29 April 2000. DWF.
      Added a pixmap to get proper scaling in skinny windows. 16 May 2000. DWF.
      Forgot I can't do pixmaps in all devices. :-( Fixed. 7 Aug 2000. DWF.
      Added support of PostScript at behest of Benjamin Hornberger. 11 November 2004. DWF.
      Cleaned up the code a bit. 28 Feb 2011. DWF.
      Fixed non-square window algorithm to reflect my original intentions. 10 June 2011.

(See str_size.pro)

## TEXTBOX

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
      TEXTBOX

     PURPOSE:

      This function allows the user to type some text in a
      pop-up dialog widget and have it returned to the program.
      This is an example of a Pop-Up Dialog Widget.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

      Utility, Widgets

     CALLING SEQUENCE:

      thetext = TextBox()

     INPUTS:

      None.

     KEYWORD PARAMETERS:

      CANCEL: An output parameter. If the user kills the widget or clicks the Cancel
           button this keyword is set to 1. It is set to 0 otherwise. It
           allows you to determine if the user canceled the dialog without
           having to check the validity of the answer.

           theText = TextBox(Title='Provide Phone Number...', Label='Number:', Cancel=cancelled)
           IF cancelled THEN Return

      GROUP_LEADER: The widget ID of the group leader of this pop-up
           dialog. This should be provided if you are calling
           the program from within a widget program:

              thetext = TextBox(Group_Leader=event.top)

           If a group leader is not provided, an unmapped top-level base widget
           will be created as a group leader.

      LABEL: A string the appears to the left of the text box.

      TITLE:  The title of the top-level base. If not specified, the
           string 'Provide Input:' is used by default.

      VALUE: A string variable that is the intial value of the textbox. By default, a null string.

      XSIZE: The size of the text widget in pixel units. By default, 200.

     OUTPUTS:

      theText: The string of characters the user typed in the
           text widget. No error checking is done.

     RESTRICTIONS:

      The widget is destroyed if the user clicks on either button or
      if they hit a carriage return (CR) in the text widget. The
      text is recorded if the user hits the ACCEPT button or hits
      a CR in the text widget.

     MODIFICATION HISTORY:

      Written by: David W. Fanning, December 20, 2001.
      Added VALUE keyword to set the initial value of the text box. 4 Nov 2002. DWF.

(See textbox.pro)

## TEXTLINEFORMAT

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TextLineFormat

     PURPOSE:

           This is a utility program for taking a line of text and shortening
           it to a defined maximum length. The result of the function is a string
           array in which no line of text in the string array is longer than the maximum
           length. The text is broken into "words" by white space. The algorithm is
           modified slightly if there are LF (line feeds) in the text, or if any single
           word in the text is too large to fit on a line.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           formattedText = TextLineFormat(theText)

     INPUTS:

           theText:   The line of text that is to be formatted.

     KEYWORDS:

           LENGTH:    The maximum line length allowed in the resulting text array.
                      Set to 60 characters by default. Lines greater than length
                      can be permitted if Line Feeds (ASCII 10B) are found
                      in the text or single words are too large to fit on a line.

     MODIFICATION HISTORY:

           Written by David Fanning, June 2005.
           Fixed a small problem with cumulative total not counting spaces between
              words. Changed the default size to 60. DWF. 18 August 2005.
           Added check for LF in text to accommodate reading netCDF file attributes.
               If LF are present, I break on these, and return. 15 Feb 2008. DWF.
           Better handling of lines with no white space in them for breaking. 23 March 2009. DWF.

(See textlineformat.pro)

## TEXTURE_SURFACE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TEXTURE_SURFACE

     PURPOSE:

           The purpose of this program is to demonstrate how to
           create a simple surface plot with an image applied as
           a texture in object graphics.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Widgets, Object Graphics.

     CALLING SEQUENCE:

           TEXTURE_SURFACE, data, x, y, Image=image

     REQUIRED INPUTS:

           None. Fake data will be used if no data is supplied in call.

     OPTIONAL INPUTS

           data: A 2D array of surface data.

           x: A vector of X data values.

           y: A vector of Y data values.

     OPTIONAL KEYWORD PARAMETERS:

           BORDERCOLOR : A three element array [R, G, B] describing the color
           used to draw the non-textured part of the surface if POSITION is
           specified.

           COLORTABLE: The number of an IDL color table to use for the image
           texture. Used only if the supplied image is 2D. Ignored otherwise.

           EXACT:  Set this keyword to get exact axis scaling.

           _EXTRA: This keyword collects otherwise undefined keywords that are
            passed to the surface initialization routine.

           GROUP_LEADER: The group leader for this program. When the group leader
           is destroyed, this program will be destroyed.

           IMAGE: An 8-bit or 24-bit image you wish to use for the image texture.

           LANDSCAPE: Set this keyword if you are printing in landscape mode. The
           default is Portrait mode. The Landscape keyword on the PRINTER object
           is set, but not all printers will honor this keyword setting. If yours
           does not, set Landscape mode in the Printer Setup dialog.

           POSITION: A four element array of the form [x1, y1, x2, y2] that will
           position the image with its lower-left corner at (x1,y1) and its upper-
           right corner at (x2,y2) in the device coordinate system of the surface.
           In other words, if my surface is a 41 by 41 array, and I want the image
           positioned with lower-left at (5,10) and upper-right at (25,18), then
           I call the program like this: Texture_Surface, Position=[5, 10, 25, 18].

           VECTOR: Set this keyword if you want vector printing (as opposed to
           the default bitmap printing).

           XTITLE: A string used as the X title of the plot.

           YTITLE: A string used as the Y title of the plot.

           ZSCALE: A number larger than or equal to 0.001 and less than or equal to 1.0 that affects Z scaling.

           ZTITLE: A string used as the Z title of the plot.

     COMMON BLOCKS:

           None.

     EXAMPLE:

           To use this program with your surface data and 2D image, type:

            IDL> data = cgDemoData(2)
            IDL> image = cgDemoData(7)
            IDL> Texture_Surface, data, Image=image, Colortable=33

     RESTRICTIONS:

            Requires the ASPECT program from the Coyote Library:

               http://www.idlcoyote.com/programs/aspect.pro

     MODIFICATION HISTORY

           Written by David W. Fanning, 1 Nov 2001, from previous Simple_Surface code.
           Modifications suggested by Karl Shultz added to allow surface color
              specification and improved resolution about image edges when
              positioning images. BORDERCOLOR keyword added. DWF. 4 Nov 2001.
           The surface now maintains the same X/Y aspect ratio as the surface data. DWF. 8 April 2002.
           Added ZSCALE keyword. DWF. 8 April 2002.
           Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See texture_surface.pro)

## TRANSFORM_VOLUME

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           TRANSFORM_VOLUME

     PURPOSE:

           The purpose of this program is to transform (e.g., rotate,
           scale, and translate) a 3D array or volume.

     AUTHOR:

           Martin Downing,
           Clinical Research Physicist,
           Grampian Orthopaedic RSA Research Centre,
           Woodend Hospital, Aberdeen, AB15 6LS.
           Pnone: 01224 556055 / 07903901612
           Fa: 01224 556662
           E-mail: m.downing@abdn.ac.uk

     CATEGORY:

          Mathematics, graphics.

     CALLING SEQUENCE:

          result = TRANSFORM_VOLUME( volume )

     INPUTS:

           volume:    The 3D array or volume to be transformed.

     OPTIONAL KEYWORDS:

          BUFFER_SIZE: To reduce memory overhead the routine processes the job in chunks, the number
             of elements of which can be set using the BUFFER_SIZE keyword, set this keyword to
             0 to force the whole array to be processed at one time. The default value is 128.

          MISSING: The value to return for transformed values outside the bounds of
             the volume. (Passed to the INTERPOLATE function.) Default is 0.

          T3DMAT: The homogeneous transforamtion matrix. If this keyword is not present,
             the following keywords can be used to create a homogeneous transformation matrix:

             ROTATION - The rotation vector [rx,ry,rz]. The order of rotation is ZYX.
             TRANSLATE - The translation vector [tx,ty,tz].
             SCALE - The scale vector [sx,sy,sz].
             CENTRE_ROTATION - The centre of rotation [cx,cy,cz].

     OUTPUTS:

           result:    The transformed array or volume.

     COMMON BLOCKS:

           None.

     DEPENDENCIES:

           The program uses the library INTERPLOLATE routine, which currently (IDL 5.4)
           uses linear interpolation. Note that the operation is performed in chunks,
           each of which is independant of the result of the others, so the operation
           could easiliy be parallelised.

     MODIFICATION HISTORY:

           Written by: Martin Downing, 16 September 2001.
           Added MISSING keyword. Removed INPLACE keyword. 25 Nov 2001. MD

(See transform_volume.pro)

## UNDEFINE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           UNDEFINE

     PURPOSE:
           The purpose of this program is to delete or undefine
           an IDL program variable from within an IDL program or
           at the IDL command line. It is a more powerful DELVAR.
           Pointer and structure variables are traversed recursively
           to undefine any variables pointed to in the pointer or in
           a structure dereference.

     AUTHOR:
           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1642 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:
           Utilities.

     CALLING SEQUENCE:
           UNDEFINE, variable

     REQUIRED INPUTS:
           variable: The variable to be deleted. Up to 10 variables may be specified as arguments.

     SIDE EFFECTS:
           The variable no longer exists.

     EXAMPLE:
           To delete the variable "info", type:

            IDL> Undefine, info

            IDL> var = ptr_new({a:ptr_New(5), b:findgen(11), c: {d:ptr_New(10), f:findgen(11)}})
            IDL> Help, /Heap
            Heap Variables:
                # Pointer: 3
                # Object : 0
               LONG      =            5
               LONG      =            10
               STRUCT    = ->  Array[1]

            IDL> Undefine, var
            IDL> Help, /Heap
            Heap Variables:
                # Pointer: 0
                # Object : 0
            IDL> Help, var
             VAR               UNDEFINED =

     MODIFICATION HISTORY:
           Written by David W. Fanning, 8 June 97, from an original program
           given to me by Andrew Cool, DSTO, Adelaide, Australia.
           Simplified program so you can pass it an undefined variable. :-) 17 May 2000. DWF
           Simplified it even more by removing the unnecessary SIZE function. 28 June 2002. DWF.
           Added capability to delete up to 10 variables at suggestion of Craig Markwardt. 10 Jan 2008. DWF.
           If the variable is a pointer, object or structure reference the variable is recursively traversed
              to free up all variables pointed to before the variable is itself destroyed. 10 June 2009. DWF.
           Updated to allow undefining of pointer arrays. 8 October 2009. DWF.
           Valid pointers that point to undefined variable can cause an infinite loop. Now using
               Heap_Free, rather than recursion, with pointers. 30 May 2013. DWF.

(See undefine.pro)

## VCOLORBAR

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           VCOLORBAR

     FILENAME:

           vcolorbar__define.pro

     PURPOSE:

           The purpose of this program is to create a vertical
           colorbar object to be used in conjunction with other
           IDL 5 graphics objects.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com/

     CATEGORY:

           IDL Object Graphics.

     CALLING SEQUENCE:

           thisColorBar = Obj_New('VColorBar')

     REQUIRED INPUTS:

           None.

     INIT METHOD KEYWORD PARAMETERS:

           COLOR: A three-element array representing the RGB values of a color
              for the colorbar axes and annotation. The default value is
              white: [255,255,255].

           NAME: The name associated with this object.

           NCOLORS: The number of colors associated with the colorbar. The
              default is 256.

           MAJOR: The number of major tick divisions on the colorbar axes.
              The default is 5.

           MINOR: The number of minor tick marks on the colorbar axes.
              The default is 4.

           PALETTE: A palette object for the colorbar. The default palette
               is a gray-scale palette object.

           POSITION: A four-element array specifying the position of the
               colorbar in the arbitary coordinate system of the viewplane
               rectangle. The default position is [0.90, 0.10, 0.95, 0.90].

           RANGE: The range associated with the colorbar axis. The default
               is [0, NCOLORS].

           TITLE: A string containing a title for the colorbar axis
               annotation. The default is a null string.

     OTHER METHODS:

           Clamp (Procedure): Given a two-element array in the data range of
              the colorbar, the colorbar image is clamped to this range. In
              other words, the range of colors is clamped to the specified
              range. Values above or below the range in the colorbar are set to
              the minimum and maximum range values, respectively.

           GetProperty (Procedure): Returns colorbar properties in keyword
              parameters as defined for the INIT method. Keywords allowed are:

                   COLOR
                   MAJOR
                   MINOR
                   NAME
                   PALETTE
                   POSITION
                   RANGE
                   TITLE
                   TRANSFORM

           SetProperty (Procedure): Sets colorbar properties in keyword
              parameters as defined for the INIT method. Keywords allowed are:

                   COLOR
                   NAME
                   MAJOR
                   MINOR
                   PALETTE
                   POSITION
                   RANGE
                   TITLE
                   TRANSFORM

     SIDE EFFECTS:

           A VCOLORBAR object is created. The colorbar INHERITS IDLgrMODEL.
           Thus, all IDLgrMODEL methods and keywords can also be used. It is
           the model that is selected in a selection event, since the SELECT_TARGET
           keyword is set for the model.

     EXAMPLE:

           To create a colorbar object and add it to a plot view object, type:

           thisColorBarObject = Obj_New('VColorBar')
           plotView->Add, thisColorBarObject
           plotWindow->Draw, plotView

     MODIFICATION HISTORY:

           Written by David W. Fanning, 19 June 97.
           Changed the optional "colorbarmodel" parameter to an
               optional GETMODEL parameter. 26 June 97. DWF.
           Fixed bug in the way the color palette was assigned. 13 Aug 97. DWF.
           Added missing container object to self structure. 13 Aug 97. DWF.
           Removed image model, which was a workaround for
               broken 5.0 objects. 5 Oct 97. DWF
           Fixed cleanup procedure to clean up ALL objects. 12 Feb 98. DWF.
           Changed IDLgrContainer to IDL_Container to fix 5.1 problems. 20 May 98. DWF.
           Modified colorbar to INHERIT an IDLgrModel object. This allows me to
               add the colorbar to other models directly. 20 Sept 98. DWF.
           Added NAME keyword to give the colorbar a name. 20 Sept 98. DWF.
           Changed a reference to _Ref_Extra to _Extra. 27 Sept 98. DWF.
           Fixed bug when adding a text object via the TEXT keyword. 9 May 99. DWF.
           Fixed a bug with getting the text object via the TEXT keyword. 16 Aug 2000. DWF.
           Added the TRANSFORM keyword to GetProperty and SetProperty methods. 16 Aug 2000. DWF.
           Added RECOMPUTE_DIMENSIONS=2 to text objects. 16 Aug 2000. DWF.
           Added a polygon object around the image object. This allows rotation in 3D space. 16 Aug 2000. DWF.
           Removed TEXT keyword (which was never used) and fixed TITLE keyword. 8 Dec 2000. DWF.
           Added ENABLE_FORMATTING keyword to title objects. 22 October 2001. DWF.
           Added a CLAMP method. 18 November 2001. DWF.
           Forgot to pass extra keywords along to the text widget. As a result, you couldn't
              format tick labels, etc. Fixed this. Any keywords appropriate for IDLgrTick objects
              are now available. 26 June 2002. DWF.
           Fixed a problem with POSITION keyword in SetProperty method. 23 May 2003. DWF.
           Removed NORMALIZE from source code. 29 Nov 2005. DWF.
           Font sizes have changed. Now using a 12 point font. 6 May 2011. DWF.
           Changed FSC_Normalize to cgNormalize to reflect new name. 6 Feb 2013. DWF.

(See vcolorbar__define.pro)

## WINDBARB

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           WINDBARB

     PURPOSE:

           This is routine for drawing wind barbs on a map.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Graphics.

     CALLING SEQUENCE:

           Windbarb, x, y, speed, direction

     REQUIRED INPUTS:

           x:            The X location of the wind barb, expressed in data coordinates.
                         Positive X is pointing in EAST direction.

           y:            The Y location of the wind barb, expressed in data coordinates.
                         Positive Y is pointing in NORTH direction.

           speed:        The wind speed, expressed in knots.

           direction:    The wind direction in degrees clockwise from north. Winds from
                         the NE come at 45 degrees, and the wind "arrow" points in the
                         direction from which the window is blowing. (The wind arrow
                         points in the direction of the station circle, with the "barbs"
                         of the arrow at the end of the arrow from which the wind is coming.)

     KEYWORDS:

          ASPECT:        The aspect ratio of the map or plot in the display window.

          CLIP:          A four-element array in normalized coordinates [x0,y0,x1,y1] giving
                         the lower-left and upper-right corner of a cliping rectangle. This
                         is normally the extent of your plot. See the example below.

          COLOR:         The name of the color to draw the wind barbs in. May be a vector
                         the same length as X.

          LENGTH:        The approximate length of the wind barb in normalized coordinates.
                         Will be set to 0.066 of the plot distance in the X direction by default.

          MAP_ROTATION:  The clockwise rotation in degrees of the map North from the
                         top of the plot. Will be set to 0.0 by default.

          SOUTHERN_HEMISPHERE: Windbarb "feathers" are traditionally drawn in the clockwise
                         direction in the northern hemispere and countercolockwise in the
                         southern hemisphere. Default is "northern" type feathers. Set this
                         keyword to select "southern" type feathers.

          STATION:       Set this keyword if you want to draw the wind barbs with station symbols.
                         (Requires STATIONPLOT from the Coyote Library.)

     RESTRICTIONS:

           Requires cgColor and STATIONPLOT from the Coyote Library:

               http://www.idlcoyote.com/programs/cgColor.pro
               http://www.idlcoyote.com/programs/stationplot.pro

     EXAMPLE:

        Window, Title='Wind Barbs', /Free
        seed = -3L
        lon = Randomu(seed, 9) * 360 - 180
        lat = Randomu(seed, 9) * 180 - 90
        speed = Randomu(seed, 9) * 100 + 5.0
        direction = Indgen(9)*45
        Erase, Color=cgColor('Ivory', !P.Background)
        Polyfill,[0.1, 0.1, 0.9, 0.9, 0.1], [0.1, 0.9, 0.9, 0.1, 0.1], /Normal, Color=cgColor('light gray')
        Map_Set, /Cylindrical, Position=[0.1, 0.1, 0.9, 0.9], Color=cgColor('Steel Blue'), /NoErase
        Map_Grid, Color=cgColor('Charcoal', !D.Table_Size-2)
        Map_Continents, Color=cgColor('Sea Green', !D.Table_Size-3)
        Windbarb, lon, lat, speed, direction, /Station, Color='Indian Red', /Southern_Hemisphere

        To clip the windbards that fall outside the plot, substitute these two lines
        for the last line in the example above:

        clip = [0.1, 0.1, 0.9, 0.9]
        Windbarb, lon, lat, speed, direction, /Station, Color='Indian Red', Clip=clip

     MODIFICATION HISTORY:

           Written by:  David W. Fanning, 20 May 2003.
           It has been called to my attention that the wind barbs are pointing
             in *exactly* the wrong direction. Sigh... Rotated by 180 degrees. DWF. 8 June 2004.
           Now someone complains that the *corrected* version is off by 180 degrees! Sheesh!
             Clearly, I'm no meteorologist. Both lines of code are in the file. Please use the one
             you like the best. :-) (Line 177-178) 20 July 2004. DWF.
           Added a CLIP keyword so you can clip the output to the extend of your graphics plot. 12 Nov 2004. DWF.
           Added THICK keyword 23 February 2005. DWF.
           After further research, I've reverted to the direction specified originally.
           And I have changed the "feathers" to point clockwise normally, and counterdlockwise
             if the SOUTHERN_HEMISPHERE keyword is set. Here are my sources (21 July 2005. DWF):

                http://ww2010.atmos.uiuc.edu/(Gh)/guides/maps/sfcobs/wnd.rxml
                http://www.al.noaa.gov/WWWHD/pubdocs/windbarb.html
          Fixed a small CLIP problem. 21 July 2005. DWF.

(See windbarb.pro)

## WINDOWAVAILABLE

[Previous Routine] [Next Routine] [List of Routines]

     NAME:
           WindowAvailable

     PURPOSE:

           This function returns a 1 if the specified window index number is
           currently open or available. It returns a 0 if the window is currently
           closed or unavailable.

     AUTHOR:

           FANNING SOFTWARE CONSULTING
           David Fanning, Ph.D.
           1645 Sheely Drive
           Fort Collins, CO 80526 USA
           Phone: 970-221-0438
           E-mail: david@idlcoyote.com
           Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     CATEGORY:

           Utilities

     CALLING SEQUENCE:

           available = WindowAvaiable(windowIndexNumber)

     INPUTS:

           windowIndexNumber:   The window index number of the window you wish to
                                know is available or not.

     KEYWORDS:

           None.

     NOTES:

           The window vector obtained from the DEVICE command is not always the same length. It
           is normally (on my machine) 65 elements long, but can be much longer if you have lots
           of IDL windows open (by calling cgPickColorName, for example). But if no windows with
           index numbers greater than 65 are open, IDL shinks the larger vector to the smaller one
           as part of its housekeeping operations, which means it happens on their timetable, not yours.
           This can result in the user having "stale" index numbers greater than 65, but no larger vector
           to check them against. I have modified the code to return a 0 in this case, assuming that
           whatever window your index number points to is long gone. I have not experience any ill effects
           by doing this, but I STRONGLY advice you to ALWAYS know what window you are drawing into
           when you issue a graphics command.

     MODIFICATION HISTORY:

           Written by David W. Fanning, June 2005.
           Modified to return 0 if the window index number is larger than the number of elements
                 in the WINDOW_STATE array. 25 June 2008. DWF.

(See windowavailable.pro)

## WINDOWIMAGE

[Previous Routine] [List of Routines]

     :Description:
       Allows the user to interactively adjust image contrast by means of "windowing and
       leveling" the image. Move the cursor vertically in the window to adjust the image
       stretch "window". Move the cursor horizontally in the window to adjust the image
       "level".

     :Categories:
        Graphics

     :Params:
        image: in, required, type=any
             Any 2D array that you wish to adjust the contrast of.

     :Keywords:
         brewer: in, optional, type=boolean, default=0
             Set this keyword to indicate a Brewer color table is desired.
         colortable: in, optional, type=integer, default=0
              The index number of a color table to load with cgLoadCT.
         neutralcolor: in, optional, type=string
             The name of the color to use for values outside the image "window" in
             the color table. If a default grayscale color table is loaded, the default
             color is "rose", otherwise the default is "black".
         reverse: in, optional, type=boolean, default=0
             Set this keyword if you wish to reverse the color table.

     :Examples:
        To see a demonstation::
           IDL> WindowImage

     :Author:
           FANNING SOFTWARE CONSULTING::
               David W. Fanning
               1645 Sheely Drive
               Fort Collins, CO 80526 USA
               Phone: 970-221-0438
               E-mail: david@idlcoyote.com
               Coyote's Guide to IDL Programming: http://www.idlcoyote.com

     :History:
         Change History::
            Written, 29 November 2010. DWF.
            Added color protection to the program. 30 Nov 2010. DWF.
            Modification of cgImage command to prevent flashing. 27 Feb 2011. DWF.

     :Copyright:
         Copyright (c) 2010, Fanning Software Consulting, Inc.

(See windowimage.pro)