External Communication with JS9

The JS9 Analysis menu provides flexible support for running a macro-expanded external analysis command on the web server and displaying results in the browser. But there are other scenarios in which it might be desirable for an external process to communicate with the JS9 client:

If you have installed the Node.js-based server-side helper (or Electron.js for the Desktop JS9 app), this sort of external communication is supported by the js9 script and its underlying js9Msg.js module. The script runs Node.js (or Electron.js) with js9Msg.js as its first argument. (See Installing a Server-side Helper for more more information about server-side helpers.)

To display the js9 script options, type:

  sh> js9 --help

Using command line syntax, the js9 script will send a single JS9 command to the browser and return the results:

  sh> js9 cmap heat        # change colormap to heat
  OK
  sh> js9 cmap             # return the current colormap
  heat

If the "-" or "--pipe" argument is supplied, js9 will read commands from stdin. You can send multiple commands to the script's standard input (comments and blank lines are ignored):

  sh> cat test.cmds
  # colormap
  cmap heat
  # scale
  scale log
  # regions using image coords
  region circle {"x":588, "y":590, "radius":30, "tags":"source"}
  region circle {"x":390, "y":430, "radius":50, "tags":"background"}
  sh> cat test.cmds | js9 -

Note that DS9/Funtools region syntax can also be used for regions:

  sh> cat test2.cmds
  cmap heat
  scale log
  wcssys fk5
  region box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163)
  region ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599)
  region polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) {"tags": "background"}
  sh> cat test2.cmds | js9 -

Finally, the - (or --pipe) switch also allows you to specify a string on the JS9 command line that will prefix all lines read from stdin. This allows you to send a regions file to JS9:

  sh> cat ds9.reg
  # Region file format: DS9 version 4.1
  global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1
  fk5
  box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163)
  ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599)
  polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) # background
  sh> cat ds9.reg | js9 - region
(Without the - ("dash") switch, standard input will not be read. The "region" command will be executed to return current regions.)

A list of available JS9 commands can be retrieved using the ''help' command:

  sh> js9 help
  analysis     	run/list analysis for current image (ana)
  colormap     	set/get colormap for current image (cmap)
  colormaps    	get list of available colormaps (cmaps)
  help     	get list of available commands
  helper     	get/set helper connection
  image     	get name of currently loaded image or display specified image
  images     	get list of currently loaded images
  load     	load image(s)
  pan     	set/get pan location for current image
  pix2wcs     	get image pixel value for specified wcs position
  print     	print image window
  regions     	add region to current image or list all regions (reg, region)
  scale     	set/get scaling for current image
  scales     	get list of available scales
  url     	display a url
  wcssys     	set/get wcs system for current image
  wcsu     	set/get wcs units used for current image
  wcssystems   	get list of available wcs systems
  wcsunits     	get list of available wcs units
  wcs2pix     	get wcs position for specified image pixel
  zoom     	set/get zoom for current image
These are the same commands that are available to the JS9 light-weight Console window.

In addition to the commands above, you also can execute calls from the JS9 Public API:

  # add a red circle region
  sh> js9 AddRegions circle '{"color":"red", "tags": "foo"}'
  # change color of all regions to violet and change the tags too
  sh> js9 ChangeRegions all '{"color":"violet","tags":"goo"}'
  # change color of selected regions to violet and change the tags too
  sh> js9 ChangeRegions selected '{"color":"violet","tags":"goo"}'
  # change color of red regions to violet
  sh> js9 ChangeRegions red '{"color":"violet"}'
  # change color of regions with "source" tag to violet
  sh> js9 ChangeRegions source '{"color":"violet"}'
  # get colormap
  sh> js9 GetColormap
  {"colormap":"grey","contrast":"3","bias":"0.8"}
  # set colormap
  sh> js9 SetColormap viridis 1 0.5
  # get scale parameters
  sh> js9 GetScale 
  {"scale":"log","scalemin":0,"scalemax":51}
  # set scale
  sh> js9 SetScale linear
