by Joseph Long

I spend most of my time working from the command-line, so being able to inspect an astronomical FITS format image in DS9 with ds9 -multiframe -zoom to fit ./thing.fits as fast as I can type it is useful to me. (Except, obviously, I have an alias for those options. I'm not an animal.)

SAO distributes X11 builds of DS9 for macOS, which I can launch from the command line, so I use those. Now, their "Aqua" builds of ds9 for macOS use the Tcl/Tk framework's implementation of the native macOS widgets (prettier!) and Finder double-click-ability (convenient!) at the cost of convenient command-line launching and, most recently, incompatibility with Dark Modeā„¢ on macOS Monterey (disaster!).

So, I stick with the command line version. Sometimes, though, I want to open a FITS file by double-clicking it in the Finder. This is the hack I came up with to enable that.

Step 0. Get the command-line (X11) version of ds9

Go to the ds9 download page and get the appropriate X11-based release for your OS. Extract the file, and put it (both ds9 and somewhere on your $PATH. Remember the full path to it for the next step. You should also make sure that you can start it from the terminal, that XQuartz works, etc.

Step 1. Open Script Editor

Only "applications" can open files in macOS, not dinky little "executables". So, we have to make an "application."

In your /Applications/Utilities folder, there's an app called "Script Editor". Open it up and paste this in:

on run
end run

on open dropped_files
end open

on process(dropped_files)
    set file_list to ""
    repeat with file_path in dropped_files
        set file_list to file_list & " " & quoted form of POSIX path of file_path
    end repeat
    do shell script "/Users/yourusername/.local/bin/ds9 -multiframe -zoom to fit " & file_list & " &> /dev/null &"
end process

You'll need to modify /Users/yourusername/.local/bin/ds9 to be the full path where you installed the ds9 binary. You can also tweak the options following the path to ds9. The ampersand (&) is the concatenation operator, so what we're doing is constructing a command like we'd type in the terminal to launch ds9 with one or more files as arguments. The final &> /dev/null & backgrounds the process and indicates we don't care about its outputs at all, so that the script can exit without waiting for ds9.

Save as "File Format: Application" to create a .app bundle (I called mine

Step 2. Edit Info.plist

App bundles are just folders, so for the next trick open in a text editor.

Right before the final </dict>, add:

            <string>Flexible Image Transport System image</string>

You can check if everything's right using plutil, e.g.

% plutil OK

(Note: This edit should be sufficient to make the app a drop target for FITS files, but it seems like LaunchServices can get confused. You might need a magic incantation like /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -domain local -domain system -domain user to regenerate the list of file associations.)

Double-click your app bundle to launch an XQuartz version of ds9.

Step 3. Update file associations (if needed)

There's probably a command-line way to do this, but right-clicking on a one .fit and one .fits file and choosing Get Info gets you the window shown below. Select your new .app under the "Open with:" section and click "Change All..." to get this prompt

Image showing Get Info window where "Open With" has been set to the new

Confirm by clicking "Continue," and we're done. Now, double-clicking any .fits or .fit file should open an XQuartz ds9 window. Dragging multiple files onto the icon will open them within the same window as separate frames.


I cobbled this together from a couple places: First,, which has a more flexible solution for launching arbitrary scripts. Second, the bundle keys and values were taken from this StackOverflow answer, though it omits the fact you must include <key>CFBundleDocumentTypes</key> before the array.


← return home
Background image of the Carina nebula by NASA, ESA, N. Smith (University of California, Berkeley), and The Hubble Heritage Team (STScI/AURA)