The scripting approach is based on using a Lua script that is passed by the client and runs on the server. The script controls the whole scanning process, going either point by point or by any more complex commands, that may now or in future include piecewise linear data acquisition without stopping, use of lift mode, starting/stopping feedback, conditions, etc.

All relevant internal data are passed to all functions as a single opaque structure p, that is globally available. It contains all the scanned points, their number and other data needed internally. The scanned points are independently passed to the client, which is not done by this script. The script only controls the scanning and data collection process. To create your scan procedure, create the runit function as in the example script.

Collected data can be assigned to different sets. If sets (other than set 0) should be used, the set_scan_storage command should be used to ensure that the set arrays are allocated. Note that there are no scan parameters that could be passed from the server via client-server interface. Everything that should be controlled by the script should be fixed in the script (range, resolution, number of points) and cannot be changed on the fly. It is assumed that every scan is initiated by sending the script using the run_scan_script command via the client-server interface. Everything that is not controlled by the script (e.g. feedback loop PID parameters) and is also related to the microscope operation when not scanning, continues to be controlled independently via server and client and can be eventually changed on the fly.

Available functions:

gws_clear(p): clear all measured data points

gws_get_nvals(p): get number of data points stored so far, returns the number

gws_get_x(p): get actual x value

gws_get_y(p): get actual y value

gws_get_z(p): get actual z value

gws_get_e(p): get_actual error signal value

gws_get_in(p, channel): get actual additional value of particular channel

gws_get_t(p): get actual timestamp value

gws_get_z_at(p, x, y, from, to, set): get_stored z value closest to x,y, from given data range and set, returns the value

gws_get_entry(p, index): get position and feedback data stored at given index, returns x,y,z,e,ts,set

gws_get(p, string): get actual value of a parameter defined in description of the get command

gws_set_feedback(p, on): set feedback on or off. When off, the last set z value is used for piezo

gws_set_speed(p, speed): set speed, in m/s

gws_set_fm_feedback(p, on): set fm feedback (PLL)

gws_set_fm_amplitude_feedback(p, on): set fm amplitude feedback gws_set_gen_amplitude(p, channel, amplitude) set generator amplitude

gws_set_kpfm_feedback(p, on): set KPFM feedback

gws_move_to(p, x, y ,z): move to x, y, z (in metres), z runs only if feedback is off

gws_store_point(p, set): store actual readings with index of a specific set returns the stored data index

gws_check_if_stopped(p): returns 1 if there was a stop command from client

gws_check_if_paused(p): returns the pause flag, if it is 1, scan should be paused

gws_get_scan_param(p, key): get value of scan parameter identified by string key

gws_scan_and_store(p, xto, yto, nvals, set): moves to xto, yto, while scanning n vals with given set number, vals locations are equidistant.

gws_scan_and_store_lift(p, xto, yto, nvals, set, zindex, lift, no_fb_action): – performs line scan in lift mode, using globally available z data starting at zindex (and successive values) as the topography. Parameter no_fb_action can be used to prevent the feedback to be set automatically off before lift and on after that (user has to do it)

gws_get_period(p, start, end):determines the lateral period, in pixels, from the measured data between integers start and end

gws_get_correlation_length(p, start, end):determines the data correlation length, in pixels, from the measured data between integers start and end

gws_get_optimum_angle(p, start1, end1, angle1, ..., start5, end5, angle5): determines the optimum angle of scan to minimize measured period, based on five profiles taken at different angles and already available in the measured data set in the integer ranges startX...endX.

gws_set_zpiezo(p, value): set manually zpiezo value (works when feedback is off, but can be used to set the value that is kept after we switch it off)

gws_set_zpiezo_to_actual(p): set manually z piezo to the actual reported value, useful prior to switching the feedback off in order to force it to stay on the last value.

Sample scripts

Running a 5×5 points, 1×1 µm range regular scan formed by individual points, followed by a lift scan.

local scan = {}

function scan.runit()
  gws_clear(p)                                -- clear all points
  gws_set_feedback(p, 1)                      -- feedback on, probably it already is
  for x = 0, 1e-6, 0.25e-6            	      -- first pass
 	for y = 0, 1e-6, 0.25e-6
    	    gws_move_to(p, x, y, 0)
    	    gws_store_point(p, x, y, 0)       -- we store the data as set 0
  n = gws_get_nvals(p)                        -- data index where first pass ends

  gws_move_to(p, 0, 0, 0)                     -- move back to 0,0
  z = gws_get_z(p)                            -- get the actual height
  gws_move_to(p, 0, 0, z + 100e-9)            -- set where to move when feedback off
  gws_set_feedback(p, 0)                      -- switch off feedback

  for x = 0, 1e-6, 0.25e-6           	      --second pass
 	for y = 0, 1e-6, 0.25e-6
    	    z = gws_get_z_at(p, x, y, 0, n, 0)
    	    gws_move_to(p, x, y, z + 100e-9)
    	    gws_store_point(p, x, y, 1)       -- now we store the data as set 1

 gws_set_feedback(p, 1)                       -- switch feedback on again

return scan

Scanning line by line, 500×500 pixels, checking if user had stopped the scan.

local scan = {}

function scan.runit()
	local z = gws_get_z(p)

	gws_move_to(p, 0, 0, z);

	for iy = 1,500 do
    	local xfrom = 0
    	local xto = 500*20e-9
    	local y = iy * 20e-09

    	gws_scan_and_store(p, xto, y, 500, 0);
    	gws_move_to(p, xfrom, y, z);

    	if gws_check_if_stopped(p)==1 then
       	print("stopped on lua side")
       	return scan

return scan