Setting up an IDL working environment in Mac OSX 10.10 (Yosemite) (IDL, IDLWAVE and Aquamacs)

Introduction

A lot of astronomy work is done in IDL still though there is a push from some to move to python. This is no doubt influenced by python being free, not requiring licences, being easy to install and having great community support. However IDL is often necessary if you've been given a code and is still quite a popular language. Installing it and working with it can be tricky. I'm posting a short description of how to install IDL and setup IDLwave and Aquamacs for Mac OSX 10.10.


Components

  • IDL: Coding language from Exelis which will require an installation.
  • XQuartz: http://www.xquartz.org/
  • IDL Licence: A licence to use this proprietary code. You'll need to speak to your systems admin or whoever handles your IDL distribution and ask for the licence file.
  • To do this you will need to send them two pieces of information; your hostname and your hostID.
  • Open a terminal and type hostname which will return your hostname
  • Open an XQuartz terminal and type ifconfig. Look for the "en0:" line and underneath it you will see either ether or wi-fi. Take the alphanumeric code next to it (12 digits long) and remove the semi-colons (":"). This is your hostID.
  • Aquamacs: This is a text editor that is a version of emacs for mac. It has a great set of keyboard shortcuts and supports IDL wave. http://aquamacs.org/
  • IDLwave: Part of the IDL installation, allows the compilation and running of IDL code in an inferior shell. This is roughly equivalent to ipython. 


