# What's New in IDL 8.4

Note: If you are new to IDL or upgrading from an older version, see also:

- What's New in IDL 8.3
- What's New in IDL 8.2.3
- What's New in IDL 8.2.2
- What's New in IDL 8.2.1
- What's New in IDL 8.2
- What's New in IDL 8.1
- What's New in IDL 8.0

## New Features

### ALOG2 Function

The ALOG2 function computes the logarithm base-2 of the input variable.

### BigInteger Class

The BigInteger class allows you to create and manipulate integer numbers of any size. You can use BigIntegers in mathematical expressions in combination with other BigIntegers or regular numbers. The BigInteger class also has numerous methods for exploring the properties of your BigInteger numbers. For example:

b = BigInteger(2)^1279 - 1

HELP, b

PRINT, '2^1279 - 1 is prime?', b.IsPrime() ? 'true' : 'false'

c = b.NextPrime()

PRINT, 'next prime is ', c - b, ' greater'

IDL prints:

B BIGINTEGER <ID=1 LENGTH=1279 bits> = 1.0407932194664400...x10^385

2^1279 - 1 is prime? true

next prime is 2056 greater

For more examples see the BigInteger class.

### BOOLEAN Variables

You can now create BOOLEAN variables which only contain the values 0 (false) or 1 (true). Boolean variables are actually variables of type BYTE with a special boolean flag. Because they are type BYTE, boolean variables can be used anywhere that a byte variable is used.

There are also two new system variables, !TRUE and !FALSE, which are boolean variables with the value 1 and 0, respectively.

The boolean flag is used when printing out HELP information, when modifying elements within a boolean array, and when converting to and from JSON. For example:

a = [0.0, 1.0, 0.0, 3.0]

b = BOOLEAN(a)

b[2] = "yes" ; equal to "true"

HELP, b

PRINT, b

PRINT, JSON_SERIALIZE(b)

IDL prints:

B BOOLEAN = Array[4]

0 1 1 1

[false,true,true,true]

For more information, see the BOOLEAN and BOOLARR functions.

### Code Coverage

You can now analyze the code coverage for your applications using the CODE_COVERAGE function. The function returns the line numbers of code that were executed and not executed for your given routine. In addition, the Code Coverage feature has been integrated into the Workbench. You can turn on Code Coverage highlighting for Editors, as well as display Code Coverage statistics in the Profiler View:

For more details see the CODE_COVERAGE function, the Code Coverage Workbench page, and the Profiler View.

### Folder Watching System

The new FOLDERWATCH object monitors folders for changes and invokes a user-defined callback whenever a change occurs. This enables IDL programmers to create a "batch" client that watches a specified "hot folder" and subsequently performs processing when specific conditions have been met (e.g. a file has been added to, modified, or deleted from the folder).

; Get working directory

CD, CURRENT=c

f = FOLDERWATCH( c, 'MyCallback', /ADDED )

### FFT Power Spectrum

The new FFT_POWERSPECTRUM function computes the Fourier Power Spectrum of an array. In addition, the function can return additional information including the amplitude, phase and significance levels associated with the result.

### Generate Code in New Graphics

The Generate Code method generates the code needed to reproduce the contents of a graphics window. This method can be used to generate code after changes have been made interactively in the graphics window, e.g., moving, resizing, or changing properties.

p = PLOT(/TEST, THICK=3, COLOR='red', LAYOUT=[2,1,1])

b = BARPLOT(/TEST, FILL_COLOR='green', LAYOUT=[2,1,2], /CURRENT) p.GenerateCode, 'mycode.pro'

You also have the option to save all the data used in the visualizations within the graphics window so you can share the generated code.

For more information on generating code, see the Generate Code Guide Me.

### Lambda Functions and Procedures

You can now create simple inline routines that can be used for functional programming. These Lambda routines can be used with the new ::Filter, ::Map, and ::Reduce methods, or you can simply call them as standalone functions or procedures. For example:

; Use Map to return the square root of a number

var = [0:5]

PRINT, var.Map(LAMBDA(n: sqrt(n)))

IDL prints:

0.000000 1.00000 1.41421 1.73205 2.00000 2.23607

