X

NV5 Geospatial Blog

Each month, NV5 Geospatial posts new blog content across a variety of categories. Browse our latest posts below to learn about important geospatial information or use the search bar to find a specific topic or author. Stay informed of the latest blog posts, events, and technologies by joining our email list!



Not All Supernovae Are Created Equal: Rethinking the Universe’s Measuring Tools

Not All Supernovae Are Created Equal: Rethinking the Universe’s Measuring Tools

6/3/2025

Rethinking the Reliability of Type 1a Supernovae   How do astronomers measure the universe? It all starts with distance. From gauging the size of a galaxy to calculating how fast the universe is expanding, measuring cosmic distances is essential to understanding everything in the sky. For nearby stars, astronomers use... Read More >

Using LLMs To Research Remote Sensing Software: Helpful, but Incomplete

Using LLMs To Research Remote Sensing Software: Helpful, but Incomplete

5/26/2025

Whether you’re new to remote sensing or a seasoned expert, there is no doubt that large language models (LLMs) like OpenAI’s ChatGPT or Google’s Gemini can be incredibly useful in many aspects of research. From exploring the electromagnetic spectrum to creating object detection models using the latest deep learning... Read More >

From Image to Insight: How GEOINT Automation Is Changing the Speed of Decision-Making

From Image to Insight: How GEOINT Automation Is Changing the Speed of Decision-Making

4/28/2025

When every second counts, the ability to process geospatial data rapidly and accurately isn’t just helpful, it’s critical. Geospatial Intelligence (GEOINT) has always played a pivotal role in defense, security, and disaster response. But in high-tempo operations, traditional workflows are no longer fast enough. Analysts are... Read More >

Thermal Infrared Echoes: Illuminating the Last Gasp of a Dying Star

Thermal Infrared Echoes: Illuminating the Last Gasp of a Dying Star

4/24/2025

This blog was written by Eli Dwek, Emeritus, NASA Goddard Space Flight Center, Greenbelt, MD and Research Fellow, Center for Astrophysics, Harvard & Smithsonian, Cambridge, MA. It is the fifth blog in a series showcasing our IDL® Fellows program which supports passionate retired IDL users who may need support to continue their work... Read More >

A New Era of Hyperspectral Imaging with ENVI® and Wyvern’s Open Data Program

A New Era of Hyperspectral Imaging with ENVI® and Wyvern’s Open Data Program

2/25/2025

This blog was written in collaboration with Adam O’Connor from Wyvern.   As hyperspectral imaging (HSI) continues to grow in importance, access to high-quality satellite data is key to unlocking new insights in environmental monitoring, agriculture, forestry, mining, security, energy infrastructure management, and more.... Read More >

1345678910Last
11997 Rate this article:
No rating

Coming in IDL 8.6 - Repeating Timers

Jim Pendleton

A couple years ago I wrote a blog article on the topic of the new TIMER class in IDL 8.3. In the upcoming IDL 8.6 release, a new REPEAT keyword will be added to the Timer::Set method.

We like to write device control software in the Custom Solutions Group here at NV5 so this new feature will come in handy.

The typical case for using a timer with REPEAT arises from the need to ensure processing at a regular interval, for example in the display of an animation at a specific frames-per-second rate, or in the consistent collection of data from a device.

This REPEAT keyword is a toggle to force the timer to fire at the specified interval. This relieves the callback code of the need for an explicit call to manually reset the timer during the processing of the preceding event. It produces a truly regular "heartbeat" of events.

It is most appropriate to use this style of timer when the processing time of the callback is less than the timer's interval. If the timer events cannot be drained at a rate greater than the interval at which they're added to the queue, this solution is not generally recommended, or the interval needs to be adjusted accordingly.

The IDL Code Profiler should be used to determine if there is a potential for conflict between the callback execution time and the sampling rate. Also be aware that your measurements will depend on the current platform and system load, so be judicious when deploying solutions like this to other computers with different performance characteristics from the device under test.

A timer callback can be thought of as a higher-priority interrupt to the main IDL interpreter loop. It will take precedence over the otherwise-executing code.

When the interpreter is between execution of lines of .pro code, if a timer event is found on the queue the timer's callback routine will be executed first, taking precedence over the next line of IDL code. This also applies to compiled code in IDL SAVE files.

When the callback is completed, the interpreter returns to its regularly-scheduled execution, which may include the processing of additional timer callbacks.

In other words, the IDL interpreter remains single-threaded. The timer callback will be executed as an interruption to the currently-executing context. In fact, a timer will interrupt even modal WIDGET_BASE dialogs. In many cases, it may be wise to use a mechanism such as TIMER's ::Block/::Unblock methods or a system semaphore to prevent the possibility of re-entrance.

Example

The following source code shows the behavior of the timer event queue when /REPEAT is set.

PRO myTimerCallback3, id, c
COMPILE_OPT IDL2
t = systime(1)
c.dt.add, t - c.t
c.t = t
c.counter++
wait, c.counter ge 20 && c.counter le 40 ? .51 : .001
print, 'in callback ', c.counter
done = c.counter eq 100
if (done) then begin
    p  = plot(c.dt.toarray(), ytitle = 'dt', xtitle = 'iteration', $
        title = 'Execution time per iteration')
    void = Timer.Cancel(id)
endif
END


PRO async_timer_example_repeat3
COMPILE_OPT IDL2
; Create a timer that will fire 5 times per second.
c = {counter : 0L, t : systime(1), dt : list()} 
id = Timer.Set( 0.2, 'myTimerCallback3', c, /REPEAT )
END

A new timer object is created that fires off events at an interval of 0.2 seconds, regardless of what else may be going on in the IDL main thread.

In the callback, the first 19 iterations are executed with just a 1-millisecond WAIT delay, simulating a light CPU load.

Iterations 20 through 40 are executed with a 0.51-second delay, over twice the timer object's repetition interval.  This simulates a heavier CPU load and helps to show that the timer continues to run and queue events at its own rate in the background.

The remaining steps revert to the shorter wait time.

Internally, the code keeps track of the clock time between callback execution at each step.

The plot of the result is shown below.

The labels indicate the dominant driver for the execution rate at each interval.

Initially, the timer's heartbeat keeps us on track with a regular 0.2 second interval between callbacks.

The next set of iterations are dominated by the 0.51 second WAIT inside each callback.  If we had been displaying a video playback, the frame rate would be decreased substantially during this time.

The third set of iterations shows the effect of emptying the queue of the accumulated timer events that could not be processed immediately at the time they were fired, due to the WAIT statements in the previous block. If this had been video playback, these frames would have all been displayed very rapidly.

After the queue is emptied, the regular heartbeat is attained again. Video playback would return to "real time".

If you were to remove the /REPEAT keyword and add a call to Timer::Set in the callback routine, you could compare the effects. Your choice in your own code will be based on your prioritization of "real time" versus "lagging but consistent" sampling.

Please login or register to post comments.