Shadow backend

This is a deprecated backend. raycing is much more functional. Module shadow works with shadow input files, starts the ray-tracing and gets its output.


Shadow3 is not supported.


xrtQook and xrtGlow do not work with this backend. A beamline created in Shadow cannot be visualized by xrtGlow.

Description of shadow

… can be found in the manual pages of your shadow distribution. In connection with using shadow in xrt, it is important to understand the naming of the output beam files and the naming of parameters in the setup files.

Preparation for a shadow run


on shadow under Windows Vista and 7:

Under Windows Vista and 7 shadow does not work out of the box because of epath (a part of shadow) reporting an error. There is a workaround consisting of simply stopping the Windows’ Error Reporting Service.

Create a folder where you will store your ray-tracing script and the output images. Make it as Python’s working directory. Create there a sub-folder tmp0. Put there your shadow project file along with all necessary data files (reflectivities, crystal parameters etc.). Run shadow and make sure it correctly produces output files you want to accumulate (like star.01).

Now you need to generate two command files that run shadow source and shadow trace. These are system-specific and also differ for different shadow sources. Under Windows, this can be done as follows: set the working directory of shadowVUI as your tmp0, run Source in shadowVUI and rename the produced shadowvui.bat to shadow-source.bat; then run Trace and rename the produced shadowvui.bat to shadow-trace.bat.

Try to run the generated command files in order to check their validity.

If you want to use multi-threading then copy tmp0 to tmp1, tmp2 etc. (in total as many directories as you have threads).

Scripting in python

The simplest script consists of 4 lines:

import xrt.runner as xrtr
import xrt.plotter as xrtp
plot1 = xrtp.XYCPlot('star.01')
xrtr.run_ray_tracing(plot1, repeats=40, updateEvery=2, threads=1)

Modifying input files

There are two types of input files in shadow:

  1. Of ‘Namelist’ or ‘GFile’ type (both are in terminology of shadow). These are parameter files which consist of lines field = value. Examples of this type are: start.xx and end.xx. Such files describe optical elements and two sources: geometrical and bending magnet.
  2. Of a non-named type consisting of lines of values, one value per line. Examples are xsh_input_source_tmp.inp and xsh_nphoton_tmp.inp. Such files describe two other sources: wiggler and undulator.

If you want to run a series of ray tracing studies for variable physical or geometrical parameters (e.g. for a variable meridional radius of a focusing mirror), you have to find out which parameter in the shadow’s input files controls the desired variable. The only way for this is to play with the parameter in a GUI (I use shadowVUI) and look for changes in the corresponding start.xx text file. Once you have discovered the needed parameter, you can change it in your Python script. There are two functions for this:

xrt.backends.shadow.modify_input(fileNameList, *editlines)

modifies a shadow text input file (like start.NN) which consists of lines field = value.

fileNameList: str or list of str
A list of file names is useful when executing shadow in parallel in several directories.

editlines: list of tuples of strings (field, value).

0 if successful, otherwise -1.
>>> modify_input('start.00',('istar1',str(seed)))  #change seed

xrt.backends.shadow.modify_xsh_input(fileNameList, *editlines)

modifies a shadow xsh text input file (like xsh_nphoton_tmp.inp) which consist of lines of values, one value per line.

fileNameList: str or list of str
A list of file names is useful when executing shadow in parallel in several directories.
editlines: list of tuples (fieldNo: int, value: str)
fieldNo is zero-based index of the modified parameter.
0 if successful, otherwise -1.
>>> modify_xsh_input('xsh_nphoton_tmp.inp', (2, energyRange[0]),
                     (3, energyRange[1]))

The 1st parameter in the above functions is a simple file name or a list of file names. If you run with several threads or processes then you must modify all the versions of the shadow input file in the directories tmp0, tmp1 etc. The following function helps in doing this:

xrt.backends.shadow.files_in_tmp_subdirs(fileName, processes=1)

Creates and returns a list of full file names of copies of a given file located in the process directories. This list is needed for reading and writing to several versions of one file (one for each process) in one go. Useful in user’s scripts.

>>> start01 = shadow.files_in_tmp_subdirs('start.01', processes=4)
>>> shadow.modify_input(start01, ('THICK(1)', str(thick * 1e-4)))

Writing a loop generator

A sequence of ray tracing runs is controlled by a generator (a function that returns by yield) which modifies the shadow input files, optionally specifies information text panels, define the output file names etc. in a loop. The same generator is used for normalization, if requested, when it is (quickly) run in the second pass.

Consider an example:

import xrt.runner as xrtr
import xrt.plotter as xrtp
import xrt.backends.shadow as shadow
plot1 = xrtp.XYCPlot('star.01') #create a plot
textPanel = plot1.fig.text(0.88, 0.8, '', transform=plot1.fig.transFigure,
  size=14, color='r', ha='center') #create a text field, see matplotlib help
threads = 2
start01 = shadow.files_in_tmp_subdirs('start.01', threads)
def plot_generator():
    for thick in [0, 60, 400, 1000, 1500]: #thickness in um
        shadow.modify_input(start01, ('THICK(1)', str(thick * 1e-4)))
        filename = 'filt%04imum' %thick #output file name without extension
        plot1.saveName = [filename + '.pdf', filename + '.png']
        textPanel.set_text('filter\nthickness\n%s $\mu$m' %thick)

xrtr.run_ray_tracing(plot1, repeats=40, generator=plot_generator,
  threads=threads, globalNorm=True)