Você está na página 1de 7

gem files - a quick guide

May 30, 2017

1 Introduction
A gem file is a text file which contains sequential instructions to create the
elements of the simulation. There are various commands that can be used to
construct the world structures, but here only the most important will be revied
(the others can be found in the documentation).
Gem files couple the geometrical description system to LUA commands.
LUA is a programming language written by two brazillian fellows; it is of note
because it’s the language the very good media player VLC is written into. It
is possible to insert LUA statements in the gem files, provided that each LUA
statement is preceded by a #. They are extremely useful to define constants and
to include parametric elements in the simulation (i.e. arrays of field shaping
rings). Comments can be inserted in the code, preceeding them with a ;.
Before starting the description of the commands, it is important to under-
stand that they follow a nested structure, which means that each command can
be found only in certain parts of the code itself, nested into others: for example,
the program will get angry if it finds an electrode statement nested into a box
statement, as electrode is one of the most external commands (in fact is the
outermost used in the definition of, yeah, electrodes). The commands that re-
quire numerical arguments all have some defaults presets. One can then ignore
what it is not needed, provided that the missing argument is still accounted for.
For example, if one wants to locate the origin 100 workplane point further along
z, without touching x and y, he could write: locate( , , 100)
More on this later, when the locate command is described. Suffice to say
that the two missing spots followed by commas mean that the default value for
x and y is taken, which for the "locate" command is 0 for both the coordinates.
More on that later.

2 gem statements
pa_define(nx, ny, nz, Symmetry, Mirror, Type, ng)
It’s usually the first (or one of the first) statements one finds into gem files,
and it is the one that defines the potential array itself and its features. This

1
command doesn’t require anything else nested into it.
nx and ny are the xy dimensions, in workplane points. Minimum is 3. nz
is the z dimension. Minimum is 1 (defining a 2D array). Larger values imply a
3D array.
Symmetry can be either cylindrical or planar. A c or p will suffice (the
compiler only checks the first letter).
Mirroring can be None, X, Y, Z, XY, YZ, XZ, XZY.
• 3D array - all mirroring legal;
• planar 2D - all mirroring legal except Z;

• cylindrical 2D - Y mirroring required, X legal, Z illegal.


Type can be Electrostatic or Magnetic - again E or M will suffice.
ng is the magnetic scaling parameter (not discussed).
Example:

pa_define(101,51,71,p,yz,m,30)

electrode(potential)
Define fill point type of electrode and its associated potential to use.
Example:

electrode(200) ; defines an electrode of voltage 200V


{

fill{...} ; will be used to determine what’s the shape of the electrode


}

fill{ }
Tells the compiler it has to start taking into account what happens into the
volumes nested into it.
Fill{} by itself doesn’t have arguments or values, but it requires the inclu-
sion of at least one (or more) within or notin instruction (or within_inside
and notin_inside - more on all these commands later).
Example:

fill
{
within{ circle(0,0,20) }
within{ circle(100,10,20) }
notin_inside{ circle(0,10,10) }
notin_inside{ circle(100,20,10) }

2
}

This Fill command contains two within and two notin_inside. The structure
is self-explicating: the within/notin commands require additional commands
to be nested into them. The first two within create filled circles in position (0,0)
and of radius 20 the former; and in position (100,10) with radius 20 the latter.
notin_inside "fills with void" the associated circles (with the caveat that, if a
point defined by the nested instruction is onto the surface modelled by SIMION,
it is not emptied); the result of these instructions will be the creation of two
hollow spheres.

It is fundamental to keep in mind that, at the level of gem files,


SIMION works in terms of WORKPLANE POINTS. This means that
curved surfaces are going to be very "pixellated", instead of smooth.
Of course, if the structure is large (or, conversely, the scale factor is
very small), the resulting 3D representation is going to be smooth;
but still, a sphere looks like as if it’s made of LEGO blocks. This
means that "radii" of spheres don’t always correspond to a fixed
number of workplane points: along the vertical, for example, the
first hollow sphere could have an external radius of 20 wp, and an in-
ternal radius of 10 wp, but along a diagonal direction these numbers
could be, of course, different.

within{ } or within_inside{ }
These commands, nested into Fill{} statements, tell the compiler that what’s
nested into them (typically a shape) must be solid, filled, as if turned black in
the drawing section of the program. Again, the difference between the within
and within_inside lies in the treatment of border points, which are filled in
the first case, left empty in the second.
Example:

fill{
within{ sphere(0,0,0,50,30,50) }
notin{ sphere(0,0,0,45,25,45) }
}

This creates the right half of an ellipsoid shell (more on the "sphere" statement
later) centered at (0,0,0) with an outer radius of (50,30,50)wp and an inner
radius of (45,25,45)wp.