Next use Lambda with the Filter method to return prime numbers:

var = [2:50]

lam = LAMBDA(n:n le 3 || MIN(n mod [2:FIX(SQRT(n))]))

newvar = var.Filter(lam)

PRINT, newvar

IDL prints:

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

We can also make function calls directly on the returned Lambda variable:

compile_opt idl2

; Are these prime numbers?

PRINT, lam(499), lam(4999), lam(49999), lam(499999), lam(4999999)

IDL prints:

1 1 1 0 1

See LAMBDA and LAMBDAP for details.

### Variable Attributes

You can now access special attributes on all IDL variables. For example:

var = RANDOMU(seed, 200, 100)

PRINT, var.length

PRINT, var.ndim

PRINT, var.dim

PRINT, var.typecode

PRINT, var.typename

IDL prints:

20000

2

200 100

4

FLOAT

These attributes provide a convenient shorthand for the SIZE, N_ELEMENTS, and TYPENAME functions, and are also faster to call. See Variable Attributes for details.

### Static Methods for IDL Variables

You can now call special static methods on all IDL variables except objects and structures. For example:

var1 = RANDOMU(seed, 200, 100)

PRINT, var1.Mean()

PRINT, var1.Total()

var2 = var1.Sort()

HELP, var2

IDL prints:

0.501100

10022.0

VAR2 FLOAT = Array[20000]

Another example using strings:

str = " IDL is Hard. "

if (str.Contains("hard", /FOLD_CASE)) then $

str = str.Replace("hard", "fun", /FOLD_CASE)

str = str.ToUpper()

str = str.Trim() ; remove leading/trailing whitespace

PRINT, str

IDL prints:

IDL IS FUN.

In many cases, calling the static method will be faster and more efficient than the equivalent function call. For example, the ::Sort and ::Uniq methods both avoid making an intermediate "index" array and just return the sorted or unique elements.

Many of these methods provide new functionality. For example, see the IDL_String::Capwords, ::Startswith, ::EndsWith, and ::Replace methods.

###### IDL Variable methods

Compare Convert Diff Equals Filter Finite FromBits | Hashcode HasValue IsFinite IsInfinite IsNaN IsReal | Map NestedMap PtrValid Reduce Reform Shift | Sort ToBits ToDouble ToInteger ToString Uniq

###### String methods

Capwords CharAt Compress Contains EndsWith Extract | IndexOf Insert Join LastIndexOf Matches Remove | Replace Reverse Split StartsWith Strlen | Substring ToByte ToLower ToUpper Trim

###### Number methods

Ceil Floor Imaginary | Mean Median Min | Max Product Real | Round Signum Total

###### Integer methods

BitGet BitLength BitSet | BitShift ToASCII ToBinary | ToHex ToOctal |

###### Pointer methods

PtrType Valid |  |  |

For details see Static Methods and Attributes.

## Updates

### ARRAY_EQUAL function NOT_EQUAL and QUIET keywords

The ARRAY_EQUAL function has new keywords: NOT_EQUAL and QUIET. The NOT_EQUAL keyword reverses the meaning of the test, which is useful for checking whether an array contains a particular value or not. The QUIET keyword suppresses any type conversion errors. See ARRAY_EQUAL for details.

### ERRORPLOT Properties

ERRORPLOT has two new properties: ERRORBAR_LINESTYLE and ERRORBAR_THICK, to control the linestyle and thickness of just the error bars.

### FILE_DELETE with Recycling

The FILE_DELETE procedure now has a RECYCLE keyword, which will send files to the operating system's recycle (or trash) bin, instead of permanently deleting them. This keyword is only available on Windows platforms and is quietly ignored on other platforms.

### Hash and List have new Filter, Map, NestedMap, Reduce methods

The List, Hash, Dictionary, and OrderedHash objects have three new methods:

- The Filter method passes each data value through a boolean filter function or Lambda function and returns only values that pass the test.
- The Map method passes each data value through a user-defined function or Lambda function.
- The Reduce method passes each data value cumulatively from left to right through a user-defined function or Lambda function and returns a single scalar result.

