Last modified: November 2016

URL: https://cxc.cfa.harvard.edu/chips/ahelp/chips4.html
AHELP for CIAO 4.11 ChIPS v1

chips

Context: chips

Synopsis

Introduction to ChIPS, the CIAO plotting package

Description

ChIPS - the CIAO Imaging and Plotting System - is the plotting system for CIAO. It allows users to create line and image plots interactively - with undo capabilities and a GUI - or from a script. It can be used for both data analysis - e.g. to plot a lightcurve - and to create publication-quality figures.

This document provides an introduction to ChIPS; more information is available on the ChIPS website, including a gallery of ChIPS visualizations.

ChIPS is designed for use in a variety of modes: as a user-interactive application and in batch mode. ChIPS is an importable module for the Python scripting language and is available as a C/C++ library for software developers.

Interactive mode

In interactive mode, undo and redo commands allow the user to easily step forward and backward through previous commands. Users have fine control over the figure display: setting colors, changing font styles, repositioning objects. The many object attributes can be changed at any time during the session, and the change is immediately visible in the ChIPS window. The default values may also be changed and saved as a preferences files, which can be used in any ChIPS session.

Batch mode

ChIPS can be run so that no display (i.e. X window) is created or updated, whilst still being able to create visualizations in the supported output formats (e.g. postscript, PDF, PNG, and JPEG). This allows ChIPS to be used in a data processing pipeline, or run in the background, when user interaction is not required. See the "Running ChIPS in batch mode" section below for more information.

The ChIPS GUI

The graphical user interface (GUI) allow users to adjust the layout of their plots, select and make edits to most of the properties of the visualization, and add annotations, such as labels and lines, directly to the visualization. A Python terminal is built into the GUI, allowing access to ChIPS and other Python commands. The GUI is available to any process that creates a ChIPS plot, such as Sherpa and Prism.

The GUI is launched by right clicking on an existing ChIPS window and selecting "Show GUI" or by running the show_gui command from within a ChIPS session.

Features include:

Futher information is available from the built-in help menu in the GUI and via "ahelp chipsgui".

Key concepts

There are several key concepts that define how ChIPS works (they can also be listed by saying ahelp -c concepts):

Concept Ahelp page Description
Entity Creation entitycreation ChIPS uses a hierarchical approach to constructing plots. Any number of windows may exist, and each window may contain zero or more frames which themselves can contain a number of plots. These plots represent the data including curves, histograms, contours and images, as well as annotations such as lines, labels, regions, points and color bars.
Entity Attributes attributes Each displayed item - be it a curve, label, plot, or window - has a set of attributes that control its appearance and behavior. These attributes can be changed even after the entity has been created.
Editing Attributes setget There are a number of ways that the attributes of an entity can be read or written (i.e. changed).
The current (selected) objects currency Since there may be multiple instances of any object, ChIPS internally tracks which objects are currently being accessed. Those objects being accessed are considered "current"; the overall state of the system is referred to as "currency."
Entity Selection chipsid The ChipsId structure is used to change the current item in ChIPS; e.g. to select a different curve or plot.
Preference settings preferences Whilst entity settings can be set when an entity is created, or changed after it has been created, they can also be changed using the ChIPS preference settings, so that new entities will inherit your chosen values.
Coordinate systems coordsys ChIPS uses a number of different coordinate systems when placing entities.
Depth depthcontrol Depth control allows the user to specify the depth at which each object is placed within a frame. Modifying the depth of objects also controls how they overlap.

Plotting data

The main "objects" used to display your data are:

Object Description
Curve Two dimensional data (e.g. x,y pairs), and errors can be included on either or both axes. The points can be connected by lines and marked by symbols.
Histogram This is for data that has been binned (e.g. a histogram) in one dimension. The bins can be inferred or explicitly given, either by giving the center or both edges of the bins. Errors can be drawn for the histogram value (e.g. y).
Contour A contour plot of an image or set of (x,y,z) arrays that fill a regular grid. The contour levels can be chosen automatically, given explicity, or changed after display.
Image Display of a two-dimensional image. Three-color images (e.g. r,g,b) can be created, including support for the alpha (transparency) channel.

