Issue I296 [gem,mostlyresolved] Support variable substitution and macros in GEM files As of SIMION 8.0.4-TEST13, the GEM file loader includes a preprocessor that performs variable substitution and evaluates Lua code. A new example GEM file (examples\geometry\macro.lua) illustrates the use of this new feature: ; Example SIMION GEM file using preprocessing to expand Lua variables ; and macros. ; Preprocessing is a new feature SIMION 8.0.4. ; ; Lines starting with '#' or text inside $() are interpreted as Lua ; code and evaluated. If $() contains an expression (rather than a ; statement), the result is outputted. All other text is outputted ; verbatim. ; These variables are intended to be adjusted by the user. ; Note: both # and $ syntax are shown for demonstration. # local ro = 45 -- outer radius, gu # local ri = 40 -- inner radius, gi $(local nshells = 4) ; number of shells ; Now do some calculations on those variables. Note: math.ceil(x) is ; the ceiling function: it returns the integer closest to but no ; greater than x. # local hw = math.ceil(ro * 1.1) -- half width, gu # local nx = hw * 2 + 1 -- num array points in x ; Define array size. pa_define($(nx),$(nx),$(nx), planar, non-mirrored) ; Declare a function to be used later. ; This returns the voltage for electrode number n. $( local function volts(n) return n^2 * 10 + n + 1 end ) ; This locate centers the shells in the array. locate($(hw),$(hw),$(hw), 1, 0,0,0) { ; Now define a loop that creates each shell. # for n=1,nshells do # local rop = ro * n / nshells # local rip = ri * n / nshells electrode($(volts(n))) { ; example calling a function fill { within{sphere(0,0,0, $(rop))} notin {sphere(0,0,0, $(rip - 1))} } } # end } ; Note: the following two lines are equivalent: fill { within { box3d(0,0,0, $(nx),0,$(nx)) }} # _put("fill { within { box3d(0,0,0, " .. nx .. ",0," .. nx .. ") }}") ; Print output to the log window. This can be ; useful for debugging. # print("Hello from GEM file. nx=" .. nx) When SIMION loads a GEM file containing macros (e.g. macro.gem), it processes those macros, writes the result to temporary file (e.g. macro.processed.gem), and loads that temporary file. Reported by dennisc 2005-09-21 and others. Original user comments: For Ver 8.0 maybe Following would be nice but not essential, I usually create GEM files using a high level language, this allows me to use or specify constants, gaps between elements etc at the beginning of the program, If SIMION could deal with simple arithmetic expressions of the form R1 = R2*4 + D then this High Level Step would not be necessary as often e.g. at top of GEM file specify constansts X1 = 0 Y1 = 5 R1 = 10.0 R2 = R1 + D later on in GEM file one could specify electrode.. CIRCLE(X1, Y1, R1, R2) changes could then be made without having to edit the whole GEM file 8.0? Reply: A number of others have requested this feature of course, and I have needed it too. The current solution, which a number of users do use, is to pre-process the GEM files with another language (e.g. Perl/Python, C, C-preprocessor, or some templating language). I've even generated a library for doing this in LISP (I never released that code, and I'm not sure how many people would really like to use LISP rather than more directly in Perl/Python.) These methods work and are very flexible. Building the functionality directly into the GEM files will take some work to do it right, and the result still might not be flexible enough for everyone. However, it does seem like basic functionality for this should be there, and I will keep this in mind as other programatic features in SIMION (e.g. PRG code) are reworked. Perhaps as a compromise, I could allow users to plug-in custom preprocessors which will get invoked transparently as the GEM file is read. In any case, this issue should be addressed better at some time in some way somwewhere. Finally for now, how about a new electrode or line type called "GRID" input parameter would include lines per inch or mm to simulate actual wires used to make grids .... just thinking Reply: (low priority) -Not sure. There's various ways to define grids and more-or-less accurate ways of doing it. If one wants to model a curved grid (like in your example) with the real field distortions caused by the wires, that's a bit involved. There are ways to do it with ion jumping tricks in PRG code, but it would take some work to set up--but it might be easier to set up after some improvements to SIMION's user programming freatures. I'll add this to the bottom of the list, but it's something to keep in mind. -- see dennisc email about grids04b.gem and edge_fill theo-2005-11-16 [[Another suggestion that would be helpful would be in the geometry files. It would be nice if we could also use variable names of our own and then enter the distances as a variable. A gem file made like that could then be readily changed. For example I am designing a hemispherical analyzer. The two radii R1 and R2 could be used as variables which could be initialized in the begining of the gem file. Then in the future if you would want to make a different analyzer all you would have to do is change the initial values and if you had written the gem file properly everything else would take of itself.]] Note: a planned GEM2 might expand these capabilities even further. Largely resolved in 8.0.4-TEST13.