First off...Install IDL

  • Go to http://www.xquartz.org/ and install XQuartz if you don't already have it
  • Get your hostID and hostname. (See above)
  • Send them to your administrator and ask for a licence.
  • Create an account at Exelis
  • Sign into Exelis
  • Go to Downloads page
  • Download the IDL version you want for Mac. (8.5 is latest at time of writing and the one I'm using.)
  • Install IDL, (this will also install IDLwave)


Setting up Environment Variables

Now we have the software we need installed we need to set up the environment variables to tell each piece where the others are. Firstly open up your .bash_profile
  • open ~/.bash_profile
Append your PATH variable with the path to your IDL installation. If you haven't created a PATH variable you could do something like this:
  • export $PATH="/Applications/exelis/idl85/bin/idl:$PATH"
    • (Breakdown: "export" is used to set environment variables in bash which MacOSX 10.10 uses. $PATH is a variable called to find out where executables can be found if needed. The /Applications/exelis/idl85/bin/idl should be the path to your idl executable. The :/$PATH at the end adds the rest of your PATH variable, (set by the operating system) to the path, effectively amending it.
    • Troubleshooting:
      • Checking the Path: If you have done this correctly you should be able to run idl in the terminal and it will load. Type exit to quit.
      • Nothing Happened: Try closing and opening a new terminal. Your .bash_profile only loads in the beginning of your session.
      • Now my terminal doesn't work! (Can't use ls and other basic executables.) If you mess up this PATH variable somehow you can also explicitly state the parts that the OS want you to include. This would look like
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin


Install Aquamacs

If your idl now works in the terminal we can now make it work in aquamacs. You can download and install the dmg at http://aquamacs.org/.

Once it's installed we'll need to update a few environment variables so it will run IDLWAVE. First off, some handy emacs/aquamacs commands and syntax:

Definitions

  • C-h : Control and 'h' held at the same time
  • M-h : Alt and 'h' help at the same time
  • SPC : Space bar
  • RET : Return/enter

Some useful Commands

  • C-h v variablename RET : Get HELP on a VARIABLENAME
  • C-h f functionname RET : Get HELP on a FUNCTIONNAME
  • C-s string RET : Find STRING in the text
  • M-x f PATH : Load the file PATH
  • M-: (getenv ("PATH") : Evaluate a function, in this case the getenv function. 
  • C-c C-s : Open IDLwave
  • C-c C-d C-d : Compile current code
  • C-x C-s : Save the current text
Setting up IDLwave in aquamacs should be as easy as inputting the following:

  • C-h v idlwave-shell-explicit-file-name RET
Look at the help file and then click customise, this will open a new frame. Type the path to your version of idl in the grey box:
  • /Applications/exelis/idl85/bin/idl
Then save using C-x C-s and then close. Restart your aquamacs and terminal and now if you open a .pro file IDLwave should load.

  • Troubleshooting:
    • IDLwave does NOT run. (Error messages that idl can't be found): Ensure that you're linking to the correct IDL executeable. Do this by going to a terminal and typing
      • type -a idl
    • This will give you the path that the executable is from. This is the path that goes in the grey box.

Path problems with IDLwave, Aquamacs and MacOSX

There are two ways, now, to run aquamacs. Firstly we could run from the terminal by typing in aquamacs. This process would inherit its environment variables from the terminal and you would be able to use your PATH and IDL_PATH variables. 

If you run aquamacs from the application launcher instead it may not inherit these variables. If you do have this problem you could install the package exec-path-from-shell which was written for just this purpose. 


Bonus Round!

Setting up a package manager

Emacs (and aquamacs) can be customised greatly using packages. These are files with the suffix .el which will change your experience, adding things like tab autocompletion and automatic spacing in your text. Installing these packages can be a hassle manually. This is how I've found to get the best package manager for Yosemite.

Firstly create a .emacs file. You can actually put this stuff into the ~/Library/Preferences/Aquamacs Emacs/Preferences.el file (Aquamacs will check and load in both) but I find that's a little harder to remember and the .emacs file is the same from Linux emacs.

  • Breakdown: Emacs loads up your preferences from a few files including the most important .emacs file (a hidden file in your user directory). To create one on mac just open up the file and save. You can even do it in aquamacs now!
    • aquamacs ~/.emacs
Put the following into your .emacs file and save it

(require 'package)
(package-initialize)
(add-to-list 'package-archives
    '("melpa-stable" . "http://stable.melpa.org/packages/") t)
(package-refresh-contents)

  • Breakdown: This allows us to search an archive of available pacakges and automatically refreshes the contents when you open up a new session. Melpa is a package repository and it is updated regularly. You could also look into ELPA or Marmalade but I find this one has the best archive.
If you now would like to load a package type in any aquamacs window

  • M-x list-packages
Which will open up the list of packages that are available, from there just click the link to the package you want and there will be install instructions. Much easier than looking for it yourself.

Example: exec-path-from-shell.el

This is the package I mentioned earlier designed to ensure aquamacs inherits your environment variables from the terminal. This shouldn't be a problem if you always load from the terminal as I do but you can feel free to test it out. To install this package we simply open up aquamacs however you like, type "M-x list-packages" and scroll until you find the link for exec-path-from-shell. Click the link and a new frame or window will open. Then just click install and follow the instructions. If you'd like to check if it's installed you can go back to the list-packages window and scroll to it and it will say "installed" next to the name.

  • Troubleshoot:
    • The package I want is not in the the list: Try refreshing the list with M-x package-refresh-contents
    • The package I want is still not in the list: Ensure that the link you've put in your .emacs file is to an upto date archive.

Adding third party libraries

There are some good third party libraries for IDL. The coyote library particularly is very good for plotting. If you would like to install one simply download the zip file, e.g. from http://www.idlcoyote.com/code_tips/installcoyote.php and unzip it. Move the folder to where your idl bin is i.e.

/Applications/exelis/idl85/bin/

So there will now be a path

/Applications/exelis/idl85/bin/coyote

which contains the contents of the zip file.

Then in your .bash_profile add

export $IDL_PATH="+/Applications/exelis/idl85/bin/coyote"

  • Breakdown:
    • Export will add the variable, IDL_PATH is a variable used by IDL, the + symbol at the start of the path lets the PATH contain all the folders within that path.
If you want to add more paths you can do so by separating them with a semi-colon (:) e.g.

export $IDL_PATH="+/Applications/exelis/idl85/bin/coyote:+/Applications/exelis/idl85/bin/astron"




Using SWIG to make python modules from C++ using the Vector library

Sometimes we need fast computing from a low level language such as C++ while maintaining the usability of a language like Python which makes data visualisation easier.  To make this work it is possible to wrap C++ so that it becomes a shared library that can be imported to python.

This is particularly useful with Vectors, a C++ library that can be a little nicer to use than the standard arrays.

I'll give an example of the steps below.

Start with your function that you want to be usable in python. 

example.cpp


#include <vector>
#include <iostream>
std::vector<int> testfunction(std::vector <int>& value){
  std::cout <<"Running\n";
  return value;
}



Here we've made a very simple vector function. It's only purpose is to tell us that it is running. We need a header file for the function

example.h






#ifndef TEST_H_
#define TEST_H_
#include <vector>
#include <iostream>

std::vector<int> testfunction(std::vector <int>& value);

#endif




Now we have our function let's make ourselves an input file for SWIG. This will tell it what functions we are using and how to cast them for Python.

example.i


%module example
%{
#include "example.h"
%}

%include "std_vector.i"
// Instantiate templates used by example
namespace std {
   %template(IntVector) vector<int>;
}

// Include the header file with above prototypes
%include "example.h"




The structure of this file is important. Firstly the %module example gives the title that we will eventually use for our python module. We must include the header file we made and the std_vector.i library for SWIG so that it understands vectors. We then give SWIG a template which will let it understand what vector we are passing it. (Google around to find out more about these template functions and which ones might be right for your code, SWIG has great documentation.)

Finally we include example.h for SWIG itself.


Now we can run all this, here are the compile functions for this example:


makefile


 swig -c++ -python example.i

 gcc -fpic -c example.cpp example_wrap.cxx -I /opt/ioa/software/python/2.7.8/include/python2.7
 gcc -Wl,--gc-sections -fPIC -shared -lstdc++ example.o example_wrap.o -o _example.so






We've got our shared library and our module _example.so. All we have to do is call it in python!




>>> import example as e
>>> x=e.IntVector(5)
>>> e.testfunction(x)

"Pretty" plots in IDL

Using IDL a lot I am a little tired of typing out the specific keywords for plots every time. I have quickly created a "pretty.pro" to go with CHloadct.pro which updates the plot variables to nicer ones. The changes are below:



Add the code to your path and then type pretty before plotting and they become much easier to read.


;-------------------------------------------;

;pretty

;-------------------------------------------;

;Makes plots that much prettier


;Christina Hedges

;chedges@ast.cam.ac.uk

;-------------------------------------------;



pro pretty 

  loadct,39,/silent

  device,decomposed=0

  !p.font=1

  !p.charsize=4

  !p.color=cgcolor('black')

  !p.background=cgcolor('white')

  !x.thick=3

  !y.thick=3

  !x.margin*=0.8

  !p.thick=2

  plotsym,0,/fill

end

Much better! If, for whatever reason, you want to undo the pretty plot just use "cleanplot.pro" which resets everything.

IDL Color Tables: How to get more (and make your own!)

After researching the issue for quite some time I have noticed there aren't really many easily available color table files that you can download to include in your IDL codes. I also noticed that it's actually a little tricky to find out how to make your own. So I've decided to post a small collection of my own color tables with a read in file for people to use!


Download the files here!

CHloadct

CHloadct.pro will read in saved color table files like the normal "loadct" will. It is very simple and includes a reverse command so if you like any of the tables below, (which I use for plotting contours mainly,) then feel free to download the .zip file. To use simply add the CHloadct directory to your IDL path and you're away. 

Use

CHloadct,'SUNSET',/reverse



 for example to load in the sunset table in reverse.




The zip file can be found here and contains the above save files to get you started. If anyone is using this and it's working well please let me know if you could do with more color tables, I'll try to update the files whenever I create any good new ones.

Creating your own Color Tables in IDL

To create color tables you can use a very handy command "xpalette".
In the command line type in xpalette and hit enter and a pop up box will appear. In this box there is a window on the right hand side, filled with the color table you had previously loaded.

Use the controls to alter the colors in each pixel of the window on the right.



It looks daunting but you don't have to do all 256 pixels! Try putting one corner as one color and another as a different color. Use "set mark" on the first pixel, highlight the second colored pixel and click interpolate! You should have a smooth color change.

If your screen starts looking pixelly or isn't updating use "Redraw" to refresh.

When you're done, go back to your command line and type

tvlct,r,g,b,/get

This will grab the rgb values of the color table you've created. Then, to save them do something like:

save,r,g,b,filename='BLUE-RED.sav'

And save the file in the CHloadct directory. (This will allow you to load it up like all the rest!) That should be it! Enjoy your new color table!