All these objects can be combined in the same visualization, even in the same plot - e.g. to have a contour plot on top of an image.

Images and contours can be displayed for data which contains a 2D linear transform or a WCS tangent-plane projection. Axes can be created either as two separate linear or logarithmic scales, or as a tangent-plane projection for displaying points, histograms, or curves (where appropriate).

Annotations

The following "annotation" objects are provided:

Object Description
Label A label can be placed at a point. The size, font, style, color, contents and position of the label can be changed.
Point A symbol can be drawn at a point (x,y). The shape, size, color and position can be changed.
Line Two or more pairs of (x,y) values connected by straight lines. The color, thickness, style and position of the line can be adjusted.
Region Similar to the line but the last point is connected to the first and the insides can be filled, with either a solid or opaque color or a range of patterns.
Color bar A color bar can be added to an image to indicate the mapping between pixel value and color.

Although not explicitly listed above, axes and plots also have labels that can be set and changed.

Saving a ChIPS session

The ChIPS session can be saved into a platform-independent state file. The session can then be restored at any time, even on a different computer. Alternatively a Python script can be created which can be used to re-create the visualization. See ahelp save_state and ahelp make_script for more details.


Examples

Example 1

Displaying a set of (x,y) points from a file

In this example we start ChIPS and then use it to plot the energy vs pi values from a file (we use the -n option to avoid displaying a banner on start up):

unix% chips -n
chips-1> add_curve("evt2.fits[sky=region(src.reg)][cols pi,energy]")
chips-2> set_curve(["line.style", "noline", "symbol.style", "square"])
chips-3> set_plot_xlabel("PI")
chips-4> set_plot_ylabel("Energy (eV)")
chips-5> add_label(0.1, 0.9, "src.reg", ["coord_sys", PLOT_NORM])
chips-6> set_label(["size", 18])
chips-7> print_window("plot.ps")

Once the curve has been displayed we change the properties of the curve, using the set_curve command. After this command has been entered the ChIPS window will be updated, changing the symbol style to square and removing the line drawn connecting the points. See ahelp entitycreation, ahelp attributes and ahelp chipsopt for more information on these concepts.

Labels are added to the axes using the set_plot_xlabel() and set_plot_ylabel() commands, and then a label added to the plot itself using the add_label() command. In this call we place the label in the top-left corner of the plot since we specified that the coordinates (0.1,0.9) are in the "PLOT_NORM" coordinate system (where 0,0 is the bottom-left of the plot and 1,1 is the top-right). See "ahelp coordsys" for more information on the coordinate-system support in ChIPS.

After changing the size of the font used to display the label we create a postscript plot using the print_window() command. If the call had said

chips-7> print_window("plot.ps", ["printdialog", True])

then a GUI would appear allowing you to change the print options, such as page size, format, and page margins.

Using make_figure

The ChIPS module also contains the make_figure routine (see "ahelp make_figure") which will read in a file and plot it, chosing between curves or contours depending on whether the file is a table or image, and set up appropriate axis and plot labels. The commands above could therefore have been replaced by:

chips-1> make_figure("evt2.fits[sky=region(src.reg)][cols pi,energy]")
chips-2> set_curve(["line.style", "noline", "symbol.style", "square"])
chips-3> add_label(0.1, 0.9, "src.reg", ["coord_sys", PLOT_NORM])
chips-4> set_label(["size", 18])
chips-5> print_window("plot.ps")

Note that the make_figure() command can be used to also create histogram or image plots by explicitly giving the desired plot type, as discussed in its ahelp page.

Using the GUI

The ChIPS GUI can be started using the "show_gui()" command from the ChIPS command line or by using the right-mouse button in the ChIPS window to bring up a menu of options, one of which is "Show GUI".

Example 2

Adding data to the plot

Here we add data - this time using numpy arrays - to the visualization created in the previous example.

chips-8> x = np.arange(1, 1025)
chips-9> y = (x-1) * 14.6
chips-10> add_curve(x, y, ["symbol.style", "none", "line.color", "red"])
chips-11> set_curve(["line.thickness", 3])
chips-12> get_curve()