The List object also has a new NestedMap method, which passes the data values and arguments in a nested loop, to perform list comprehension.

For details see List, Hash, Dictionary, and OrderedHash.

### Hash and OrderedHash with Case-Insensitive Keys

You can now create Hash and OrderedHash objects with case-insensitive keys. If the FOLD_CASE keyword is set, then the case for string keys will be ignored when accessing keys, adding new keys, removing keys, or changing values. Note that even though the key matching is case insensitive, these objects always preserve the case of the key when it was originally set. See Hash for details.

### List.Sort() Method

The List object has a new List::Sort method which lets you sort the list elements using an optional compare function.

### IDL_Container can now hold Pointers

The IDL_Container class has the following improvements:

- You can now store pointers within an IDL_Container. The container must contain only object or only pointers (not a mix).
- There is a new IDL_Container::Equals method which tests a container of pointers against an input value.
- By using a cached "current position" pointer, IDL_Container::Get is now significantly faster for sequential gets.

For details see IDL_Container.

### IDL Workbench

Better chromacoding and formatting for structure fields and system variables.

### IDLgrAxis

Added TICKUNITS="numeric" and TICKUNITS="scientific" as optional types to IDLgrAxis.

### New NOSAVE Compiler Option

If a routine is marked with `compile_opt nosave`, then it will be excluded from IDL save files, unless the routine was specifically included as an input argument to the SAVE routine. See compile_opt for details.

### IDLitComponent has a new ::UnregisterProperty method

You can now unregister properties from any object than inherits from IDLitComponent. Unregistered properties will no longer appear in the Property Sheet for that object, but can still be accessed through ::GetProperty and ::SetProperty. See IDLitComponent::UnregisterProperty for details.

### Graphics Windows with No Toolbar

By default, graphics windows are created with a toolbar containing some common tools such as Print and Save. You can use the new NO_TOOLBAR keyword to avoid creating the toolbar. This allows you to create graphics windows that are smaller than the default size. This keyword is available on all graphics functions such as PLOT or WINDOW.

### Graphic Save and CopyWindow Produces Smoother Output

By default, when saving to a bitmap that is less than 300 dots-per-inch, IDL will now use anti-aliasing to produce a smoother output image. You can use a new ANTIALIAS keyword to control this default behavior. See the ::CopyWindow and ::Save methods for details.

### ISA function COMPLEX, FLOAT, INTEGER, STRING keywords

The ISA function has new keywords: COMPLEX, FLOAT, INTEGER, STRING. These allow you to test the data type of the input variable. See ISA for details.

### JSON_SERIALIZE Enhancements

When converting an IDL structure, you can now set a new LOWERCASE keyword to convert the tag names to lowercase in the resulting JSON string.

JSON_SERIALIZE now converts byte values into integer values (in the range 0–255) instead of a "true/false" boolean. Before, JSON_SERIALIZE used to convert all non-zero byte values to "true", which caused a loss of data.

See JSON_SERIALIZE for details.

### Support for Unicode Characters Beyond $FFFF

IDL's object and new graphics now allow you to input Unicode characters that have up to 8 hexadecimal digits. For example:

p = PLOT(/TEST, TITLE="!Z(10900)", FONT_NAME="Aegean")

Note: This example will only work if you have the Aegean font installed on your system.

### Library updates

cURL library updated to version 7.36.0.

- Resolves Heartbleed security bug.

OpenSSL library updated to version 1.0.1g.

- Resolves Heartbleed security bug.

HDF5 library updated to provide read-only support for SZIP (v2.1) compression.

### Non-Blocking Timers

The TIMER object now has Block and Unblock methods. IDL no longer automatically interrupts callbacks.

### Video Read

In previous versions of IDL messages from FFmpeg would be reported as errors and IDLffVideoRead object initialization would fail.

Now in IDL 8.4 if the video file contains any video or audio codecs that are not supported then IDL will quietly ignore these codecs and continue to open the file.

Users can set the new VERBOSE keyword to force IDL to issue informational messages when it encounters any unsupported codecs.

## Note

IDL 8.4 will be the last version to include the obsolete Live Tools routines. After IDL 8.4 these routines will no longer be included with the IDL distribution.