notin{ } or notin_inside{ }
Analogously to their within counterpart, these commands empty the points
described by the entity nested into them.

3
locate(x, y, z, scale, azimuth, elevation, rotation){ }
Redefines the position of the origin in the gem file. During the writing of the
gem file for the spectrometer, for example, it was useful to locate the origin in
the position of the source.
NOTE: this shift in the origin affects only the writing of the gem file, not
the simulation itself! For example, in the gem file the source was in position
(1825,0,0)wp, with the first electrode of the electron spectrometer in position
(1925,0,0). After the locate, the origin of the gem file was on the source, and
thus when writing the code for the first electrode of the electron spectrometer
was in position (100,0,0). After compiling the simulation, though, the position
of the source is the usual (1825,0,0), not (0,0,0)! locate is a very useful tool to
move around the origin for ease of drawing.
The description of the arguments of locate requires the definition of internal
coordinates and external coordinates, contraptions defined by SIMION for the
description of its simulation; personally I have never used anything more than
x, y and z, and left the rest at its default values. Additional informations are
present in the documentation.
It is interesting that locate statements can be nested into each other. In
that case, the nested locate take as the origin the position of their parent
statement.
Example:

fill
{
locate(100,100,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
}
locate(100,50,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
}
locate(50,50,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
}
locate(50,100,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
}
}

4
This code draws 4 circles separated by a certain amount of space. After each
locate, the origin switches back at the usual (0,0,0) of the drawing environment.
But then, the code can be rewritten like this:

fill{
locate(100,100,0){ ; outermost
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
locate(0,-50,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
locate(-50,0,0){
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
locate(0,50,0){ ; innermost
within{ circle(0,0,10) }
notin{ circle(0,0,7) }
}
}
}
}
}

The innermost locate is the fourth, while the first is the outermost. In sequence,
the first moves the origin in the top-right corner; then from there it moves to the
bottom-right corner; then to the bottom-left corner; and finally in the top-left
corner.
It is evident that a configuration like this - since the snippet of code to
actually draw the circle is always the same easily lends itself to the use of
recursive statements, that will be implemented in LUA.

3 Shapes
The gem syntax can recognize a lot of shapes; the informations regarding them
can be found in the documentation. Shapes are usually the innermost compo-
nents of the code, showing up nested into fill{within{...}} statements. Here
are the most useful, in general.

box(xmin, ymin, xmax, ymax)


Defines a box whose boundaries are given by its arguments. Note that when
working with a cylindrical geometry, boxes will turn into rings. box was the
most used shape in the drawing of the spectrometer.

5
circle(xc, yc, rx, ry)
Defines a circle or ellipse. xc and yx are the coordinates of the center; rx and
ry the values of the x and y radii. If ry is left blank, it will default to rx.

polyline(x,y, x,y, ...)


Defines a polyline whose segment edges are at the various x,y coordinates.

The following shapes will be most useful in a 3D environment.

box3d(xmin, ymin, zmin, xmax, ymax, zmax)


Defines a 3D box. Arguments are self-explicating.

cylinder(xc, yc, zc, rx, ry, length)


Defines a circular or elliptical cylinder. If ry is not specified, it will default to
rx.

NOTE: length is always converted to its absolute value and extends


in the minus z axis direction. This means that to draw a cylinder,
xc, yc and zc define the position of the "top" base, and the cylinder
will extend "downwards".

sphere(xc, yc, zc, rx, ry, rz)


Defines a sphere centered in (xc,yc,zc) and with matching radii. If ry is blank,
it will default to rx; if rz is blank, it will default to ry.
These are the main commands recognized by the compiler of the gem files.
Many other of them are availbale, whose scope is wider and which allow more
customisation, but these are the bare minimum to write a working model.

4 LUA commands
To enter LUA commands, they have to be preceded by a #. The syntax is
of course that of the LUA language: this specific language is very tolerant of
indentation customisation (like C++ but unlike Python), doesn’t require any
specific endline (unlike C++ but like Python) and is generally very forgiv-
ing. Documentation can be found online, but it’s not very different from more
widespread programming languages, and once one has gotten the gist of it, it’s
fairly straightforward. For example, a for cycle is:

# starting_value = 0
# ending_value = 10
# step = 1

6
# for i = starting_value , ending_value, step do
...
# end

In the gem files, when handling variables in the framework of the LUA language,
no particular care is needed: if the starting_value is defined somewhere be-
fore, everything is okay. Instead, if one has to use variables coupled to a gem
statement, then they have to be written in a special way:

# voltage = 200
electrode($(voltage)){...}
electrode($(voltage * 2)){...}

Variables have to be enclosed into $([name_of_the_variable] ) statements to


be used. Even mathematical operations have to be enclosed into that syntax.
The rest of the LUA syntax can be readily found online and is beyond the
scopes of this quick guide.

Você também pode gostar