STScI Logo
STScI Logo
HST
Banner

The PyRAF FAQ

Last edited: 27 Feb 2008, after copied from the June 2004 FAQ Wizard version.


1. Installation


2. Startup


3. Tasks


4. Parameters


5. Graphics


6. General information


1. Installation


1.1. How do I download and install PyRAF?

Instructions for downloading and installing the latest version of PyRAF are available at

http://www.stsci.edu/resources/software_hardware/pyraf/current/download


1.2. I am on a Mac. Can I use PyRAF without running X?

Yes. PyRAF v1.7 (ticket #86) included a beta Mac-native version of PyRAF, that is, a way to run PyRAF natively on MacOS (via Aqua libraries) without calling or linking with or requiring X11. As of PyRAF v1.8, this will be a more stable capability, though we have not yet had a great deal of feedback.

At current, this does not require anything different during installation. It can be activated at run-time with the setting of an environment variable and the use of a native (i.e not X11-linked) version of Python on your Mac (e.g. MacPorts). That's right - no more need to build special X-linked versions of python/matplotlib/tcl/tk/libpng/etc.

To run this version of PyRAF on MacOS:

  • setenv PYRAF_WUTIL_USING_AQUA 1
  • If you don't want to reinstall PyRAF, simply change the top line of your "pyraf" start up script to use a non-X linked version of Python (e.g. /usr/bin/python, etc).
That will provide the basic capability. You will of course also want the automatic focus changing and mouse moving (like PyRAF does on Linux). For this you will need to:
  • install "PyObjC" (pyobjc.sourceforge.net) under the non-X linked Python you are using (note: you may skip this on OS X 10.5 since that comes with PyObjC pre-loaded, though we should state that PyObjC v2.2 is very easy to install via "easy_install")
In addition, if you want to see smooth AGG graphics and scalable fonts, see the matplotlib question in the Graphics below.

Please let us know how it goes.


2. Startup


2.1. How do I execute a Python script when PyRAF starts up?

You can do this, although it is a bit obscure. If the PYTHONSTARTUP environment variable is set to a filename, Python (and PyRAF) execute the Python code in that file at startup. You can do any general Python initialization that you like in that file; it is also possible to do some special initialization if the user is running PyRAF. Here is one approach:

(1) Define PYTHONSTARTUP (if you haven't already):

      setenv PYTHONSTARTUP "/home/rlw/python/pythonstartup.py"
(2) Add this special code in PYTHONSTARTUP:

      # PyRAF initialization
      import sys, os
      executable = sys.argv[0]
      while os.path.islink(executable):
            executable = os.readlink(executable)
      if os.path.split(executable)[1] == "pyraf":
            # this code executes only if this is a pyraf session
            from pyraf import iraf
            startup = iraf.osfn("home$pyraflogin.py")
            if os.path.exists(startup):
                  execfile(startup)
            del startup
      del executable   # clean up namespace
What that does is execute a file in your IRAF home directory named pyraflogin.py, if it exists. (This is similar to the approach the CL uses for home$loginuser.cl.) That file can do whatever initialization you want. It runs in the user's namespace, so it can define variables & functions, do imports, etc. It can also execute pyraf/iraf tasks. Here is a sample:

      # import some Python modules
      import re, urllib
      # set an IRAF environment variable
      iraf.set(mypython="home$python/")
      # run an IRAF task
      iraf.spy()
We will probably eventually migrate this capability into the PyRAF startup file itself so it is easier to use.


2.2. How can I make my PyRAF session start up faster?

Use the 'saveToFile' function to save a copy of your environment to a file, and specify that file on the command line when you start up. Immediately after starting PyRAF, type the command
      saveToFile mystartup.save
or in Python syntax
      iraf.saveToFile('mystartup.save')
Then next time you start up PyRAF, use
      pyraf mystartup.save
to run PyRAF. Depending on how many packages and tasks you define during your startup process, this will start up about twice as fast as the standard login process.

The disadvantage of this approach is that it also restores parameters for any tasks and packages that run during the startup process to their values when you did the save. But that should not be a problem as long as you don't run any complex tasks at startup time. You should repeat this process (starting up PyRAF with no initial save file) when your login.cl or the IRAF system changes.


2.3. Why do I get messages about the "CL script cache" when I start up?

You may see messages when you start up PyRAF:

      Unable to open CL script cache file /home/rlw/iraf/pyraf/pyraf.Database
      Unable to open any CL script cache for writing
This is a sign that you are running a very old version of PyRAF and should upgade to the current version. The old version had some restrictions on running multiple PyRAF sessions simultaneously, but the current version has no such restrictions.


2.4. Why does PyRAF fail on startup with a message about togl.so?

If PyRAF has the following error on start-up, the problem is the directory path to the Togl shared object (togl.so) is not set.

      File "/usr/ra/pyraf/irafimport.py", line 30, in _irafImport
         return _originalImport(name, globals, locals, fromlist)
      ImportError: ld.so.1: /usr/local/bin/python: fatal: togl.so: open
      failed: No such file or directory
One can resolve this issue by adding the togl.so directory path to the default search path for libraries. This can be done by adding the following line to your .setenv file:

      % setenv LD_LIBRARY_PATH /yourToglDirectoryPath:${LD_LIBRARY_PATH}
Togl should be a subdirectory of the directory location where the Tcl/Tk libraries reside. The Togl subdirectory should contain togl.so.


3. Tasks


3.1. How do I define an IRAF task in a Python script?

To define an IRAF task that is defined as a CL script, use the usual 'task' command. On the PyRAF command line, the syntax is familiar from IRAF:

      --> task mytask=home$mytask.cl
Inside a Python script, you must convert this to the equivalent Python syntax:

      from pyraf import iraf
      iraf.task(mytask="home$mytask.cl")
For information on how to define a task that calls a Python function instead of a CL script, see the next question.


3.2. How do I create an IRAF task that calls a Python function?

It is possible to define a Python function that is works just like any other IRAF task. It has parameters that have specific types (integer, string, etc.), are learned and persist between sessions, can be edited with epar, prompt for values, etc. Here is an example.

Create two files, pytestmodule.py and pytest.par. pytest.par is a standard IRAF parameter file that contains the parameter definitions:

      spar,s,a,"spar default",,,"string parameter"
      j,i,h,5,,,"hidden integer parameter"
      bpar,b,h,no,,,"hidden boolean parameter"
      mode,s,h,"al"
The comma-separated fields in this file are the parameter name, type (s=string, i=integer, etc.), mode (h=hidden), default value, minimum value (or choice list), maximum value, and prompt string. See the IRAF documentation and numerous examples of .par files in the IRAF distribution for more information.

pytestmodule.py is a Python file that contains both the Python function definition and the IRAF task definition:

      from pyraf import iraf
      # define a function to be wrapped as an IrafTask object
      def pytest(spar, j, bpar):
         """spar is a string, j is an int, bpar is a boolean; j, bpar are hidden"""
         print "pytest: spar `%s' j `%s' bpar `%s'" % (spar,j,bpar)
         k = j+5
         if bpar:
            print 'bpar true: k=j+5=',k
         else:
            print 'bpar false: k=j+5=',k
      # create the IrafTask object wrapping the function pytest
      # call it 'pytest', with parameters from 'pytest.par'
      t = iraf.IrafTaskFactory(taskname='pytest', value='pytest.par',
function=pytest)

The parameters to the function need to be in the same order as in the parameter file. They do not necessarily need to have the same names as in the .par file (though they do in this example.) When the task is called, the task wrapper takes care of applying constraints (e.g. ensuring that parameters have the right types and that they meet the min/max/choice requirements.) It will also prompt for values for non-hidden parameters. Note that (unlike in IRAF CL tasks) the prompt always happens, even if the parameter is not used in the function, and it happens only once before the function is called.

The 'function' keyword parameter to IrafTaskFactory is what gets called when the task executes. There are no quotes around it (because it is not a string, it is the function itself.) If you want, you can specify a function using the full name, e.g. mod.func for a function 'func' defined in module 'mod'. The function can even be a method of some Python object, in which case it will have access to the instance attributes of that object.

The function is called with the actual values of the parameters (in the above example, a string, an int, and a boolean yes/no value.) If you change the values of the parameter variables inside the function, it does not change the corresponding IRAF parameter values. If you need to change the saved parameter values, you can do this inside the function:

      spar = "new value for spar"
      iraf.pytest.spar = spar
Once you have created the task object, it is automatically available at the pyraf command line:

      --> import pytestmodule
      --> lpar pytest
             spar = spar default    string parameter
               (j = 5)              hidden integer parameter
            (bpar = no)             hidden boolean parameter
            (mode = al)
      --> epar pytest
      --> pytest j=10
      string parameter ('spar default'): abcde
      pytest: spar `abcde' j `10' bpar `no'
      bpar false: k=j+5= 15
The task will also show up in the current package listing you get when you type '?'. Once the task is defined as shown above, you can invoke it from CL scripts too by calling it just like any other task. As far as PyRAF is concerned it is just another IRAF task. Naturally you can't use it from the IRAF CL though.

Currently the only parameter types supported are those used by IRAF tasks. If you pass a Python variable not supported by IRAF (for example, a file handle or module) then the task wrapper attempts to convert it to the requested type. That can lead to some surprising behavior:

      --> iraf.pytest(sys)
      pytest: spar `<module 'sys' (built-in)>' j `5' bpar `no'
      bpar false: k=j+5= 10
Note that the sys module's descriptive string is passed to pytest() instead of the sys module itself.


3.3. How do I set an IRAF environment variable?

At the PyRAF command line, set an IRAF environment variable uses the usual syntax:

      set myenvvar=home$test/
The Python equivalent to this (which you can use inside Python scripts) is:

      from pyraf import iraf
      iraf.set(myenvvar="home$test/")


3.4. How do I redirect output when running tasks in a Python script?

The shell-style redirection used at the PyRAF command line does not work inside Python scripts. Instead, Python tasks have some special keyword parameters (Stdin, Stdout, Stderr) that can be used for input & output redirection. Here are a few examples.

First, here are some simple cases in the command-line syntax:

      --> imhead dev$pix > imhead.stdout
      --> imhead dev$pix >& imhead.stderr_and_stdout
      --> imhead dev$pix >& imhead.stderr_only > imhead.stdout_only
      --> head nlines=5 < .cshrc

The Python syntax equivalents to these are:

      from pyraf import iraf
      iraf.imhead("dev$pix", Stdout="imhead.stdout")
      iraf.imhead("dev$pix", Stderr="imhead.stderr_and_stdout")
      iraf.imhead("dev$pix", Stderr="imhead.stderr_only",
Stdout="imhead.stdout_only")
      iraf.head(nlines=5, Stdin=".cshrc")
When a string is specified for one of these special keyword parameters, it is assumed to be a file name. You can also pass a Python filehandle (e.g., as is returned from the built-in open() function). In fact, any Python object with the necessary read() or write() method can be used. This can be used to implement the equivalent of pipes. In command-line syntax:

      --> imhead dev$pix long+ | head nlines=5
A PyRAF equivalent to this is:

      import StringIO
      fh = StringIO.StringIO()
      iraf.imhead("dev$pix", long=1, Stdout=fh)
      fh.seek(0)
      iraf.head(nlines=5, Stdin=fh)
      fh.close()

Another special behavior of the Stdout keyword is that if it is set to a non-zero integer value, the output of the task is returned as a list of strings, with one string for each output line. For example,

      --> s = iraf.imhead("dev$pix", Stdout=1)
      --> print s
      ['dev$pix[512,512][short]: m51  B  600s']
If such a list of lines is passed as the Stdin parameter, the input is read from it. So another equivalent to the piping example given above is:

      s = iraf.imhead("dev$pix", long=1, Stdout=1)
      iraf.head(nlines=5, Stdin=s)
or even just:

      iraf.head(nlines=5, Stdin=iraf.imhead("dev$pix",long=1,Stdout=1))


4. Parameters


4.1. How can I access CL parameters such as gcur, imcur, list, etc.? How can I do the equivalent of =gcur?

The cl has a number of predefined parameters, e.g. s1, s2, s3. If you assign a value to s1:

      s1 = "test"
then you create a Python variable rather than using the cl variable of the same name.

To avoid this, access the cl parameters using 'iraf.cl.s1' instead. This form can be used both in assigning and retrieving values:

      iraf.cl.s1 = "test"
      print iraf.cl.s1

Getting a graphics cursor position using '=gcur' is just a special case (since gcur is a CL parameter). Its PyRAF equivalent is:

      print iraf.cl.gcur
or, at the interactive command line, simply type:

      iraf.cl.gcur

Note, do NOT accidentally type:

      iraf.cl.gcur()

as the use of the parenthesis is incorrect - 'gcur' is not a function call.


4.2. How do I run epar on a remote terminal (without X Windows support)?

You can't run epar, however you can run tpar - a text-based parameter editor added in PyRAF v1.3.

Note also that you can set parameters by changing the task's attributes as described in the PyRAF Tutorial.


4.3. How can I see the value of a string which is longer than the entry widget in epar?

You can use the left-most mouse button to do a slow "scroll" through the entry, or you can use the middle-mouse button to "pull" the value in the entry back and forth quickly. In either case, just click in the entry widget with the left-most or the middle mouse button and then drag the mouse to the left or the right. If there is a selection highlighted, the middle mouse button may paste it in when clicked. It may be necessary to click once with the left mouse button to undo the selection before using the middle button.

You can also use the left and right arrow keys to scroll through the selection. Control-A jumps to the beginning of the entry, and Control-E jumps to the end of the entry.


4.4. How do I get a list of the parameters for an IRAF task?

In PyRAF, IRAF task objects have a number of methods that can be useful in scripts. The getParList() method returns a list of the task parameters. Here is an example:

      --> from pyraf import iraf
      --> plist = iraf.imhead.getParList()
      --> for par in plist:
      ...     print par
      <IrafParS images s a 'dev$pix' None None "image names">

      <IrafParS imlist s h '*.imh,*.fits,*.pl,*.qp,*.hhh' None None "default
image names">
      <IrafParB longheader b h no None None "print header in multi-line
format">
      <IrafParB userfields b h yes None None "print the user fields
(instrument parameters)">
      <IrafParS mode s h 'al' None None "">
      <IrafParI $nargs i h 0 None None "">
The list returned by getParList() consists of parameter objects that contain the complete descriptions of each parameter. If you print them (as in the example), the string gives the parameter class, name, type, mode, value, minimum, maximum, and prompt string. You can retrieve or change the parameter values using the get() and set() methods:

      --> par = plist[0]
      --> print par
      <IrafParS images s a 'dev$pix' None None "image names">
      --> print par.get()
      dev$pix
      --> par.set('newvalue')
      --> print par.get()
      newvalue
Note that these parameters are actually shared with the original task (they are not copies), so modifying them also changes the task parameters:

    --> lpar imhead
           images = newvalue        image names
          (imlist = *.imh,*.fits,*.pl,*.qp,*.hhh) default image names
      (longheader = no)             print header in multi-line format
      (userfields = yes)            print the user fields (instrument parameters)
            (mode = al)
If you want a completely independent set of parameters, use the Python copy module or the optional docopy parameter to getParList:

      --> plist1 = iraf.imhead.getParList(docopy=1)         # this is a copy
      --> import copy
      --> plist2 = copy.deepcopy(iraf.imhead.getParList())  # so is this
Here are a few other task methods that may be handy for manipulating parameters:

   getDefaultParList() Returns list of all parameter objects with default values.
   getParObject(name)  Returns the IrafPar object for the given parameter.
   getParDict()        Returns dictionary of all parameter objects.  Example:
                       --> d = iraf.imhead.getParDict()
                       --> print d['mode']
                       <IrafParS mode s h 'al' None None "">


4.5. How do I create a copy of a task parameter list and edit it with epar?

The parameter list returned by the getParList() task method (see the previous question) cannot be editted directly using epar. However, you can convert it to an IrafParList object:

      --> from pyraf import iraf
      --> from pyraf.irafpar import IrafParList
      --> plist = IrafParList('imhead', parlist=iraf.imhead.getParList(docopy=1))
IrafParList objects have methods to do various useful things:

      lParam()                Lists parameters in lpar format
      eParam()                Run parameter editor
      dParam()                Print parameters in dpar (assignment) format
      saveParList(filename)   Save parameters to file in .par format
Parameters that have been saved to a file can be used to create an IrafParList as well:

      --> plist.saveParList('mylist.par')
      '5 parameters written to mylist.par'
      --> newplist = IrafParList('imhead', filename='mylist.par')
      --> newplist.eParam()
You can get a complete list of the available IrafParList methods using help(plist).


4.6. How do I save parameters for a task in the uparm directory or in a file?

IRAF task objects have a special method, saveParList(), that saves the current list of parameters to a file in the standard IRAF .par format:

      --> iraf.imhead.saveParList('myfile.par')
      '5 parameters written to myfile.par'
If the filename is omitted, the parameters are saved in the uparm directory in a file with the usual name created from a combination of the task and package. You can print task.scrunchName() to see the filename.

If you just want to insure that the parameters used in the call to an IRAF task get saved in your uparm directory, include the special keyword parameter _save as a task parameter:

      --> iraf.imhead('dev$pix', _save=1)
In the absence of the _save parameter, the parameters used for task execution do not get saved. Note that this is also the default when executing IRAF tasks from CL scripts, but in Python scripts you do have the option to decide that parameters should be saved.

See the answer to the previous question (on making copies of parameter lists and editing them with epar) for more information on using these .par files.


4.7. How do I run a task with a list of parameters?

The task parameter lists from the getParList() method or from .par files (see previous questions) can be used to run an IRAF task with a completely specified set of parameters. This can be a useful way to run the same task with various parameter sets for different purposes. For example, to create a file with a parameter set:

      from pyraf import iraf
      from pyraf.irafpar import IrafParList
      task = iraf.imstat
      plist = IrafParList(task.getName(), filename='mypars.par',
              parlist=task.getParList(docopy=1))
      iraf.epar(plist)
Now we have created the file 'mypars.par' with the desired parameters. To run the task using those parameters, set the special ParList task keyword parameter to the .par filename:

      iraf.imstat(ParList='mypars.par')
or alternatively ParList can accept an IrafParList instead of a filename:

      plist = IrafParList('', filename='mypars.par')
      iraf.imstat(ParList=plist)


4.8. How do I handle when a task's parameter name conflicts with Python syntax?

You might run into a problem calling IRAF tasks that have parameters which conflict with Python reserved words. Here is an example (from ticket #57):

      --> noao               
      --> onedspec
      --> iraf.dispcor(input=specname, output=specname, global='NO')              
        File "", line 1
          iraf.dispcor(input=specname, output=specname, global='NO')
                                                       ^
      SyntaxError: invalid syntax
In this case, the parameter named 'global' matches the Python reserved word with the same name.

However, the parameter's value can be manipulated this way:

      iraf.dispcor.setParam('global','yes')
to set it, and then:
      iraf.dispcor.getParam('global')
to find out the value of this parameter.

You can then call dispcor without specifying the value of this parameter.


5. Graphics


5.1. How do I plot graphics to the image display, xgterm, or any other graphics device?

If the stdgraph environment variable is set to a graphics device for which the CL uses its own built-in kernel (such as xgterm or xterm), PyRAF uses its own built-in graphics window. Since the PyRAF graphics window requires X-windows, you can't run graphics tasks when remotely logged in without X-windows (e.g. through a terminal emulator.)

For most purposes the PyRAF graphics window is preferred. Note that you can run PyRAF in an xgterm terminal window, but the graphics will appear in the standard PyRAF plot window. If you need to use other IRAF graphics devices, do this:

      set stdgraph=stgkern
      iraf.stdgraph.device="xterm"  # or whatever device
This forces the use of the standard IRAF graphics kernel. You cannot run interactive graphics tasks (that read the graphics cursor position, e.g. splot) using this approach, but non-interactive graphics tasks should work. You will generally need to do a gflush to get the graphics to appear.

Setting stdgraph to devices that are not built-in to IRAF (e.g., "stdplot" or "imdr") also works for non-interactive graphics. In that case you do not have to use the special "stgkern" value for stdgraph.

We do plan to add the capability of doing interactive plot overlays on the image display, and we will probably support interactive graphics on some other devices in the future.


5.2. How do I create a new graphics window?

Use the gwm.window() function to create a new graphics window:

      from pyraf import gwm
      gwm.window('New Window Name')
If the new window name is omitted, an unused default name of the form 'graphics<n>' is selected. If a window with the specified name already exists, the graphics focus is switched to that window (so that the next plot will appear there), but the existing window is not modified.


5.3. How do I switch the plots so they go to a different (existing) graphics window?

To switch the graphics focus, use the gwm.window() function with the name of an existing graphics window (the name appears in the window header bar):

      from pyraf import gwm
      gwm.window('graphics1')
The 'graphics1' window is not modified, but the next plot will appear in that window. If a graphics window with the specified name does not exist, a new window is created.


5.4. How do I get a list of the graphics windows, delete windows, etc.?

There are functions in the pyraf.gwm module that can be used to manage the graphics windows:

  gwm.window([windowName])        Create new window or switch focus to
                                  existing window
  gwm.delete([windowName])        Delete specified window (active window if
                                  name is omitted)
  gwm.raiseActiveWindow()         Raise the active window to the front on
                                  the screen
  gwm.getActiveWindowName()       Returns name of the active window
  gwm.getGraphicsWindowManager()  Returns the graphics window manager object
The latter function can be used to get a list of all the graphics windows:

      --> wm = pyraf.gwm.getGraphicsWindowManager()
      --> print wm.windows.keys()
      ['graphics2', 'graphics1']
The windows attribute is a dictionary with entries for all existing graphics windows.


5.5. How do I print a plot?

There are several different ways to print or save a plot displayed in the graphics window.

The File->Print graphics menu item can be used to print the current plot on your default IRAF printer, as specified by the stdplot variable.

pyraf.gki.printPlot() can be called from a Python script (or typed at the PyRAF command line) to do the same thing.

In gcur mode -- while running an interactive IRAF graphics task so the crosshair cursor is visible in the graphics window -- typing an equal sign = or the colon command :.snap prints the plot.

The File->Save graphics menu item can also be useful for printing. It allows you to save the graphics metacode for the current plot to a file. That metacode can be later loaded back into the graphics window (using File->Load) and can also be printed using special purpose IRAF tasks. For example, the plot.stdplot task takes a metacode file as input and prints the result to the stdplot output device.


5.6. Can I automate igi graphics using a native python script?

Yes! Use the "Stdin" facility. Put the igi commands you wish to execute in a list, with each item in the list being a command line, for example:

      from pyraf import iraf
      from iraf import stsdas, graphics, stplot, igi, gflush
      s = ['zsection "myimage[100:300,500:600]"']
      s = s + ['location 0.1 0.9 0.1 0.9']
and so on, and then

      s = s + ['end']   # don't forget to terminate the igi script
      igi(Stdin = s)    # execute the commands
      gflush            # flush the graphics buffer.
If you've set up igi for postscript output ('psi-port' or 'psi-land'), this should produce an eps file.


5.7. Why do I get an X Error (X_QueryColors, BadValue) using "epar" on Linux?

Some Linux users are seeing a color-related X Error with 2007/2008 versions of their X server. This may appear during a call to eparam or during a plot. The error looks like the following:

     --> epar display
     X Error of failed request:  BadValue (integer parameter out of range for
operation)
       Major opcode of failed request:  91 (X_QueryColors)
       Value in failed request:  0xff141312
       Serial number of failed request:  2524
       Current serial number in output stream:  2524
This seems to be due to a change in the default behavior of the Xorg X server software (v7.2 or v7.3). By default, the "Composite" extension is now enabled, but this causes color depth conflicts with PyRAF graphics. Composites are used for some 3-D rendering effects (e.g in Mandriva), but if you do not directly rely on this extension, the problem can be easily resolved by disabling the extension. To do so, place these lines in your system's "xorg.conf" file:
     Section "Extensions"
        Option "Composite" "Disable"
     EndSection
and then restart your X server (a reboot may be necessary).

As an alternative, "Nedit" users found a work-around for the same issue by setting the XLIB_SKIP_ARGB_VISUALS environment variable. In (t)csh:

     > setenv XLIB_SKIP_ARGB_VISUALS 1
     > pyraf
The topic is discussed in this Nedit thread.

Also, if you do not yet have an Xorg configuration file (e.g. some Fedora Core 10 installs do not have one in /etc/X11/xorg), you may generate one via:

  1. as su, type "yum install system-config-display"
  2. type 'system-config-display' and configure proper display and video driver

Note that color depth issues in general may be debugged by running "xwininfo" and clicking on any GUI components in question.


5.8. Can I plot via matplotlib for smoother plot lines and fonts?

Yes! PyRAF is now able to plot using a matplotlib graphics kernel (since v1.6, ticket #80). The use of anti-grain geometry (AGG) has the advantage of making plot lines look smoother, and matplotlib's own builtin fonts produces plot text that is more legible at varying window sizes.

PyRAF does not make matplotlib an installation requirement, so as to leave installation as simple as possible. However, if the user has matplotlib installed on their machine (with the TkAgg back-end), they may enable the matplotlib graphics kernel by simply setting an environment variable:

      setenv PYRAFGRAPHICS matplotlib

Note that PyRAF does receive plotting instructions at a very low level (GKI), so there are limits to how much matplotlib widgetry can be brought to bear inside the PyRAF graphics windows.


6. General information


6.1. Why do I get a syntax error when what I've typed is perfectly legal IRAF CL syntax?

Most likely because you either typed the name of a package or task that has not yet been loaded or you are trying to use CL syntax that doesn't begin with a task, package, or keyword name (for example, =gcur). In the first case, if PyRAF does not see the task name in the list of currently loaded tasks, it assumes what you typed is in Python syntax and treats as such. This will generally lead to some syntax error. Likewise, if you don't start the line with a name of some sort, PyRAF assumes that you are typing a Python statement.


6.2. Why don't the IRAF 'del' or 'print' commands work?

Because these are also Python keywords. The PyRAF interpreter also allows Python statements, so we do not allow any CL mode commands to start with Python keywords. Type 'clPrint' (note the capital P) to execute the IRAF 'print' command (although the Python print statement should usually suffice). Type more of the IRAF 'delete' command, e.g. 'dele', to remove the ambiguity with the Python del statement.


6.3. Why can't I recall commands in a Solaris cmdtool window?

This is the result of a bug in cmdtool, not a problem with PyRAF. For example, if you try to run tcsh in the window, it has the same problem (it appears to ignore the arrow keys.)

The fix is to turn off the cmdtool scrollbar by right-clicking in the window and selecting 'Disable Scrolling' from the 'Scrolling' menu. Or you can use another type of terminal window (e.g., xterm) instead of cmdtool.


6.4. Why do I get an error when I try to print to a pipe (e.g, when running scan or scanf)?

This results in an error:

      --> print ("382 4783") | scan(i,j)
      Traceback (innermost last):
         File "<console>", line 1, in ?
      NameError: scan
This problem is caused by mixing Python syntax with CL syntax. The print statement is interpreted in Python mode (because "print" is a Python keyword and also because it has an open parenthesis). That puts the whole line into Python mode, so scan is not found. The command will work fine inside a CL script (since it is legal CL even if it is not legal Python.) In PyRAF you can do this:

      --> clPrint "382 4783" | scan(i,j)
      --> print iraf.cl.i, iraf.cl.j
      382 4783

Note that you have to use clPrint instead of just print to avoid conflicts with the Python print command, and you have to leave the parentheses off the clPrint to get into CL emulation mode so the pipe is properly translated. Also note the somewhat awkward syntax for accessing the CL parameters i, j (which are not the same as Python variables i, j).

In Python code (including at the PyRAF command line) there are better alternatives to scan. Here's one Python approach:

      --> f = string.split("382 4783")
      --> print f
      ['382', '4783']
      --> i = int(f[0])
      --> j = int(f[1])
      --> print i,j
      382 4783
Or if you want a 1-line alternative:

      --> i, j = map(int, string.split("382 4783"))
The combination of the Python string and re modules for string processing is generally more powerful than scan/scanf, and the results go into simple Python variables instead of CL task parameters.


PyRAF home / Feedback to help@stsci.edu

Copyright  | Help  | Printable Page