Basic Concepts

Basic pyXSIM Concepts

In this section we will describe some basic concepts of pyXSIM that one should familiarize themselves with.

“Photon” Lists vs. “Event” Lists

If one is attempting to create synthetic observations for use with instrument models, this is done by first creating a “photon list”, which is then used to create an “event list”. The first is a sample of photons with cosmologically redshifted energies that are distributed in 3D, associated with their original cells or particles. This is a large sample that is then used to create the event list, at which point a line-of-sight observation direction is chosen, which projects the photons to the sky plane and shifts the photon energies via Doppler shifting from the line-of-sight velocity of the originating cell.

These concepts are described in more detail in Overview of pyXSIM’s Photon Lists.

SIMPUT Catalogs

The SIMPUT standard is a FITS file format used by pyXSIM to convert event lists (mentioned above) to a format that can be read in by instrument simulation software such as SOXS, SIXTE, MARX, or SIMX. See Producing Realistic Observations Using External Packages for more details.

pyXSIM Limitations

pyXSIM currently has the following limitations, which may or may not be lifted in the future:

  • pyXSIM is currently unable to simulate any sources with any optical thickness, self-absorption, or self-scattering.

  • pyXSIM is currently unable to simulate any sources with explicit time dependence.

  • pyXSIM is currently limited to datasets in Cartesian coordinates.

Basic yt Concepts

In this section we will outline some basic yt concepts that you will need to familiarize yourself with in order to use pyXSIM effectively. If you are familiar with how yt works, you can safely skip this section.


Most commonly, one will be working with a dataset that was generated by some simulation code, i.e. FLASH, Enzo, Athena, etc. These datasets are loaded using yt.load:

ds = yt.load("sloshing_nomag2_hdf5_plt_cnt_0150")

Alternatively, if you have data from a non-supported dataset format or some 3D arrays that were generated from scratch, there are a number of ways to create in-memory datasets in yt.

Data Objects

Once you have a dataset object, it can be used to create geometrical “data objects” in three dimensions in yt. For example, to create a sphere, one would use:

sp = ds.sphere("c", (1.0, "Mpc"))

where the first argument is the center of the sphere (here "c" means the center of the simulation domain) and the second is the radius, which is given as a (value, unit) tuple. One could also have supplied a particular coordinate value such as [0.1, 0.3, 0.5] for the center.

As another example, to create an object containing all of the data in the simulation domain, use:

dd = ds.all_data()

Other data objects can be created–for more information about the various data objects and the options to use to create them, check out the yt documentation on data objects.

Unitful Quantities

yt employs a symbolic unit system when dealing with physical quantities with units. pyXSIM uses yt’s unit system to keep track of the units of various quantities such as exposure times, effective areas, distances, energies, etc. You can read more about the yt unit system and how it works here.

Most routines in pyXSIM which ask for unitful quantities will accept them in one of three forms:

  • A YTArray or YTQuantity with the correct dimensions, i.e. YTArray([30., 45.], "deg")

  • A (value, unit) tuple with the correct dimensions, i.e. (3.0, "keV")

  • A floating-point number, in which case default units will be assumed

In the latter case, the default units for various dimensionful quantities are:

  • Length (for distances to sources): \(\rm{Mpc}\)

  • Time: \(\rm{s}\)

  • Velocity: \(\rm{km/s}\)

  • Area: \(\rm{cm^2}\)

  • Energy: \(\rm{keV}\)

  • Angle: \(\rm{degree}\)

To be on the safe side, it’s always recommended to provide some unit information, since the units will be checked for correct dimensionality and will be converted if necessary.

Field Specifications

This means that whenever pyXSIM accepts a field specification as an argument, it will need to be in one of the following two forms:

  • A string (yt will look up the field by its name). Examples are: "density", "particle_velocity_x", "temperature", "emission_measure", etc.

  • A tuple of two strings, the first string specifying the field type and the second specifying the field name. Examples are: ("gas", "density"), ("PartType0", "Temperature"), etc.

Either way of specifying fields is acceptable, but if you want to make absolutely sure you get the correct field, it is better to specify in the second form, since this will correspond to a unique field.