Note that the opts object is passed as a JSON string, and returned objects are also in JSON format.

The js9 script can talk to a JS9 instance if the script is run from:

Note that the js9 script on one host cannot communicate with a target browser on another host (unless the first host is the helper host).

If a JS9 instance is connected to a helper on a remote host, you can use the --host or --helper switch to specify the remote host to contact. For example, if the helper is running on js9.cfa.harvard.edu, you can send a command to your instance of JS9 this way:

  sh> js9 --host https://js9.si.edu region circle
  OK

If more than one instance of JS9 appears on a single web page, the --id switch can differentiate between instances. The value of the id switch is the div id for that JS9 instance. For example, if two instances of JS9 having div ids of "JS9" and "myJS9" are defined on the same page, then js9 can communicate with the latter in this way:

  sh> js9 --id myJS9 region circle
  OK
  sh> js9 --id myJS9 region 
  ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")
or, from the readline loop:
  sh> js9 --id myJS9
  JS9> region circle(23:23:26.929, +58:48:50.381, 14.76")
  OK
  JS9> region
  ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")

Putting the last two techniques together, you can talk to one of many JS9 instances on a page connected to a remote helper this way:

  sh> js9 --host https://js9.si.edu --id myJS9 cmap heat
  OK

Ordinarily, the js9 script talks to a displayed JS9 web page. It also can be used to start the JS9 Desktop app and load an image into the app's web page. The JS9 Desktop app simply requires that you install Electron.js, which is available here:

  http://electron.atom.io/
On a Mac, Electron.app should be installed in the /Applications folder (or set the JS9_ELECTRON_APP environment variable to point to the path of Electron.app). On Linux, the electron program should be placed in your PATH.

Once this is done, use the -a switch to specify the app startup and the -w or --webpage switch to specify a web page (default is a nice, basic JS9 web page).

  sh> js9 -a ~/data/casa.fits
will start the JS9 Desktop app with a basic JS9 web page and load the Cas-A FITS files into the page, while:

sh> js9 -a -w ~/js9/js9basics.html ~/data/casa.fits

will display the same image in one of the JS9 demo pages.

When JS9 is used in Desktop mode, the browser same-origin policy does not apply, so you can load FITS URLs directly:

sh> js9 -a https://js9.si.edu/js9/fits/m13.fits

The js9 script also can be used to start up a new browser, display a JS9 web page, and then load an image into that page. To do this, use the -b or --browser switch to specify the browser (chrome, safari, or firefox) and the -w or --webpage switch to specify a web page (default is a nice, basic JS9 web page). For example:

  sh> js9 -b chrome ~/data/casa.fits
will start a Chrome browser with a basic JS9 web page and load the Cas-A FITS files into the page, while:

sh> cd ~/data sh> js9 -b firefox -w ~/js9/js9basics.html casa.fits

will display the same image in one of the JS9 demo pages. (Note that, in this case, the js9 script figures out the full pathname of the FITS file.)

Instead of supplying the browser name each time on the command line, you can set the environment variable JS9_BROWSER and just use the -b switch with no argument. (Note that you still must supply the -b switch, which tells the script to start a browser.) Similarly, the default web page can be configured using the JS9_WEBPAGE environment variable:

    sh> export JS9_BROWSER=chrome
    sh> export JS9_WEBPAGE=$HOME/js9/js9basics.html
    sh> js9 -b ~/data/casa.fits

Care must be taken that no JS9 web page is already being displayed when the -b or --browser switch is utilized, or else the specified image will be loaded into the existing web page (and no new browser will be started). Also, it is important to note that the Google Chrome browser must be started by the js9 script or it must be started by you using the --allow-file-access-from-files switch. Without this switch, Chrome will not permit a local HTML file to read other files. Finally, Mac OSX Safari occasionally experiences delayed data transfers when the js9 messaging script is located in a different Space (desktop) from the browser window, so keep these in the same Space.

Last updated: August 16, 2017