Here we have added a thick red line on top of the data points. Note that the add_curve() command can accept attribute values, such as "line.color", and that the set_curve() call in line 11 changes the "current" curve (ie the one created in line 11) rather than the first curve we created. The properties (ie attributes) of an object can be retrieved using the get_<object> call; here we use it in line 12 to get the properties of the current curve. The return value is an object which gets displayed by the application; the output looks like

baddata = 1
depth = 100
err.caplength = 10
err.color = default
err.down = False
err.left = False
err.right = False
err.style = line
err.thickness = 1.0
err.up = False
id = None
limit.length = 0.0500000007451
limit.override = True
line.color = red
line.style = 1
line.thickness = 3.0
stem = None
symbol.angle = 0.0
symbol.color = default
symbol.fill = True
symbol.size = 5
symbol.style = 0

See ahelp get_curve and ahelp set_curve for more information.

Example 3

Multiple plots

In this example we add another plot to the window, re-sizing the first plot at the same time, and add data to this second plot.

chips-13> split(2)
chips-14> adjust_grid_ygap(0.2)
chips-15> undo()
chips-16> adjust_grid_ygap(0.1)
chips-17> add_image("evt2.fits[sky=region(src.reg),energy=500:7000][bin
sky=1]")
chips-18> set_xaxis(["tickformat", "ra"])
chips-19> set_yaxis(["tickformat", "dec"])
chips-20> set_image(["colormap", "heat", "threshold", [0,5]])

The split() command is used to create the second plot; when called with no arguments it ensures there are two vertically-aligned plots but it can be used to create a grid of n by m plots. The adjust_grid_ygap() command is used to add a gap between the plots; we decide that a value of 0.2 is too large so undo the change in line 15, then change to a spacing of 0.1. In this particular example there is no need to call undo() since the gap can be changed multiple times.

In the second plot we decide to display an image of the data, using the add_image command, and chose to change the axes to use sexagesimal notation. We finish off by changing the colormap and threshold used to display the image.

Example 4

Currency

The info() and info_current() commands let you find out the names of the objects that have been created:

chips-21> info()

Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.57)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      Curve [crv1]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv2]
    Plot [plot2]   (0.15,0.15)  .. (0.90,0.48)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      Image [image1]
      X Axis [ax1]
      Y Axis [ay1]

chips-22> info_current()

Window [win1]
  Frame [frm1]
    Plot [plot2]
      Image [image1]
      X Axis [ax1]
      Y Axis [ay1]
    Coord Sys [Data]
    Coord Sys ID [ds0.0.1.7]

These names can be used to select which object is current; for instance to change the first curve we created we need to change to the first plot and then select that curve:

chips-23> current_plot("plot1")
chips-24> set_curve("crv1", ["symbol.color", "green"])

which will change the squares to green in the top plot. We can even delete objects, such as the second plot (and so all its contents such as the image and axes):

chips-25> delete_plot("plot2")

after which the info() command returns:

chips-26> info()
          
Window [win1]
  Frame [frm1]
    Plot [plot1]   (0.15,0.57)  .. (0.90,0.90)
      Border bottom [bx1]  top [bx2]  left [by1]  right [by2]
      Curve [crv1]
      X Axis [ax1]
      Y Axis [ay1]
      Curve [crv2]

See the ahelp currency page for more information on currency.

Note that the undo() command can be used to restore objects that were accidentally deleted, so

chips-27> undo(2)

not only restores the image but also changes the symbols in the first curve back to their default color (white on screen and black in hardcopy values). See ahelp colors for information on the color support in ChIPS.

Example 5

Axis changes

We now clear out the previous plots and display a light curve, showing how axis ranges and scales can be changed.

chips-28> clear()
chips-29> add_curve("lc1.fits[cols dt,count_rate,count_rate_err]")
chips-30> add_curve("lc2.fits[cols dt,count_rate,count_rate_err]")
chips-31> set_curve("all", ["symbol.style", "none"])
chips-32> limits(X_AXIS, 5000, 30000)
chips-33> log_scale(Y_AXIS)
chips-34> limits(Y_AXIS, 0.1, 100)
chips-35> add_curve("lc3.fits[cols dt,count_rate,count_rate_err]")
chips-36> set_curve(["symbol.style", "none"])

