FLY2 File

The FLY2 File is the successor to the FLY File of SIMION 7.0 and is significantly more flexible. Details on FLY2 are available in the FLY2 appendix of the 8.0/8.1 SIMION User Manual.

See also Particle Initial Conditions.


This page is abridged from the full SIMION 8.1.1 "Supplemental Documentation" (Help file). The following additional sections can be found in the full version of this page accessible via the "Help > Supplemental Documentation" menu in SIMION 8.1.1:
  • Sequences in FLY2 Files

Custom Distributions in FLY2 files

As of 8.0.4-TEST2, a custom distribution can be incorporated in a FLY2 file as Lua code. To do this, the FLY2 file must be edited as text in a text editor since it cannot be done via the GUI. Create your own Lua function that returns random numbers, pass this function to the distribution function, and use that wherever you need inside the particle definitions. Here’s a simple example:

function my_dist() return simion.rand() ^ 2 end
particles {
  standard_beam {
    n = 100,
    mass = 10, charge = -1,
    ke = distribution(my_dist)

The following example FLY2 file defines a chi-square distribution in terms of a Gaussian distribution and uses this in the particle definitions:

local STAT = require "simionx.Statistics"

function chi_square3()
  local stdev = 1
  local mean = 5
  return (STAT.gaussian_rand()^2 + STAT.gaussian_rand()^2
          + STAT.gaussian_rand()^2) * stdev + mean

particles {
  standard_beam {
    n = 10,
    ke = distribution(chi_square3)

To check this is working properly, temporarily change “How are particles defined?” to “Individually (.ION)” on the particle definition screen and examine the definition of each particle. Make sure that the KE parameter is properly randomized.

There are techniques as well as preexisting routines for generating random variables according to various distributions. The rand() function returns returns uniformly distributed random numbers between 0 and 1. The STAT.gaussian_rand() function used above returns Gaussian distributed random numbers with mean 0 and standard deviation 1. Some distributions like chi_square() can be written in terms of others or generated by various algorithms. Consult Wikipedia for details on specific distributions.

Further information is Post 3325 and Post 1618.

Be careful not to save the FLY2 file from the SIMION GUI because that will overwrite your custom code in an expanded form.

Another approach is to use an ION File with individual particle definitions generated from external software. See Particle Initial Conditions.

Programmatically Defining Particle Sets (Advanced)

You can also programmatically build the beam definitions in the FLY2 file, like this:

-- Use "for" loop to build the table passed to "particles".
local t = {coordinates = 0}
for i=1, 10 do
  local x = i^2 + i
  t[#t+1] = standard_beam {
    n = 1,
    tob = 0,
    mass = 0.00054857990946,
    charge = -1,
    ke = 0.1,
    position = vector(x, 1, 0)
    direction = vector(1, 0, 0)

or this:

local function round(x) return math.floor(x+0.5) end
local xoffset = 1
local yoffset = 1
local zoffset = 1

-- Define an array of line sequences.
local t = {}
for jj=0,5 do
  t[#t+1] = line_sequence {
    first = vector(xoffset-(10-jj),yoffset+round(jj*math.sqrt(3)),zoffset),
    step = vector(1,0,0),
    n = 20-2*jj

particles {
  standard_beam {
    position = concatenated_sequence(t)

What is meant by window and pupil?

Windows and pupils are described some in the FLY2 appendix of the 8.0/8.1 SIMION User Manual, but some more explanation is given here. This is a way to define a beam by two apertures, referred to here as the window and the pupil. For each point on the window aperture and each point on the pupil aperture, a ray originates at the window point and is directed toward the pupil point. This could be an infinite number of rays, so we only same a representative subset of them to trace (Monte Carlo Method). However, a ray only reaches its intended pupil point if it travels in a straight line (field free), which is likely an approximation. If you specify either a window or pupil in the FLY2, then the “source position” will be interpreted as the other of the two apertures. Particles always start tracing from the source position.

 -- Example: Create randomized circular beam with window and pupil.
 standard_beam_define {
   n = 100,
   position = disc_distribution {  -- i.e. the window aperture
     center_position = {0, 0, 0},
     axis_direction = {0, 1, 0},
     radius = 2
   pupil_position = disc_distribution {
     center_position = {0, 10, 0},
     axis_direction = {0, 1, 0},
     radius = 1

The pupil contains a set of points. The window contains another set of points. The FLY2 file allows these sets to be sampled with either sequences or distributions. A sequence has the usual mathematical meaning: an ordered list of values. A distribution also has the usual mathematical meaning: values from the set are randomly sampled with certain probabilities (like simion.rand()). In a way, both are similar since both can create a sequence of values, though the latter sequence tends to be nondeterministic and its length is unbounded.

For each ray created, to choose the coordinates of the window point (x1,y1,z1) and and pupil point (x2,y2,z2), we sample the next value of (x1,y1,z1) from the sequence or distribution for the window and the next value of (x2,y2,z2) from the sequence or distribution in the pupil. If both the source and window are sequences of size M and N respectively then all M x N combinations of points are sampled in lexicographic order (like a Cartesian product).


This page is abridged from the full SIMION 8.1.1 "Supplemental Documentation" (Help file). The following additional sections can be found in the full version of this page accessible via the "Help > Supplemental Documentation" menu in SIMION 8.1.1:
  • Passing parameters to FLY2 files for different runs
  • Making x, y, and z distributions dependent
  • Ellipse
  • Rotating particles in cylindrical symmetry to 2D plane
  • Lorentz Distribution
  • Lambert Cosine
  • Rejection Sampling
  • Rectangular Pupil

Converting to an ION file

A FLY2 file can be converted into an ION File by loading the FLY2 in the SIMION Particles Define screen, switching How are particles defined? to Individually (.ION) and then saving.

Here is an undocumented way to do that programatically:

local fh = assert('1.ion', 'w'))

Disabling Randomization

If a FLY2 file contains distributions, it will give different particles on each run. Sometimes for testing you want runs to be repeatable and therefore want to disable this randomization. To disable randomization convert the FLY2 file to an ION file, as described above.

Alternately, seed the random number generators at the top-level of your workbench user program:

math.randomseed(1); simion.seed(1)

You may want to seed both random number generators as above since we may change the FLY2 to use the real SIMION random number generator (rather than the Lua one).

An option in the FLY2 file to do this directly is currently not available (TODO?):

particles {

Other advanced uses of FLY2 files include

  • quadrilateral.fly2 - See SIMION Example: misc (quadrilateral.fly2, 8.1, 2016-12-15) for an example of a FLY2 with starting points within an arbitrary quadrilateral, either uniformly or randomly distributed.
  • SIMION Example: field_emission (fe_rays.fly2) defines particle emission as a function of the electric field magnitude over an electrode surface (Fowler-Nordheim emission). Inside the FLY2 file, it uses the simion.pas API to read the fields from a PA. fe_rays.lua also uses a technique similar to SIMION Example: random_fly2.


  • 2014-07-21: Allow charge weighting factor (CWF) to be negative in particle definitions–useful for Poisson solver piclib.lua.