Test Plane

A test plane is designed to record information about particles when they intersect the plane.

The most basic way to utilize test planes is the “Crossing Plane X/Y/Z=” option in Data Recording. See “Selecting When to Record” in the SIMION User Manual [8.0/8.1] for details (Section 8.6.7 in 8.0/8.1, p. 8-23 in 7.0).

A yet more flexible approach utilizing one or more test planes that may or may not be orthogonal to the axes and that are controlled programmatically is shown in SIMION Example: test_plane [8.0.5].

Examples

Q: How do I use the test plane library?

As seen in SIMION Example: test_plane, the way it works is you first copy the testplanelib.lua into your project (IOB) folder and import the library into your Lua code. Then define a test plane object specifying a point on the plane, a vector normal to that plane, and a function to call when particles cross that plane:

local TP = simion.import 'testplanelib.lua'

local test3 = TP(80,0,0, 1,1,0,
  -- example of function to call on reaching test plane.
  function()
    print(ion_number, ion_vz_mm)
  end
)

Then you need to call the segments in this test plane from your own segments. There are only two segments to call:

function segment.tstep_adjust()
  test1.tstep_adjust()
end
function segment.other_actions()
  test1.other_actions()
end

You can add your own code to those segments. You can define multiple test planes if you want, like in the original example.

That’s one way to do this. There are other ways simply by adding your own code inside an other_actions segment:

simion.workbench_program()

local seen = {}  -- avoids multiple calls per particle
function segment.other_actions()
  if ion_px_mm >= 10 and not seen[ion_number] then
    print(ion_number, ion_vz_mm)
    seen[ion_number] = true
  end
end

That’s roughly what the test plane library does internally, although the test plane library also adjusts times steps to ensure other_actions is called precisely when the particle crosses the plane rather than having time steps occur slightly before and after the plane crossing.

Q: How can I record data at every certain fixed distance step size, similar to the ‘time markers’ feature but for position.

You can use test planes SIMION Example: test_plane. to create a series of test planes like this in a user program:

simion.workbench_program()
local TP = simion.import 'testplanelib.lua'

local planes = {}
for i=1,20 do
  local plane = TP(i*2,0,0, 1,0,0, function() mark() end)
  table.insert(planes, plane)
end

function segment.tstep_adjust()
  for i=1,#planes do planes[i].tstep_adjust() end
end

function segment.other_actions()
  for i=1,#planes do planes[i].other_actions() end
end

The above defines 20 test planes along a series of x positions and each time a particle crosses the test plane it creates a marker. You can use Data Recording to record “When=All Markers”.

Q: How can I change the test plane by adjustable variables or across multiple runs?

To do this, you must define the test plane from within a segment, not the top-level of the program. The top level is only executed once at the very start of the Fly’m and before user changes to adjustable variables from the Variables tab are read. The initialize_run or flym segment can be good for this purpose:

simion.workbench_program()
local TP = simion.import 'testplanelib.lua'
adjustable xtest = 100
function segment.flym()
  for i=1,3 do
    xtest = i * 100
    run()
  end
end
local test1
function segment.initialize_run()  -- called at beginning of each run in Fly'm
  test1 = TP(xtext,0,0, 1,0,0, function()
    print(ion_px_mm, ion_py_mm, ion_px_mm)
  end)
end
function segment.tstep_adjust()
  test1.tstep_adjust()
end
function segment.other_actions()
  test1.other_actions()
end

See Also