The clear() call removes all existing ChIPS objects, so that the add_curve() call creates a new window, frame, plot and curve. Here we chose to plot the DT column that gives the elapsed time from the start of the obervation rather than the TIME column and also plot up the errors on each bin. Two curves are created, then both are changed to remove the symbol (using the special currency of "all" to indicate all curves in the current plot). Note that the limits on both axes change to ensure that both curves are visible.

In line 32 we change the X axis limits to restrict the plot to the range 5000 to 30000, then we change the Y axis to use a logarithmic scale and then change its range to 0.1 to 100. Since the limits have now been explicitly set, adding a new object to the plot, such as the third light curve in line 35, does not change the limits.

Example 6

Using ChIPS from Python

The ChIPS environment allows you to enter Python commands interactively, but you can also you ChIPS from a Python script. For instance the following code

#!/usr/bin/env python

import sys
from pychips.all import *

def plot_profile(fname):
    make_figure("{}[cols cel_r,cel_bri]".format(fname), "histogram")
    log_scale(Y_AXIS)

def makeplot(fname):
    set_preference("window.display", "false")
    plot_profile(fname)
    print_window("prof.ps", ["clobber", True, "fittopage", True,
                 "orientation", "landscape"])
    print("Created: prof.ps")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        sys.stderr.write("Usage: {} filename\n".format(sys.argv[0]))
        sys.exit(1)

    makeplot(sys.argv[1])

if saved as plot_prof and made executable via 'chmod u+x plot_prof' can be used to create a plot of the radial profile of a source by saying

unix% ./plot_prof prof.fits
Created: prof.ps

where prof.fits was created by dmextract using opt=generic. In the script we set the window.display preference to "false" to ensure that no on-screen window is created, since this code is not meant to be run interactively.


Starting ChIPS

From the CIAO command line, type chips to start the interactive application. The chips application accepts a set of command-line arguments which can be displayed with the '-h' flag:

unix% chips -h
-- chips
  usage: chips [-x] [-n] [-b] [-rcfile file] <file>
     -x       launch chips shell in separate display terminal
     -n       do not print banner
     -b       batch mode
     -rcfile  load a user specifiable preference file
     <file>   Python command file to execute

The "Running ChIPS in batch mode" section describes the -b flag. The contents of the resource file used by the -rcfile flag are described in "ahelp chipsrc".

The startup script loads the ChIPS module, as well as the CRATES module, which handles file input and output ("ahelp crates"). See the "Starting ChIPS" thread has more details.

The ChIPS Resource File: .chips.rc

When ChIPS is started - either directly by the "chips" command or from another CIAO application such as Sherpa - it processes the $HOME/.chips.rc resource file (unless the -rcfile command-line flag is used). The resource file specifies attribute settings for the ChIPS commands and can be customized to the user's preferences; refer to "ahelp chipsrc" for details.

Getting Help

There are several ways to access the ChIPS help files.

From the CIAO command line

Syntax, description and examples for a specific command:

unix% ahelp <command>

Within ChIPS

Within the ChIPS application, ahelp or the native Python help system can be used:

chips> ahelp <command>
chips> ahelp(<command>)
chips> ahelp("<command>")
chips> ,ahelp <command>
chips> !ahelp <command>
chips> help <command>

It is also possible to do a wildcard search:

chips> add*?
chips> *contour?

Loading the ChIPS Module

To import the ChIPS and CRATES modules in Python without using the "chips" startup script:

from pychips import *
from pychips.hlui import *
from pycrates import *

The pycrates module is only needed if you want to use any of its routines for reading files ("ahelp -c crates").

You may also find it useful to load the numpy module

import numpy as np

Loading Advanced ChIPS Functions

A number of ChIPS functions are distributed as a separate module of advanced commands. These functions are primarily those whose capability is available from a higher-level ChIPS command; for instance, set_line_color() was moved because its functionality is available from the set_line() function. More advanced undo/redo commands (e.g. using undo and redo buffers) and software error handling commands were moved to this module as well.

Users who wish to access the advanced commands simply have to load the additional module into ChIPS:

from pychips.advanced import *

Loading all ChIPS modules

The pychips.all module provides a short cut to loading all the ChIPS modules - pychips, pychips.hlui, and pychips.advanced - which means you can use any of:

from pychips.all import *
import pychips.all as pychips
import pychips.all

Tracking down errors

When an error occurs, the default behavior of both ChIPS and Sherpa is to display the error itself but not to display the location of the error (the Python traceback), since this information is often not useful in an interactive environment.

To get this traceback information - e.g. when debugging a Python script - change the sys.tracebacklimit variable to a positive integer; this value controls the number of entries that are displayed (and defaults to 0). For example:

sys.tracebacklimit = 2

Running ChIPS in batch mode

If ChIPS is invoked with the batch-mode option, e.g. "chips -b", the "window.display" preference will be set to false. To have the display on, include a set_preference call at the beginning of the script to set "window.display" to true. In addition, if a connect command is issued within the script, it will automatically disconnects from the chips server if it is attached to one.

ChIPS always requires the presence of a X server, even when used in a script or program which does not produce on-screen plots (e.g. the "window.display" preference has been set to "false"). When a ChIPS server is started, it tries to connect to the X-display indicated by the DISPLAY environment variable, which can result in one of three cases:

DISPLAY environment variable is valid

In this case the ChIPS server will use the indicated X display for its plots.

DISPLAY environment variable is invalid or unset

If the server can not connect to the X display - e.g. the DISPLAY variable is not set or is invalid - then it will try to start up a temporary, virtual, framebuffer using the Xvfb program. If this works then the ChIPS commands will work, including calls to print_window(), but there will be no on-screen display.

No DISPLAY and no Xvfb

If the Xvfb program does not exist on your system then the server will fail to start up and report the following:

chips ERROR: Failed to open DISPLAY or Xvfb session- exiting chipsServer

Starting Xvfb manually

If you know that your program is going to be run with no active X display then you can set up Xvfb manually, and use it, rather than let ChIPS fall through to using it as described above. A simple example follows:

unix% Xvfb :9 &
unix% setenv DISPLAY :9

after which any program using ChIPS will use the virtual frame buffer. This is particularly useful if you plan to run multiple programs or scripts that use ChIPS, since the server will not have to spend time setting up Xvfb itself.

Client-Server interaction

ChIPS is implemented as a client-server system, which allows multiple clients to connect to a single server, as highlighted below. However, by default, the system is set up to use a single client per server, and you can have many servers running at the same time, which means that the following is only needed for advanced applications.

Starting a server

When the ChIPS module is loaded into a Python session, then the client code is loaded. If no server has been joined or created, then the first ChIPS call that requires a server - which is most commands - will automatically start up a new server instance. Alternatively, the connect() routine can be used to connect to an existing servre, or the create_server() routine will start up a new server.

Finding servers

The list_servers() and check_server_exists() commands are used to find out about existing servers. Applications that use ChIPS - such as Prism - may also provide information on the server they are using.

Changing servers

The disconnect() call will stop the connection between a client and server. Note that a ChIPS server will automatically exit when it has no more clients connected to it.

Using multiple clients

If multiple clients are connected to a server then there is the possibility of a race condition if commands from the different clients are sent at the same time. To avoid this a client can use the lock() command to ensure that it will be the only one talking to the server, since any access by other clients during a lock will hang. The lock is broken by the locking client either calling unlock() or closing down. Note that there is no way to tell if a server is locked without trying to access it and seeing if the request hangs.

Using the GUI

The ChIPS GUI creates a new client, as described in ahelp chipsgui.

Changes in CIAO 4.9

Python 3.5

ChIPS is now compatible with Python 3.5. The version available in CIAO depends on the installation; use

% python --version

to check. CIAO 4.9 provides either Python 2.7.11 or 3.5.1.

IPython

The version of IPython shipped with CIAO has been upgraded to version 4.2.0 (it was 3.0.0 in CIAO 4.8). When ChIPS is first started, users may see a warning message about this change (and be required to answer questions about the upgrade).

OS-X fixes

Several hard-to-trigger segfaults have been addressed on OS-X.


Bugs

See the bugs pages on the ChIPS website for an up-to-date listing of known bugs.

See Also

chips
chipsgui, chipsrc, show_gui
concepts
aspectratio, attributes, chipsid, chipsopt, colors, coordsys, currency, depthcontrol, entitycreation, preferences, setget