LWDAQ Command Reference

For LWDAQ Version 10.6.12
© 2004−2020 Kevan Hashemi, Brandeis University
© 2006−2023 Kevan Hashemi, Open Source Instruments Inc.

Contents

Introduction
Scripts
Utils.tclDriver.tclTools.tcl
Interface.tclInstruments.tclViewer.tcl
SCAM.tclCamera.tclGauge.tcl
Rasnik.tclRFPM.tclFlowmeter.tcl
WPS.tclInclinometer.tclTerminal.tcl
Voltmeter.tclReceiver.tclDosimeter.tcl
BCAM.tclThermometer.tclDiagnostic.tcl
Script Commands
LWDAQ_aboutLWDAQ_acquireLWDAQ_acquire_button
LWDAQ_activity_ReceiverLWDAQ_analysis_BCAMLWDAQ_analysis_Camera
LWDAQ_analysis_DiagnosticLWDAQ_analysis_DosimeterLWDAQ_analysis_Flowmeter
LWDAQ_analysis_GaugeLWDAQ_analysis_InclinometerLWDAQ_analysis_Rasnik
LWDAQ_analysis_RasnikLWDAQ_analysis_Rasnik_NikhefLWDAQ_analysis_Receiver
LWDAQ_analysis_RFPMLWDAQ_analysis_SCAMLWDAQ_analysis_Terminal
LWDAQ_analysis_ThermometerLWDAQ_analysis_ViewerLWDAQ_analysis_Voltmeter
LWDAQ_analysis_WPSLWDAQ_bind_command_keyLWDAQ_button_confirm
LWDAQ_button_waitLWDAQ_button_warningLWDAQ_byte_poll
LWDAQ_byte_readLWDAQ_byte_writeLWDAQ_clock_widget
LWDAQ_closeLWDAQ_close_all_socketsLWDAQ_cmd_Voltmeter
LWDAQ_command_referenceLWDAQ_config_readLWDAQ_config_write
LWDAQ_controller_resetLWDAQ_controls_CameraLWDAQ_controls_Diagnostic
LWDAQ_controls_FlowmeterLWDAQ_controls_GaugeLWDAQ_controls_Inclinometer
LWDAQ_controls_ReceiverLWDAQ_controls_RFPMLWDAQ_controls_Thermometer
LWDAQ_controls_ViewerLWDAQ_controls_VoltmeterLWDAQ_crop_Viewer
LWDAQ_daq_BCAMLWDAQ_daq_CameraLWDAQ_daq_Diagnostic
LWDAQ_daq_DosimeterLWDAQ_daq_FlowmeterLWDAQ_daq_Gauge
LWDAQ_daq_InclinometerLWDAQ_daq_RasnikLWDAQ_daq_Receiver
LWDAQ_daq_RFPMLWDAQ_daq_SCAMLWDAQ_daq_Terminal
LWDAQ_daq_ThermometerLWDAQ_DAQ_to_GIF_ViewerLWDAQ_daq_Viewer
LWDAQ_daq_VoltmeterLWDAQ_daq_WPSLWDAQ_debug_log
LWDAQ_decimal_to_binaryLWDAQ_delay_secondsLWDAQ_driver_init
LWDAQ_echoLWDAQ_edit_scriptLWDAQ_enable_text_undo
LWDAQ_exec_DiagnosticLWDAQ_execute_jobLWDAQ_extended_BCAM
LWDAQ_extended_RasnikLWDAQ_extended_SCAMLWDAQ_find_files
LWDAQ_firmware_versionLWDAQ_flash_secondsLWDAQ_get_dir_name
LWDAQ_get_file_nameLWDAQ_get_lwdaq_configLWDAQ_GIF_to_DAQ_Viewer
LWDAQ_global_var_nameLWDAQ_hardware_idLWDAQ_hardware_version
LWDAQ_html_contentsLWDAQ_html_splitLWDAQ_html_tables
LWDAQ_image_pixelsLWDAQ_image_sensor_clearLWDAQ_image_sensor_transfer
LWDAQ_info_buttonLWDAQ_infobuttons_BCAMLWDAQ_infobuttons_Dosimeter
LWDAQ_infobuttons_RasnikLWDAQ_infobuttons_SCAMLWDAQ_init_BCAM
LWDAQ_init_CameraLWDAQ_init_DiagnosticLWDAQ_init_Dosimeter
LWDAQ_init_FlowmeterLWDAQ_init_GaugeLWDAQ_init_Inclinometer
LWDAQ_init_main_windowLWDAQ_init_RasnikLWDAQ_init_Receiver
LWDAQ_init_RFPMLWDAQ_init_SCAMLWDAQ_init_Terminal
LWDAQ_init_ThermometerLWDAQ_init_ViewerLWDAQ_init_Voltmeter
LWDAQ_init_WPSLWDAQ_inside_widgetLWDAQ_instrument_analyze
LWDAQ_instrument_closeupLWDAQ_instrument_printLWDAQ_instrument_save
LWDAQ_instrument_unsaveLWDAQ_instruments_initLWDAQ_integer_write
LWDAQ_interface_initLWDAQ_ip_addr_matchLWDAQ_is_error_result
LWDAQ_job_doneLWDAQ_library_settingsLWDAQ_list_commands
LWDAQ_loginLWDAQ_loop_buttonLWDAQ_loop_time
LWDAQ_loop_time_DiagnosticLWDAQ_mac_readLWDAQ_MacOS_Open_File
LWDAQ_make_instrument_menuLWDAQ_make_tool_menuLWDAQ_monitor_open
LWDAQ_monitor_refreshLWDAQ_most_recent_byteLWDAQ_ndf_create
LWDAQ_ndf_data_appendLWDAQ_ndf_data_checkLWDAQ_ndf_data_read
LWDAQ_ndf_string_appendLWDAQ_ndf_string_checkLWDAQ_ndf_string_read
LWDAQ_ndf_string_writeLWDAQ_offLWDAQ_off_Diagnostic
LWDAQ_onLWDAQ_on_DiagnosticLWDAQ_open
LWDAQ_open_documentLWDAQ_postLWDAQ_preferences
LWDAQ_printLWDAQ_proc_declarationLWDAQ_proc_definition
LWDAQ_proc_descriptionLWDAQ_proc_listLWDAQ_process_exists
LWDAQ_process_stopLWDAQ_psc_DiagnosticLWDAQ_put_file_name
LWDAQ_queue_clearLWDAQ_queue_errorLWDAQ_queue_start
LWDAQ_queue_stepLWDAQ_queue_stopLWDAQ_quit
LWDAQ_ram_deleteLWDAQ_ram_readLWDAQ_ram_write
LWDAQ_randomLWDAQ_random_wait_msLWDAQ_read_button
LWDAQ_read_image_fileLWDAQ_read_scriptLWDAQ_reboot_Diagnostic
LWDAQ_receive_byteLWDAQ_receive_dataLWDAQ_receive_integer
LWDAQ_refresh_DiagnosticLWDAQ_refresh_FlowmeterLWDAQ_refresh_Gauge
LWDAQ_refresh_ReceiverLWDAQ_refresh_RFPMLWDAQ_refresh_Thermometer
LWDAQ_refresh_VoltmeterLWDAQ_relay_rebootLWDAQ_report_error
LWDAQ_resetLWDAQ_reset_DiagnosticLWDAQ_reset_instrument_counters
LWDAQ_reset_ReceiverLWDAQ_run_toolLWDAQ_save_settings
LWDAQ_save_text_windowLWDAQ_schedule_taskLWDAQ_scheduler
LWDAQ_script_descriptionLWDAQ_server_acceptLWDAQ_server_info
LWDAQ_server_interpreterLWDAQ_server_openLWDAQ_server_start
LWDAQ_server_stopLWDAQ_set_base_addr_hexLWDAQ_set_bg
LWDAQ_set_bitLWDAQ_set_bounds_ViewerLWDAQ_set_command_reg
LWDAQ_set_command_reg_binaryLWDAQ_set_command_reg_hexLWDAQ_set_data_addr
LWDAQ_set_delay_secondsLWDAQ_set_delay_ticksLWDAQ_set_device_addr
LWDAQ_set_device_elementLWDAQ_set_device_typeLWDAQ_set_dimensions_Viewer
LWDAQ_set_driver_muxLWDAQ_set_fgLWDAQ_set_image_sensor
LWDAQ_set_multisource_elementLWDAQ_set_repeat_counterLWDAQ_set_results_Viewer
LWDAQ_set_voltmeter_deviceLWDAQ_sleepLWDAQ_sleep_Diagnostic
LWDAQ_sleepall_DiagnosticLWDAQ_smallint_writeLWDAQ_socket_accept
LWDAQ_socket_closeLWDAQ_socket_flushLWDAQ_socket_interpreter
LWDAQ_socket_listenLWDAQ_socket_openLWDAQ_socket_protocol
LWDAQ_socket_readLWDAQ_socket_uploadLWDAQ_socket_write
LWDAQ_software_versionLWDAQ_sort_filesLWDAQ_spawn_tool
LWDAQ_splitLWDAQ_start_jobLWDAQ_stdin_console_execute
LWDAQ_stdin_console_startLWDAQ_stdin_console_stopLWDAQ_stop_button
LWDAQ_stop_instrumentsLWDAQ_stop_vwaitsLWDAQ_stream_delete
LWDAQ_stream_readLWDAQ_stream_writeLWDAQ_support
LWDAQ_text_widgetLWDAQ_time_stampLWDAQ_tool_configure
LWDAQ_tool_dataLWDAQ_tool_helpLWDAQ_tool_init
LWDAQ_tool_openLWDAQ_tool_referenceLWDAQ_tool_reload
LWDAQ_tool_rewrite_dataLWDAQ_tool_saveLWDAQ_tool_unsave
LWDAQ_ToolmakerLWDAQ_Toolmaker_backLWDAQ_Toolmaker_delete
LWDAQ_Toolmaker_delete_allLWDAQ_Toolmaker_executeLWDAQ_Toolmaker_forward
LWDAQ_Toolmaker_loadLWDAQ_Toolmaker_repeatLWDAQ_Toolmaker_save
LWDAQ_tools_initLWDAQ_toplevel_text_windowLWDAQ_toplevel_window
LWDAQ_transmit_commandLWDAQ_transmit_command_binaryLWDAQ_transmit_command_hex
LWDAQ_transmit_DiagnosticLWDAQ_transmit_messageLWDAQ_unsave_settings
LWDAQ_unschedule_taskLWDAQ_updateLWDAQ_url_download
LWDAQ_url_openLWDAQ_utils_initLWDAQ_view_array
LWDAQ_view_text_fileLWDAQ_vwaitLWDAQ_vwait_var_name
LWDAQ_wait_for_driverLWDAQ_wait_msLWDAQ_wait_seconds
LWDAQ_wakeLWDAQ_wake_DiagnosticLWDAQ_watch
LWDAQ_widget_listLWDAQ_write_buttonLWDAQ_write_image_file
LWDAQ_xml_getLWDAQ_xml_get_listLWDAQ_xy_Viewer
LWDAQ_zoom_Viewer
Library Commands
lwdaq_altlwdaq_bcamlwdaq_bcam_calib
lwdaq_configlwdaq_data_manipulatelwdaq_diagnostic
lwdaq_dosimeterlwdaq_drawlwdaq_draw_raw
lwdaq_error_stringlwdaq_fftlwdaq_filter
lwdaq_flowmeterlwdaq_gaugelwdaq_graph
lwdaq_image_characteristicslwdaq_image_contentslwdaq_image_create
lwdaq_image_destroylwdaq_image_existslwdaq_image_histogram
lwdaq_image_manipulatelwdaq_image_profilelwdaq_image_results
lwdaq_inclinometerlwdaq_metricslwdaq_photo_contents
lwdaq_rasniklwdaq_rasnik_shiftlwdaq_receiver
lwdaq_rfpmlwdaq_scamlwdaq_shadow
lwdaq_simplexlwdaq_tcblwdaq_voltmeter
lwdaq_wps
Library Routines
ave_stdevbcam_coord_from_mountbcam_from_global_point
bcam_from_global_vectorbcam_image_positionbcam_source_bearing
bcam_source_positioncoastline_xcoastline_x_progress
coastline_xycoastline_xy_progressfrequency_components
glitch_filterglitch_filter_xyglitch_filter_y
global_from_bcam_pointglobal_from_bcam_vectorlinear_interpolate
matrix_inversenearest_neighborspikes_x
straight_line_fitsum_sinusoidstkcolor
window_functionwps_calibratewps_wire_plane
xyz_axis_rotatexyz_cross_productxyz_difference
xyz_dot_productxyz_global_from_local_pointxyz_global_from_local_vector
xyz_lengthxyz_line_line_bridgexyz_line_plane_intersection
xyz_local_from_global_pointxyz_local_from_global_vectorxyz_plane_plane_intersection
xyz_point_line_vectorxyz_rotatexyz_rotation_from_axes
xyz_sumxyz_unit_vectorxyz_unrotate

Introduction

When it starts up, LWDAQ installs hundreds of Tcl/Tk commands for use in instruments and tools. The script commands are those installed by the Tcl/Tk scripts that LWDAQ runs at start-up. The library commands are those installed by the lwdaq.so shared library that LWDAQ loads at start-up. This library has been compiled from our Pascal source code. Script commands all begin with LWDAQ in upper case letters, while library commands all begin with lwdaq in lower case letters.

The Tcl/Tk scripts define the script commands are in the ./LWDAQ.app/Contents/LWDAQ directory of the LWDAQ software installation, and its sub-directories. You will also find them on our Sources Page. We describe these scripts in turn below. Each script command has its own entry in this manual, with its Tcl declaration and its in the TCL comments above the declaration in the script.

The Pascal files that define the library commands are in the ./Sources directory. Each operating system has its own version of lwdaq.so, but all versions define the same commands. Each library command takes some mandatory parameters, and a list of optional parameters. You specify the mandatory parameters by passing their values directly to the command, in the correct order. You specify optional parameters with a list of option names in the form "?option value?". You can specify any number of these options, and in any order. Here is an example library command call from the Rasnik instrument script.

set result [lwdaq_rasnik $image_name \
	-show_fitting $config(analysis_show_fitting) \
	-show_timing $config(analysis_show_timing) \
	-reference_code $config(analysis_reference_code) \
	-orientation_code $config(analysis_orientation_code) \
	-pixel_size_um $info(analysis_pixel_size_um) \
	-reference_x_um $info(analysis_reference_x_um) \
	-reference_y_um $info(analysis_reference_y_um) \
	-square_size_um $config(analysis_square_size_um) ]

The lwdaq.pas file acts as an interface between our Pascal libraries and Tcl/Tk. It provides init_Lwdaq, which Tcl/Tk calls when it loads the lwdaq dynamic library, and it defines all the library commands. The init_Lwdaq routine installs these commands in the TCL interpreter. The lwdaq.pas file is a Pascal main program rather than a Pascal unit, even though we compile it into a dynamic library. The GPC compiler expects a main program if it is to include the "_p_initialize" routine in the compiled object. We will need this routine to be present in the lwdaq.o object when we link the final lwdaq.dylib dynamic library with GCC.

The lwdaq command (lower case) grants access to a selection of mathematical routines declared in our Pascal library. We call these the lwdaq routines to distinguish them from the lwdaq commands, of which lwdaq is an exmaple. The following command calls our linear interpolator on a set of x-y data pairs to estimate the value of a curve at x=2.


lwdaq linear_interpolate 2 "0 0 3 3 6 6"

You will find a list of the routines available through the lwdaq command in a table below, as well as descriptions of each of them.

The image parameters taken by many of the library commands are the names of images in the LWDAQ image list. This list of images is maintained in memory by the library commands. Each image contains its pixel intensities and an overlay in which the library routines can draw lines. You draw an image in a TK photo widget with lwdaq_draw. First lwdaq_draw renders the pixel intensity in the photo, and then it renders the overlay. The same image can be rendered in multiple TK photos. When an instrument captures consecutive images from a data acquisition system, it is deleting previous images (now redundant) from the LWDAQ image list, creating a new image, filling it with the acquired pixel intensities, and rendering the image in the same TK photo in the instrument window.

Scripts

Here we have section for each of the LWDAQ scripts.

Utils.tcl

Utils.tcl contains file input-output routines, the LWDAQ event queue, time and date routines, debug and diagnostic routines, and the manual routines. The LWDAQ Event Queue is an event scheduler that allows us to perform simultaneous live data acquisition from multiple instruments by scheduling the acquision actions so they do not overlap with one another. The LWDAQ Scheduler, controlled by the schedule routines, allows us to schedule tasks in a manner similar to that of the Unix "cron" utility.

Driver.tcl

Driver.tcl defines procedures that communicate with data acquisition drivers and system controllers through TCPIP sockets. The Driver.tcl routines call the sockeet-handling routines defined in Utils.tcl.

Tools.tcl

Tools.tcl contains routines that configure and manage polite and standard LWDAQ tools. It provides the Tool Maker and Run Tool commands for the Tool menu.

Interface.tcl

Interface.tcl creates the LWDAQ graphical user interface.

Instruments.tcl

Instruments.tcl contains the routines that set up the common foundations upon which all LWDAQ instruments are built.

Viewer.tcl

Viewer.tcl defines the Viewer instrument.

SCAM.tcl

SCAM.tcl defines the SCAM instrument.

Camera.tcl

Camera.tcl defines the Camera instrument.

Gauge.tcl

Gauge.tcl defines the Gauge instrument.

Rasnik.tcl

Rasnik.tcl defines the Rasnik instrument.

RFPM.tcl

RFPM.tcl defines the Radio-Frequency Power Meter (RFPM) instrument.

Flowmeter.tcl

Flowmeter.tcl defines the Flowmeter instrument.

WPS.tcl

WPS.tcl defines the WPS instrument.

Inclinometer.tcl

Inclinometer.tcl defines the Inclinometer instrument.

Terminal.tcl

Terminal.tcl defines the Terminal instrument.

Voltmeter.tcl

Voltmeter.tcl defines the Voltmeter instrument.

Receiver.tcl

Receiver.tcl defines the Receiver Instrument for LWDAQ.

Dosimeter.tcl

Dosimeter.tcl defines the Dosimeter instrument.

BCAM.tcl

BCAM.tcl defines the BCAM instrument.

Thermometer.tcl

Thermometer.tcl defines the Thermometer instrument.

Diagnostic.tcl

Diagnostic.tcl defines the Diagnostic instrument.

Script Commands

LWDAQ_about

proc LWDAQ_about {}

LWDAQ_about creates a message box that pops up and tells us about the program.

LWDAQ_acquire

proc LWDAQ_acquire {instrument}

LWDAQ_acquire acquires data for the instrument called $instrument from either a file, or an existing image in memory, or directly from the daq. After acquiring, it applies analysis if enabled and returns a result string.

LWDAQ_acquire_button

proc LWDAQ_acquire_button {name}

LWDAQ_acquire_button is for use with instrument acquire buttons.

LWDAQ_activity_Receiver

proc LWDAQ_activity_Receiver {}

LWDAQ_activity_Receiver opens a new panel that shows a table of telemetry channels and the number of samples received per second from each in the most recent acquisition.

LWDAQ_analysis_BCAM

proc LWDAQ_analysis_BCAM {{image_name ""}}

LWDAQ_analysis_BCAM applies BCAM analysis to an image in the lwdaq image list. By default, the routine uses the image $config(memory_name).

LWDAQ_analysis_Camera

proc LWDAQ_analysis_Camera {{image_name ""}}

LWDAQ_analysis_Camera applies Camera analysis to an image in the lwdaq image list. By default, the routine uses the image $config(memory_name).

LWDAQ_analysis_Diagnostic

proc LWDAQ_analysis_Diagnostic {{image_name ""}}

LWDAQ_analysis_Diagnostic displays the power supply measurements carried by the $image_name and displays them in the diagnostic instrument window. It calculates average values for the power supply voltages and current consumption and returns these parameters, as well as other information about the driver. By default, the routine uses the image $config(memory_name).

LWDAQ_analysis_Dosimeter

proc LWDAQ_analysis_Dosimeter {{image_name ""}}

LWDAQ_analysis_Dosimeter applies Dosimeter analysis to an image in the lwdaq image list. By default, the routine uses the image named $config(memory_name). It calculates the vertical slope of intensity in cnt/row first. The analysis working with the original image when analyis_enable=1, but switches to using the image after subtraction of background gradient when analysis_enable>=2. With analysis_enable=2 the image in memory remains the same, and analysis operates on a copy of the original. With analysis_enable=3, the analysis replaces the original image with the gradient-subtracted image. The analysis calculates charge density in cnt/px next. The charge density is combined intensity of bright hits divided by the number of pixels in the analysis bounds of the image. A hit is a spot that satisfies the analysis_threshold string. The threshold string specifies a minumum intensity for pixels in a hit. The string "20 & 2 <" specifies a minimum intensity twenty counts above background, and indicates that the background should be the average intensity of the image. The same string sets a limit of two pixels in any valid hit. Following the charge density is the standard deviation of intensity, the value of the threshold intensity, and the number of hits found in the image. Each hit is represented by its total brightness above background, and if analysis_include_ij=1, the row and column number of the pixel closest to the optical center of the hit. Following these values, the analysis will list one or more bright hits in order of descending brightness. With analysis_num_hits="*", all hits found will be listed. With analysis_num_hits="10", ten hits will be listed. If only three hits exist, the remaining seven hits will be represented by brightness "-1" and position "0 0".

LWDAQ_analysis_Flowmeter

proc LWDAQ_analysis_Flowmeter {{image_name ""}}

LWDAQ_analysis_Flowmeter takes the flowmeter RTD sensor resistance measurements in $image_name and plots a graph of sensor temperature versus time in the Flowmeter window. It returns a string containing the inverse time-constant of the cool-down phase. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_Gauge

proc LWDAQ_analysis_Gauge {{image_name ""}}

LWDAQ_analysis_Gauge takes the RTD resistance measurements contained in $image_name and plots a graph of temperature versus time for each sensor whose resistance is recorded in the image. It calculates the average value of each temperature and returns the averages as a string. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_Inclinometer

proc LWDAQ_analysis_Inclinometer {{image_name ""}}

LWDAQ_analysis_Inclinometer converts the ADC measurements contained in $image_name into voltages, and plots them in the Inclinometer window. It calculates the average value of the voltage, the slope, and the standard deviation, and returns these in a string. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_Rasnik

proc LWDAQ_analysis_Rasnik {{image_name ""}}

LWDAQ_analysis_Rasnik applies rasnik analysis to an image in the lwdaq image list. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_Rasnik

proc LWDAQ_analysis_Rasnik {{image_name ""}}

No description available.

LWDAQ_analysis_Rasnik_Nikhef

proc LWDAQ_analysis_Rasnik_Nikhef {{image_name}}

No description available.

LWDAQ_analysis_Receiver

proc LWDAQ_analysis_Receiver {{image_name ""}}

LWDAQ_analysis_Receiver applies receiver analysis to an image in the lwdaq image list. By default, the routine uses the image $config(memory_name).

LWDAQ_analysis_RFPM

proc LWDAQ_analysis_RFPM {{image_name ""}}

LWDAQ_analysis_RFPM converts the ADC measurements contained in $image_name into voltages, and plots them in the RFPM window. By default, the routine uses image $config(memory_name). If analysis_enable is set to 1, the analysis returns the peak-to-peak value of the signal on all four RFPM signal paths in units of ADC counts. If analysis_enanalysis is 2, the analysis returns the rms values of the signals.

LWDAQ_analysis_SCAM

proc LWDAQ_analysis_SCAM {{image_name ""}}

LWDAQ_analysis_SCAM applies SCAM analysis to an image in the lwdaq image list. By default, the routine uses the image $config(memory_name).

LWDAQ_analysis_Terminal

proc LWDAQ_analysis_Terminal {{image_name ""}}

LWDAQ_analysis_Terminal scans an image received from a Terminal data acquisition, and turns it into a string of numbers.

LWDAQ_analysis_Thermometer

proc LWDAQ_analysis_Thermometer {{image_name ""}}

LWDAQ_analysis_Thermometer takes the RTD resistance measurements contained in $image_name and plots a graph of temperature versus time for each sensor whose resistance is recorded in the image. It calculates the average value of each temperature and returns the averages as a string. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_Viewer

proc LWDAQ_analysis_Viewer {{image_name ""}}

LWDAQ_analysis_Viewer calls the analysis of another instrument to analyze an image in the Viewer panel. If report is set, the routine draws the image in the Viewer panel and writes the results of analysis to the text window.

LWDAQ_analysis_Voltmeter

proc LWDAQ_analysis_Voltmeter {{image_name ""}}

LWDAQ_analysis_Voltmeter converts the ADC measurements contained in $image_name into voltages, and plots them in the Voltmeter window. It calculates the average value of the voltage, the slope, and the standard deviation, and returns these in a string. By default, the routine uses image $config(memory_name).

LWDAQ_analysis_WPS

proc LWDAQ_analysis_WPS {{image_name ""}}

LWDAQ_analysis_WPS applies WPS analysis to an image in the lwdaq image list. By default, the routine uses the image $config(memory_name).

LWDAQ_bind_command_key

proc LWDAQ_bind_command_key {window letter command}

LWDAQ_bind_command_key binds the specified command letter to the specified command on all platforms. We use the "command" key on MacOS and the "control" key on Windows and Linux. If the window is an empty string, we bing the key to the root window.

LWDAQ_button_confirm

proc LWDAQ_button_confirm {s}

LWDAQ_button_confirm opens a toplevel window called "Confirm" and prints message $s in the window. The procedure returns after the user presses a button.

LWDAQ_button_wait

proc LWDAQ_button_wait {{s ""}}

LWDAQ_button_wait opens a toplevel window with a continue button and waits until the user presses the button before closing the window and continuing. An optional message, s, may be printed in the window along with the continue instruction.

LWDAQ_button_warning

proc LWDAQ_button_warning {s}

LWDAQ_button_warning opens a toplevel window called "Warning" and prints message, s, in the window. The procedure returns after the user presses a button.

LWDAQ_byte_poll

proc LWDAQ_byte_poll {sock addr value}

LWDAQ_byte_poll tells the relay at the other end of TCPIP socket $sock to wait until the byte it reads from address $addr has value $value. The value we pass to the routine is a string of characters that represent a decimal number. The routine converts this string into a binary byte. The strings "-1" and "255" both get converted into the same binary value, 255, which is -1 in 2's compliment.

LWDAQ_byte_read

proc LWDAQ_byte_read {sock addr}

LWDAQ_byte_read reads a byte from the controller address space on a driver. The read takes place through a socket open with the driver called $sock, and reads a byte from controller address $addr. The routine returns the byte as a decimal number. The addr parameter is a string of characters representing a decimal number. The routine translates the parameter into a four-byte integer before transmitting it to the driver. The routine returns a string of characters that represents a decimal number.

LWDAQ_byte_write

proc LWDAQ_byte_write {sock addr value}

LWDAQ_byte_write writes byte $value through TCPIP socket $sock to controller address $addr. The addr and value parameters are strings of characters that represent decimal numbers. The routine translates these into a four-byte integer and a single-byte value before transmitting them to the driver.

LWDAQ_clock_widget

proc LWDAQ_clock_widget {{wf ""}}

LWDAQ_clock_widget creates a text widget that displays second-by-second current time. If you specify a window name, the clock widget will appear in the window, packed towards the top. Otherwise the routine creates a new toplevel window for the clock.

LWDAQ_close

proc LWDAQ_close {name}

LWDAQ_close closes the window of the named instrument.

LWDAQ_close_all_sockets

proc LWDAQ_close_all_sockets {}

LWDAQ_close_all_sockets closes all open sockets and returns an empty string.

LWDAQ_cmd_Voltmeter

proc LWDAQ_cmd_Voltmeter {cmd}

LWDAQ_cmd_Voltmeter takes the top three nibbles of a sixteen bit command word and adds the correct nibble at the end to set the logic outputs.

LWDAQ_command_reference

proc LWDAQ_command_reference { {file_name ""} }

LWDAQ_command_reference generates the LWDAQ software command reference manual automatically, using the files ./Sources/lwdaq.pas for Pascal library routine entries and the template file ./LWDAQ.app/Contents/LWDAQ/CRT.html, as well as our LWDAQ command listing and help extraction routines. By default, the routine creates the command reference in the current LWDAQ working directory, and names it Commands.html.

LWDAQ_config_read

proc LWDAQ_config_read {sock}

LWDAQ_config_read reads the configuration parameters from the LWDAQ relay at the other end of an open TCPIP socket $sock, and returns them if they are valid. If the contents are not valid, the routine reports an error. The parameters the routine reads are those in the relay's RAM. These are the the ones in effect on the relay. They are not the ones written in the relay's EEPROM configuration file. There is no way to read the EEPROM configuration directly. The EEPROM parameters are loaded into ram after a hardware reset, which can be performed by pressing a button on the driver, or with LWDAQ_relay_reboot.

LWDAQ_config_write

proc LWDAQ_config_write {sock config}

LWDAQ_config_write writes $config to the configuration EEPROM on the relay. The new configuration parameters will not take effect until you reboot the driver. Until then, the existing parameters in the driver's RAM will remain in effect.

LWDAQ_controller_reset

proc LWDAQ_controller_reset {sock}

LWDAQ_controller_reset writes the value 1 to the software reset byte on a controller at the other end of socket $sock, thus resetting all its state machines and registers. The relay remains unaffected.

LWDAQ_controls_Camera

proc LWDAQ_controls_Camera {}

LWDAQ_controls_Camera creates buttons that configure the Camera for various image sensors.

LWDAQ_controls_Diagnostic

proc LWDAQ_controls_Diagnostic {}

LWDAQ_controls_Diagnostic creates secial controls for the Diagnostic instrument.

LWDAQ_controls_Flowmeter

proc LWDAQ_controls_Flowmeter {}

LWDAQ_controls_Flowmeter creates secial controls for the Flowmeter instrument.

LWDAQ_controls_Gauge

proc LWDAQ_controls_Gauge {}

LWDAQ_controls_Gauge creates secial controls for the Gauge instrument.

LWDAQ_controls_Inclinometer

proc LWDAQ_controls_Inclinometer {}

LWDAQ_controls_Inclinometer creates secial controls for the Inclinometer instrument.

LWDAQ_controls_Receiver

proc LWDAQ_controls_Receiver {}

LWDAQ_controls_Receiver creates secial controls for the Receiver instrument.

LWDAQ_controls_RFPM

proc LWDAQ_controls_RFPM {}

LWDAQ_controls_RFPM creates secial controls for the RFPM instrument.

LWDAQ_controls_Thermometer

proc LWDAQ_controls_Thermometer {}

LWDAQ_controls_Thermometer creates secial controls for the Thermometer instrument.

LWDAQ_controls_Viewer

proc LWDAQ_controls_Viewer {}

LWDAQ_controls_Viewer creates secial controls for the Viewer instrument.

LWDAQ_controls_Voltmeter

proc LWDAQ_controls_Voltmeter {}

LWDAQ_controls_Voltmeter creates special controls for the Voltmeter instrument.

LWDAQ_crop_Viewer

proc LWDAQ_crop_Viewer {}

LWDAQ_crop_Viewer crops the Viewer's image to its analysis bounds and draws it in the Viewer panel.

LWDAQ_daq_BCAM

proc LWDAQ_daq_BCAM {}

LWDAQ_daq_BCAM captures an image from the LWDAQ electronics and places the image in the lwdaq image list. It provides background subtraction by taking a second image while flashing non-existent lasers. It provides automatic exposure adjustment by calling itself until the maximum image intensity lies within peak_min and peak_max. For detailed comments upon the readout of the image sensors, see the LWDAQ_daq_Camera routine.

LWDAQ_daq_Camera

proc LWDAQ_daq_Camera {}

LWDAQ_daq_Camera captures an image from the LWDAQ electronics and places the image in the lwdaq image list.

LWDAQ_daq_Diagnostic

proc LWDAQ_daq_Diagnostic {}

LWDAQ_daq_Diagnostic reads configuration paramters from the LWDAQ hardware, and records them in a result string, which it returns.

LWDAQ_daq_Dosimeter

proc LWDAQ_daq_Dosimeter {}

LWDAQ_daq_Dosimeter captures an image from the LWDAQ electronics and places the image in the lwdaq image list.

LWDAQ_daq_Flowmeter

proc LWDAQ_daq_Flowmeter {}

LWDAQ_daq_Flowmeter reads configuration parameters from the LWDAQ hardware, and records them in a result string, which it returns.

LWDAQ_daq_Gauge

proc LWDAQ_daq_Gauge {}

LWDAQ_daq_Gauge reads configuration paramters from the LWDAQ hardware, and records them in a result string, which it returns.

LWDAQ_daq_Inclinometer

proc LWDAQ_daq_Inclinometer {}

LWDAQ_daq_Inclinometer reads samples out of an input channel.

LWDAQ_daq_Rasnik

proc LWDAQ_daq_Rasnik {}

LWDAQ_daq_Rasnik captures an image from the LWDAQ electronics and places the image in the lwdaq image list. It provides background subtraction by taking a second image while flashing non-existent LEDs. It provides automatic exposure adjustment by calling itself until the maximum image intensity lies withint peak_min and peak_max.

LWDAQ_daq_Receiver

proc LWDAQ_daq_Receiver {}

LWDAQ_daq_Receiver reads data from a data device. It fetches the data in blocks, and opens and closes a socket to the driver for each block. Although opening and closing sockets introduces a delay into the data acquisition, it allows another LWDAQ process to use the same LWDAQ driver in parallel. Some receivers provide a register that gives the number of messages available for download in its memory. In the absence of such a register, there is no way to determine the number of messages available for download, so this routine estimates the number of messages available using aquire_end_ms, which it updates after every block download to be equal to or greater than the millisecond absolute time of the last clock message in the block. By subtracting the end time from the current time, the routine obtains an estimate of the length of time spanned by the messages available in the data receiver. The routine also maintains an estimate of the number of messages per clock message in the recording. It multiplies this ratio by the available time and the clock frequency to get its estimate of the number of messages avaialable in the data receiver. The routine reports errors with the key word "corrupted" to indicate an error that merits resetting the data receiver. but the routine does not reset the data receiver itself.

LWDAQ_daq_RFPM

proc LWDAQ_daq_RFPM {}

LWDAQ_daq_RFPM reads samples out of an input channel.

LWDAQ_daq_SCAM

proc LWDAQ_daq_SCAM {}

LWDAQ_daq_SCAM captures an image from the LWDAQ electronics and places the image in the lwdaq image list. It provides background subtraction by taking a second image while flashing non-existent lasers. It provides automatic exposure adjustment by calling itself until the maximum image intensity lies within peak_min and peak_max. For detailed comments upon the readout of the image sensors, see the LWDAQ_daq_Camera routine.

LWDAQ_daq_Terminal

proc LWDAQ_daq_Terminal {}

LWDAQ_daq_Terminal reads a string of characters or a block of data froma data device.

LWDAQ_daq_Thermometer

proc LWDAQ_daq_Thermometer {}

LWDAQ_daq_Thermometer reads configuration paramters from the LWDAQ hardware, and records them in a result string, which it returns.

LWDAQ_DAQ_to_GIF_Viewer

proc LWDAQ_DAQ_to_GIF_Viewer {}

LWDAQ_DAQ_to_GIF_Viewer opens a browser in which you select multiple DAQ image files, and converts them to GIF files, writing them into the same directory with suffix ".gif".

LWDAQ_daq_Viewer

proc LWDAQ_daq_Viewer {}

LWDAQ_daq_Viewer is a dummy procedure for the standard aquire button.

LWDAQ_daq_Voltmeter

proc LWDAQ_daq_Voltmeter {}

LWDAQ_daq_Voltmeter reads samples out of an input channel.

LWDAQ_daq_WPS

proc LWDAQ_daq_WPS {}

LWDAQ_daq_WPS captures an image from the LWDAQ electronics and places the image in the lwdaq image list. It provides background subtraction by taking a second image while flashing non-existent lasers. It provides automatic exposure adjustment by calling itself until the maximum image intensity lies within peak_min and peak_max.

LWDAQ_debug_log

proc LWDAQ_debug_log {s}

LWDAQ_debug_log opens a file named by the debug_log value, in the program directory, and appends a string to the end of it, then closes the file.

LWDAQ_decimal_to_binary

proc LWDAQ_decimal_to_binary {decimal {length 32}}

LWDAQ_decimal_to_binary takes a decimal integer, $decimal, and returns the least significant $length digits of its binary representation as a string of ones and zeros. By default, $length is 32, which is also the maximum value of $length supported by the routine. We include comment in the code to explain our use of binary format and binary scan. It turns out that we have to use both these routines to achieve our end. First we format the integer as a binary object, then we scan this binary object for its bits.

LWDAQ_delay_seconds

proc LWDAQ_delay_seconds {sock value {flagname ""}}

LWDAQ_delay_seconds tells a driver at the other end of $sock to pause for $value seconds. If the delay is less than max_delay_seconds, the routine sends the delay commands to the driver and exits. The driver will be left executing the delay. But if the delay is greater than max_delay_seconds, the routine sends a sequence of delay job commands to the driver and waits for each one to complete before sending the next. In this way, the socket is kept open and no timeout will occur.

LWDAQ_driver_init

proc LWDAQ_driver_init {}

LWDAQ_driver_init initializes the global variable LWDAQ_Driver that describes the LWDAQ Relay and LWDAQ Controller sections of the LWDAQ Driver.

LWDAQ_echo

proc LWDAQ_echo {sock s}

LWDAQ_echo takes a string and sends it to a driver in an echo message. It waits for a data return message containing a string, which should match the string it sent.

LWDAQ_edit_script

proc LWDAQ_edit_script {{cmd "Open"} {src ""}}

LWDAQ_edit_script creates and controls a text editor window. It returns the name of the window. The window provides New, Open, Save, and SaveAs buttons. The routine takes a command "cmd" and a text source "src" as input parameters. The "Open" command creates a new, empty, editing window. It treats the source parameter as a file name. If the named file is an empty string, edit_script opens a file browser so the user can select a file, and it reads that file into the editing window. Otherwise, if the named file exists, edit_script reads the contents of the named file into the editing window. It sets the window title equal to the file name. Note that the Open command does not create a new file. The "Save" command takes an editor window name as its source, and saves the contents of that editor window to the file named in the editor window's title. The "SaveAs" command also takes a window as its source but opens a browser for the user to choose a destination file. The "New" command opens a new editor window with a default file name. It ignores the source parameter. In the text editor window, we use command-z to undo, command-s to save the text to the title file. The New button in the text editor opens a file called Untitled.txt, which we assume does not exist.

LWDAQ_enable_text_undo

proc LWDAQ_enable_text_undo {t}

LWDAQ_enable_text_undo turns on a text widget's undo stack. This stack will consume memory as it gets larger, so you should leave the stack off when you are repeatedly and automatically updating the text window contents, as we do in the System Monitor or the Acquisifier windows.

LWDAQ_exec_Diagnostic

proc LWDAQ_exec_Diagnostic {operation}

LWDAQ_exec_Diagnostic opens a socket to a driver and calls the specified operation routine.

LWDAQ_execute_job

proc LWDAQ_execute_job {sock job}

LWDAQ_execute_job tells a driver to execute job with job identifier $job through socket $sock. The driver will be busy thereafter for however long it takes to execute the job, but the routine will return as soon as the TCPIP messages required to instruct the driver have been transmitted. Note that if you have lazy_flush set to 1, the job won't execute until you flush the socket, close it, or read from it. The job parameter is a string of characters representing a decimal number.

LWDAQ_extended_BCAM

proc LWDAQ_extended_BCAM {}

LWDAQ_extended_BCAM tries to assign optimal values to peak_max and peak_min, and adjust the analysis boundaries to enclose the spots within a number of pixels of their centers. You direct the configuration calculations with the extended_parameters string, which contains parameters as a list. The string "0.6 0.9 20 1" sets peak_min to 60% of saturation, peak_max to 90% of saturation, shrinks the image bounds to 20 pixels around the spot center, and adjusts individual source exposure times. If you don't want a border, specify bounds to be 0 (instead of 20). If you don't want to adjust multiple sources individually, specify 0 for individual_sources.

LWDAQ_extended_Rasnik

proc LWDAQ_extended_Rasnik {}

LWDAQ_extended_Rasnik tries to assign optimal values to peak_max and peak_min. You direct the configuration with info(extended_parameters), which contains min_frac and max_frac. With the string "0.6 0.9", the configuration sets peak_min to 60% of saturation, peak_max to 90% of saturation.

LWDAQ_extended_SCAM

proc LWDAQ_extended_SCAM {}

LWDAQ_extended_SCAM tries to assign optimal values to peak_max and peak_min, and adjust the analysis boundaries to enclose the spots within a number of pixels of their centers. You direct the configuration calculations with the extended_parameters string, which contains parameters as a list. The string "0.6 0.9 20 1" sets peak_min to 60% of saturation, peak_max to 90% of saturation, shrinks the image bounds to 20 pixels around the spot center, and adjusts individual source exposure times. If you don't want a border, specify bounds to be 0 (instead of 20). If you don't want to adjust multiple sources individually, specify 0 for individual_sources.

LWDAQ_find_files

proc LWDAQ_find_files {directory pattern}

LWDAQ_find_files takes a directory and a glob matching pattern to produce a list of all matching files in the directory and its sub-directories. It assembles the list by calling itself recursively. The routine is not sensitive to case in the matching pattern. The list is not sorted.

LWDAQ_firmware_version

proc LWDAQ_firmware_version {sock}

LWDAQ_firmware_version reads the controller's firmware version number through open socket $sock, and returns the version.

LWDAQ_flash_seconds

proc LWDAQ_flash_seconds {sock value}

LWDAQ_flash_seconds is like LWDAQ_delay_seconds, except it flashes a source for an arbitrarily long period, rather than just waiting. When the total flash time is greater than the maximum single-flash time supported by the driver, the routine creates a total flash time by adding together smaller flashes. Ten seconds of flash time will take more than ten seconds to implement because of the delays in communication between computer and driver.

LWDAQ_get_dir_name

proc LWDAQ_get_dir_name { {initialdir ""} }

LWDAQ_get_dir_name opens a file browser and allows you to select a directory. We can specify an initial directory for the file search. By default the search begins in the LWDAQ working directory.

LWDAQ_get_file_name

proc LWDAQ_get_file_name { {multiple 0} {initialdir ""} }

LWDAQ_get_file_name opens a file browser window and allows the user to select one or more files in the file system. The user can select multiple files when multiple is one (1). By default, multiple is zero (0). The routine starts in the LWDAQ working directory, and when the user selects a file, it sets the working directory to the directory containing the file. If the user selects no file, or presses the cancel button in the pop-up window, the routine does nothing. We can specify an initial directory for the file search. By default the search begins in the LWDAQ working directory.

LWDAQ_get_lwdaq_config

proc LWDAQ_get_lwdaq_config {option}

LWDAQ_get_lwdaq_config takes a lwdaq_config option name and returns its value. We can get all the values of all options with "lwdaq_config", but this routine extracts one particular option value for the convenience of the calling routine. When we specify the option, we must not include the dash suffix.

LWDAQ_GIF_to_DAQ_Viewer

proc LWDAQ_GIF_to_DAQ_Viewer {}

LWDAQ_GIF_to_DAQ_Viewer opens a browser in which you select multiple GIF image files, and converts them to DAQ files, writing them into the same directory with suffix ".daq".

LWDAQ_global_var_name

proc LWDAQ_global_var_name {}

LWDAQ_global_var_name will return a unique name for a global variable.

LWDAQ_hardware_id

proc LWDAQ_hardware_id {sock}

LWDAQ_hardware_id reads the controller identifier number from the LWDAQ driver at the other end of TCPIP socket $sock, and returns the identifier.

LWDAQ_hardware_version

proc LWDAQ_hardware_version {sock}

LWDAQ_hardware_version reads the controller's hardware version number through open socket $sock, and returns it.

LWDAQ_html_contents

proc LWDAQ_html_contents { {cell_spacing 4} {num_columns 4} {file_name ""} }

LWDAQ_html_contents creates a table of contents for an HTML document. Each h2 and h3 level heading must have a unique name in the document, because this routine uses the heading text as the identifier for each heading line. The table of contents will be placed underneath an h2 heading with text "Contents". Any pre-existing table of contents between this h2 heading and the next h2 heading will be removed from the document. The routine takes three optional parameters. The first two are cell_spacing and num_columns for the h3 heading tables beneath each h2 heading. The third parameter is the name of the HTML file to be processed.

LWDAQ_html_split

proc LWDAQ_html_split {{file_name ""}}

LWDAQ_html_split takes a long file with h2-level chapters and splits it into chapter files. It puts the chapter files in a new directory. If the original file is called A.html, the directory is A, and the chapters are named A_1.html to A_n.html, where n is the number of chapters. There will be another file called index.html, which is the table of contents. Each chapter provides a link to the table of contents, to the previous chapter, and to the next chapter. Each preserves the header and stylsheets used in the original file. All local html links get displaced downwards by one level in order to account for the chapters being buried in a new directory. Internal links in the document are broken, so you will have to go in and fix them by hand. Any h2-level heading called "Contents" will be removed from the list of chapter, because we assume it's a table of contents generated by the routine LWDAQ_html_contents.

LWDAQ_html_tables

proc LWDAQ_html_tables { {file_name ""} }

LWDAQ_html_tables extracts all the tables from an HTML document and writes them to a new HTML document with Tables_ added to the beginning of the original document's file root. The routine takes one optional parameter: the name of the HTML document.

LWDAQ_image_pixels

proc LWDAQ_image_pixels {image_name {left -1} {top -1} {right -1} {bottom -1}}

LWDAQ_image_pixels returns a string containing the intensities of all pixels in a rectangular area in the image. By default, the routine uses the analysis boundaries, but we can also specify our own left, top, right, and bottom boundaries in that order. The pixels form an array by use of spaces and line breaks. There is a line break at the end of each row of pixels and a space between each column. You can paste the output from this routine directly into a spreadsheet and obtain a two-dimensional intensity array.

LWDAQ_image_sensor_clear

proc LWDAQ_image_sensor_clear {sock type}

LWDAQ_image_sensor_clear clears charge from an image sensor so it will be ready to expose. We pass the routine a socket to the driver and a device type number that identifies the image sensor.

LWDAQ_image_sensor_transfer

proc LWDAQ_image_sensor_transfer {sock type}

LWDAQ_image_sensor_transfer moves the image from the exposure array into the storage or transfer array, is such an array exists in the image sensor. We pass the routine a socket to the driver and a device type number that identifies the image sensor.

LWDAQ_info_button

proc LWDAQ_info_button {name}

LWDAQ_info_button makes a new toplevel window with a button that lets you see the instrument script. Below the button are the elements of the instrument's info array. You can change the elements by typing in the entry boxes.

LWDAQ_infobuttons_BCAM

proc LWDAQ_infobuttons_BCAM {f}

LWDAQ_infobuttons_BCAM creates buttons that allow us to configure the BCAM for any of the available image sensors. The general-purpose instrument routines will call this procedure when they create the info panel.

LWDAQ_infobuttons_Dosimeter

proc LWDAQ_infobuttons_Dosimeter {f}

LWDAQ_infobuttons_Dosimeter creates buttons that allow us to configure the Dosimeter for any of the available image sensors.

LWDAQ_infobuttons_Rasnik

proc LWDAQ_infobuttons_Rasnik {f}

No description available.

LWDAQ_infobuttons_SCAM

proc LWDAQ_infobuttons_SCAM {f}

LWDAQ_infobuttons_SCAM creates buttons that allow us to configure the SCAM for any of the available image sensors. The general-purpose instrument routines will call this procedure when they create the info panel.

LWDAQ_init_BCAM

proc LWDAQ_init_BCAM {}

LWDAQ_init_BCAM creates all elements of the BCAM instrument's config and info arrays.

LWDAQ_init_Camera

proc LWDAQ_init_Camera {}

LWDAQ_init_Camera creates all elements of the Camera instrument's config and info arrays.

LWDAQ_init_Diagnostic

proc LWDAQ_init_Diagnostic {}

LWDAQ_init_Diagnostic creates all elements of the Diagnostic instrument's config and info arrays.

LWDAQ_init_Dosimeter

proc LWDAQ_init_Dosimeter {}

LWDAQ_init_Dosimeter creates all elements of the Dosimeter instrument's config and info arrays.

LWDAQ_init_Flowmeter

proc LWDAQ_init_Flowmeter {}

LWDAQ_init_Flowmeter creates all elements of the Flowmeter instrument's config and info arrays.

LWDAQ_init_Gauge

proc LWDAQ_init_Gauge {}

LWDAQ_init_Gauge creates all elements of the Gauge instrument's config and info arrays.

LWDAQ_init_Inclinometer

proc LWDAQ_init_Inclinometer {}

LWDAQ_init_Inclinometer creates all elements of the Inclinometer instrument's config and info arrays.

LWDAQ_init_main_window

proc LWDAQ_init_main_window {}

LWDAQ_init_main_window initialize the main window and defines the menubar.

LWDAQ_init_Rasnik

proc LWDAQ_init_Rasnik {}

LWDAQ_init_Rasnik creates all elements of the Rasnik instrument's config and info arrays.

LWDAQ_init_Receiver

proc LWDAQ_init_Receiver {}

LWDAQ_init_Receiver creates all elements of the Receiver Instrument's config and info arrays.

LWDAQ_init_RFPM

proc LWDAQ_init_RFPM {}

LWDAQ_init_RFPM creates all elements of the RFPM instrument's config and info arrays.

LWDAQ_init_SCAM

proc LWDAQ_init_SCAM {}

LWDAQ_init_SCAM creates all elements of the SCAM instrument's config and info arrays.

LWDAQ_init_Terminal

proc LWDAQ_init_Terminal {}

LWDAQ_init_Terminal creates all elements of the Terminal instrument's config and info arrays.

LWDAQ_init_Thermometer

proc LWDAQ_init_Thermometer {}

LWDAQ_init_Thermometer creates all elements of the Thermometer instrument's config and info arrays.

LWDAQ_init_Viewer

proc LWDAQ_init_Viewer {}

LWDAQ_init_Viewer creates all elements of the Viewer instrument's config and info arrays.

LWDAQ_init_Voltmeter

proc LWDAQ_init_Voltmeter {}

LWDAQ_init_Voltmeter creates all elements of the Voltmeter instrument's config and info arrays.

LWDAQ_init_WPS

proc LWDAQ_init_WPS {}

LWDAQ_init_WPS creates all elements of the WPS instrument's config and info arrays.

LWDAQ_inside_widget

proc LWDAQ_inside_widget {w x y}

LWDAQ_inside_widget takes a widget name and widget-local x and y coordinate and returns true iff the point (x,y) is inside the widget. There may be an existing TclTk routine for this, but we can't find it.

LWDAQ_instrument_analyze

proc LWDAQ_instrument_analyze {instrument {id ""}}

LWDAQ_instrument_analyze calls an instrument's analysis routine after checking its analysis_enable flag, and catches errors from the analysis routine. It assumes that the image it is to analyze is the image named in the instrument's memory_name parameter. The routine places an identifier in the result, as provided by the id parameter. By default, id becomes the memory name. The routine also prints the result to the panel text window.

LWDAQ_instrument_closeup

proc LWDAQ_instrument_closeup {x y name}

LWDAQ_instrument_closeup deduces column, row, and intensity of the pixel at the tip of our mouse pointer when we double-click on an image in any of the LWDAQ instruments. It prints the column, row, and intensity to the instrument's text window, which we assume exists or else the inspector routine would not have been called. This routine is bound to the double-press button event within the instrument image displays. If the Viewer instrument is open, a region around the pixel will be displayed and zoomed so we can see detail. The routine calls Viewer routines to accomplish the crop and zoom.

LWDAQ_instrument_print

proc LWDAQ_instrument_print {instrument print_str {color black}}

LWDAQ_instrument_print prints the result of analysis to an instrument text window using LWDAQ_print. If the verbose_result is set in the instrument's config array, then the routine uses the verbose_description list in the info array to describe each element of the result on on separate lines. We intend for this routine to be used only for printing instrument results in the instrument window. If you want to print anything else in the instrument window, use LWDAQ_print with the text window name $info(text). The info(text) element is set even if the instrument window is not open, and LWDAQ_print checks to see if the text window exists before it prints.

LWDAQ_instrument_save

proc LWDAQ_instrument_save {name}

LWDAQ_instrument_save saves instrument settings to a settings file in the LWDAQ configuration directory, so they will be loaded automatically when LWDAQ is next launched, or when a new LWDAQ is spawned. There is one parameter we don't want to save or read back: the name of the data image, which is something that cannot persist from one launch of LWDAQ to the next. It returns the name of the settings file.

LWDAQ_instrument_unsave

proc LWDAQ_instrument_unsave {name}

LWDAQ_instrument_unsave deletes a perviously-saved instrument settings file, if one exists. It returns the name of the settings file that was deleted, or an empty string if no file was found.

LWDAQ_instruments_init

proc LWDAQ_instruments_init {}

LWDAQ_instruments_init initializes the instruments routines.

LWDAQ_integer_write

proc LWDAQ_integer_write {sock addr value}

LWDAQ_integer_write writes a four-byte integer $value through open TCPIP socket $sock to controller address $addr. The addr and value parameters are strings of characters that represent decimal numbers.

LWDAQ_interface_init

proc LWDAQ_interface_init {}

LWDAQ_interface_init initializes the interface routines, installs operating system dependent event handlers, and configures the default fonts for the graphical user interface.

LWDAQ_ip_addr_match

proc LWDAQ_ip_addr_match {addr_1 addr_2}

LWDAQ_ip_addr_match takes two IP address strings and compares them to see if they point to the same driver socket. If the addresses match, the routine returns a 1. If they don't match, it returns a 0. A * in either parameter is a wild card, and will match.

LWDAQ_is_error_result

proc LWDAQ_is_error_result {s}

LWDAQ_is_error_result returns 1 if and only if the first string begins with "ERROR: " (case sensitive).

LWDAQ_job_done

proc LWDAQ_job_done {sock}

LWDAQ_job_done returns 1 if the driver's job register reads back zero, and 1 otherwise.

LWDAQ_library_settings

proc LWDAQ_library_settings {}

LWDAQ_library_settings allows us to edit the settings used by the analysis libraries. These are accessible through the lwdaq_config command. We make an array of options and values which the user can edit and then apply.

LWDAQ_list_commands

proc LWDAQ_list_commands { {pattern *} }

LWDAQ_list_commands lists LWDAQ commands in the console and returns an empty string.

LWDAQ_login

proc LWDAQ_login {sock password {error_on_fail 1}}

LWDAQ_login attempts to log into a LWDAQ relay with a login message and password $password. The routine recognises "no_password" as a key phrase to skip the login attempt and return the value 0. Otherwise, the routine sends the password and waits for an answer from the relay. An answer of 1 is success and 0 is failure. On success, the routine returns 1. On failure, the routine will generate an error by default, or return -1 if you pass the value 0 for error_on_fail.

LWDAQ_loop_button

proc LWDAQ_loop_button {name}

LWDAQ_loop_button is for use with instrument loop buttons.

LWDAQ_loop_time

proc LWDAQ_loop_time {sock}

LWDAQ_loop_time reads the contents of a LWDAQ Driver's loop timer register and returns it. The driver is at the other end of an open TCPIP socket named $sock.

LWDAQ_loop_time_Diagnostic

proc LWDAQ_loop_time_Diagnostic {sock}

LWDAQ_loop_time_Diagnostic executes a LWDAQ loop job on the Diagnostic instrument's target device, reads out the LWDAQ Driver's loop timer, and prints the loop time in the Diagnostic text window.

LWDAQ_mac_read

proc LWDAQ_mac_read {sock}

LWDAQ_mac_read reads the mac address of the Ethernet chip on the LWDAQ relay at the other end of open TCPIP socket $sock, and returns the address as a string of hexadecimal characters.

LWDAQ_MacOS_Open_File

proc LWDAQ_MacOS_Open_File {theAppleEvent theReplyAE}

No description available.

LWDAQ_make_instrument_menu

proc LWDAQ_make_instrument_menu {}

LWDAQ_make_instrument_menu destroys the current instrument menu and makes a new one that matches the current list of instruments.

LWDAQ_make_tool_menu

proc LWDAQ_make_tool_menu {}

LWDAQ_make_tool_menu destroys the current tool menu and makes a new one that matches the current selection of tools in the Tools, More, and Spawn directories.

LWDAQ_monitor_open

proc LWDAQ_monitor_open {}

LWDAQ_monitor_open opens the system monitor window.

LWDAQ_monitor_refresh

proc LWDAQ_monitor_refresh {}

LWDAQ_monitor_refresh updates the system monitor window, if it exists, and posts itself for re-execution in the TCL event loop.

LWDAQ_most_recent_byte

proc LWDAQ_most_recent_byte {sock}

LWDAQ_most_recent_byte reads the contents of a LWDAQ Driver's mrb register and returns it. The driver is at the other end of an open TCPIP socket named $sock. The mrb register contains the most recent byte to be written to the Driver's ram, either by the relay or by the controller.

LWDAQ_ndf_create

proc LWDAQ_ndf_create {file_name meta_data_size}

LWDAQ_ndf_create creates a new Neuroscience Data Format file, which is the format used by LWDAQ to store archives of continuous time-series data. The NDF format begins with a four-byte format identifier, which is the string " ndf" (note the space at the beginning of the identifier string. Next come three four-byte numbers in big-endian format (most significant byte first). These are the byte offset to meta-data space, byte offset to data space, and the length of meta-data string when last written. If the length is zero, routines that read the meta-data string should check the length for themselves. The header may contain additional binary information particular to the application. The meta-data space follows the header and contains only a null-terminated character string. The data space comes next, and occupies the remainder of the file. This routine creates a new file with an empty string and no data.

LWDAQ_ndf_data_append

proc LWDAQ_ndf_data_append {file_name data}

LWDAQ_ndf_data_append appends new data to an NDF file.

LWDAQ_ndf_data_check

proc LWDAQ_ndf_data_check {file_name}

LWDAQ_ndf_data_check returns the byte location of the file's data block and the length of the data block. If the file is not NDF, the routine returns an error.

LWDAQ_ndf_data_read

proc LWDAQ_ndf_data_read {file_name start_addr num_bytes}

LWDAQ_ndf_data_read reads num_bytes of data out of an NDF file data block, starting at byte start_addr. The first byte in the data block is byte zero. If you specify * for num_bytes, the routine reads all available data bytes from the file. If the file does not contain the bytes requested, the routine returns all the bytes that can be read.

LWDAQ_ndf_string_append

proc LWDAQ_ndf_string_append {file_name meta_data}

LWDAQ_ndf_string_append appends a meta-data string to the one that already exists in an NDF file. It speeds itself up by using the actual length value stored in the file header. It does not read the existing string from the file. The routine takes roughly 100 us to append a one-byte string regardless of the length of the existing string, and 1 ms to append a 10-kbyte string (on a 1.3 GHz G3 iBook).

LWDAQ_ndf_string_check

proc LWDAQ_ndf_string_check {file_name}

LWDAQ_ndf_string_check returns the byte location of the file's meta-data string, the maximum length of the string and the actual length of the string. If the file is not NDF, the routine returns an error.

LWDAQ_ndf_string_read

proc LWDAQ_ndf_string_read {file_name}

LWDAQ_ndf_string_read returns the meta-data string in an NDF file.

LWDAQ_ndf_string_write

proc LWDAQ_ndf_string_write {file_name meta_data}

LWDAQ_ndf_string_write re-writes the meta-data string in an NDF-file on disk but leaves the data intact. The routine takes roughly 100 us to write a one-byte string and 1 ms to write a 10-kbyte string (on a 1.3 GHz G3 iBook).

LWDAQ_off

proc LWDAQ_off {sock}

LWDAQ_off turns off power to all devices connected to the driver listening at the other end of $sock.

LWDAQ_off_Diagnostic

proc LWDAQ_off_Diagnostic {sock}

LWDAQ_off_Diagnostic turns off the device power.

LWDAQ_on

proc LWDAQ_on {sock}

LWDAQ_on turns on power to all devices connected to the driver listening at the other end of $sock.

LWDAQ_on_Diagnostic

proc LWDAQ_on_Diagnostic {sock}

LWDAQ_on_Diagnostic turns on the LWDAQ device power.

LWDAQ_open

proc LWDAQ_open {name}

LWDAQ_open opens the named instrument's window. We recommend that you post this routine to the event queue, or else it will conflict with acquisitions from the same instrument that are taking place with the window closed. The routine returns the name of the instrument window.

LWDAQ_open_document

proc LWDAQ_open_document {fn}

LWDAQ_open_document takes a file name and opens the file according to its file extensions. On MacOS, we call this procedure from tk::mac::OpenDocument.

LWDAQ_post

proc LWDAQ_post {event {place "end"}}

LWDAQ_post adds the $event script to the LWDAQ Manager event list. If you set the optional parameter "place" to "front" or "1", the the event gets added to the front of the queue, in first place. If "place" is "end" or "0", the event is added to the end of the queue. If "place" is any other positive integer greater than zero, the event is inserted into the queue in the position given by the integer, or the end of the queue if no such position exists.

LWDAQ_preferences

proc LWDAQ_preferences {}

LWDAQ_preferences opens a window with all the LWDAQ_Info settings. It returns the name of a custom frame in which we can put additional widgets.

LWDAQ_print

proc LWDAQ_print {args}

LWDAQ_print prints a string to the end of a text device. The text device can be a text window or a file. When the routine writes to a text window, it does so in a specified color, unless the string begins with "ERROR: ", "WARNING: ", or "SUGGESTION: ", in which case the routine forces the color itself. If you pass "-nonewline" as an option after LWDAQ_print, the routine does not add a carriage return to the end of the print string. The routine also recognises "-newline", which is the default. The routine assumes the text device is a text window if its name starts with a period and this period is not followed by a forward slash or a backslash. If the text window exists, the routine writes the print string to the end of the window. If the text device is either "stdout" or "stderr", the routine writes directly to these channels. If the text device is a file name and the directory of the file exists, the routine appends the string to the file, or creates the file if the file does not exist. The routine will not accept any file name that contains a space, is an empty string, or is a real number. If the routine cannot find any valid device that matches the device name, it will write the string to stdout provided the default_to_stdout flag is set. Otherwise the routine does nothing. Another service provided by the routine is to replace any double occurrances of "ERROR:" and "WARNING:" that might arise as we pass error and warning strings through various routines before they are printed. The routine returns the name of the text widget, file, or channel it wrote to.

LWDAQ_proc_declaration

proc LWDAQ_proc_declaration {{proc_name "LWDAQ_*"} {file_name ""} }

LWDAQ_proc_declaration returns a list of procedure declarations that match proc_name from the script file specified by file_name. The script must indicate a procedure declaration by quoting the procedure name after "proc " on a new line.

LWDAQ_proc_definition

proc LWDAQ_proc_definition {{proc_name "LWDAQ_*"} {file_name ""} }

LWDAQ_proc_definition returns a list of procedure definitions that match proc_name from the script file specified by file_name. The script must indicate the start of a procedure definition by quoting the procedure name after "proc " on a new line. It must indicate the end of the procedure definition with a line consisting only of a single right-brace "}".

LWDAQ_proc_description

proc LWDAQ_proc_description {{proc_name "LWDAQ_*"} {file_name ""} {keep_breaks 0} }

LWDAQ_proc_description returns a list of procedure descriptions, such as this one, as exctracted from the TCL/TK script that defines the procedure. If there are procedures in the script that match the proc_name parameter, but do not have their own descriptions, the routine returns an empty element in its list. The script must indicate the description by quoting the procedure name after "" on a new line. If you pass keep_breaks=1, the procedure will retain the original line breaks, which can be useful for printing directly to the TCL console.

LWDAQ_proc_list

proc LWDAQ_proc_list {{proc_name "LWDAQ_*"} {file_name ""} }

LWDAQ_proc_list returns a list of all procedures declared in the specified file that match the proc_name string. The proc_name can contain wild cards * and ?. Each procedure must be declared on a new line that begins with "proc " followed by the procedure name.

LWDAQ_process_exists

proc LWDAQ_process_exists {id}

LWDAQ_process_exists checks if an operating system process exists. We pass the routine an id number and the routine returns 0 for false (does not exist) and 1 for true (exists). If the id is zero, we always return false.

LWDAQ_process_stop

proc LWDAQ_process_stop {id}

LWDAQ_process_stop attempts to stop an operating system process using its id number. If the process id is zero, the routine does nothing. Otherwise it calls the local operating system's kill command to stop the process. It returns the message given by the kill process.

LWDAQ_psc_Diagnostic

proc LWDAQ_psc_Diagnostic {image_name}

LWDAQ_psc_Diagnostic checks the power supply voltages recorded in a Diagnostic image to see if they are within the bounds defined by the min_* and max_* info parameters. The routine returns a string of warnings. If this string is empty, no problems were encountered.

LWDAQ_put_file_name

proc LWDAQ_put_file_name {{name ""}}

LWDAQ_put_file_name opens a file browser window and allows the user to specify an output file. The browser allows the user to select an existing directory in the file system, and to type in a name for the file within that directory. If the "name" parameter is set when this procedure is called, the value of "name" will be the default file name in the browser window. The routine returns the name of the file that was written to. An empty string indicates that no file was written.

LWDAQ_queue_clear

proc LWDAQ_queue_clear { {pattern "*"} }

LWDAQ_queue_clear clears the event queue of any events matching the globular matching string passed into the routine. By default, the routine clears all events from the queue.

LWDAQ_queue_error

proc LWDAQ_queue_error {event error_result}

LWDAQ_queue_error displays an error for the event queue.

LWDAQ_queue_start

proc LWDAQ_queue_start {}

LWDAQ_queue_start starts the event queue if it's not running already.

LWDAQ_queue_step

proc LWDAQ_queue_step {}

LWDAQ_queue_step takes the first event out of the event queue deletes it, executes it, and posts itself to execute again after a delay of queue_ms.

LWDAQ_queue_stop

proc LWDAQ_queue_stop {}

LWDAQ_queue_stop stops the LWDAQ event manager.

LWDAQ_quit

proc LWDAQ_quit {}

LWDAQ_quit sends quit commands to all queued processes, then exits.

LWDAQ_ram_delete

proc LWDAQ_ram_delete {sock addr length {value 0}}

LWDAQ_ram_delete sets the LWDAQ Controller's data address equal to $addr and then clears a block of $length bytes starting from address $addr in the LWDAQ Controller memory. The bytes are set to zero unless another value is passed to the routine. The addr, length, and value parameter are character strings representing decimal numbers.

LWDAQ_ram_read

proc LWDAQ_ram_read {sock addr length}

LWDAQ_ram_read sets the LWDAQ Controller's data address equal to $addr, reads $length consecutive bytes from this same address location, and returns these bytes as a byte array. The routine is intended for use with a RAM portal, where each consecutive read from the portal returns a consecutive byte in RAM. The addr and length parameters are character strings representing decimal numbers.

LWDAQ_ram_write

proc LWDAQ_ram_write {sock addr data}

LWDAQ_ram_write sets the LWDAQ Controller's data address equal to $addr and writes a block of data byte by byte into the RAM Portal. The addr parameter is a string of characters representing a decimal number. The data parameter is a block of binary bytes.

LWDAQ_random

proc LWDAQ_random {{min 0.0} {max 1.0}}

LWDAQ_random returns a number between min and max. If both min and max are integers, then the number returned is also and integer. If either min or max is real, then the number returned is real. The random calculation we take from Practical Programming in TCL and TK by Brent Welch et al.

LWDAQ_random_wait_ms

proc LWDAQ_random_wait_ms {{min 0} {max 1000}}

LWDAQ_random_wait_ms waits for a random number of milliseconds between min and max. During the wait, it passes control to the TCL/TK event loop so that idle tasks can be executed.

LWDAQ_read_button

proc LWDAQ_read_button {name}

LWDAQ_read_button reads an image from disk. It allows the user to specify multiple files, and opens them one after another. It returns an empty string instead of the list of files, which might otherwise overwhelm our system server.

LWDAQ_read_image_file

proc LWDAQ_read_image_file {infile_name {image_name ""}}

LWDAQ_read_image_file reads an image file from disk into the lwdaq image list and returns its list name. If the file name ends with ".gif" (case insensitive), the routine reads the file as a GIF image. The gray-scale values in the first line of the image should, for best results, contain a DAQ image header. The DAQ header contains the image dimensions, the analysis bounds, and a result string. Two- dimensional image data begins only on the second line of the image. If the file name ends with ".ndf", the routine reads the file as an NDF (Neuroscience Data Format) file. It creates a new image that is approximately square, and large enough to contain the NDF data. It sets the image result string equal to the NDF meta-data string. It copies the NDF data into the image data area, which begins with the first pixel of the second row in the new image. If the file name ends with any other extension, the routine reads the image in as a DAQ file. You can specify a name for the image if you like, otherwise the routine will assign its own name.

LWDAQ_read_script

proc LWDAQ_read_script {fn}

LWDAQ_read_script reads a file from disk and returns its contents.

LWDAQ_reboot_Diagnostic

proc LWDAQ_reboot_Diagnostic {sock}

LWDAQ_reboot_Diagnostic re-boots the server.

LWDAQ_receive_byte

proc LWDAQ_receive_byte {sock}

LWDAQ_receive_byte receives a data return message and scans its contents for single-byte integer. It returns this integer as a string of characters representing a decimal number.

LWDAQ_receive_data

proc LWDAQ_receive_data {sock}

LWDAQ_receive_data receives a LWDAQ Message Protocol data return message from a socket and returns the message contents. The routine returns the data as a block of binary bytes. It supports the lwdaq protocol only.

LWDAQ_receive_integer

proc LWDAQ_receive_integer {sock}

LWDAQ_receive_integer receives a data return message and scans its contents for a four-byte integer in big-endian byte order (most significant byte received first). The routine returns a string of characters that represent a decimal number.

LWDAQ_refresh_Diagnostic

proc LWDAQ_refresh_Diagnostic {{image_name ""}}

LWDAQ_refresh_Diagnostic refreshes the display of the data, given new display settings. It calls the Diagnostic instrument's analysis procedure.

LWDAQ_refresh_Flowmeter

proc LWDAQ_refresh_Flowmeter {}

LWDAQ_refresh_Flowmeter refreshes the display of the data, given new display settings. It calls the Flowmeter analysis procedure.

LWDAQ_refresh_Gauge

proc LWDAQ_refresh_Gauge {}

LWDAQ_refresh_Gauge refreshes the display of the data, given new display settings. It calls the Gauge analysis routine, which assumes that certain parameters are stored in the image's results string.

LWDAQ_refresh_Receiver

proc LWDAQ_refresh_Receiver {}

LWDAQ_refresh_Receiver refreshes the display of the data, given new display settings.

LWDAQ_refresh_RFPM

proc LWDAQ_refresh_RFPM {}

LWDAQ_refresh_RFPM refreshes the display of the data, given new display settings. RFPM analysis assumes that certain parameters are stored in the image's results string.

LWDAQ_refresh_Thermometer

proc LWDAQ_refresh_Thermometer {}

LWDAQ_refresh_Thermometer refreshes the display of the data, given new display settings. It calls the Thermometer analysis routine, which assumes that certain parameters are stored in the image's results string.

LWDAQ_refresh_Voltmeter

proc LWDAQ_refresh_Voltmeter {}

LWDAQ_refresh_Voltmeter refreshes the display of the data, given new display settings. Voltmeter analysis assumes that certain parameters are stored in the image's results string.

LWDAQ_relay_reboot

proc LWDAQ_relay_reboot {sock}

LWDAQ_relay_reboot resets the relay without affecting the controller. This routine is supported only by relay software versions thirteen and up.

LWDAQ_report_error

proc LWDAQ_report_error {task message}

LWDAQ_report_error displays an error.

LWDAQ_reset

proc LWDAQ_reset {}

LWDAQ_reset stops all instruments, closes all sockets, stops all vwaits, and the event queue, sets the global reset variable to 1 for a period of time, and then sets all the instrument control variables to Idle.

LWDAQ_reset_Diagnostic

proc LWDAQ_reset_Diagnostic {sock}

LWDAQ_reset_Diagnostic reboots the controller logic.

LWDAQ_reset_instrument_counters

proc LWDAQ_reset_instrument_counters {{value 0}}

LWDAQ_reset_instrument_counters sets all the counters to the specifiec value, or to 1 if no value is specified.

LWDAQ_reset_Receiver

proc LWDAQ_reset_Receiver {}

LWDAQ_reset_Receiver resets and configures a data receiver. It resets the data receiver address and timestamp registers, thus emptying its message buffer and resetting its clock. It destroys the receiver instrument's data buffer and working image. It resets the acquired data time, a parameter we use to stop the Receiver Instrument attempting download too many messages from the data receiver. If the receiver is capable of saving a list of enabled channels that it should select for recording, the reset routine sends the daq_channels list to the receiver so as to select them.

LWDAQ_run_tool

proc LWDAQ_run_tool {{tool ""} {mode "Communal"}}

LWDAQ_run_tool runs a tool script. It takes two optional parameters: the tool name and the mode in which the tool is to run. If pass no paramters, these two default to an empty string and "Communal" mode. With an empty string for the tool name, when we are running with graphics, the routine opens a browser and asks the user to select a file. The routine deduces the tool name from the file name and runs the tool. If we pass it a tool name, the routine looks for the tool script in Tools, Tools/More, Tools/Spawn, the default directory, and the working directory in that order. The routine deduces the tool name from the root of the file name. Once we have the tool name and its script file name, we prepare to run the tool. The mode can have one of three possible values: Standalone, Slave, or Communal. If the mode is "Standalone" or "Slave", the routine deletes the Instrument and Tool menus. If the mode is Communal, the routine leaves these menus intact. When the tool starts up in Standalone of Slave mode, it should take over the main window for its own interface and delete the usual Quit button. When the tool starts up communal, it should create a new toplevel window for its interface. In Slave mode, the tool should set itself up to receive commands through stdin from its master, and send output through stdout. In Standalone mode, the tool should operate independent of stdin and stdout.

LWDAQ_save_settings

proc LWDAQ_save_settings {}

LWDAQ_save_settings saves the library settings and a selection of other core LWDAQ settings to disk.

LWDAQ_save_text_window

proc LWDAQ_save_text_window {window_name file_name}

LWDAQ_save_text_window saves the contents of text window $window_name to a file named $file_name.

LWDAQ_schedule_task

proc LWDAQ_schedule_task {name schedule command}

LWDAQ_schedule_task adds a new task to the schedule list. If the name conflicts with an existing task, we replace that task with the new definition. If the scheduler is not running, this routine starts the scheduler. The routine checks the format of the task schedule to make sure all five constraints are specified either with an integer value or a wild card. If the task does not conform to our required format, we return an error.

LWDAQ_scheduler

proc LWDAQ_scheduler {{next_check "0"}}

LWDAQ_scheduler takes a schedule of tasks and executes the tasks at their scheduled times. The tasks and schedules are stored in the global "scheduled_tasks" list. Each list entry consists of four elements. The first element is the name of the task. The second element is its schedule of execution. We define schedules in the same format as Unix "crontab files". The schedule string consists of five values separated by spaces. They are: minute (0-59), hour (0-23), day of month (1-31), month (1-12), and day of week (0-6, Sunday is 0). A wildcard character, "*", for a constraint means the constraint will be ignored. We have "0 23 * * *" schedules Daily at 11 PM, "30 22 * * *" schedules Daily at 22:30, "0 23 1 * *" schedules every first day of the month at 23:00, "0 23 * * 0" schedules every Sunday at 23:00. If the string is all stars, the scheduler never executes the task, so "* * * * *" means "never". The third element is the Tcl script that the scheduler will run when the specified minute arrives, or soon after it arrives. The fourth element is the most recent time the task was executed, in Unix seconds. If the scheduler misses the scheduled time by less than "scheduler_window" seconds, the scheduler will execute the task, otherwise it will skip the task. The scheduler accepts an optional parameter "next_check" that specifies the next second in which the scheduler should check for tasks that need to be started. We start the scheduler by calling it with not parameters, or with a zero argument. We stop it with a negative argument. If the scheduler's log name is not an empty string, we use it as the name of a channel or file to which we append notifications of tasks run by the scheduler. To add and subtract tasks from the scheduler's list, we use the schedule_task and unschedule_task routines defined below. The schedule routine starts the scheduler if it is not running already. The unschedule routine stops the scheduler if there are no tasks in the list. Thus we interact with the scheduler through these schedule and unschedule routines, rather than by calling the scheduler routine itself.

LWDAQ_script_description

proc LWDAQ_script_description {{file_name ""} {keep_breaks 0} }

LWDAQ_script_description returns the introductory paragraph of a TCL/TK script. It extracts the script name from the file_name parameter. The script name is the tail of the file_name. The script must indicate the introductory paragraph by quoting the script name after "" on a new line. If you pass keep_breaks=1, the procedure will retain the original line breaks, which can be useful for printing directly to the TCL console.

LWDAQ_server_accept

proc LWDAQ_server_accept {sock addr port}

LWDAQ_server_accept is called when a remote control socket opens. The first thing the routine does is check that the IP address of the TCPIP client matches the server's address_filter. The routine installs the LWDAQ_server_interpreter routine as the incoming data handler for the remote control socket, and it lists the new socket in the LWDAQ open socket list. If succesful, it returns a one, otherwise a zero.

LWDAQ_server_info

proc LWDAQ_server_info {{sock "nosocket"}}

LWDAQ_server_info returns a string giving the name of the specified socket. The routine is intended for use within the System Server, where we pass the name of a socket to the routine, and it returns the name and various other pieces of system information. If, however, you call the routine from the console or within a script, it will return the same information, but with the socket name set to its default value. When you send the command "LWDAQ_server_info" to the System Server over a System Server socket, the System Server calls LWDAQ_server_info with the name of this same socket, and so returns the socket name along with the system information. The elements returned by the routine are a socket number, the time in seconds, the local platform, the program patchlevel, and the TCL version.n

LWDAQ_server_interpreter

proc LWDAQ_server_interpreter {sock}

LWDAQ_server_interpreter receives commands from a TCPIP socket and handles them according to the server mode. With execute and post modes, the routine executes the line it receives as a Tcl command at the global scope. With echo mode, it writes back the same line. In receive mode it sets the global server line variable to the line just received, and adds a new entry to the server commands list. This new entry is itself a list containing the line as its first element and the socket through which the line was received in the second element.

LWDAQ_server_open

proc LWDAQ_server_open {}

LWDAQ_server_open opens the remote control window. In the window, you specify an IP address match string to filter incoming connection requests. You specify the IP port at which LWDAQ should listen. You provide match strings for the commands that the remote control command interpreter should process. When you press Run, the server is running and listening. When you press Stop, it stops. You cannot adjust the listening port while the server is running.

LWDAQ_server_start

proc LWDAQ_server_start {}

LWDAQ_server_start starts up the remote control server socket.

LWDAQ_server_stop

proc LWDAQ_server_stop {}

LWDAQ_server_stop stops the remote control server socket, and closes all open sockets.

LWDAQ_set_base_addr_hex

proc LWDAQ_set_base_addr_hex {sock value}

LWDAQ_set_base_addr_hex sets the four bytes of the driver's base address to $value. The value parameter is a string of characters representing an eight-digit hexadecimal number, plus an optional colon and number as in daq_driver_socket of an instrument configuration. The routine uses only the hex number. The routine translates the character string into a four-byte integer. The driver is at the other end of open TCPIP socket $sock. The base address register exists in LWDAQ components like the VME-TCPIP Interface (A2064), where it sets the base position in VME address space of the LWDAQ Driver with VME Interface to which subsequent instructions to the A2064 should be directed. We call this routine whenever we open a TCPIP socket to a LWDAQ component. The routine accepts a hex number followed by a colon and an integer, either in the format "00E00000:7" or "E0:7" where "E0" is an abbreviation of the full thirty-two bit address "00E00000". It uses the hex number before the colon as the base address.

LWDAQ_set_bg

proc LWDAQ_set_bg {widget color}

LWDAQ_set_bg takes the name of a widget and makes sure its background color is set to "color". If the background is already "color", the routine does nothing. If graphics are disabled, the routine does nothing. This routine abbreviates our code, and avoids unnecessary drawing by first checking to see if the background color has already been set to the desired value. It is similar to LWDAQ_set_fg.

LWDAQ_set_bit

proc LWDAQ_set_bit {binary_string bit_num {value 1}}

LWDAQ_set_bit takes a string of ones and zeros, called binary_string, and sets bit number $bit_num to $value. By default, $value is 1, in keeping with the electrical engineer's meaning of the word "set".

LWDAQ_set_bounds_Viewer

proc LWDAQ_set_bounds_Viewer {}

LWDAQ_set_bounds_Viewer applies the Viewer's DAQ bounds to its local image and re-draws in the Viewer panel.

LWDAQ_set_command_reg

proc LWDAQ_set_command_reg {sock value}

LWDAQ_set_command_reg sets a driver's command register to $value through TCPIP socket $sock. The value parameter is a string of characters representing a decimal number. This decimal number will be translated into a sixteen-bit value before transmission to the driver.

LWDAQ_set_command_reg_binary

proc LWDAQ_set_command_reg_binary {sock value}

LWDAQ_set_command_reg_binary sets a driver's command register to $value, where $value is a binary string representation of the register's sixteen bits. For example, the value "1111111111111111" represents hexadecimal value 0xFFFF, or decimal value 65535.

LWDAQ_set_command_reg_hex

proc LWDAQ_set_command_reg_hex {sock value}

LWDAQ_set_command_reg_hex sets a driver's command register to $value, where $value is a hexadecimal string representation of the register's sixteen bits.

LWDAQ_set_data_addr

proc LWDAQ_set_data_addr {sock value}

LWDAQ_set_data_addr sets the four bytes of the driver's data address to $value. The driver is at the other end of open TCPIP socket $sock. The value parameter is a string of characters representing a decimal number.

LWDAQ_set_delay_seconds

proc LWDAQ_set_delay_seconds {sock value}

LWDAQ_set_delay_seconds sets a driver's delay timer to a number of ticks that will count down to zero in $value seconds. The driver is at the other end of TCPIP socket $sock. The value parameter is a character string representing a decimal number.

LWDAQ_set_delay_ticks

proc LWDAQ_set_delay_ticks {sock value}

LWDAQ_set_delay_ticks sets a driver's delay timer to $value through socket $sock. The value parameter is a character string representing a decimal number.

LWDAQ_set_device_addr

proc LWDAQ_set_device_addr {sock value}

LWDAQ_set_device_addr sets the device address register on a driver to $value through TCPIP socket $sock. The driver will be busy with this instruction for a few tens of microseconds thereafter, as it switches its driver sockets and transmits a new address down the newly active socket. The value parameter is a character string representing a decimal number.

LWDAQ_set_device_element

proc LWDAQ_set_device_element {sock value}

LWDAQ_set_device_element sets a driver's device type register to $value through socket $sock. The value parameter is a character string representing a decimal number.

LWDAQ_set_device_type

proc LWDAQ_set_device_type {sock value}

LWDAQ_set_device_type sets a driver's device type register to $value through socket $sock. The value parameter is a character string representing a decimal number.

LWDAQ_set_dimensions_Viewer

proc LWDAQ_set_dimensions_Viewer {}

LWDAQ_set_dimensions_Viewer creates a new image with dimensions specified in the dimension control boxes. The analysis boundaries remain the same. We draw the new image in the Viewer panel. If our default is to delete old Viewer images, we do so.

LWDAQ_set_driver_mux

proc LWDAQ_set_driver_mux {sock driver {mux 1}}

LWDAQ_set_driver_mux sets the device address register on a driver so as to select driver socket $driver and multiplexer socket (also known as the branch socket) $mux. The driver will be busy for a few tens of microseconds thereafter, as it switches target sockets. The driver socket can be a simple integer specifying the socket on a LWDAQ driver, or it can be of the form b:a, where "b" is a 32-bit "base address" expressed as an eight-digit hex string, and "a" is a decimal number. The base address selects one of several drivers associated with $sock. We might have a VME crate holding twenty LWDAQ Drivers (A2037A) and a single VME-TCPIP interface (A2064). The $sock connection is with the A2064, and we instruct the A2064 to select one of the twenty drivers using "b" in $driver. For example, 00E0000:3 would select the driver at VME base address hexadecimal 00E00000, and socket 3 within that driver. We can also specify the base address in an abbreviated fasion like this: "E0:3", and the missing six zeros will be added to the address to compose the full eight-digit address. If we do not specify a base address, the routine does not bother setting the base address on the TCPIP interface at $sock. It uses $driver as the decimal socket number.

LWDAQ_set_fg

proc LWDAQ_set_fg {widget color}

LWDAQ_set_fg takes the name of a widget and makes sure its foreground color is set to "color". If the foreground is already "color", the routine does nothing. If graphics are disabled, the routine does nothing. This routine abbreviates our code, and avoids unnecessary drawing by first checking to see if the foreground color has already been set to the desired value. It is similar to LWDAQ_set_bg.

LWDAQ_set_image_sensor

proc LWDAQ_set_image_sensor {name instrument}

LWDAQ_set_image_sensor takes a LWDAQ device type name and an instrument name as parameters. It sets up the named instrument to use the named device type for image capture. The routine sets the image height and width, the device type number, and the analysis boundaries to suit the new image sensor. Some instruments have the daq device type in the config array, and other in the info array. This routine handles both contingencies by looking for the parameters in both places. The list of supported image sensors is stored in the LWDAQ_Driver(image_sensors) global list. The following sensor names are included: TC255 TC237 KAF0400 KAF0261 ICX424 ICX424Q. To get the complete and up-to-date list, consult the image_sensors list with the help of the LWDAQ console.

LWDAQ_set_multisource_element

proc LWDAQ_set_multisource_element {sock value power}

LWDAQ_set_multisource_element composes the command that will select multisource element number "value" and turn it on to power level "power". If the value is a simple integer, the routine uses this integer as the byte to select the source element. If the value is an alpha-numeric code of the form Xn, where X is a single letter of any case and n is a decimal number 0-15, the routine uses the letter to select a set of sixteen sources and the number to select the source within this set. Thus A1 is source number 1 in the 1st set of sixteen, and is equivalent to selecting source number 1, while P15 is source number 15 in the 16th set of sixteen, and is equivalent to selecting source number 255.

LWDAQ_set_repeat_counter

proc LWDAQ_set_repeat_counter {sock value}

LWDAQ_set_repeat_counter sets a driver's repeat counter to $value through socket $sock. The value parameter is a character string representing a decimal number.

LWDAQ_set_results_Viewer

proc LWDAQ_set_results_Viewer {}

LWDAQ_set_results_Viewer sets the results string of the local image.

LWDAQ_set_voltmeter_device

proc LWDAQ_set_voltmeter_device {device}

No description available.

LWDAQ_sleep

proc LWDAQ_sleep {sock}

LWDAQ_sleep sends a driver's target device to sleep through $sock.

LWDAQ_sleep_Diagnostic

proc LWDAQ_sleep_Diagnostic {sock}

LWDAQ_sleep_Diagnostic sends the target device to sleep.

LWDAQ_sleepall_Diagnostic

proc LWDAQ_sleepall_Diagnostic {sock}

LWDAQ_sleepall_Diagnostic sends a range of devices to sleep. The routine starts with driver socket 1 and multiplexer socket 1, and proceeds to driver socket 1, multiplexer socket b, where b is the second number in sleepall_params. The routine moves on to driver socket 2 and repeats the same procedure, and so on, up to driver socket a, where a is the first number in sleepall_params.

LWDAQ_smallint_write

proc LWDAQ_smallint_write {sock addr value}

LWDAQ_smallint_write writes a two-byte integer $value through open TCPIP socket $sock to controller address $addr. The addr and value parameters are strings of characters that represent decimal numbers.

LWDAQ_socket_accept

proc LWDAQ_socket_accept {sock addr port}

LWDAQ_socket_accept is an example socket acceptance routine. It sets up the socket to call LWDAQ_socket_interpreter whenever a new line of data arrives from the socket.

LWDAQ_socket_close

proc LWDAQ_socket_close {sock}

LWDAQ_socket_close closes a socket if it exists. If the socket is listed in the LWDAQ open sockets list, this routine will remove the socket from the list. If the socket is a LWDAQ client, the routine sends an end of transmission character before closing the socket, and also applies a delay of a few milliseconds afterwards to give LWDAQ Drivers with older software time to get ready to accept another connection. Use this routine to close sockets opened by LWDAQ_socket_open. The routine always returns an empty string.

LWDAQ_socket_flush

proc LWDAQ_socket_flush {sock}

LWDAQ_socket_flush flushes output from a socket. Use this routine with a socket opened by LWDAQ_socket_open, but not with sockets opened with the bare Tcl socket command.

LWDAQ_socket_interpreter

proc LWDAQ_socket_interpreter {sock}

LWDAQ_socket_interpreter is an example socket interpreter. It calls the LWDAQ socket closing routine to make sure that the open_sockets list is kept up to date.

LWDAQ_socket_listen

proc LWDAQ_socket_listen {{accept ""} {port ""}}

LWDAQ_socket_listen opens a server socket for listening on the specified port on the local machine. You specify an acceptance procedure that TCL will call when the server accepts a new connection.

LWDAQ_socket_open

proc LWDAQ_socket_open {target {protocol ""}}

LWDAQ_socket_open opens a connection to a TCPIP server and returns the socket name. The target parameter is of the form a:b where a is an IP address in standard x.x.x.x format or a host name, b is an IP port number in decimal format. The port number can be omitted, in which case the routine assumes a default port number. The optional parameter is the message protocol name. Supported protocols are "lwdaq" and "basic". The default is "lwdaq". To get the basic protocol, specify basic when you open the socket. The lwdaq protocol differs from basic in that it transmits an end of transmission code when we close the socket. The routines that exchange messages with lwdaq servers are in the Driver.tcl file, and there you will see the transmit and receive routines checking the socket info to determine the socket protocol. If you open a socket with LWDAQ_socket_open, be sure to flush it and close it with the LWDAQ flush and close routines also. If you use the bare flush and close commands provided by Tcl, the LWDAQ socket list will become garbled. In some situations, mixing the bare and LWDAQ commands can lead to lost data, or the substitution of zeros for image data.

LWDAQ_socket_protocol

proc LWDAQ_socket_protocol {sock}

LWDAQ_socket_protocol determines the message protocol in use on a socket.

LWDAQ_socket_read

proc LWDAQ_socket_read {sock size}

LWDAQ_socket_read reads $size bytes from the input buffer of $sock. If the global LWDAQA_Info(blocking_sockets) variable is 1, the read takes place in one entire data block. While the data arrives, the LWDAQ program freezes. If the same variable is 0, the this procedure reads the data in fragments, allowing the program to respond to menu and window events between fragments. The routine collects all the necessary fragments together and returns them. Use this routine with sockets opened by the LWDAQ_socket_open command. If the size parameter is not an integer, but instead the word "line", we read characters from the socket until we get a newline character, or until a timeout occurs.

LWDAQ_socket_upload

proc LWDAQ_socket_upload {target data}

LWDAQ_socket_upload opens a socket to a server, writes a data string to the socket, and closes the socket. The target parameter is of the form a:b where a is an IP address in standard x.x.x.x format or a host name, b is an IP port number in decimal format. The routine treats the string as a binary object and transmits it without a carriage return at the end.

LWDAQ_socket_write

proc LWDAQ_socket_write {sock data}

LWDAQ_socket_write sends data to a socket's output buffer. Normally, we don't send out our data until the buffer is full or we are about to read from the socket. We call this 'lazy flushing'. Sending many instructions in one data packet is more efficient, and we get to use the TCP/IP buffer as a place to construct the string of commands. But if we want to see what is happening on the driver, we might want to send instructions to the LWDAQ Relay immediately. In that case, we set the lazy_flush flag to zero. We must make sure puts does not add a newline character to the end of every binary array it sends. Use this routine with sockets opened by LWDAQ_socket_open.

LWDAQ_software_version

proc LWDAQ_software_version {sock}

LWDAQ_software_version fetches the relay software version from a driver through an open socket $sock.

LWDAQ_sort_files

proc LWDAQ_sort_files {fnl}

LWDAQ_sort_files takes a list of file names and sorts them by the file name without directory name, which in Tcl we call the file tail.

LWDAQ_spawn_tool

proc LWDAQ_spawn_tool {tool {commands ""} {cfn ""}}

LWDAQ_spawn_tool runs a tool in a new and independent LWDAQ process. In the spawned LWDAQ, the root window does not contain the Quit button, but instead presents the Tool window. When the new LWDAQ process starts up, it uses a configuration file to launch the specified tool and take over the root window. The tool must be designed for spawning, in that it can deal with a window that is named ".toolname" or just "." We can pass in our own configuration commands into the routine through the commands string, and these will be written to the configuration file after the standalone run command. We can pass a configuration file name in for the spawn routine to use, in cases where we are spawning many processes consecutively, each with their own custom configuration, and we don't want to over-write one file before it has been used. If we don't provide a file name, the spawn routine generates a file in the temporary directory. When the routine launches the new process, it does so using the command-line "--spawn" option, which suppresses any console or pipe that might otherwise be connected to the new process. By this means, the new process will not quit when the process that created it quits.

LWDAQ_split

proc LWDAQ_split {s}

LWDAQ_split takes a list of parameters delimited by white space, colons, commas, equal-signs, semi-colons, and null characters. It returns a list containing no empty elements.

LWDAQ_start_job

proc LWDAQ_start_job {sock job}

LWDAQ_start_job tells a driver to begin a job execution by writing job identifier $job to the job register at socket $sock. The job parameter is a string of characters representing a decimal number.

LWDAQ_stdin_console_execute

proc LWDAQ_stdin_console_execute {}

LWDAQ_stdin_console_execute executes a command supplied from stdin and writes the result stdout.

LWDAQ_stdin_console_start

proc LWDAQ_stdin_console_start {}

LWDAQ_stdin_console_start turns the standard input, which will exist when we start LWDAQ from a terminal on UNIX, LINUX, Windows and MacOS. We check to see if a console package is available to make a full-functioning console interface. If not, we use a crude console with no arrow implementation, no history, and no insertion.

LWDAQ_stdin_console_stop

proc LWDAQ_stdin_console_stop {}

LWDAQ_stdin_console_stop disables the console, so that standard input and output are no longer being used to provide and respond to Tcl commands.

LWDAQ_stop_button

proc LWDAQ_stop_button {name}

LWDAQ_stop_button is for use with instrument stop buttons. If the state of the instrument is already Stop, the stop button tries a little harder to make the instrument stop: it closes stops all existing LWDAQ vwait routines.

LWDAQ_stop_instruments

proc LWDAQ_stop_instruments {}

LWDAQ_stop_instruments stops all looping instruments.

LWDAQ_stop_vwaits

proc LWDAQ_stop_vwaits {}

LWDAQ_stop_vwaits sets all vwait variables generated by the above routine, which aborts all the current LWDAQ vwaits. Because TCL vwaits are nested, LWDAQ_stop_vwaits will cause any depth of nesting to terminate, even it the nesting is in deadlock.

LWDAQ_stream_delete

proc LWDAQ_stream_delete {sock addr stream_length value}

LWDAQ_stream_delete writes a constant byte value repeatedly to the same controller address, so as to clear consecutive memory locations. It is like the stream read in reverse, except the data value is always $value, where $value is a string of digits that represent a decimal value. The addr, stream_length, and value parameters are all strings of characters that represent decimal numbers. The routine translates the strings into two four-byte integers and a byte value respectively before transmitting them to the driver.

LWDAQ_stream_read

proc LWDAQ_stream_read {sock addr stream_length}

LWDAQ_stream_read reads $stream_length bytes out of controller address $addr on the driver at the other end of TCPIP socket $sock, and returns the entire stream. The routine is intended for use with the controller's stream read location, which presents consecutive bytes in the controller RAM on consecutive reads by the relay. The addr and stream_length parameters are strings of characters that represent decimal numbers. The routine translates both into four-byte integers before transmitting them to the driver. The routine returns a block of binary data.

LWDAQ_stream_write

proc LWDAQ_stream_write {sock addr data}

LWDAQ_stream_write writes a block of bytes to the same controller address so as to transfer them into a memory block through a memory portal. It is like the stream read in reverse. The addr parameter is a string of characters that represents a decimal number. The data parameter is a block of binary bytes that will be transmitted without modification. The routine translates the addr string into a four-byte integer before transmitting to the driver.

LWDAQ_support

proc LWDAQ_support {}

LWDAQ_support allows you to move windows while running a computation. You simply include a call to this routine in your repeating loop. Every support_ms, the routine will call LWDAQ_update to handle system activity.

LWDAQ_text_widget

proc LWDAQ_text_widget {wf width height {scrolly 1} {scrollx 0}}

LWDAQ_text_widget opens a text window within the specified window frame. The text window has its "undo" stack turned off. The text widget is a child of an existing window frame "wf", and will be given the name $wf.text, which is returned by the routine. By default, the window has a y scrollbar, but no x scrollbar. If we have an x scrollbar we turn off the text wrapping. We bind the Command-B key to clear the widget of text, and we set the tab size to a quarter-inch.

LWDAQ_time_stamp

proc LWDAQ_time_stamp { {s ""} }

LWDAQ_time_stamp returns a year, month, date, hour, seconds time-stamp string for record keeping, or converts a [clock seconds] result into a time-stamp.

LWDAQ_tool_configure

proc LWDAQ_tool_configure {name {num_columns 2}}

LWDAQ_tool_configure opens a configuration panel so we can set a tool's configuration array elements. It also provides for extra configuration buttons by returning the name of a frame below the Save button.

LWDAQ_tool_data

proc LWDAQ_tool_data {name}

LWDAQ_tool_data extracts data lines from a tool's script and returns them as a string. The routine trims white spaces from the start and end of the data.

LWDAQ_tool_help

proc LWDAQ_tool_help {name}

LWDAQ_tool_help extracts help lines from the tool script. If the help consists only of an http reference, the routine attempts to open the link and display the help web page. Otherwise, the routine prints the help text in a new text window.

LWDAQ_tool_init

proc LWDAQ_tool_init {name version}

LWDAQ_tool_init performs initialization common to all LWDAQ tools. If the tool is already being presented in graphical mode with a window, we do not re-initialize the tool, but simply raise its window. If no such window exists, we delete any existing tool arrays, and initialize some variables common to all tools.

LWDAQ_tool_open

proc LWDAQ_tool_open {name}

LWDAQ_tool_open opens a tool window if none exists, and returns the name of the window. The routine assumes that the tool has already been initialized. If the tool window does exist, the routine raises the tool window and returns an empty string. If graphics are disabled, the routine returns an empty string. The routine recognises two special opening modes, Standalone and Slave, in which the tool will take over the main window and delete the Quit button.

LWDAQ_tool_reference

proc LWDAQ_tool_reference {{script ""}}

LWDAQ_tool_reference generates an HTML manual page for the routines defined in a LWDAQ tool script. We name the tool script and the routine does the rest. The routine creates the tool reference in the LWDAQ directory, and names it Tool.html. If we don't specify a a file, the routine will open a file browser. The routine writes an h3-level title, a declaration showing the parameters that we must pass into the procedure, and the description of the procedure extracted from the comments above.

LWDAQ_tool_reload

proc LWDAQ_tool_reload {name}

LWDAQ_tool_reload closes the tool and opens it again. We use this procedure when we are developing a tool. It allows us to re-load with the new tool script with one button press.

LWDAQ_tool_rewrite_data

proc LWDAQ_tool_rewrite_data {name data}

LWDAQ_tool_rewrite_data replaces the existing data portion of a tool script with a new data string.

LWDAQ_tool_save

proc LWDAQ_tool_save {name}

LWDAQ_tool_save writes a tool's configuration array to disk.

LWDAQ_tool_unsave

proc LWDAQ_tool_unsave {name}

LWDAQ_tool_unsave deletes a tool's saved configuration array.

LWDAQ_Toolmaker

proc LWDAQ_Toolmaker {}

LWDAQ_Toolmaker makes a new toplevel window for the Toolmaker. You enter a sequence of commands in the text window, and you can execute this sequence, which we call a script, with the Execute button. When you press Execute, your script will disappear from the text window, but you can make it re-appear with the Back button. The Toolmaker keeps a list of the scripts you have executed, and allows you to navigate and edit the list with the Forward, Back, and Clear buttons. You can save the list to a file with Save, and read a previously-saved list with Load. The file will contain all your scripts delimited by XML-style marks at the beginning and end of each script respectively. For each Execute, Toolmaker creates a new toplevel text window. You can print to the lower one (which is intended for results) by referring to it as $t, and using it with a text widget routine like LWDAQ_print, or calling it directly with its TK widget command, $t.

LWDAQ_Toolmaker_back

proc LWDAQ_Toolmaker_back {}

LWDAQ_Toolmaker_back clears the script text window, decrements the script index, and displays the previous script in the Toolmaker comamnd list.

LWDAQ_Toolmaker_delete

proc LWDAQ_Toolmaker_delete {}

LWDAQ_Toolmaker_delete deletes the current entry from the script list.

LWDAQ_Toolmaker_delete_all

proc LWDAQ_Toolmaker_delete_all {}

LWDAQ_Toolmaker_delete_all clears all entries from the script list.

LWDAQ_Toolmaker_execute

proc LWDAQ_Toolmaker_execute {{save 1}}

LWDAQ_Toolmaker_execute extracts the script in the Toolmaker's text window, appends it to the Toolmaker script list, creates a new toplevel text window or selects the existing toplevel execution window, and executes the script at the global level. It prints out results as the script requires, and print errors in red when they occur. The script can refer to the text widget with the global variable "t". Above the text window is a frame, "f", also declared at the global level, which is packed in the top of the window, but empty unless the script creates buttons and such like to fill it.

LWDAQ_Toolmaker_forward

proc LWDAQ_Toolmaker_forward {}

LWDAQ_Toolmaker_forward clears the script window, increments the script index, and displays the next script in the Toolmaker script list. If you have reached the end of the list, it displays a blank screen, ready for a fresh script.

LWDAQ_Toolmaker_load

proc LWDAQ_Toolmaker_load {{file_name ""}}

LWDAQ_Toolmaker_load reads a previously-saved script library or an individual script from a file and appends the script or scripts to the current script list. It returns the file name.

LWDAQ_Toolmaker_repeat

proc LWDAQ_Toolmaker_repeat {}

LWDAQ_Toolmaker_repeat executes the previous script without adding a copy of it to the list of scripts.

LWDAQ_Toolmaker_save

proc LWDAQ_Toolmaker_save {{file_name ""}}

LWDAQ_Toolmaker_save saves the current Toolmaker script list to a file. It returns the file name.

LWDAQ_tools_init

proc LWDAQ_tools_init {}

LWDAQ_tools_init initializes the Tools routines.

LWDAQ_toplevel_text_window

proc LWDAQ_toplevel_text_window {{width 84} {height 30}}

LWDAQ_toplevel_text_window creates a new text window. It returns the name of the toplevel window containing the text widget. You can construct the name of the text widget itself by adding .text to the window name.

LWDAQ_toplevel_window

proc LWDAQ_toplevel_window { {title ""} }

LWDAQ_toplevel_window will make a new top-level window with a unique name, and returns its name.

LWDAQ_transmit_command

proc LWDAQ_transmit_command {sock value}

LWDAQ_transmit_command instructs a driver to transmit LWDAQ command $value to its current target device. The routine instructs the driver through open TCPIP socket $sock. The driver will be busy for a few microseconds thereafter as it transmits the command, but the routine will return almost immediately. Note that if you have lazy_flush set to 1, the messages produced by the routine will remain in $sock's output buffer until you flush the socket, close it, or read from it. The value parameter is a string of characters representing a decimal number.

LWDAQ_transmit_command_binary

proc LWDAQ_transmit_command_binary {sock value}

LWDAQ_transmit_command_binary is the same as LWDAQ_transmit_command except it takes a binary string representation of the command value. Thus the string "0001001001001000" represents command "1248" in hexadecimal notation, or "4680" in decimal.

LWDAQ_transmit_command_hex

proc LWDAQ_transmit_command_hex {sock value}

LWDAQ_transmit_command_hex is the same as LWDAQ_transmit_command except it takes a hexadecimal string representation of the command value. Thus "1248" represents command "4680" in decimal and "FFFF" represents "1111111111111111" as a binary string.

LWDAQ_transmit_Diagnostic

proc LWDAQ_transmit_Diagnostic {sock}

LWDAQ_transmit_Diagnostic transmits each hex word in info(commands) to the target device (info(repeat) + 1) times. We set the device element number before transmitting any commands, because self-contained LWDAQ systems (those of Form C) use the device element to direct the command to different internal components.

LWDAQ_transmit_message

proc LWDAQ_transmit_message {sock id contents}

LWDAQ_transmit_message sends a message through a socket. The routine detects which protocol the socket uses and formats the message accordingly. The message identifier is passed to the procedure in $id and the contents are in $contents. The routine supports the lwdaq and basic message formats. The id parameter is a string of chracters that represent a decimal number. The contents parameter is a block of binary bytes.

LWDAQ_unsave_settings

proc LWDAQ_unsave_settings {}

LWDAQ_unsave_settings deletes any existing core settings file.

LWDAQ_unschedule_task

proc LWDAQ_unschedule_task {name}

LWDAQ_unschedule_task removes the named task from the scheduler's list. If there are no more tasks in the list, this routine stops the scheduler.

LWDAQ_update

proc LWDAQ_update {}

LWDAQ_update passes control to the TclTk event handler for update_ms. During this time, the event handler can perform window updates, respond to mouse clicks, and service TCPIP sockets.

LWDAQ_url_download

proc LWDAQ_url_download {url}

LWDAQ_url_download downloads the source file of a url so we can parse it and extract text fields.

LWDAQ_url_open

proc LWDAQ_url_open {url}

LWDAQ_url_open starts a browser window and directs the browser to open the url and either display or save its contents to disk, as if we cut and pasted the url into the default browser's address field. An html link will be displayed. A zip archive will be saved to disk.

LWDAQ_utils_init

proc LWDAQ_utils_init {}

LWDAQ_utils_init initializes the untils routines.

LWDAQ_view_array

proc LWDAQ_view_array {array_name}

LWDAQ_view_array opens a new window that displays the contents of a global TCL array. It and allows you to change the values of all elements in the array.

LWDAQ_view_text_file

proc LWDAQ_view_text_file {file_name}

LWDAQ_view_text_file reads a text file into a new top-level text window. The routine returns the name of the top-level window. The name of the text widget used to display the file is $w.text, where $w is the top-level window name.

LWDAQ_vwait

proc LWDAQ_vwait {var_name}

LWDAQ_vwait calls vwait, but also keeps a list of the current vwait variable stack, which the System Monitor uses to keep track of LWDAQ vwaits.

LWDAQ_vwait_var_name

proc LWDAQ_vwait_var_name {}

LWDAQ_vwait_var_name will return a unique name for a global vwait variable. All LWDAQ routines that call TCL's vwait routine use a global timeout variable assigned by this routine, so that its partner routine LWDAQ_stop_vwaits can go through all existing timeout variables and set them, which aborts the vwaits.

LWDAQ_wait_for_driver

proc LWDAQ_wait_for_driver {sock {approx 0}}

LWDAQ_wait_for_driver waits until the driver has finished executing all pending commands. If you expect the commands to take more than a few seconds, specify how long you expect them to take with the optional $approx parameter. By specifying the approximate delay, you allow this routine to avoid a TCPIP read timeout.

LWDAQ_wait_ms

proc LWDAQ_wait_ms {time_ms {vwait_var_name ""}}

LWDAQ_wait_ms waits for the specified time. By default, the routine assigns a unique global name of its own. But it allows you to specify the name of the variable that will be used to control the delay. In this way, you can abort the waiting period by setting the variable from a button or some other event command. When the waiting is done, we unset the waiting variable. When the waiting is aborted, we cancel the waiting command so that the waiting variable will not be set later. We return the value to which the vwait variable was set.

LWDAQ_wait_seconds

proc LWDAQ_wait_seconds {t {vwait_var_name ""}}

LWDAQ_wait_seconds waits for the specified time.

LWDAQ_wake

proc LWDAQ_wake {sock}

LWDAQ_wake wakes up a driver's target device through socket $sock.

LWDAQ_wake_Diagnostic

proc LWDAQ_wake_Diagnostic {sock}

LWDAQ_wake_Diagnostic turns on any repeater on the driver socket, selects a multiplexer socket, and wakes up the target device. To make sure the repeater is on, the wake routine transmits a non-zero address from the driver socket before it transmits the target branch address.

LWDAQ_watch

proc LWDAQ_watch {watch_var watch_val command}

LWDAQ_watch waits for a global variable to aquire a particular value, at which point it executes a command. We give the name of the global variable and the awaited value. When the condition is met, the procedure executes the command, otherwise it posts itself to the event queue. The command is a script.

LWDAQ_widget_list

proc LWDAQ_widget_list {w}

LWDAQ_widget_list returns a list of all existing children of the window or widget you pass to the routine. If you pass just ".", then the routine will list all existing widgets and windows. The routine calls itself recursively.

LWDAQ_write_button

proc LWDAQ_write_button {name}

LWDAQ_write_button writes the current image to disk

LWDAQ_write_image_file

proc LWDAQ_write_image_file {image_name outfile_name}

LWDAQ_write_image_file writes an image to disk in the LWDAQ image format. If the file name has tail ".gif" or ".png" (case insensitive), the routine saves the file in GIF or PNG format respectively. If the file name ends with ".ndf", the routine treats the image as a container for one-dimensional data, skipping the first row (row zero) and starting from the first pixel of the second row (pixel zero of row one). Otherwise, the routine saves the image in the DAQ format. In a GIF, PNG and DAQ files, the LWDAQ image header, with dimensions, analysis bounds, and results string, will be embedded in the first line of the image. In an NDF file, this header information is lost. The results string is saved in the meta-data string. When we save to GIF and PNG we use the Tk built-in routines that export photos to GIF and PNG files. We draw the image in a Tk photo using lwdaq_draw. We make sure we draw the pixels one-to-one by looking up the prevailiing display_zoom value and passing its inverse to lwdaq_draw as an additional zoom value. We use the Tk photo's write function to create the GIF or PNG file. Another thing we must do when saving the GIF or PNG files is make sure lwdaq_draw does not draw the analysis bounds on the image, nor anything from the overlay.

LWDAQ_xml_get

proc LWDAQ_xml_get {xml tag}

LWDAQ_xml_get calls LWDAQ_xml_get_list and returns the contents of the first list entry in the result. We use this routine to extract the value of a field in an xml record.

LWDAQ_xml_get_list

proc LWDAQ_xml_get_list {xml tag}

LWDAQ_xml_get_list takes an xml string and extracts the list of records from the database that matches a specified tag you specify. If an xml string contains one thousand entries delimited by ..., the routine returns a TCL list of the contents of all the entries when you pass it the xml string and the tag "donor". You don't pass it the brackets on either side of the tag, even though these brackets always appear in the xml string. Each element in the list the routine returns will be the contents of a single record, with its start and end tags removed. You can now apply this same routine to each element in this list sequentially, to extract fields from each record, and you can apply LWDAQ_xml_get to these fields to look at sub-fields and so on.

LWDAQ_xy_Viewer

proc LWDAQ_xy_Viewer {x y cmd}

LWDAQ_xy_Viewer takes as input an x-y position relative to the top-left corner of the image display widget. By passing one of three commands, it sets the corners of the analysis boundaries. The motion command adjusts the bottom-right corner. The press command sets the top-left corner. The release command sets the image analysis bounds with the rectangle drawn. We bind this routine to the image widget and remove the binding that exists in all other instruments to the image closeup routine.

LWDAQ_zoom_Viewer

proc LWDAQ_zoom_Viewer {}

LWDAQ_zoom_Viewer re-draws the image in the panel with the latest zoom setting.

Library Commands

lwdaq_alt

lwdaq_alt image xycoordinates ?option value?

lwdaq_alt extracts power measurements from data recorded by an Animal Location Tracker (ALT, A3038) so as to measure the location of Subcutaneous Transmitters (SCTs), such as our Subcutaneous Transmitters (SCT), Implantable Inertial Sensors (IIS), or Implantable Stimulator-Transponders (IST). The routine assumes that the global electronics_trace is a valid xy_graph created by lwdaq_receiver, giving a list of x-y values in which x is an integer time and y is an integer index. The message corresponding to time x is the y'th message in the Receiver Instrument image to which we applied the lwdaq_receiver routine. The electronics_trace will be valid provided that the most recent call to the lwdaq electronics library was the lwdaq_receiver with either the "extract" or "reconstruct" instructions.

The routine takes two parameters and has several options. The first parameter is the name of the image that contains the tracker data. The indices in electronics_trace must refer to the data space of this image. An index of n points to the n'th message in the data, with the first message being number zero. Each message starts with four bytes and is followed by one or more payload bytes. The payload bytes contain one or more power measurements.

The second parameter is a list of locations of detector coils, given as a sequence of numbers x, y, z separated by spaces. When calculating the location of a transmitter, lwdaq_alt will center each detector on these coordinates. All coordinates are assumed to be greater than or equal to zero, so that (-1,-1,-1) will be recognised as an invalid location. When we pass "-1 -1 -1" as the coordinate of a coil, lwdaq_alt does not include the coil in its position calculation. We use position "-1 -1 -1" for auxiliary antenna coils in animal location trackers. The A3038C, for example, provides fifteen tracker coils and a sixteenth auxiliary antenna input that may be used for reception of telemetry signals and for measuring background power. We use any position (-1,y,z) for coils we want to ignore. We might have sixteen detector antennas divided into two sets of eight for monitoring the location of animals in two habitats. When we calculate position in the first habitat, we ignore the coils arranged in the second habitat. We set the coordinates of the coils we want to ignore to "-1 y z", where y and z can be anything. In a two-dimensional tracker platform such as the A3038C, the value of the z-coordinate will be shared by all coils. Regardless of the arrangent of antennas, all z-coordinates must be greater than zero. We must make it impossible for the measured position of the transmitter to come out as "0.0 0.0 0.0" because we use this origin position to indicate "no position measurement obtained in this interval". For the A3038C we set the z-coordinage to 2.0, the approximate distance from the center of its detector coils to a transmitter sitting on the platform.

The lwdaq_alt routine supports the following options:

OptionFunction
-payloadPayload length in bytes, default 16.
-scaleNumber of eight-bit counts corresponding to 10 dB power increase, default 30.
-extentRadius for coil inclusion about coil with maximum power.
-percentileFraction of power measurements below chosen value, default 50.
-backgroundString of background power levels to be subtracted from coil powers, default all 0.
-slicesNumber of sub-intervals for which we calculate power and position, default 1.

The output contains x, y, and z in whatever units we used to specify the coil centers, followed by a string of detector power values. If slices > 1, we will have slices lines in our output string, each giving the position and powers values for a fraction of the interval represented by the data image. The purpose of the slices option is to permit us to play through a recording with eight-second intervals and yet obtain tracker measurements with a sample period that is some integer fraction of the interval period. The unit of activity is coil center units per slice interval. If we have break the interval into eight slices and specify coil positions in centimeters, the activity will be centimeters per eighth of a second.

The -background option allows us to specify background power levels for all detector coils, in anticipation of a need to calibrate detectors. By default, these background powers are all zero. If we pass an empty string for the background powers, lwdaq_alt will use zeros. The -extent value sets a maximum distance from the location of the transmitter to a coil used to calculate the transmitter location. The -payload value is the number of bytes added to the core four-byte message in order to accommodate the power values. A fifteen-coil tracker has payload sixteen and returns sixteen power values. The first fifteen are the powers from the coils, in the order defined by the tracker's geometry map. The sixteenth value is either zero or the power we obtain from an auxiliary detector module.

lwdaq_bcam

lwdaq_bcam image ?option value?

lwdaq_bcam finds spots in images. It is used by the BCAM Instrument to analyze BCAM images. The routine clears the image overlay for its own use. By default, lwdaq_bcam returns six numbers for each of the spots it finds. In the example below, we read a sample image and apply BCAM analysis, asking for the location of two spots.

set img [LWDAQ_read_image_file Images/BCAM_tape.gif]
lwdaq_bcam $img -num_spots 2 -threshold "10 #"
2681.66 964.12 2313 72 0.556 62 959.30 883.76 2306 72 0.499 62

The first two numbers for each spot are the x and y position in microns of the spot, or the x position in microns and the anticlockwise rotation in milliradians. Position (0,0) is the top-left corner of the top-left pixel in the image. Rotation zero is vertical. The third value is an integer giving the number of pixels in the spot. The fourth value is an integer giving the intensity of the brightest pixel in the spot. The fifth number is the derivative of spot position with analysis threshold. The sixth number is an integer giving the threshold intensity used to distinguish between pixels that are bright enough to be in a spot and those that are not. This threshold intensity may have been specified directly by an absolute threshold string, or it may have been deduced from the image itself with the use of a threshold symbol.

OptionFunction
-num_spotsThe number of spots the analysis should find.
-thresholdString specifying threshold intensity and spot size.
-colorColor for spot outlining in overlay, default red.
-pixel_size_umTells the analysis the pixel size (assumed square)
-show_timinigIf 1, print timing report to gui text window.
-show_pixelsIf 1, mark pixels above threshold.
-analysis_typeSelects analysis type, default weighted centroid.
-sort_codeSpecifies how the spots are to be sorted in the output string.
-return_thresholdIf 1, return threshold string results only, default 0.
-return_boundsIf 1, return spot bounds only, default 0.
-return_intensityIf 1, return spot intensity only, default 0.
-add_x_umAdd this value in microns to the spot x-position, default 0.
-add_y_umAdd this value in microns to the spot y-position, default 0
-reference_umReference line y-position for line fits, default 0

The routine makes a list of spots in the image. The threshold string, included with the -threshold option, tells lwdaq_bcam how to distinguish background pixels from spot pixels. The threshold string must specify a threshold intensity, or a means of calculating a threshold intensity. All the spot-locating routines called by lwdaq_bcam use the net intensity of pixels, which is the image intensity minus the threshold intensity, with negative values clipped to zero.

The threshold string must begin with an integer, t. After t comes an optional threshold symbol. If there is no threshold symbol, the routine assumes the "*" symbol. The "*" symbol tells the routine to use intensity t as the threshold. The string "20 *" means any pixel with intensity 20 or greater is a spot or part of some larger spot. The "%" symbol means that the threshold is some fraction of the way from the minimum image intensity to the maximum intensity, where the minimum and maximum are obtained from within the image analysis boundaries. The value of t is treated as a percentage. The string "10 %" in an image with minimum intensity 40 and maximum intensity 140 results in a threshold of 50. The "#" symbol is similar to the "%" symbol, except the average intensity takes the place of the minimum. The string "10 #" in an image with average intensity 50 and maximum intensity 140 results in a threshold of 59. The "$" symbol means the threshold is t counts above the average intensity. The string "5 $" in an image with average intensity 50 results in a threshold of 55. The "&" symbol uses the median intensity to obtain the threshold. The string "5 &" in an image with median intensity 62 results in a threshold of 67. The "@" symbol uses the minimum intensity to obtain the threshold. String "20 @" in an image with minimum intensity 42 produces a threshold of 62. In each of these calculations, the BCAM analysis also defines a "background" intensity, which it uses only when we want it to calculate and report to us the total brightness of a spot. The background is the average (# and $), minimum (% and @), median (&), or simply zero (*).

Following the threshold value and threshold symbol there are two further, optional criteria we can use to restrict the routine's choice of spots. The first parameter must be an integer, n, which specifies the number of pixels above threshold in a spot. If n is followed by the symbol ">", spots must contain at least n pixels or else they are rejected. The symbol "<" means spots must contain at most n pixels. If the symbol is omitted, we assume n is a minimum.

The next parameter in the threshold must be a real number, e, which specifies the maximum eccentricity of the spot, which is the maximum ratio of width to height, or height to width. Spots that have greater eccentricity will be rejected by the routine. The second parameter cannot be included without the first, but if you use 0 for the first, the routine ignores the first parameter and moves on to the second.

The lwdaq_bcam routine identifies all distinct sets of contiguous pixels above threshold, eliminates those that do not meet the test criteria, determines the position and total net intensity of each remaining set, sorts them in order of decreasing total net intensity, and eliminates all but the first -num_spots sets. The total net intensity is the sum of the net intensities of all the pixels in the set. By default, the routine returns the position of each spot in microns with respect to the top-left corner of the image. To convert from pixels to microns, the routine uses -pixel_size_um, and assumes the pixels are square.

There are several ways that lwdaq_bcam can analyze an image. We can manipulate the image before analysis, or we can operate on the original image. Regardless of what image the analysis works on, it still drawss the results of analysis in the overlay of the original image so that we will see the results when we display the image. We can find the weighted centroid of the pixels in the spot, fit an ellipse to the perimeter of the spot, or fit a straight line to the pixels in the spot. We specify a combination of manipulation and calculation with the analysis_type parameter, which correspond to the spot_use constants in spot.pas.

ValueManipulationCalculationDescription
1noneweighted centroidCentroid of intensity for point source images
2noneedge of elliptical spotPerimiter fit for retroreflecting targets
3nonevertical stripeWeighted fit to a vertical stripe
4negatevertical shadowWeighted fit to a vertical shadow
5grad_ivertical edgeWeighted fit to edge pixels.
6negateedge of elliptical shadowWeighted fit to edge pixels.
Table: Analysis Types, Image Manipulations and Calculations

With analysis_type=1, which is the default, the position of the spot is the weighted centroid of its net intensity. With analysis_type=2, the routine fits an ellipse to the edge of the spot. The position is the center of the ellipse. With analysis_type=3 the routine fits a straight line to the net intensity of a bright stripe. The analysis returnsthe x-coordinate of the intersection of this straight line with a reference line. We specify the y-coordinate of a horizontal reference line with reference_um. In place of a y-coordinate of the line, the routine returns its anti-clockwise rotation in milliradians. With analysis_type=4, the routine negates the image, turning a dark shadow into a bright stripe, and then applies vertical stripe analysis to the negated image. With analysis_type=5, the routine obtains the absolute horizontal gradient of intensity and applies vertical stripe analyis to the gradient image. With analysis_type=6, the routine negates the image, finds bright spots, and fits an ellipse to their edges. With analysis=7, the routine negates the image, finds the bright spots in the negated image, and calculates their centroids.

With return_threshold=1, the routine does no spot-finding, but instead returns a string of five values obtained by interpreting the threshold string and examining the image. These five values are four integers and one real. The integers are threshold intensity, background intensity, minimum numbser of pixels in a valid spot, maximum number of pixels in a valid spot, and maximum eccentricity of a valid spot. With return_bounds=1 and return_threshold=0, the routine returns as its result string the boundaries around the spots. It chooses the same boundaries it draws in the image overlay. Each spot boundary is given as four integers: left, top, right, and bottom. The left and right integers are column numbers. The top and bottom integers are row numbers. Each spot gets four numbers, and these make up the result string, separated by spaces. With return_intensity=1, return_bounds=0, and return_threshold=0, the routine returns only the total intensity above background of the spot for each spot. Note that this total intensity above background is not the same as the net intensity of the spot, which is the intensity above threshold. The centroid analysis uses the intensity above threshold, not the total intensity above background.

The sort_code has the following meanings, and dictates the order in which the spots are returned in the result string.

spot_decreasing_brightness=1;
spot_increasing_x=2;
spot_increasing_y=3;
spot_decreasing_x=4;
spot_decreasing_y=5;
spot_decreasing_max=6;
spot_decreasing_size=7;
spot_increasing_xy=8;

Thus with spot_decreasing_x as the value for sort_code, the routine sorts the num_spots brightest spots in order of decreasing x position, which means spots on the right of the image will appear first in the result string. With spot_decreasing_brightness, which is the default, the spot with the highest total net intensity comes first. But with spot_decreasing_max, the spot with the highest maximum intensity comes first. With spot_decreasing_size, the spot with the largest number of pixels comes first.

With show_pixels=0, which is the default value, the routine draws red boxes around the spots. These boxes are of the same size as the spots, or a little bigger if the spots are small. If num_spots=1 and the number of pixels in the spot is greater than min_pixels_for_cross, the routine draws a cross centered on the spot instead of a box around it. When show_pxels=1, the routine marks all the pixels in each spot, so you can see the pixels that are above threshold and contiguous.

The color we use to mark the image with the results of analysis is given in the -color option. You specify the color with an integer. Color codes 0 to 15 specity a set of distinct colors, shown here.

lwdaq_bcam_calib

lwdaq_bcam_calib device_calibration apparatus_measurement ?option value?

lwdaq_bcam_calib takes as input an apparatus measurement and a device calibration, and returns a parameter calculation. The routine calls parameter_calculation in the bcam.pas. This routine supports bcam cameras and bcam sources for all types of bcam and both j_plates and k_plates.

lwdaq_config

lwdaq_config ?option value?

lwdaq_config sets global variables that control the operation of the lwdaq libraries. If you specify no options, lwdaq_config returns a string giving you the current values of all the options, except the -eol option. Each option requires a value, which will be assigned to the global variable names in the option. Here are the options and their expected value types. Boolean variables you specify with 0 for false and 1 for true.

OptionTypeFunction
-stdout_availableBooleanstandard output channel is available, default 1
-stdin_availableBooleanstandard input channel is available, default 0
-track_ptrsBooleantrack memory allocation, default 0
-text_nameStringtext window, channel, or file in which to print messages, default stdout
-photo_nameStringphoto in which to draw images and graphs, default none
-zoomRealdisplay scaling for images draw by lwdaq_gui_draw, default 1.0
-display_zoomRealdisplay scaling for all images drawn by library routines, default 1.0
-intensifyStringintensification type for images,
none, mild, strong, or exact, default exact
-wait_msIntegermilliseconds to pause during lwdaq_gui_wait, default -1
-gamma_correctionRealimage drawing gamma correction, default 1.0
-rggb_red_scaleRealimage drawing red brightness, default 1.0
-rggb_blue_scaleRealimage drawing blue brightness, default 1.0
-fsrIntegerfield size for real numbers returned in strings, default 1
-fsdIntegerdecimal places for real numbers returned in strings, default 6
-eolStringend of line characters for text windows and files, default chr(10)
-append_errorsBooleanAppend errors to global error string, default 0
-log_nameStringName of debugging log file, default "lwdaq_log.txt"
-log_errorsBooleanWrite errors to log file, default 0
-show_detailsBooleanWrite execution details to text window, default 0
-exit_commandStringA Tcl command to execute on exit, default ""

The lwdaq library routines can write to Tk text windows through -text_name and -photo_name. The -text_name should specify a Tk text widget (such as .text), stdout, or a file name. The default is stdout. If the -text_name does not begin with a period, indicating a text window, nor is it stdout, we assume it is the name of a file. File names cannot be numbers. If the file name contains a path, that path must exist. The -show_details option is used by some library routines to generate additional exectution details that will be printed to the text window specified by -text_name.

The library routines can draw an image in a Tk photo by calling gui_draw and specifying the name of the image. The photo that will receive the image is the one named by a global variable we set with the -photo_name option. The -photo_name must be an existing Tk photo (such as bcam_photo), and has default value "none", which disables the drawing. By default, gui_draw is set to lwdaq_gui_draw. The -intensify specifies gui_intensification for lwdaq_gui_draw. The -display_zoom option specifies gui_display_zoom, which applies an additional scaling to all images drawn by lwdaq_draw or by gui_draw. The lwdaq_draw routine multiplies its image-specific zoom value by the global gui_display_zoom to obtain a total scaling value. The -display_zoom option is designed to accommodate different computer display resolutions, which sometimes result in lwdaq images being too large or too small. The gamma correction sets the gray scale image display gamma correction used by lwdaq_draw and lwdaq_rggb_draw. By default it is 1.0, which gives us a linear relationship between the image pixel intensity and the display pixel intensity. The rggb_red_scale and rggb_blue_scale parameters determine how we increase the brightness of the red and blue component of the display pixel with respect to the green component. By default, these are also 1.0.

During execution, analysis routines can pause to allow us to view intermediate drarwing results by means of the -wait_ms option. If we set -wait_ms to 1000, the analysis routine will pause for one second. If we set -wait_ms to -1, Tk will open a window with a Continue button in it, which we click before the analysis proceeds.

Many routines return real numbers in strings. These real numbers will have a fixed number of decimal places equal to the global Pascal variable fsd and a total field size equal to the global Pascal variable fsr.

The global error_string variable is used by all the command routines in lwdaq.pas. Each command routine resets error_string and checks it when it's finished. If error_string is not empty, the routine will return an error condition and error_string will be its result. The append_errors option tells the analysis library to append new errors to error_string instead of over-writing previous errors with the new error. By default, append_errors is false. When we set log_errors to 1, each error reported by the report_error routine will, in addition, be written to a log file with the global debug_log procedure.

The -exit_command option allows us to specify a Tcl command that will be executed during an orderly exit from the lwdaq process. This command will be executed if the user presses the Quit button or enters an exit command in some other way, but not if the user closes the main window with a window-destroy button. Default exit command is empty.

lwdaq_data_manipulate

lwdaq_data_manipulate image_name manipulation ?parameters?

lwdaq_data_manipulate operates upon the data in an image, and we intend it for use with instruments that store one-dimensional arrays of data in an image's intensity array. Our convention, when using the intensity array in this way, is to start storing data in the first column of the second row. This leaves the first row free for header information when we store the image to disk. We refer to the block of memory starting with the first byte of the second row, and ending with the last byte of the last row, as the data space. We specify bytes in the data space with their byte address, which is zero at the first byte in the data space. The routine returns a byte array in the case of the read manipulation, or an empty string otherwise. In the event of an error, it returns an error description. The write, shift, and clear manipulations affect the data in the image.

ManipulationFunction
writeWrites a block of data into the data space.
readReads a block of data from the data space.
shiftShifts data towards start of data space.
clearClears the data.
noneNo action.

The write function requires two parameters: the data you wish to write to the data space and the byte address at which you want the first byte of your data to be written. The following command writes the contents of data to the data space of the image named image_name starting at the first byte in the data space (which is the first pixel in the second row).

lwdaq_data_manipulate image_name write 0 $data

The read function requires two parameters: the number of bytes you wish to read from the data space and the byte address at which you want to start reading. The following command reads 10000 bytes starting at byte address 100, and returns them as a byte array. If the image has 100 pixels per row, the first byte the routine reads will be the first pixel in the third row of the image.

lwdaq_data_manipulate image_name read 100 10000

The following commands read 200 bytes from the image, starting with the 50'th byte, and transforms them into a list of signed integers, on the assumption that the 200 bytes represent 100 consecutive, two-byte signed binary values with the most significant byte first (big-endian byte ordering).

lwdaq_data_manipulate image_name read 50 200

The shift function requires one parameter: the number of bytes to the left by which you want the data to be shifted. Shifting to the left is in the direction of the start of the data space. If you specify a negative shift, the routine shifts the data to the right, in the direction of the end of the data space.

The clear function takes no parameters. It clears all the byte in the data space to zero.

lwdaq_diagnostic

lwdaq_diagnostic image ?option value?

lwdaq_diagnostic analyzes sixteen-bit adc samples from the driver supplies. It assumes that five numbers specifying the relay software version, the driver assembly number, the driver hardware version, the controller firmware version, and the data transfer speed are all saved in the input image's results string. The routine leaves these numbers in the results string after it is done.

lwdaq_dosimeter

lwdaq_dosimeter image ?option value?

lwdaq_dosimeter finds hits in images. It is called by the Dosimeter Instrument. The routine clears the image overlay for its own use.

OptionFunction
-num_hitsThe number of hits the analysis should find, default 0.
-thresholdString specifying threshold intensity and hit size limits.
-colorColor for hit outlining in overlay, default green.
-show_timinigIf 1, print timing report to gui text window, default 0.
-show_pixelsIf 1, mark pixels above threshold, default 0.
-subtract_gradientIf 1, subtract the image gradient before finding hits, default 0.
-include_ijIf 1, include column and row of hit centers, default 0.

The lwdaq_dosimeter routine measures the vertical slope of intensity in the image, which is a measure of the sensor dark current, and then finds all the bright pixels in the image, which we call hits, as directed by a threshold string. The -threshold string tells lwdaq_dosimeter how to distinguish background pixels from bright pixels. A bright pixel is one with intensity above the threshold intensity. The brightness of a bright pixel is its intensity minus the background intensity. The threshold string uses the same syntax as the lwdaq_bcam routine. It allows us to define the background, threshold, limits on the number of pixels a hit may contain, and a limit for its eccentricity.

The lwdaq_dosimeter routine identifies all sets of contiguous pixels above threshold in the analysis bounds. It eliminates those that have too few or too many pixels, and those that are too eccentric. It adds up the total intensity above backround of the accepted hits, and the total number of pixels in the accepted hits. Now the routine composes its output string. First comes the vertical slope of intensity, which we call the intensity-slope, in units of ADC counts per row, or cnt/row. Next comes the total intensity of all accepted hits divided by the total number of pixels in the analysis bounds, which we call the charge density, in units of counts per pixel, or cnt/px. The next value is the standard deviation of intensity in the analysis bounds, in counts. The fourth number is the threshold intensity used to isolate bright pixels, also in counts. The fifth number is the total number of bright pixels in all accepted hits, also in counts. Following these five numbers is an optional list of hits. If num_hits ≥ 0, it spectifies the number of hits to be listed. If num_hits < 0, all valid hits will be listed. By default, each hit is listed by its brightness above background. Non-existent hits are indicated with brightness −1. If include_ij is set, the brightness of each hit is followed by the image column and row of the pixel containing its intensity centroid.

With subgract_gradient=0, the dosimeter analysis operates entirely upon the original image. But with subgract_gradient=1, the analysis obtains the intensity-slope with the original image, but then subtracts the average intensity gradient from the analysis bounds and continues with bright-pixel collection in the gradient-subtracted image.

The color we use to outline bright pixels is given in the -color option. You specify the color with an integer. Color codes 0 to 15 specity a set of distinct colors, shown here.

See the Dosimeter Instrument Manual for more information about the option values.

lwdaq_draw

lwdaq_draw image photo ?option value?

lwdaq_draw transfers the contents of a lwdaq image into a Tk photo. We pass the lwdaq image name followed by the Tk photo name, and then our options in the form ?option value?. When the routine draws the image, it over-writes the first few pixels in the first image row with a header block containing the image dimensions, its analysis bounds, and its results string.

The -intensify option can take four values: mild, strong, exact, and none. Mild intensification displays anything darker than four standard deviations below the mean intensity as black, and anything brighter than four standard deviations above the mean intensity as white. In between black and white the display is linear with pixel brightness. Strong intensification does the same thing, but for a range of two standard deviations from the mean. Exact displays the darkest spot in the image as black and the brightest as white. In all three cases, we calculate the mean, standard deviation, minimum, and maximum intensity of the image within the analysis bounds, not across the entire image.

The -zoom option scales the image as we draw it in the Tk photo. This scaling is in addition to the scaling called for by the global gui_display_zoom parameter, which we set with lwdaq_config. The Tk photo will expand or contract to match the size of the zoomed image. The product of the zoom value and the global gui_display_zoom can take any value between 0.1 and 10. But the effective value of the scaling factor is dicated by the requirements of sub-sampling. If the scaling factor is greater than 1, we round it to the nearest integer, e, and draw each image pixel on the screen as a block of e×e pixels. If -zoom is less than 1, we round its inverse to the nearest integer, c. We draw only one pixel out of every c pixels in the Tk photo. If the scaling factor is 0.3, we draw every third pixel. If 0.4, we draw every third pixel if your computer rounds 1/0.4 to 3, or every second pixel if your computer rounds 1/0.4 to 2. With scaling factor 0.0, we draw every tenth pixel. Prior to drawing, the image overlay may contain lines that show the results of analysis or mark features in the image. These lines are likely to be only one pixel wide. If we are sub-sampling the image, all such markings will be partially erased. When drawing with a scaling factor less than 0.5, lwdaq_draw spreads out each pixel in the overlay so that, when subsampled, the integrity of the overlay markings is preserved. After the draw, the overlay markings remain spread, which means that subsequent drawing of the same image with a larger scaling factor will appear with thicker overlay lines.

With -clear set to 1, lwdaq_draw clears the overlay in the lwdaq image before drawing in the Tk photo. The overlay may contain a graph or oscilloscope display, or analysis indicator lines. If you don't want these to be displayed, set -clear to 1. Whatever was in the overlay will be erased from the overlay before drawing.

By default, -show_bounds is 1, and the routine draws a blue rectangle to show the the image analysis boundaries, which are used by image analysis routines like lwdaq_rasnik and lwdaq_bcam. But with -show_bounds set to 0, this blue rectangle is not drawn. If you want to be sure that you don't have a blue rectangle drawn over your gray-scale image, you should also specify -clear 1, so that lwdaq_draw will clear the image overlay of any pre-existing blue rectangles.

lwdaq_draw_raw

lwdaq_image_draw image photo ?option value?

lwdaq_draw_raw renders a block of raw image data in a Tk photo. The -pix_fmt option follows the naming conventions of ffmpeg. We currently recognise formats "gray" for eight-bit gray-scale, and "rgb24" for three-byte color. The -width and -height options specify the dimensions of the image. The -zoom option scales the image as we draw it in the Tk photo. See lwdaq_draw for description of these last three options.

lwdaq_error_string

lwdaq_error_string ?option value?

lwdaq_error_string returns the global error string into which our library routines record potentially fatal errors they encounter during execution. If we set the -append_errors flag with lwdaq_config, the string will contain all errors encountered, separated by line breaks. Otherwise, the string will contain only the most recent error. Each error line begins with the error prefix string, which is defined in utils.pas. If we pass the -value option, we provide a string that is to take the place of the current error string. If this string parameter is empty, the error string is cleared.

lwdaq_fft

lwdaq_fft data ?option value?

lwdaq_fft applies a fast fourier tranfsorm to a waveform and returns the complete discrete fourier transform (DFT). In general, the DFT transforms a set of N complex-valued samples and returns a set of N complex-valued frequency components. We assume the samples, are uniformly-spaced with respect to some one-dimensional quantity such as time or distance. The sample period is the separation of the samples in this one-dimensional quantity. We denote the sample period with T and the one-dimensional quantity we denote as t. We denote the sample at t = nT with xn, where n is an integer such that 0≤nN−1. We denote the transform components Xk, where k is an integer such that 0≤kN−1. Each transform component represents a complex sinusoidal function in t. The k'th sinusoid, Sk, has frequency k/NT. Its magnitude and phase are given by Xk.

Sk = Xk ekt/NT

In the text-book definition of the discrete fourier transform, Xk is N times larger, and we must divide by N to obtain the sinusoidal amplitude. But we pre-scaled our components by 1/N so we return the sinusoidal comonents directly. If we express Xk as a magnitude, Ak, and a phase Φk, we get the following expression for the sinusoid.

Sk = Ak ekt/NTk

Sk = Akcos(2πkt/NTk) +iAksin(2πkt/NTk)

When our inputs xn are real-valued, we find that the the k'th component of the transform is the complex conjugate of component Nk. A feature of all discrete transform is Xk = Xk−N. Thus XN−k = X−k, the component with frequency −k/NT. We observe that cos(v) = cos(−v) and sin(v) = −sin(−v), so the −k'th component is the complex conjugate of the k'th component. This means that the Nk'th component is equal to the k'th component.

Sk + S−k = 2Akcos(2πkt/NTk)

The 0'th and N/2'th components we cannot sum together using the above trick. But these components always have phase 0 or π when the inputs are real-valued. We can represent them with two real-valued numbers, where the magnitude of the number is the magnitude of the component and the sign is the phase 0 or π.

The lwdaq_fft routine will accept N complex-valued samples in the form xn = u+iv and return N complex-valued components in the form Xk = U+iV. We specify complex-valued input with option "-complex 1". The default option, however, is "-complex 0", which specifies real-valued input and returns N/2 real-valued components. We obtain the N/2 components by adding each Xk to its complex conjugate XN−k. We express these real-valued frequency components with two numbers each, 2Ak and Φk. These represent a cosine with amplitude 2Ak, angular frequency 2πk/NT (rad/s), and phase shift Φk (rad).

The 0'th component of the real-valued transform is an exception. It contains two numbers, but neither of them is a phase. One is the magnitude of the 0'th component, which is the DC component, and the N/2'th component, which is the Nyquist-frequency component.

The lwdaq_fft routine insists upon N being a power of two so that the fast fourier transform algorithm can divide the problem in half repeatedly until it arrives at transforms of length 1. For the fast fourier transform algorithm itself, see the fft routine in utils.pas. For its real-valued wrapper see fft_real.

lwdaq_config -fsr 1 -fsd 2
lwdaq_fft "1 1 1 1 1 1 1 0"
0.88 0.13 0.25 -2.36 0.25 -1.57 0.25 -0.79

In the example, we supply the routine with eight real-valued samples and obtain a transform of eight numbers. The first number tells us the magnitude and phase of the 0-frequency component. This number is equal to the average value of the samples, and is often called the "DC-component". The second number gives us the Nyquist-frequency component, which is the component with period two sample intervals. Here, the Nyquist-frequency component is the 4-frequency component with period N/4 (N=8). We multiply a cosine by this mangnitude and we obtain the 4-frequency component of the transform. Its phase can be either +π or −π, and so is represented by the signe of the component magnitude.

The remaining components in the tranform, 1 through 3, are each represented by two numbers, a magnitude, a, and a phase Φ. We obtain the value of component k at time t with acos(2πkt/NT+Φ). If we use sample number, n, instead of time, the component is acos(2πkn/N+Φ).

lwdaq_fft "1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0" -complex 1
0.88 0.00 -0.09 -0.09 -0.00 -0.13 0.09 -0.09 0.13 0.00 0.09 0.09 0.00 0.13 -0.09 0.09

We submit the same data to the complex version of the transform by accompanying each sample with a zero phase, so as to indicate a real value with a complex number. The result is a transform that is equivalent to our first, abbreviated transform. You can see the N/4 component as "0.13 0.00" and the 0 component as "0.88 00". There are two N/1 frequency components "-0.09 -0.09" and "-0.09 0.09". Their magnitude is 0.127 and their phases are −3π/4 and −π/4. When we add these magnitudes together we obtain the N/1 component of the real-valued transform, which is 0.25 as shown above. The phase of the N/1 component is −3π/4 = −2.36 radians, which is also what we see in the real-valued transform above.

Here is another example. In this case, the N/4 component is zero, as is the 0 component.

lwdaq_fft "1 1 1 1 -1 -1 -1 -1"
0.00 0.00 1.31 -1.18 0.00 0.00 0.54 -0.39 
lwdaq_fft "1 0 1 0 1 0 1 0 -1 0 -1 0 -1 0 -1 0" -complex 1
0.00 0.00 0.25 -0.60 0.00 0.00 0.25 -0.10 0.00 0.00 0.25 0.10 0.00 0.00 0.25 0.60 

If the samples were taken over 1 s, the eight components represent frequencies 0, 1, 2, and 3 Hz. So we see the square wave of frequency 1 Hz has harmonics at 1 Hz and 3 Hz. The fourier series expansion of a square wave has harmonics of amplitude 4/nπ for the n'th harmonic. The first harmonic in the fourier series would have amplitude 1.27. Our 1-Hz component has amplitude 1.31. The discrete fourier transform is an exact representation of the original data, but it does not provide all the harmonics of the fourier series. Therefore, the existing harmonics are not exactly of the same amplitude as those in the fourier series.

The phases of the components in our example are also correct. The first harmonic is offset by −1.18 radians, which means it is a cosine delayed by 1.18/2π = 0.188 of a period, or 1.5 samples. We see that a cosine delayed by 1.5 samles will reach its maximum between samples 1 and 2, which matches our input data. In the example below, we change the phase of the input by π and we see the phase of the fundamental harmonic changes by π.

lwdaq_fft "1 1 1 1 0 0 0 0"
0.50 0.00 0.65 -1.18 0.00 0.00 0.27 -0.39 
lwdaq_fft "0 0 0 0 1 1 1 1"
0.50 0.00 0.65 1.96 0.00 0.00 0.27 2.75 

We can use lwdaq_fft to perform the inverse transform, but we must invoke the "-inverse 1" option or else the inverse does not come out quite right.

set dft [lwdaq_fft "1 0 1 0 1 0 1 0 -1 0 -1 0 -1 0 -1 0" -complex 1]
0.00 0.00 0.25 -0.60 0.00 0.00 0.25 -0.10 0.00 0.00 0.25 0.10 0.00 0.00 0.25 0.60 
lwdaq_fft $dft -complex 1
0.12 0.00 -0.12 0.00 -0.12 0.00 -0.12 0.00 -0.12 0.00 0.12 -0.00 0.12 -0.00 0.12 -0.00 
lwdaq_fft $dft -complex 1 -inverse 1
1.00 0.00 0.99 -0.00 1.00 -0.00 0.99 -0.00 -1.00 0.00 -0.99 0.00 -1.00 0.00 -0.99 0.00 

The "-inverse 1" option reverses the order of the input components, which is a trick for getting the forward transform to act like an inverse transform, and then multiplies the resulting sample-values by N to account for the fact that our lwdaq_fft routine scales its frequency components by 1/N to make them correspond to sinusoidal amplitudes. The reversal of the input components and the scaling takes place in fft_inverse of utils.pas.

We can also invert our compact magnitude-phase transforms, which we derive from real-valued inputs with the "-complex 0" option (the default).

set dft [lwdaq_fft "1 1 1 1 -1 -1 -1 -1"]
0.00 0.00 1.31 -1.18 0.00 0.00 0.54 -0.39 
lwdaq_fft $dft -inverse 1
1.00 1.00 1.01 1.00 -1.00 -1.00 -1.01 -1.00 

Note the rounding errors we see because we are using only two decimal places in our examples. For the real-valued inverse transform code, see fft_real_inverse in utils.pas.

The fft, like all discrete fourier transforms, assumes that the N samples are the entire period of a repeating waveform. The N components of the transform, when inverted, give us an exact reproduction of the original N samples. As you are looking at the signal represented by the N samples, be aware that any difference between the 0'th sample and the (N-1)'th sample amounts to a discontinuity at the end of the repeating waveform. A ramp from 0 to 1000 during the N samples gives rise to a sudden drop of 1000. This sudden drop appears as power in all frequency components.

One way to remove end steps is to apply a window function to the data before you take the fourier transform. We provide a linear window function with the "-window w" option, where we apply the window function to the first w samples and the final w samples. This window function is the same one we provide separately in our window function routine. We recommend you calculate w as a fraction of N when you call lwdaq_fft. We suggest starting w = N/10. We implement the window function only for real-valued samples passed to the forward transform. If you try to apply the window function during the inverse transform or when passing complex samples to the forward transform, lwdaq_fft returns an error. That's not to say that there is no point in applying a window function in these other circumstances, but our linear window function does not have any obvious utility or meaning when so applied.

Some data contains occasional error samples, called spikes or glitches. At some point in our data analysis, we must eliminate these glitches. The lwdaq_fft "-glitch g" option allows you to specify a threshold for glitch filtering. The lwdaq_fft routine calls the one-dimensional glitch_filter from utils.pas. We provide this routine at the command line with the glitch_filter library command. The "-glitch" option is compatible only with real-valued data passed to the forward transform. A threshold value of 0 disables the filter.

lwdaq_filter

lwdaq_filter data a_list b_list ?option value?

lwdaq_filter applies a recursive filter to a sampled signal. The samples are passed to lwdaq_filter as a string of space-delimited real numbers. By default, lwdaq_filter assumes every number in the string is a sample. With the -tv_format option set to 1, lwdaq_filter assumes every other number in the string is a uniformly-spaced sample, in the form "t v ", where "t" is time and "v" is the sample. In this case, lwdaq_filter reads the v-values only.

The routine returns its answer as a string of space-delimited real numbers. By default, lwdaq_filter returns a signal with as many samples as it received, separated by spaces, and formatted withe the global fsr (field size real) and fsd (field size decimal) values. With -tv_format set to 1, lwdaq_filter copies the t-values from the input string, so as to create an output string with the same t-values, but processed v-values.

OptionFunction
-tv_formatif 0, data points "v", otherwise "t v", default 0
-ave_startif 1, over-write first sample with average, default 0

We define the digital signal processing we with lwdaq_filter to perform by means of two strings. The first string gives the coefficients a[0]..a[n] by which the input values x[k]..x[k-n] are multiplied before adding to y[k]. The second string gives the coefficients b[1]..b[n] by which the previous outputs y[k-1]..y[k-n] are multiplied before adding to y[k].

lwdaq_flowmeter

lwdaq_flowmeter image ?option value?

lwdaq_flowmeter analyzes sixteen-bit adc values by calling lwdaq_A2053_flowmeter. It assumes that two numbers specifying the sample period and the number of channels sampled are saved in the input image's results string. The routine leaves these numbers in the results string after it is done.

lwdaq_gauge

lwdaq_gauge image ?option value?

lwdaq_gauge analyzes sixteen-bit adc values by calling lwdaq_A2053_gauge. The routine assumes that two numbers specifying the sample period and the number of channels sampled are saved in the input image's results string. The routine leaves these numbers in the results string after it is done. For each gauge channel in the image, the routine returns a result, according to the result specifiers. With -ave 1, the result for each channel includes the average gauge value. With -stdev 1, the result includes the standard deviation of the gauge value. With both set to zero, the result is an empty string. The default values for ave and stdev are 1 and 0 respectively.

lwdaq_graph

lwdaq_graph data image ?option value?

lwdaq_graph takes a string of numbers and plots them in the image overlay, displaying them by means of lines between the consecutive points. The string of numbers may contain x-y value pairs, or x values only or y values only. The default is x-y values. With y_only = 1 it assumes y values only and assigns x-value 0 to the first y-value, 1 to the next, and so on. With x_only = 1 it assumes x values only and assigns y-value 0 to the first x-value, −1 to the next, and so on. The negative-going y-values are consistent with the negative-going vertical image coordinates, so that x_only is useful for plotting image properties on top of an image, such as vertical intensity profile. Thus the following code plots the vertical and horizontal intensity profiles in an image overlay

set profile [lwdaq_image_profile imagname -row 1]
lwdaq_graph $profile imagname -y_only 1 -color 3
set profile [lwdaq_image_profile imagname -row 0]
lwdaq_graph $profile imagname -x_only 1 -color 4

The graph will fill the analysis boundaries of the image unless you set entire = 1, in which case the graph will fill the entire image. The routine returns the number of points it plotted.

You can specify the values of x and y that correspond to the edges of the plotting area with x_min, x_max, y_min, and y_max. By default, however, the routine will stretch of compress the plot to fit exactly in the available space.

OptionFunction
-x_minx at left edge, if 0 with x_max = 0, use minimum value of x, default 0
-x_maxx at right edge, if 0 with x_min = 0, use maximum value of x, default 0
-y_miny at bottom edge, if 0 with y_max = 0, use minimum value of y, default 0
-y_maxy at top edge, if 0 with y_min = 0, use maximum value of y, default 0
-ac_couple1 add average y-value to y_min and y_max, default 0
-glitch>0, apply glitch filter before plotting, default 0 disabled.
-colorinteger code for the color, default 0
-clear1, clear image overlay before plotting, default 0
-fill1, fill image overlay before plotting, default 0
-widthwidth of plot line, default 1
-x_div> 0, plot vertical divisions spaced by this amount, default 0 disabled
-y_div> 0, plot horizontal divisions spaced by this amount, default 0 disabled
-y_only1, data is y-values only, default 0.
-x_only1, data is x-values only, default 0.
-entire1 use entire image for plot, 0 use analysis bounds, default 0.
-in_image1 draw as a shade of gray in the image rather than overlay, default 0.

By default, the graph will be drawn in the overlay, so it can use colors and be accompanied by grid lines that do not interfere with the underlying image data. The overlay can be transparent or white, depending upon whether we have cleared or filled the overlay respectively before calling lwdaq_graph. But if in_image is 1, the color will be treated as a shade of gray and the graph will be drawn in the image itself. By this means, we can create images for two-dimensional analysis out of graphs. When in_image is set, the x_div and y_div options are ignored.

The color codes for a graph in the overlay give 255 unique colors. You can try them out to see which ones you like. The colors 0 to 15 specify a set of distinct colors, as shown here. The remaining colors are eight-bit RGB codes. If you don't specify a color, the plot will be red. The line will be one pixel wide unless we specify a larger width with the -width option, which takes an integert value one or greater.

Some data contains occasional error samples, which we call glitches. The lwdaq_graph "-glitch g" option allows you to specify a threshold for glitch filtering. The lwdaq_graph routine calls the glitch_filter_y from utils.pas to eliminate glitches from the sequence of y-coordinates. We provide the same glitch filter at the command line with the glitch_filter_y.

lwdaq_image_characteristics

lwdaq_image_characteristics image

lwdaq_image_characteristics returns a string of numbers, each of which is some characteristic of the image. We list the characteristics in the table below. The first row of the table gives the first number in the return string. The last row gives the last number.

IndexCharacteristicDescription
0leftthe left column of the analysis bounds
1topthe top row of the analysis bounds
2rightthe right column of the analysis bounds
3bottomthe bottom row of the analysis bounds
4avethe average intensity in the analysis bounds
5stdevthe standard deviation of intensity in the analysis bounds
6maxthe maximum intensity in the analysis bounds
7minthe minimum intensity in the analysis bounds
8heightthe number of rows in the image
9widththe number of colums in the image

The lwdaq_image_characteristics routine does not use the global fsr and fsd parameters to format its output. Instead, it always provides one and only one decimal place for its real-valued characteristics.

set img [LWDAQ_read_image_file Images/Rasnik_skewed.gif]
lwdaq_image_characteristics $img
24 15 680 504 148.5 56.4 255.0 63.0 520 700

In the example above, we read in a sample image and obtain its characteristics. The analysis boundaries are set at column 24 on the left, row 15 on the top, column 680 on the right, and row 504 on the bottom. The average intensity in the image is 148.5. The standard deviation of intensity is 56.4. The maximum intensity is 255.0, which is the maximum value possible with eight-bit gray-scale images. The minimum intensity is 63.0. The number of rows in the image is 520 and the number of columns is 700.

lwdaq_image_contents

lwdaq_image_contents image

lwdaq_image_contents returns a byte array containing the intensity array from the named image. In the first line of the image the routine records the image dimensions, analysis boundry, and results string. The image dimensions and boundaries are given as two-bytes integers, and we use big-endian byte ordering, so the high-order byte is first. The rest of the image data is returned exactly as it is in the image. If the image consists of single-byte pixels, these are returned with no modification or padding. Likewise, if the image consists of two-byte words, or four-byte messages, these are returned as a block of bytes with no modification. If you specify -truncate 1, the routine removes all trailing zero-bytes from the data. When we create a new image to accomodate the same data later, we clear the image intensity array before we copy in the new data, so the image is re-constructed faithfully. This truncation is effective at reducing the size of data files from instruments that don't fill the intensity array with real data, but instead use the intensity array as a place to store one-dimensional data, and use the overlay as a white-board upon which to render the data (like the Voltmeter). If you specify -data_only 1, the routine chops off the leading row of data, leaving only the data from the first pixel of the first row onwards, which is the block of data operated upon by our lwdaq_data_manipulate routines. If you specify -record_size larger than 1, the routine makes sure that the size of the block it returns is divisible by the record size.

lwdaq_image_create

lwdaq_image_create option value ?option value?

lwdaq_image_create creates a new image and returns a unique name for the image, by which the interpreter can identify the image to other lwdaq routines.

OptionFunction
-nameSpecify the name for the image.
-resultsSet the image results string.
-widthThe width of the image in pixels.
-heightThe height of the image in pixels
-dataPixel intensity values as a binary array of bytes.
-leftLeft column of analysis bounds.
-rightRight column of analysis bounds.
-topTopm row of analysis bounds.
-bottomBottom row of analysis bounds.
-try_headerTry image data for a lwdaq-format header, default 1.

The above table lists the options accepted by lwdaq_image_create, and their functions. If you use the -name option and provide the name of a pre-existing image in the lwdaq image list, lwdaq_image_create deletes the pre-existing image. If you specify "-data $value", the routine copies $value into the image's intensity array, starting at the first pixel of the first row. When you combine "-data $value" with "-try_header 1", the routine looks at the first bytes in $value to see if it contains a valid image header, specifying image width and height, as well as analysis bounds and a results string. When the routine looks for the header, it assumes that the bytes in the header specify two-byte integers in big-endian order.

If you have -try_header 0, or if the routine's effort to find a header fails, lwdaq_image_create will look at the values you specify for the analysis bounds with the -left, -top, -right, and -bottom options. A value of −1 directs the routine to place the boundary at the edge of the image. The default values for these options are all −1.

lwdaq_image_destroy

lwdaq_image_destroy image

lwdaq_image_destroy disposes of an image. You can specify multiple images, or image name patterns with * and ? wild cards. You can enter multiple image names on the command line, too.

lwdaq_image_exists

lwdaq_image_exists image ?option value?

lwdaq_image_exists returns a list of images in the lwdaq image list that match the image_name pattern we pass to the routine. If we pass "*", it will return a list of all existing images. If there are no matching images, lwdaq_image_exists returns an empty string.

lwdaq_image_histogram

lwdaq_image_histogram image

lwdaq_image_histogram returns a histogram of image intensity within the analysis bounds of an image. The histogram takes the form of an x-y graph in a space-delimited string, with the x-coordinate representing intensity, and the y-coordinate representing frequency. Suppose we apply the histogram routine to a 20×20 image and we assume that the pixel intensities range from 0 to 3. The string "0 100 1 210 2 40 3 50" confirms that there are 400 pixels in the image, 100 with intensity 0, 210 with intensity 1, and so on.

lwdaq_image_manipulate

lwdaq_image_manipulate image_name manipulation ?option value?

lwdaq_image_manipulate returns the name of a new image derived from one or more images passed to lwdaq_image_manipulate. If we set the -replace option to 1, the routine replaces the original image with the new image. The command takes the name of an image in the LWDAQ image list, and the name of a manipulation to be performed upon this image. The currently-supported manipulations are as follows.

ManipulationFunction
noneNo manipulation of pixels, the new image is the old image.
accumulateAdd second image to first, subtract average intensity of second..
bounds_subtractSubtract a second image from the first within the analysis bounds.
combineReplaces a portion of the image.
copyCopy the image into a new image.
cropCrop the image to its analysis boundaries.
enlarge_nEnlarge the image by an integer factor n, where values 2, 3, and 4 are supported.
grad_iMagnitude of the horizontal intensity derivative.
grad_i_sHorizontal intensity derivative, signed.
grad_jMagnitude of the vertical intensity derivative.
grad_j_sVertical intensity derivative, signed.
gradMagnitude of the intensity gradient.
invertTurn image upside-down by reversing order of pixels. Top-left becomes bottom-right.
negateNegate the image. Each pixel will have value max_intensity − original_intensity.
rasnikCreate an artificial rasnik pattern in the image.
reverse_rowsReverse the order of the rows. The top row becomes the bottom row.
rows_to_columnsTop row becomes left column, left column becomes top row.
rotateRotate the image about a point by an angle in radians.
shrink_nShrink the image by an integer factor n, where values 2, 3, and 4 are supported.
soecSwap odd and even columns.
soerSwap odd and even rows.
smoothSmooth with 3×3 box filter and add contrast.
subtractSubtract a second image from the first image.
subtract_rowSubtract the row average intensity from all pixels in each row.
subtract_gradientSubtract the average gradient intensity from all pixels.
transfer_overlayTransfer the overlay of a second image into the overlay of the first image.
Table: Manipulation Codes and their Functions. All codes create a new image, except for none. With -replace 1 the old image will be replaced by the new image. With -replace 0, the new image will be distinct, with a distinct name.

The none manipulation does nothing. It does not return a new image. Instead, the none manipulation allows us to manipulate an existing image's analysis boundaries, result string, and overlay pixels.

The accumulate option allows us to combine the contrast of two images. It adds the intensity of the two images together, subtracts the average intensity of each image, and adds the mid-intensity value, which is 128 in eight-bit images. If we have ten dim x-ray images of the same device, we can add them together with the accumulate instruction so as to obtain an image with better contrast.

The bounds_subtract manipulation is like subtract, but applies the subtraction only within the analysis bounds of the first image. Elsewhere, the difference image is equal to the first image.

The copy manipulation makes a copy of an image. By default, the name of the copy will be the name of the original, which is inconvenient. So we should use the -name option with copy to specify a name for the copy. As always, when we specify a name, all existing images with that name will be deleted to make way for the new image, thus assuring us that the new image is the only one with its name. With the -replace option we disturb the behavior of the copy manipulationg by deleting the original image and replacing it with the copy.

The invert, reverse_rows, and rows_to_columns operations can be combined to obtain arbitrary square rotations of an image, as well as mirroring. If we want to rotate an image by 90° clockwise, we use reverse_rows followed by rows_to_columns. If we want to make the top-left corner the bottom-right corner while keeping the bottom-left corner in place, which is a rotation and a reflection, we use invert and then rows_to_columns.

The combine manipulation allows you to write over the data in an image, starting with the offset'th pixel. You specify offset after the data. The manipulation copies the entire contents of an m-byte binary block into the image, starting at pixel offset, and ending at pixel offset+m-1. If the copy goes past the end of the image array, the manipulation aborts without doing anything, and returns an error.

The crop manipulation extracts the pixels inside the analysis boundaries of the original image, and creates a new image containing only these pixels. The dimensions of the new image will be those of the original analysis boundaries, but with one extra row at the top to accommodate an image header when we save to disk. The new analysis boundaries will include the entire image except for row zero.

The grad manipulations either return an absolute intensity gradient or a signed intensity gradient. We calculate the horizontal gradient at pixel (i,j) by subtracting the intensity of pixel (i-1,j) from that of pixel (i+1,j). The vertical gradient is (i,j+1) minus (i,j-1). When we return the magnitude of the gradient, the intensity of the gradient image is simply the absolute value of the gradient. When we return the signed gradient, we offset the gradient image intensity by mid_intensity, which is 128 for eight-bit gray scale images. Thus an intensity of 128 means zero gradient, and an intensity of 138 means +10. When the gradient exceeds 127 or -128, we clip its value to 255 and 0 respectively. For more details, see the image_filter and subsequent routine in image_manip.pas.

The rasnik manipulation draws a rasnik pattern in the image. We specify the rasnik pattern with a string of seven numbers: origin.x, origin.y, pattern_x_width, pattern_y_width, rotation, sharpness, and noise amplitude. The origin is the image coordinates of the top-left corner of one of the squares in the chessboard. Units are pixels, not mircons. The x and y width of the squares are in the near-horizontal and near-vertical direction respectively. Units are pixels again. The rotation is counter-clockwise in milliradians of the pattern with respect to the sensor. With sharpness 1, the pattern has sinusoidal intensity variation from black to white. With sharpness less than 1, the amplitude of the sinusoidal variation decreases in proportion. With sharpness greater than one, the sinusoidal amplitude increases in proportion, but is clipped to black and white intensity, so that we obtain a sharply-defined chessboard. With sharpness 0.01 we obtain an image with alternating circles of intensity one count above and below the middle intensity, set in a field of middle intensity, as shown here. When we differentiate such an image in the horizontal direction, we get this, which defeats our frequency-based rasnik analysis. We can add noise to our simulated image with the noise amplitude parameter. If we set this to 1.0, we add a random number between 0.0 and 1.0 to each pixel.

lwdaq_image_manipulate image_name rasnik "0 0 20 30 2 10" -replace 1

In the above example, the the existing image would be replaced by a new image containing a rasnik pattern with origin at the top-left corner of the top-left pixel in the image, each square 20 pixels wide and 30 pixels high, rotated by 2 mrad anti-clockwise, with sharp edges.

The rotate manipulation rotates the entire image about a point. Do not use this routine to rotate an image in the traditional sense or right, left, or invert rotations. The routine is designed to perform non-square rotations, and will always lose some of the image that falls off the sides when we rotate. Use combinations of reverse_rows, rows_to_columns, and invert to produce traditional rotations. We specify the rotation in radians. We specify the point in image coordinates, where point (0,0) is the top-left corner of the top-left pixel, the x-axis runs left to right, the y-axis runs top to bottom, and the units of length are pixels. The point (0.5,0.5) is the center of the top-left pixel. The point (199.5,99.5) is the center of the pixel in the 200'th column and 100'th row. When we rotate a rectangular image, some parts will leave the rectangular image area. These are lost by the rotation manipulation. Opposite to these losses are regions where there is no intensity information to fill in the image area. These regions we fill in with pixels intensity equal to the average intensity of the original image within its analysis bounds. The rotation is applied to the entire image, not just the analysis area.

The smooth manipulation applies a 3×3 average filter to the image within the analysis boundaries. The value of pixel (i, j) in the new image will be proportional to the sum of the pixels (i-1..i+1, j-1..j+1) in the original image. One of the potential benifits of smoothing is to attenuate stochastic noise. We would like the smoothing to attenuate quantization noise in very dim images. But if we add the nine pixels in the 3×3 block together and dividing by nine to obtain their average, we find that our average itself suffers from quantization noise. For example, suppose eight pixels have value 100 and the ninth is 101. The average should be 100.1, but this will be rounded to 100. The smooth routine calculates the average value of the nine pixels and stores them in an array of real values. Once the array is complete, the routine tranforms the minimum to maximum range in the real-valued array into the pixel value range in the final image. If the smoothed values ranged from 98 to 102 and the final image pixels can be 0 to 255, the smooth routine transforms 98 to 0 and 102 to 255. Thus we obtain the best possible contrast in the final image, and we do the best we can to remove quantization noise.

The subtract manipulation requires you to name a second image, which will be subtracted from the first to create a third image. The two images must have the same dimensions. All pixels in the second images will be subtracted from the first image. The third image, being the difference, will be the same dimensions as the first two.

The subtract_row manipulation does not require a second image. It operates only upon the image within the analysis boundaries. Pixels outside the analysis boundaries are unchanged. Within the analysis boundaries, we subtract the average intensity of each row from the pixels in the row. The row average we obtain from the pixels in the row that lie within the analysis boundaries. In addition, we offset the intensity of the pixels in the analysis boundaries so that the intensity of the top-left pixel in the analysis bounds remains unchanged.

The subtract_gradient manipulation does not require a second image. We determine the gradient of intensity within the analysis boundaries. We measure the slope of the vertical and horizontal intensity profiles and use these to obtain the two-dimensional gradient. We subtract the intensity due to the gradient from each pixel in the analysis boundaries, but not from those outside the analysis boundaries. We thus remove both the horizontal and vertical intensity slopes from the image. We offset the intensity within the analysis boundaries so that the intensity of the top-left pixel in the analysis bounds remains unchanged.

The transfer_overlay manipulation copies the overlay of a second image into the overlay of the first. This manipulation is the only one operating upon the image ovelays. Each image has an overlay area whose colors we draw on top of the image when we display the image on the screen. Thus we can use the overlay to mark features in the image without corrupting the image itself. The overlay transfer scales the original overlay so that it fits into the rectangle of the new image. We can shrink a large image by a factor of four, analyze the quarter-sized image, record the results of analysis in the overlay, and transfer the overlay back into the original full-sized image. The transfer will make sure that the markings are aligned correctly with the features in the original image.

OptionFunction
-name valueThe name of the new image will be value.
-results valueSet the new image results string to value.
-replace valueIf value is 1, delete the original image and replace with new image, default.
-clear valueIf value is 1, clear overlay of final image, default 0.
-fill valueIf value is 1, fill overlay of final image with white, default 0.
-paint valuePaint the overlay within the analysis bounds with eight-bit color value, default 0.
-bottom valueSet the bottom of the analysis bounds to value.
-top valueSet the top of the analysis bounds to value.
-left valueSet the left of the analysis bounds to value.
-right valueSet the rigth of the analysis bounds to value.

With -name you specify the name of the new image created by the manipulation, or the existing image if there is no new image created by the manipulation. Any pre-existing images with this name will be destroyed before the name change occurs.

With -replace 0, the manipulation creates a new image and returns its name. With -replace 1, the manipulation over-writes data in the old image and returns the old image name.

The -paint option instructs lwdaq_image_manipulate to paint the entire area within the analysis bounds with the color given by value. This value should be a number between 0 and 255. The value 0 is for transparant. Other than the 0-value, the number will be treated like an eight-bit RGB code, with the top three bits for red, the middle three for green, and the bottom three for blue. Thus $E0 (hex E0) is red, $1C is green, and $03 is blue. Note that paint does not convert value into one of LWDAQ's standard graph-plotting colors, as defined in the overlay_color routine of images.pas, and used in lwdaq_graph.

In addition to the pixel manipulations, we also have options to change other secondary properties of the image. The table above shows the available manipulation options, each of which is followed by a value in the command line, in the format ?option value?.

When you specify the analysis bounds, a value of −1 is the code for "do nothing". The boundary will remain as it was. This use of the −1 code contasts with that of lwdaq_image_create, where −1 directs lwdaq_image_create to move the boundary to the edge of the image.

lwdaq_image_profile

lwdaq_image_profile image

lwdaq_image_profile returns a list of the average intensity in the analysis boundaries along the row or column directions. The profile takes the form of series of numbers in a space-delimited decimal string. The first number of a row profile is the average intensity of pixels in the leftmost column of the analysis boundaries. The last number is the average intensity of the right-most column. The first number of a column profile is the average intensity of the topmost row in the analysis boundaries. The last number is the average intensity of the bottom row. To obtain the row profile, use option -row 1, which is the default. To obtain the column profile, use -row 0.

lwdaq_image_results

lwdaq_image_results image

lwdaq_image_results returns an image's results string. When read from disk, and image result string cannot exceed the length of the first row in bytes minus the image header bytes.

lwdaq_inclinometer

lwdaq_inclinometer image ?option value?

lwdaq_inclinometer analyzes an image returned by the Inclinometer instrument. It returns the amplitude of harmonics in signals recorde in an image.

lwdaq_metrics

lwdaq_metrics data command

lwdaq_metrics takes a sequence of real numbers as input and returns a list of real-valued properties of the input sequence. The input sequence represent samples of a signal, such as an EEG recording, and the metrics represent properties of the signal, such as average value, standard deviation, maximum, minimum, coastline length, intermittency of high-frequency power, spikiness, asymmetry, and so on. The lwdaq_metrics routine is an interface with the metrics.pas library of metric-calculating routines. To select one of these routines, and control its output, we pass a command string into lwdaq_metrics following the data string.

lwdaq_photo_contents

lwdaq_photo_contents photo

lwdaq_photo_contents returns a byte array containing gray-scale intensity array corresponding to a tk photo. The routine uses the red intensity as the gray-scale intensity, which will work in a purely gray-scale image, and assumes that the red intensity is an 8-bit number.

The routine embeds the image dimensions in the first four pixels of the image by over-writing them with j_size-1 and i_size-1 each as two-byte integers in big-endian format. If the image is one that has been previously stored or drawn by lwdaq routines, the first twelve pixels of the first line will already contain the image dimensions, plus the analysis boundaries, all encoded as two-byte big-endian integers. Because the routine already knows for sure what the image dimensions are, it over-writes dimensions in the first row. But it does not over-write the analysis boundaries. These may be correct or incorrect. You can pass this routine's result to lwdaq_image_create, and have the image-creating routine check the first twelve bytes for valid analysis bounds, or ignore these bounds and use newly-specified bounds.

To assemble the 8-bit gray-scale image, the routine uses the lwdaq scratch image. If the routine were to allocate and dispose of an image, the printing activity of the disposal when -track_ptrs is set to 1 would alter the TCL return string.

lwdaq_rasnik

v image ?option value?

lwdaq_rasnik analyzes rasnik images. Specify the image with -image_name as usual. The routine clears the image overlay for its own use. The routine takes the following options, each of which you specify by giving the option name followed by its value, ?option value?. See the Rasnik Instrument for a description of the options.

OptionFunction
-reference_x_umx-coordinate of reference point.
-reference_y_umy-coordinate of reference point.
-orientation_codeSelects the analysis orientation code.
-square_size_umTells the analysis the mask square size (assumed square).
-pixel_size_umTells the analysis the pixel size (assumed square)
-show_timinigIf 1, print timing report to gui text window.
-show_fittingIf <> 0, show fitting stages with delay value ms.
-rotation_mradIf <> 0, pre-rotate image before analysis by −value.
-pattern_onlyIf 1, return pattern description not rasnik measurement.
-disable_skewIf 1, forces skew and slant values to zero, default 0.

See the Rasnik Instrument Manual for more information about the option values, in particular the reference and orientation code meanings.

The rotation_mrad option allows us to specify a large nominal rotation of the mask, positive is counter-clockwise. The rasnik routine will rotate the image so as to remove the large rotation, apply analysis, then un-rotate the image. The rotation takes place about the center of the analysis bounds.

With the -pattern_only option set, the routine returns a description of the chessboard pattern it finds in the image. The result string contains seven numbers: origin.x, origin.y, pattern_x_width, pattern_y_width, rotation, error, and extent. The origin values are the image coordinates of the top-left corner of one of the squares in the chessboard. Units are pixels, not mircons. The next two numbers are the width of the squares in the near-horizontal direction and their width in the near-vertical direction. Units are again pixels. The rotation is counter-clockwise in milliradians. The error is an estimate of the fitting accuracy in pixel widths. The extent is the number of squares from the image center over which the pattern extends. If we know that our image is neither slanted nor skewed, but has instead been severely corrupted by poor focus and dirt, we can force the skew and slant to zero with -disable_skew. Now, when we apply the rasnik analysis a hundred times to the same poor image, we have a higher chance of finding the correct pattern by accident.

lwdaq_rasnik_shift

lwdaq_rasnik_shift old_result ?option value?

lwdaq_rasnik_shift takes in a rasnik result string and shifts it to a new reference point. The routine gets the old reference point from the results string, and re-calculates the rasnik measurement using the x and y coordinates you specify with -reference_x_um and -reference_y_um.

lwdaq_receiver

lwdaq_receiver image command

lwdaq_receiver steps through the data bytes of an image, looking for valid four-byte messages, such as those transmitted by a Subcutaneous Transmitter (A3028) and received by an Octal Data Receiver (A3027). The lwdaq_receiver command takes two arguments. The first is the name of the image that contains the message data. The second is a command string. The command string in turn contains an instruction and some parameters. The function of lwdaq_receiver we describe in detail, with examples, in the Receiver Instrument manual. The lwdaq_receiver command calls another routine lwdaq_sct_receiver, which is defined in electronics.pas. The paragraphs below are the comments from the head of this lwdaq_sct_receiver function, and describe how to compose the command string we pass through lwdaq_receiver to lwdaq_sct_receiver.

lwdaq_sct_receiver analyzes receiver messages. These messages have a four-byte core, and may be accompanied by one or more bytes of payload data. The routine assumes that the first byte of the second image row is the first byte of a message. Each message takes the following form: an eight-bit signal identifier, a sixteen-bit sample value, an eight-bit time stamp, and zero or more bytes of payload. The routine will return the sixteen-bit sample values, or various characteristics of the data block, depending upon the options passed in through the command string.

The routine does not return the payload directly, but instead uses the global electronics_trace to store indices that allow another routine to extract payload values from the image data. The electronics trace is filled with message indices when we execute the "extract" or "reconstruct" instructions.

The only command that alters the image data is "purge", which eliminates duplicate messages. All other commands leave the image data untouched. Some commands alter the image result string.

In some cases, following aborted data acquisition, it is possible for the data block to be aligned incorrectly, so that the first byte of the block is not the first byte of a message, but instead the second, third, or fourth byte of an incomplete message. The routine does not handle such exceptions. If we want to deal with such corruption, we must shift the image data one byte to the left and try again until we meet with success.

The command string passed into this routine begins with options and values, followed by an instruction and parameters. We present the options and instructions in the comments below. Each option must be accompanied by an option value.

The "-size n" option tells the routine how many messages are in the image. The default value is 0, in which case the routine scans through the entire image looking until it encounters a null message or the end of the image. A null message is any one for which the first four bytes are zero. Such messages arise in corrupted recordings, but are also used to fill in the remainder of the image after the last valid message. If n > 0, the routine reads n messages even if there are null messages in the block it reads.

The "-payload n" option indicates that the four-byte core of each message is followed by n bytes of payload data. The default value of n is zero. The only instruction that returns the payload data directly is the "print" instruction. Otherwise, payload data is accessible through a list of indices passed back by the "extract" and "reconstruct" instructions.

The "-glitch x" option enables a glitch filter where applicable, as described below, the value x being the maximum absolute change in sample value that will be left intact without an attempt to over-write and remove with previous sample values. But default x is zero and the filter is disabled.

The "-divergent b" option enables tolerance of a sample clock that diverges significantly from that of the data receiver. This option affects the reconstruction instruction only. We use zero and one to indicate false and true.

The "-activity n" option sets the minimum number of samples a signal channel must contain for either plotting or listing.

Because of limitations in their logic, some data receivers may be unable to eliminate duplicate messages from their data stream. The same signal message received on two or more antennas may appear two or more times in the data. This routine eliminates these duplicates when it copies the messages from the image block into a separate message array. We will see the duplicates with the "print" and "get" instructions, which operate on the original image data. But all other instructions operate upon the message array, from which duplicates have been removed.

The "get" instruction performs no analysis of messages, but instead returns only the id, value, and timestamp of a list of messages. We specify each message with its index. The first message it message zero. A message index greater than the maximum number of messages the image can hold, or less than zero, will return zero values for all parameters.

The "purge" instruction re-writes the image data, eliminating duplicate messages and returning the number of messages in the purged data. This instruction is for diagnostic purposes only: we do not eliminate messages from the raw data before writing to disk.

The "plot" instruction tells the routine to plot all messages received from the channel numbers we specify, or all channels if we specify a "*" character. No elimination of messages nor reconstruction is performed prior to plotting, but if we use the -glitch option to enable a glitch filter, this filter will be applied to the signals before plotting and summarizing. The two parameters after the plot instruction specify the minimum and maximum values of the signal in the interval. The next parameter is either AC or DC, to specify the display coupling. After these three, we add the identifiers of the signals we want to plot. To specify all signals except the clock signal, use a "*". The routine returns a summary result of the form "id_num num_message ave stdev" for each selected channel. For the clock channel signal, which is channel number zero, the routine gives the start and end clock samples. The final two numbers in the summary result are the invalid_id code followed by the number of messages the routine did not plot.

The "print" instruction returns the error_report string followed by the content of all messages, or a subrange of messages. In the event of analysis failure, "print" will assume messages are aligned with the first data byte in the image, and print out the contents of all messages, regardless of errors found. When analysis fails because there are too many messages in the image, the result string returned by print is likely to be cut off at the end. The "print" instruction tries to read first_message and last_message out of the command string. If they are present, the routine uses these as the first and last message numbers it writes to its return string. Otherwise it returns all messages.

The "extract" instruction tells the routine to return a string containing all messages from a specified signal, but rejecting duplicates. A duplicate is any message with the same value as the previous message, and a timestamp that is at most one later than the previous message. The routine takes two parameters. The first is the identifier of the signal we want to extract. The second is the sampling period in clock ticks. The routine returns each message on a separate line. On each line is the time of the message in ticks from the beginning of the image time interval, followed by the sample value. The command writes the following numbers into ip^.results: the number of clock messages in the image and the number of samples it extracted.

The "reconstruct" instruction tells the routine to reconstruct a particular signal with the assumption that the transmission is periodic with temporal scattering of transmission to avoid systematic collisions between transmitters. Where messages are missing from the data, the routine adds substitute messages. It removes duplicate messages and messages that occur at invalid moments in time. The result of reconstruction is a sequence of messages with none missing and none extra. The instruction string for the "reconstruct" instruction begins with the word "reconstruct" and is followed by several paramters. The first parameter is the identifier of the signal we want to reconstruct. The second parameter is its nominal sampling period in clock ticks. The third parameter is "standing_value", the signal's most recent correct sample value. If the -glitch option has been used to set a non-zero glitch threshold, the routine applies this filter after reconstruction is complete. If the -divergent option has been enabled, the reconstruction permits greater disagreement between the transmitter and receiver clocks. By default, standing_value, glitch_threshold, and divent_clocks are all zero. The result string contains the reconstructed message stream with one message per line. Each message is represented by the time it occured, in ticks after the first clock in the image time interval, and the message data value. The "reconstruct" command writes the following numbers into ip^.results: the number of clock messages in the image, the number of messages in the reconstructed messages stream, the number of bad messages, and the number of substituted messages.

The "clocks" instruction returns a the number of errors in the sequence of clock messages, the number of clock messages, the total number of messages from all signals, and the byte location of clock messages specified by a list of integers. The command "clocks 0 100" might return "0 128 640 0 500" when passed a 2560-byte block of messages containing 128 valid clocks and 512 messages from non-clock signals. The last two numbers are the byte location of the 1st clock message and the byte location of the 101st clock message. A negative index specifies a clock message with respect to the end of the message block. Thus "-1" specifies the last clock message.

The "list" instruction returns a list of signal identifiers and the number of samples in the signal. Signals with no samples are omitted from the list. The list takes the form of channel identifier followed by number of samples separated by spaces.

The "auxiliary" instruction extracts and returns all auxiliary messages in a string. An auxiliary message is one in which the lower four bits are equal to fifteen. The instruction returns one message per line. For each message it writes the eight-bit channel number, the sixteen-bit timestamp, and the sixteen-bit contents.

The "system" instruction extracts and returns all system messages in a string, excluding the clock messages. An system message is one in which the lower four bits are equal to zero. The instruction returns one message per line. For each message it writes the eight-bit channel number, the sixteen-bit timestamp, and the sixteen-bit contents.

lwdaq_rfpm

lwdaq_rfpm image ?option value?

lwdaq_rfpm analyzes images from an RFPM instrument.

lwdaq_scam

lwdaq_wps image command ?arguments?

lwdaq_scam applies Silhouette Camera (SCAM) routines to SCAM images. The SCAM routines are defined in scam.pas. We pass lwdaq_scam an instruction, and one or more arguments required by the instruction.

InstructionFunction
projectProject a modelled object into an image overlay.
disagreementMeasure disagreement between actual and modelled silhouette.

The project instruction takes three arguments: a camera calibration in the SCAM's mount coordinates, an object definition in the SCAM's mount coordinates, and a number of projection lines to use to fill the overlay in the silhouette image. The object must be one of those in the library provided by scam.pas. When we want to project more complex bodies, we build them out of multiple objects.

The camera string contains nine elements. The first is the name of the camera. The following eight are the camera calibration constants, as described in the BCAM User Manual. They are the xyz camera pivot position millimeters, the angle subtended by the camera axis with the x and y axis in milliradians, a numerical code to say if the axis is forward or backwards and to identify the image sensor, the distance from the pivot point to the center of the image sensor, and the rotation of the image sensor about the camera axis.

Prior to projecting any object, we must transform its location into mount coordinates. If the object is anything other than a sphere, it will have an orientation as well, and this we must transform this orientation into mount coordinates as well. The orientation of an object is three rotations about the x, y, and z axes that bring the object from its zero orienation to its modelled orientation.The modelled object itself we specify with its own string. Each object begins with a name, such as "sphere" or "shaft". Every object has a location, which is the translation of its zero point to obtain its modelled position. All objects other than the sphere have an orientation, which is the xyz rotation we apply to the object in its zero orientation to obtain its modelled oriention. The location and orientation together define the "pose" of the modelled object.

Object Zero Point Zero Orientation
sphere center of sphere no orientation
shaft a point on the shaft axis shaft axis is parallel to x-axis
cuboid center of left face x-axis perpendicular to left face, y-axis parallel to top edge

Following the location, and possibly the orientation, of the object are one or more values giving its dimensions. A sphere consists of a location and a diameter. A shaft consists of a location and orientation in the coordinate system of the body, followed by a pair of numbers for each face of the shaft. Each pair is a diameter and distance. The distance is measured along the shaft axis from the zero point, with negative values being in the direction opposite to the axis vector. A cuboid consists of a location, an orientation, a width, a height, and a depth. The width, height, and depth are parallel to the x, y, and z axes respectively when the cuboid is in its zero orientation.

The disagreement instruction counts the number of pixels in the analysis boundaries for which the image and the overlay disagree about the location and extent of the silhouette. To determine which pixels are silhouette and which are background, the routine uses an intensity threshold. Pixels with intensity equal to or below the threshold are considered part of the silhouette. All others are background. To specify the threshold, we pass lwdaq_scam a "threshold string" immediately after the image name. The threshold string takes the same form as it does in the lwdaq_bcam routine, as illustrated in the BCAM Instrument manual. A background pixel that is marked blue from a previous SCAM body projection will remain blue. A background pixel that is not marked will remain unmarked. A silhouette pixel that is marked blue will be unmarked. A silhouette pixel that is unmarked will be marked orange. In this way, a prefect match between a solid projection and a silhouette will be entirely unmarked, while imprefections are marked either orange for silhouette without projection or blue for projection without silhouette. The marked pixels are the disagreement pixels.

The disagreement instruction's result string begins with an integer giving the number of disagreement pixels in the image. If the analysis encountered an error, this value will be "-1". Following the count are the minimum and maximum intensities in the image, also integers, and the threshold intensity used to detect the silhouette. The threshold we return as a real number so that we can support thresholds half-way between two integer values.

set img [LWDAQ_read_image_file Images/SCAM_sphere.gif]
lwdaq_scam $img disagreement "10 %"
72832 49 123 56.4

In the above example, we read the sample SCAM_sphere.gif image and apply the scam disagreement routine with a threshold string "10 %". This threshold string specifies an intensity that is 10% of the way from the minimum intensity to the maximum intensity.

lwdaq_shadow

lwdaq_shadow image ?option value?

lwdaq_shadow finds vertical or horizontal line shadows in images. We call these wire shadows because we firsst obtained them from wires in x-ray images. The image itself must be blurred enough that the minimum intensity of the shadow lies near its center. We use a simplex fitter to maximize the correlation between the image and a prototype shape. You will find this analysis described in the Fitting Analysis section of the WPS1 Manual.

OptionFunction
-approximateStop approximate shadow positions, default zero.
-pixel_size_umWidth and height of image pixels in microns.
-reference_umLocation of reference line in microns from top of image, default zero.
-show_timinigPrint timing report to gui text window, default zero.
-num_shadowsNumber of shadows you want the routine to find.

With -pre_smooth set to 1, the routine smooths the original image with a box filter before it applies the gradient and threshold. We use -pre_smooth when noise is obscuring the larger edge features in a wire image.

The shadow positions are given with respect to a horizontal reference line drawing reference_um microns down from the top edge of the top image row.

lwdaq_simplex

lwdaq_simplex start_point error_proc

lwdaq_simplex finds a point in an n-dimensional space at which an error function is a minium. The routine takes a minimum of two parameters: the initial position and an error procedure name. The initial position must be a list of n real numbers. The error procedure must be defined in the Tcl interpreter, take a list of n real numbers as its input, and return a real-valued error measurement. We call the Tcl error routine with the help of the lwdaq_simplex_error interface function. The simplex fitter starts at the initial position and moves through the n-dimensional space until it reaches a maximum number of steps specified with the "-max_steps m" option. When it stops, it returns the point of convergeance as n real numbers, the final error value, and the number of steps it took.

Option Function
-report m Print progress line every m iterations, default 0 no reporting.
-steps m Abort after m steps, default 0 is no maximum.
-scaling s Scaling factors, default s is a string of n ones.
-start_size d Simplex construction size, default d = 1.0.
-end_size d Simplex size at convergeance, default d = 0.01.
-restarts m Number of restarts before starting to shrink, default m = 0.
Table: Options Accepted by the Simplex Library Routine.

By default, the simplex routine assumes that the sensitivity of the error to each of the n coordinates is similar, so that it sets up its simplex triangle with equal length in all n dimensions. If the sensitivity of the error function is dramatically different for different coordinates, we can specify the sensitivity through the "-scaling s" option. If the error is ten times less sensitive to one coordinate than the others, we give it a scaling factor of ten and the other coordinates a scaling factor of one. If we do not specify the scaling factors, the routine assumes a value of unity for all coordinates.

When the fit takes a long time, or when we are trying to figure out why it won't converge, it's nice to have the fit print out the coordinates and the error value every m'th iteration, which we achieve with "-report m". The report calls gui_writeln, which in turn prints in a Tk text widget called gui_text_name. We set gui_text_name with lwdaq_config.

We avoid freezing LWDAQ during a long fit by calling LWDAQ_support in the error procedure. To permit the user to abort the fit, have the error procedure check a global abort flag. When the error procedure sees the abort, it can return a Tcl error to the lwdaq_simplex routine, and lwdaq_simplex will abort.

lwdaq_tcb

lwdaq_tcb image xycoordinates ?option value?

lwdaq_tcb extracts the top antenna and top power from data recorded by a Telemetry Control Box (TCB, A3042.) The top antenna is a number specifying one of the antennas connected to the TCB. Each of these antennas is capable of receiving telemetry messages from devices such as our Subcutaneous Transmitters (SCT), Implantable Inertial Sensors (IIS), or Implantable Stimulator-Transponders (IST). For each message it receives, the TCB adds a payload of two bytes to the core four-byte telemetry message. The first payload byte is the maximum power with which this message was received by any of the TCB's antennas. The second payload byte is a number identifying this antenna. We call this antenna the top antenna and its received power is the top power. The TCB-A16 antenna inputs are numbered 1-16 on the connectors on the back of the box. The top antenna number provided by the TCB-A16 gives us the antenna input to which the top antenna is connected.

If we know where our antennas are located in our recording system, the top antenna number gives us an approximate measurement of the transmitter's location. Most likely, the transmitter is nearer to the top antenna than to any other. If the transmitter is half-way between two antennas, we may see the top antenna number varying from one received message to the next. The lwdaq_tcb routine returns the median antenna number and the median power. Our assumption is that these two median values correspond to one another. We convert the antenna number into a three-dimensional position with a string of three-dimensional points, each point representing the location of an antenna in an arbitrary three-dimensional coordinate system with arbitrary units. The lwdaq_tcb routine picks the point corresponding to the top antenna and returns its three coordinates x, y, and z. We must choose the coordinate system for the antennas such that all z-coordinates are positive and non-zero. By this means, we allow our analysis of animal movement, which we apply to a history of animal position, to use coordinate "0.0 0.0 0.0" as a marker for "no measurement in this interval".

The routine takes two parameters and has several options. The first parameter is the name of the image that contains the tracker data. The indices in electronics_trace must refer to the data space of this image. An index of n points to the n'th message in the data, with the first message being number zero. Each message starts with four bytes and is followed by one or more payload bytes. The payload bytes contain one or more power measurements. The routine assumes that the global electronics_trace is a valid xy_graph created by lwdaq_receiver, giving a list of x-y values in which x is an integer time and y is an integer index. The message corresponding to time x is the y'th message in the Receiver Instrument image to which we applied the lwdaq_receiver routine. The electronics_trace will be valid provided that the most recent call to the lwdaq electronics library was the lwdaq_receiver with either the "extract" or "reconstruct" instructions. The second parameter is a list of locations of antennas, given as a sequence of numbers x, y, z separated by spaces.

The lwdaq_tcb routine supports the following options:

OptionFunction
-slicesNumber of sub-intervals for which we calculate power and position, default 1.

The lwdaq_tcb output is compatible with that of lwdaq_alt. The first three values returned are x, y, and z of the top antenna. Next comes one power value for each antenna. These are all zero except for that of the top antenna, for which the power is the value recorded by the TCB. If slices > 1, we will have slices lines in our output string, each giving the position and power for a fraction of the interval represented by the data image.

lwdaq_voltmeter

lwdaq_voltmeter image ?option value?

lwdaq_voltmeter analyzes image data for the Voltmeter instrument. We pass the routine an image name and it returns either a string of characteristics of the voltages recorded in the image, or the voltages themselves. It plots the voltages in the image overlay, according to plot ranges passed to the routine. The display looks like an oscilloscope, and provides a software trigger.

OptionFunction
-v_minThe minimum voltage for the display.
-v_maxThe maximum voltage for the display.
-t_minThe minimum time for the display.
-t_maxThe maximum time for the display.
-ac_coupleWhether to subtract the average value from display.
-positive_triggerTrigger on positive-going transition.
-v_triggerThe trigger voltage for display and extraction.
-auto_calibUse the device's reference voltages.
-valuesReturn the voltage values rather than characteristics.

The lwdaq_voltmeter routine calls lwdaq_A2057_voltmeter to analyze the samples in the image. The image results string must contain some information about the samples that will allow the analysis to parse the voltages into reference samples and signal samples. The results string will contain 5 numbers. The first two are the bottom and top reference voltages available on the LWDAQ device. In the case of the A2057 these are 0 V and 5 V, but they could be some other value on another device. The third number is the gain applied to the signal. The fourth number is the data acquisition redundancy factor, which is the number of samples recorded divided by the width of the image. Because we will use a software trigger, we want to give the routine a chance to find a trigger and still have enough samples to plot one per image column. Suppose the image contains 200 columns, then we might record 600 samples so that any trigger occuring in the first 400 samples will leave us with 200 samples after the trigger to plot on the screen. In this case, our redundancy factor is 3. The fifth number is the number of channels from which we have recorded.

The result string "0.0 5.0 10 3 2" indicates 0 V and 5 V references, a gain of 10, a redundancy factor of 3 and two channels. The channels will be plotted with the usual LWDAQ colors, with the first channel being color zero.

The analysis assumes the samples are recorded as sixteen-bit numbers taking up two bytes, with the most significant byte first (big-endian short integer). The first byte of the recorded signal should be the first pixel in the second row of the image, which is pixel (0,1). If n is the image width and r is the redundancy factory, the first n samples (therefore 2n bytes) are samples of the bottom reference voltage. After that come nr samples from each channel recorded (therefore 2nr bytes from each channel). Last of all are n samples from the top reference.

The analysis uses the bottom and top reference values to calibrate the recorded signals, which are otherwise poorly defined in their correspondance between integer values and voltages. We turn on the calibration with the auto_calib option.

The recorded signal from the last channel to be analysed can be returned as a string. Each point consists of a time and a voltage. We instruct the analysis to return the points rather than characteristics with the values option. The following line of code extracts the signal of the last channel. Time zero will be the trigger instant if a trigger was detected, and the first sample otherwise. Thus the returned string contains more data than is plotted by the voltmeter analysis in the image overlay. It contains all the samples recorded.

set trace [lwdaq_voltmeter image_name -values 1 -auto_calib 1]

When the values option is not set, as is the case by default, the analysis returns four numbers for each channel recorded. The first number is the average value of the signal. The second is its standard deviation. You can obtain the root mean square of the signal by adding the square of the average and the standard deviation, and taking the square root. The third number is an estimate of the fundamental frequency of the recorded signal, if such a frequency exists, in Hertz, as obtained from a discrete fourier transform. To obtain the discrete fourier transform, we use a subset of the data containing an exact power of two number of samples. We pass this exact power of two number of samples to our fast fourier transform routine. The fourth number is the amplitude of this fundamental frequency.

lwdaq_wps

lwdaq_wps image ?option value?

lwdaq_wps analyzes wps images. It clears the overlay for its own use. We describe the analysis in our WPS1 Manual.

pixels.
OptionFunction
-pixel_size_umWidth and height of image pixels in microns.
-reference_umLocation of reference line in microns below top edge of top row.
-show_timinigIf 1, print timing report to gui text window, default zero.
-show_edgesIf 1, show edge pixesls in image, defalut zero
-num_wiresThe number of wires you want the routine to find.
-pre_smoothSmooth the image before you take the derivative.
-mergeMerge aligned edge clusters.
-thresholdCriteria for finding spots, including threshold specification.

The -threshold string is used in the same way as in lwdaq_bcam. It can contain an intensity threshold or it can define a means to calculate the threshold. The string can also specify the minimum number of pixels a spot must contain, and its maximum eccentricity. Spots that do not meet these criteria will be marked as invalid. In this case, note that the threshold intensity will be applied to the horizontal gradient of the wire image, not the image itself.

With -pre_smooth set to 1, the routine smooths the original image with a box filter before it applies the gradient and threshold. We use -pre_smooth when noise is obscuring the larger edge features in a wire image.

With -merge set to 1, the routine checks for edge pixel clusters that are closely aligned, and merges these together. We use -merge when image contrast is so poor that the edge pixels along one side of a wire image can break into two or more separate clusters.

The wire positions are given with respect to a horizontal reference line drawing reference_um microns down from the top edge of the top image row. With show_edges equal to zero (the default value), the routine plots the image's horizontal intensity profile in green and the derivative profile in yellow. But when you set show_edges to 1, the routine no longer plots these two graphs, but instead displays the spots it finds in the derivative image, overlayed upon the original image. The edges of a wire will be covered with colored pixels. White pixels are ones that were part of spots that did not satisfy the -threshold critera.

Library Routines

The lwdaq command acts as an entry point into our analysis libraries, making various math functions available at the TCL command line. You specify the routine we wish to call, and pass arguments to the routine in strings or byte arrays or both. Most routines return results as text strings in which real numbers are encoded in characters with a fixed number of decimal places, as defined by the global constants fsr and fsd. You can set both of these with lwdaq_config. Beware that these routines can round small values to zero.

ave_stdev

lwdaq ave_stdev data

Calculates the average, standard deviation, maximum, minimum, and mean absolute deviation of of data, where data contains a string of numbers. The routine returns values separated by spaces, and formatted to fsd decimal places.

bcam_coord_from_mount

lwdaq bcam_coord_from_mount mount

Convert the ball positions of a BCAM-style kinematic mount into the pose of the mount's coordinate system. These three balls mate with a cone, slot, and flat depression under a metrology device such as a Boston CCD Angle Monitor (BCAM), Silhouette Camera (SCAM), Wire Position Sensor (WPS), or Fiber View Camera (FVC). We pass the routine the global xyz-position of the three balls in the order cone, slot, flat. The routine returns the location and orientation of the mount coordinate system. We describe how the three balls define the mount coordinate system in the BCAM User Manual. See bcam_coordinates_from_mount in bcam.pas for the exact calculation. The mount coordinate system is defined in such a way that it is always in the same location and orientation with respect to the sensor chassis, regardless of small variations in the ball arrangements between one kinematic mount and the next.

lwdaq bcam_coord_from_mount "0 1 0 -21 1 -72 21 1 -72"
0.000 1.000 0.000 -0.000 0.004 0.000

The "pose" of the mount coordinate system consists of its location and orientation. The location is the xyz-position of the mount coordinate origin in global coordinates. The rotation is three angles by which we rotate a global vector about the global x, y, and then z axis to obtain the components of the vector in mount coordinates. If we apply this rotation to the global coordinate axes, we obtain the axes of the mount coordinate system. The units of angle are radians.

Note that our bcam_from_global and global_from_bcam routines perform this conversion from ball positions to mount coordinate system themselves. We pass these routine the ball positions, not the pose of the mount coordinate system. The more generic xyz_local_from_global and xyz_local_from_global routines do, however, expect the pose of the local coordinate system. We may use these generic routines for any style of kinematic mount or body positioning, provided that we know the pose of the local coordinate system in the global coordinate system.

bcam_from_global_point

lwdaq bcam_from_global_point point mount

Obsolete Routine Transforms a point in global coordinates to a point in bcam coordinates. The bcam coordinates are those defined by a kinematic mount holding a bcam. The routine takes as input a point string containing the global xyz-position of point and a mount string containing the global xyz-positions of the centers of the cone, slot, and flat balls of the mount. Note that the routine does not accept the pose of the mount coordinate system, but instead the positions of the kinematic mounting balls.

This routine deduces the pose of the mount coordinate system itself, which is computationally intensive and unecessary. Instead of deducing the mount coordinate pose every time we transform between global and mount coordinates, call bcam_coord_from_mount once to obtain the pose of the mount coordinates, and then pass this pose into xyz_local_from_global_point.

In the following example, we transform the global point (0,1,0) into BCAM coordinates when our cone, slot and flat balls have coordinates (0,1,0), (-1,1,-1), and (1,1,-1).

lwdaq bcam_from_global_point "0 1 0" "0 1 0 -1 1 -1 1 1 -1"
0.000000 0.000000 0.000000

For a description of the BCAM coordinate system, and how it is defined with respect to a BCAM's kinematic mounting balls, consult the BCAM User Manual. We usually use millimeters to specify coordinates, because we use millimeters in our BCAM camera and source calibration constants. But the routine will work with any units of length, so long as we use the same units for both the point and the mount strings.

bcam_from_global_vector

lwdaq bcam_from_global_vector vector mount

Obsolete Routine Transforms a vector in global coordinates to a vector in bcam coordinates. The bcam coordinates are those defined by a kinematic mount holding a bcam. The routine takes as input a vector string containing the bcam xyz-components of vector and a mount string containing the global xyz-positions of the centers of the cone, slot, and flat balls of the mount. Note that the routine does not accept the pose of the mount coordinate system, but instead the positions of the kinematic mounting balls.

lwdaq bcam_from_global_vector "0 1 0" "0 1 0 -1 1 -1 1 1 -1"
0.000000 1.000000 0.000000

This routine deduces the pose of the mount coordinate system itself, which is computationally intensive and unecessary. Instead of deducing the mount coordinate pose every time we transform between global and mount coordinates, call bcam_coord_from_mount once to obtain the pose of the mount coordinates, and then pass this pose into xyz_local_from_global_vector.

bcam_image_position

lwdaq bcam_image_position source_position camera

Calculates the image coordinates of the image generated by a light source at location source_position in BCAM coordinates. We specify the BCAM itself with the camera string. The routine determines the image position by drawing a line from the source through the pivot point and instersecting this line with the plane of the image sensor. The orientation and location of the image sensor is given by the camera calibration constants. The image coordinate origin is the top-left corner of the image sensor as seen on the screen. The units of image coordinates are microns, with x going left-right and y going top-bottom.

lwdaq bcam_image_position "0 0 750" "P0001 0 0 0 0 0 1 75 0"
1.720 1.220

Here we see the image is at (1.72,1.22) in image coordinates, which is the center of a TC255P image sensor. You specify the BCAM itself with its calibration constants using the camera string, just as for bcam_source_bearing.

lwdaq bcam_image_position "1 0 750" "P0001 0 0 0 0 0 1 75 0"
1.620 1.220

Here we see movement of 1 mm at a range ten times the pivot-ccd distance causing a 100-um move on the image.

bcam_source_bearing

lwdaq bcam_source_bearing spot_center camera

Calculates the line in BCAM coordinates upon which a light source must lie for its image to be centered at spot_center. The line is returned as a string containing six numbers. The first three numbers are the coordinates of the BCAM pivot point in BCAM coordinates in millimeters. The last three numbers are a unit vector in the direction of the line. The BCAM itself we describe with its calibration constants in the camera string. The camera string contains nine elements. The first is the name of the camera, which might be its serial number. The following eight are the camera calibration constants, as described in the BCAM User Manual.

lwdaq bcam_source_bearing "1.72 1.22" "P0001 1 0 0 0 0 1 75 0"
1.000000 0.000000 0.000000 0.000000 0.000000 1.000000

The first element in the camera string is the name of the camera, even though this calculation does not use the camera name. In the example above, P0001 is the camera name, the pivot point is at (1,0,0) in BCAM coordinates, the camera axis is parallel to the BCAM z-axis, the pivot point is 75 mm from the lens, and the CCD rotation is zero. We transform point (1.72, 1.22) on the CCD (dimensions are millimeters) into a bearing that passes through the pivot point (1,0,0) in the direction (0,0,1). The point (1.72,1.22) is our aribitrarily-chosen center of the CCD in all currently-available BCAMs (it is close to the center of the TC255P image sensor, but not exactly at the center). The BCAM camera axis is the line passing through the CCD center and the pivot point.

bcam_source_position

lwdaq bcam_source_position spot_center bcam_z camera

Calculates the BCAM coordinates of a light source whose image is centered at spot_center, and which itself lies in the plane z = bcam_z in BCAM coordinates. The routine is similar to bcam_source_bearing, but we specify the BCAM z-coordinate of the source as well, in millimeters. The routine determines the position of the source by calling bcam_source_bearing and intersecting the source bearing with the z=range plane. The camera string contains the camera calibration constants, just as for bcam_source_bearing.

lwdaq bcam_source_position "1.72 1.22" 1000 "P0001 1 0 0 0 0 1 75 0"
1.000000 0.000000 1000.000000

Here we see the source is at (1, 0, 1000) in BCAM coordinates, where all three coordinates are in millimeters. You specify the BCAM itself with its calibration constants using the camera string, just as for bcam_source_bearing.

coastline_x

lwdaq coastline_x data

Returns the cumulative absolute difference in consecutive values of a sequence of real numbers. If we pass the routine "0 1 2 3 2 1 6" it returns value 10.0.

coastline_x_progress

lwdaq coastline_x_progress data

Returns a sequence of real numbers in which the n'th value is the coastline_x of the first n numbers passed into the routine. If we pass the routine "0 1 2 3 2 1 6" it returns "0 1 2 3 4 5 10". Thus the coastline_x of the entire sequence is the final number in the output sequence.

coastline_xy

lwdaq coastline_xy data

Returns the cumulative separation of consecutive values of a sequence of two-dimensional points. The routine accepts a sequence of two-dimensional points as pairs of real numbers. If we pass the routine "0 0 0 1 0 0 4 0" it returns value 6.0.

coastline_xy_progress

lwdaq coastline_xy_progress data

Takes a two-dimensional graph as input and returns a two-dimensional graph in which the y-coordinate of the n'th point represents the coastline_xy of the first n points in the input graph and the x-coordinate of the n'th point is the same as the x-coordinate of the n'th input point. Thus the coastline_xy of the entire input graph is the final y-value of the output sequence.

frequency_components

lwdaq coastline_xy_progress data

Calculates components of the discrete fourier transform of a real-valued waveform by repeated calls to frequency_component in utils.pas. We specify the M components we want to calculate with a string of M frequencies, each of which is a multiple of the fundamental frequency of the waveform, 1/NT. The frequencies provided by a full discrete fourier transform of N real samples are k/NT for k such that 0≤kN−1. If we want to obtain all N/2 components, we can use our lwdaq_fft routine instead. The frequency_components routine is designed to provide a small number of components for real-valued input data.

lwdaq_config -fsr 1 -fsd 2
lwdaq frequency_components "0 1 2 3 4 5" "0 0 0 0 1 1 1 1"
0.50 0.00 0.65 3.50 0.00 -1.91 0.27 0.83 0.00 0.00 0.27 0.30 

Here we ask for components with frequencies "0 1 2 3 4 5" and we specify data "0 0 0 0 1 1 1 1". The routine returns a string containg the amplitude, a, and phase, φ, of each specified component, separated by spaces.

Because the frequency_component routine accepts only real-valued inputs, we are certain that component k for K>0 will be the complex conjugate of component Nk, which means the two components add together to form one component of double the magnitude but with the same phase as component k. Thus frequency_component doubles the magnitude of the k'th component for k equal to 1, 2,..N/2−1 and leaves the phase unchanged.

The phase, φ, is in units of T, and refers to the phase of a sinusoid, so that the frequency component is

asin(2π(t−φ)f/N)

where f is the frequency we specified and t is the quantity that separates the samples. The quantity t might be time or distance.

The frequency need not be an integer, but if it is an integer, then this frequency will be one of those defined for the discrete fourier transform. There are times when choosing an exact frequency outside that finite set of periods is useful. For example, if we have 512 samples taken over 1 s, the discrete fourier transform contains components with frequencies 1 Hz, 2 Hz,.. 255 Hz. If we want to look for a signal at 33.3 Hz, we will find that the discrete fourier transform spreads 33.3 Hz into 33 Hz and 34 Hz, but neither component has the correct amplitude. By specifying a frequency of 33.3 Hz, we will obtain a more accurate estimate of a 33.3 Hz signal. Most of the time, however, the value of the transform outside the frequencies defined in the discrete transform is unreliable.

To improve its accuracy, the routine subtracts the average value of the waveform from each sample before it calculates the frequency components. To further improve the accuracy of the transform, we can apply a window function to waveform before it we call frequency_component. The window function smooths off the first and final few samples so that they converge upon the waveform's average value. We provide a linear window function with window_function.

glitch_filter

lwdaq glitch_filter threshold data

Applies a glitch filter to a sequence of real-valued samples. The glitch filter takes a real-valued threshold as its first parameter, followed by a list of real-valued samples. The routine calls glitch_filter from utils.pas. A "glitch" is a corruption of one or more adjacent points in a signal. Our implementation of the glitch filter is designed to eliminate glitches that arise from missing samples being replaced by corrupt or interference samples in telemetry systems. When the absolute change in value from sample n-1 to sample n exceeds the threshold, we look to see if there is another threshold-exceeding change from sample n to n+1 in the opposite direction. If so, we replace sample n with sample n-1. Otherwise, we check to see if sample n+1 has exactly the same value as sample n, and if so, we replace sample n with sample n-1. Thus a jump up or down by more than the threshold, followed by any number of identical samples, will be treated as a glitch and eliminated entirely, replaced by the sample before the jump. A threshold of 0 disables the filter. As an example, we could have:

lwdaq_config -fsd 0 -fsr 1
lwdaq glitch_filter 3.0 "0 1 20 1 0 3 1 2 3 2 2 0 8 6 7 0 0"
0 1 1 1 0 3 1 2 3 2 2 0 8 6 7 7 7

Here we see a glitch in the third sample being removed, and later we have another glitch: a jump downwards of 7 when our threshold is 3, followed by two zeros. The repetition of the exact same value is a signature of glitches in unreliable signals. When several samples go missing, and the first is a corrupted sample, the reconstruction routine we apply to the raw telemetry signal will fill in the missing samples with the value of the corrupted sample. If we specify a negative threshold, the routine still uses its absolute value, but in addition it will append to the end of the output string the number of glitches removed.

lwdaq glitch_filter -3.0 "0 0 0 0 10 0 1 2 0 0 0 0 0"
0 0 0 0 0 0 1 2 0 0 0 0 0 1

The last number in the string is the number removed.

glitch_filter_xy

lwdaq glitch_filter_xy threshold data

Applies a glitch filter to the a sequence of x-y points. The routine calls glitch_filter_xy from utils.pas. The distance between consecutive points is their two-dimensional separation. The routine works in the same way as the one-dimensional glitch_filter except it uses the separation of consecutive two-dimentional points rather than the absolute change in the value of a one-dimensional coordinate. A single-point glitch is a jump of length greater than the threshold followed by another jump of length greater than the threshold in a direction that is at least ninety degrees rotated with respect to the original jump. A threshold of 0 disables the filter.

lwdaq_config -fsd 0 -fsr 1
lwdaq glitch_filter_xy 10 "0 0 1 0 0 2 3 2 50 2 2 2 1 4 3 3"
0 0 1 0 0 2 3 2 3 2 2 2 1 4 3 3

A negative threshold causes the number of glitches to be appended to the end of the return string.

lwdaq glitch_filter_xy -10 "0 0 1 0 0 2 3 2 50 2 2 2 1 4 3 3"
0 0 1 0 0 2 3 2 3 2 2 2 1 4 3 3 1

The last number in the example above is not a sample, it is the number of glitches removed.

glitch_filter_y

lwdaq glitch_filter_y threshold data

Applies a glitch filter to the y-values of a sequence of x-y points. The routine calls glitch_filter_y from utils.pas. The result is equivalent to taking the y-values, passing them through the one-dimensional glitch_filter and re-combining the result with their x-values. We replace the glitch point in the data sequence with a point whose y-coordinate is the same as the previous point's y-coordinate. A threshold of 0 disables the filter. A negative threshold causes the number of glitches to be appended to the signal values.

lwdaq_config -fsd 0 -fsr 1
lwdaq glitch_filter_y -4.0 "1 0 2 0 3 10 4 0 5 0 6 0 7 5 8 5 9 0 10 0 11 0 12 0 13 0"
1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 3

In the example above, the final number in the output is the number of glitches removed.

global_from_bcam_point

lwdaq global_from_bcam_point point mount

Obsolete Routine Transforms a point in bcam coordinates to a point in global coordinates. The bcam coordinates are those defined by a kinematic mount holding a bcam. The routine takes as input a point string containing the bcam xyz-position of point and a mount string containing the global xyz-positions of the centers of the cone, slot, and flat balls of the mount. Note that the routine does not accept the pose of the mount coordinate system, but instead the positions of the kinematic mounting balls.

lwdaq global_from_bcam_point "0 1 0" "0 1 0 -1 1 -1 1 1 -1"
0.000000 2.000000 0.000000

This routine deduces the pose of the mount coordinate system itself, which is computationally intensive and unecessary. Instead of deducing the mount coordinate pose every time we transform between global and mount coordinates, call bcam_coord_from_mount once to obtain the pose of the mount coordinates, and then pass this pose into xyz_global_from_local_point.

global_from_bcam_vector

lwdaq global_from_bcam_vector vector mount

Obsolete Routine Transforms a vector in bcam coordinates to a vector in global coordinates. The bcam coordinates are those defined by a kinematic mount holding a bcam. The routine takes as input a vector string containing the global xyz-components of vector and a mount string containing the global xyz-positions of the centers of the cone, slot, and flat balls of the mount. Note that the routine does not accept the pose of the mount coordinate system, but instead the positions of the kinematic mounting balls.

lwdaq global_from_bcam_vector "0 1 0" "0 1 0 -1 1 -1 1 1 -1"
0.000000 1.000000 0.000000

This routine deduces the pose of the mount coordinate system itself, which is computationally intensive and unecessary. Instead of deducing the mount coordinate pose every time we transform between global and mount coordinates, call bcam_coord_from_mount once to obtain the pose of the mount coordinates, and then pass this pose into xyz_global_from_local_vector.

linear_interpolate

lwdaq linear_interpolate x_position x_y_data

Interpolates between the two-dimensional points of x_y_data to obtain an estimate of y at x=x_position. If we pass "2.5" for the x position, and "0 0 10 10" for the x-y data, the routine will return "2.500000".

matrix_inverse

lwdaq matrix_inverse matrix

Calculates the inverse of a square matrix. We pass the original matrix as a string of real numbers in matrix. The first number should be the top-left element in the matrix, the second number should be the element immediately to the right of the top-left element, and so on, proceeding from left to right, and then downwards to the bottom-right element. The command deduces the dimensions of the matrix from the number of elements, which must be an integer square. For more information about the matrix inverter, see matrix_inverse in utils.pas. The "lwdaq matrix_inverse" routine is inefficient in its use of the matrix_inverse function. The routine spends most of its time translating between TCL strings and Pascal floating point numbers. A 10x10 matrix inversion with random elements takes 1800 μs on our 1 GHz iBook, of which only 100 μs is spent calculating the inverse. The routine returns the inverse as a string of real numbers, in the same format as the original matrix.

nearest_neighbor

lwdaq nearest_neighbor point ?library?

Finds the closest point to p in a library of points. The point and the members of the library are all points in an n-dimensional space. When we call this routine, we can specify the library with the after the point by passing another string containing the library of m points. If we don't pass the library, the routine uses the library most recently passed. The routine stores the library in a global array so that it can use it again. We pass the point p as a string of n real numbers. The library we pass as a string of m×n real numbers separated by spaces. The value returned by the routine is an integer that specifies the library point that is closest to the p. The first library point we specify with integer 1 (one) and the last with integer m.

spikes_x

lwdaq spikes_x data threshold extent

Returns a list of spikes found by path-finding in a one-dimensional graph array. The values in the array represent the vertical position of a sequence of points in a two-dimensional map, while the horizontal position we construct by arranging the points in sequence with uniform spacing. The height of a map square is one mean absolute step size of the array values. The width of the map squares is the horizontal separation of consecutive points. The routine takes three parameters: data, threshold, and extent. The data is a list of real numbers. The threshold is the minimum size for spikes, in units of mean absolute steps. The extent is the maximum width for spikes. The result of the routine is a list of spikes, each of which is the index of a spike location and the size of the spike in units of mean absolute steps.

lwdaq_config -fsd 2
lwdaq spikes_x "0 0 0 0 2 9 1 0 0 7 0 7 0 9 0 0 0 0" 2 4
5.00 2.46 9.00 2.21 11.00 2.21 13.00 2.72

Above we specify a threshold of two mean absolute steps and an extent of four samples. The one-dimensional coastline of the data is 64 and there are 18 data points, so the mean absolute step size is 3.6. Sample five have value 9. We can step around sample five to sample six, missing out the spike on sample five. So our first spike has location five (5.00). To calculate the size of the first spike, we must convert the height of the spike into units of mean absolute steps, and we use the trailing edge of the spike to measure height, not the leading edge. So we have 9 as the highest point in the spike and 1 as the end of the spike to give us a height of 8 in original units, or 2.2 mean absolute steps. The horizontal distance from the peak to the trailing edge is 1 sample period, so the spike size is sqrt(sqr(2.2)+sqr(1)) = 2.46. The same logic is used to calculate the locations and heights of the remaining three spikes.

straight_line_fit

lwdaq straight_line_fit data

Fits a straight line to data, where data contains a string of numbers, alternating between x and y coordinates. The routine returns a string of three numbers: slope, intercept, and rms residual. The rms residual is the standard deviation of the difference between the straight line and the data, in the y-direction. The data "0 3 1 5 2 7 5 13" would represent a straight line with slope 2, intercept 3, and rms residual 0. The result would be "2.000000 3.000000 0.000000".

sum_sinusoids

lwdaq sum_sinusoids a.amplitude a.phase b.amplitude b.phase

Adds two sinusoidal waves of the same frequency together. You specify the two waves with their amplitude and phase. The phase must be in radians. The amplitude is dimensionless. The result contains the amplitude and phase of the sum of the two waves. If we pass the numbers "1 0 1 0.1" to the routine, it will return "1.997500 0.050000".

tkcolor

lwdaq tkcolor color_value

Returns the Tk color that matches an internal lwdaq color value. The TK color is returned as a string of the form #RRGGBB, where R, G, and B are each hexadecimal digits specifying the intensity of red, blue, and green.

window_function

lwdaq tkcolor color_value

Applies a linear window function to a series of samples. The window function affects the first and last extent samples in data. The window function calculates the average value of the data, and then scales the deviation of the first and last extent samples so that the first sample and the last sample are now equal to the average, while the deviation of the other affected samples increases linearly up to the edge of the affected sample range. The function returns a new data string with the same number of samples, but the first and last samples are guaranteed to be the same. The window function is useful for preparing data for fourier transforms.

lwdaq_config -fsd 2 -fsr 1
lwdaq window_function 5 "0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1"
0.50 0.40 0.30 0.20 0.10 0.00 0.00 0.00 0.00 0.00 1.00 1.00 1.00 1.00 1.00 0.90 0.80 0.70 0.60 0.50 

Here we see a step function being windowed so that the ends are at the average value. Note that we set the fsd (field size decimal) and fsr (field size real) configuration parameters so that we can get the output data all on one line.

wps_calibrate

lwdaq wps_calibrate device_name camera_num data

Calculates calibration constants for a single WPS camera using a data file that contains simultaneous CMM and WPS measurements. We pass the routine a device name and a camera number, followed by a calibration data string containing simultaneous WPS and CMM wire position measurements, and produces as output the WPS calibration constants that minimize the error between the WPS measurement and the CMM measured wire positions. In addition to the data string, we specify a camera number, for there are two cameras that we calibrate separately from the same data file. The input data string has the following format. We begin with the number of wire positions. The next three lines contain the global coordinates of the cone, slot, and flat ball beneath the WPS respectively, in millimeters. Then we have a line for each wire position containing a point on the wire center in millimeters and the direction of center-line as direction cosines, measured by the CMM in global coordinates. Then we have one line for each wire position, each line containing the left and right edge positions and orientations from cameras one and two. Edge positions are the intersection of the edge line with the top of the image sensor, measured in microns from the left edge of the leftmost column of pixels. Rotation is anti-clockwise positive in milliradians. Here is an example string we might pass for the third parameter data.

20
117.6545 83.1886 -17.2954 
44.6755 62.1783 -17.4321 
44.5830 104.1654 -17.2884 
103.9113 129.7997 50.2922 0.99991478 0.00889102 -0.00955959 
103.9431 125.7984 50.2779 0.99991503 0.00886584 -0.00955667 
103.9752 121.8009 50.2638 0.99991493 0.00887295 -0.00956066 
104.0085 117.7957 50.2509 0.99991502 0.00885647 -0.00956690 
104.7553 129.7766 46.4177 0.99991712 0.00873105 -0.00946149 
104.7877 125.7764 46.4037 0.99991722 0.00872038 -0.00946123 
104.8208 121.7746 46.3903 0.99991710 0.00872645 -0.00946834 
104.8535 117.7685 46.3761 0.99991723 0.00870522 -0.00947372 
104.9001 129.7467 42.5693 0.99991896 0.00852873 -0.00945121 
104.9325 125.7481 42.5566 0.99991897 0.00852404 -0.00945529 
104.9657 121.7474 42.5418 0.99991892 0.00851060 -0.00947188 
104.9986 117.7459 42.5285 0.99991894 0.00851125 -0.00946948 
105.7449 129.7706 48.6070 0.99870582 0.00888704 -0.05007694 
105.7773 125.7704 48.5933 0.99870603 0.00887005 -0.05007573 
105.8100 121.7669 48.5790 0.99870583 0.00886387 -0.05008098 
105.8418 117.7689 48.5677 0.99870663 0.00885177 -0.05006708 
104.3525 129.7877 46.2170 0.99785907 0.00839544 0.06485984 
104.3849 125.7855 46.2029 0.99785944 0.00838955 0.06485491 
104.4176 121.7886 46.1882 0.99786037 0.00837783 0.06484209 
104.4507 117.7856 46.1745 0.99786075 0.00837207 0.06483697 
2951.52 2.30 3251.61 1.53 1574.33 -10.06 1855.93 -10.40
2628.52 3.65 2949.11 0.89 1195.81 -9.60 1496.22 -10.05
2259.27 4.29 2602.12 2.89 764.15 -9.43 1086.72 -10.03	
1830.11 3.92 2198.96 3.48 266.00 -9.19 615.70 -9.85
2296.90 3.37 2585.66 3.13 2190.13 -10.10 2481.64 -10.44 
1942.95 3.48 2250.45 3.64 1839.57 -9.90 2150.22 -10.36
1537.64 5.25 1866.49 3.57 1438.10 -9.97 1771.13 -10.24
1069.53 6.08 1425.03 3.66 973.45 -9.54 1333.81 -9.85 
1686.43 4.49 1965.47 4.01 2845.86 -10.59 3150.64 -10.98 
1304.51 5.03 1602.68 3.99 2527.69 -10.61 2851.96 -10.86
868.45 6.43 1188.72 6.00 2162.36 -10.17 2509.00 -10.78
365.94 6.63 713.81 6.46 1736.76 -9.78 2111.33 -10.76
2613.07 -34.08 2907.86 -35.47 1884.75 -46.13 2171.53 -46.92
2274.25 -32.98 2587.70 -34.36 1519.15 -45.14 1824.90 -46.34
1885.62 -31.31 2221.24 -32.91 1100.95 -44.02 1429.15 -45.15
1436.90 -29.43 1798.94 -31.25 618.94 -43.16 974.19 -44.11
2366.01 69.79 2656.40 70.19 2107.85 56.37 2398.42 57.31
2014.31 69.13 2323.28 69.76 1754.36 55.21 2064.15 56.05
1612.63 68.59 1943.68 69.14 1350.65 54.26 1682.41 54.84
1147.92 68.08 1505.81 68.70 883.10 52.90 1242.29 53.82

The output takes the form of a single line of values, which we present here below headings that give the meaning of the values.

------------------------------------------------------------------------------------------------
				pivot (mm)              sensor (mm)            rot (mrad)          pivot-  error
Camera     x      y        z       x      y        z         x        y       z    ccd (mm) (um)
------------------------------------------------------------------------------------------------
C0562_1 -3.5814 88.8400 -4.9796 -12.6389 94.3849 -4.9598 -1558.772  -0.344 -566.827 10.620  1.6

The routine uses the simplex fitting algorithm to minimize the camera calibration error, and while doing so, it writes its intermediate values, and a set of final errors for the pin positions, to the current target of gui_writeln.

wps_wire_plane

lwdaq wps_wire_plane wire_center wire_rotation camera

Calculates the plane that must contain the center-line of a wire given the position and rotation of a wire image in a WPS camera. The units for wire position are millimeters, and for rotation are milliradians. We use the camera's calibration constants to determine the plane. We specify the plane in WPS coordinates, which are defined in the same way as BCAM coordinates, using the positions of the WPS (or BCAM) mounting balls. For a description of the BCAM coordinate system, consult the BCAM User Manual.

lwdaq wps_wire_plane "1.720 1.220" "0.000" "Q0131_1 0 0 0 -10 0 0 0 0 0"
0.000000 0.000000 0.000000 0.000000 0.000000 1.000000

The image position in our example is 1.720 mm from the right and 1.220 mm from the top. This is at the nominal center point of a TC255 image sensor. The wire is rotated by 0 mrad anti-clockwise in the image. The first element in the camera string is the name of the camera, even though this calculation does not use the camera name. In the example above, Q0131_1 is the camera name. It is camera number one on the WPS with serial number Q0131. In this example, the camera pivot point is at (0,0,0) in WPS coordinates, which puts it at the center of the cone ball supporting the WPS. That's clearly impossible, but we're just using simple numbers to illustrate the routine. The center of the image sensor (the CCD) is at (-10,0,0). The x-axis runs directly through the pivot point and the center of the sensor. The rotation of the sensor is (0,0,0), which means the x-axis is perpendicular to the sensor surface. Here is another example.

lwdaq wps_wire_plane "1 1.220" "10.000" "Q0131_1 0 0 0 -10 0 0 0 0 0"
0.000000 0.000000 0.000000 0.071811 0.009974 0.997368

The routine calculates the plane that contains the center of the image and the pivot point. It specifies the plane as the pivot point, which is a point in the plane, and a normal to the plane. The first three numbers in the result are the coordinates of the pivot point. The last three numbers are the normal to the plane. The normal is a unit vector.

xyz_axis_rotate

lwdaq xyz_axis_rotate point axis rotation

Rotate an xyz point about an axis line by an angle in radians.

xyz_cross_product

lwdaq xyz_cross_product vector_a vector_b

The cross product of a first xyz vector with a second xyz vector, as in a X b.

xyz_difference

lwdaq xyz_difference vector_a vector_b

Subtract a second xyz vector from a first xyx vector, as in a - b.

xyz_dot_product

lwdaq xyz_dot_product vector_a vector_b

The dot product of a first xyz vector with a second xyz vector, as in a.b.

xyz_global_from_local_point

lwdaq xyz_global_from_local_point point local

Transforms a point in global coordinates to a point in local coordinates. It is the inverse of xyz_local_from_global_point. We pass it the local coordinates of a point in the point string. We pass it the pose of the local coordinate system in the local string. The routine returns the global coordinates of the point.

lwdaq xyz_global_from_local_point "-10 0 1" "10 0 0 1.570796327 0 0"
0.000000 1.000000 -0.000000

We use bcam_coord_from_mount to obtain the pose of the mount coordinate systems for BCAM-style kinematic mounts.

lwdaq xyz_global_from_local_point "-9.950042 0.000000 -0.998334" "10 0 0 0 0.1 0"
-0.000000 0.000000 0.000000

In the example above, we have the local origin at x=10 in global coordinates. The local axes are rotated by 100 mrad about the global y-axis. Our local point is the one that corresponds to the origin of global coordinates.

xyz_global_from_local_vector

lwdaq xyz_global_from_local_vector vector local

Transforms a vector in local coordinates to a vector in global coordinates. It is the inverse of xyz_local_from_global_vector. We pass the local coordinates of a point in the point string. In the local string we pass the pose the local coordinate system as seen in the global coordinate system.

lwdaq xyz_global_from_local_vector "0 -1 0" "10 0 0 1.570796327 0 0"
0.000000 0.000000 1.000000

The "pose" consists of the xyz-position and xyz-rotation of the local coordinates in global coordinates. The units of angle are radians. The routine returns the local components of the vector.

lwdaq xyz_global_from_local_vector "4.975021 0.000000 0.499167" "10 0 0 0 0.1 0"
5.000000 0.000000 -0.000000

In the example above, we have the local origin at x=10 in global coordinates, but this has no effect upon the resulting vector. The local axes are rotated by 100 mrad about the global y-axis. Our vector is distance 5 in the global x-direction.

xyz_length

lwdaq xyz_length vector

Return the length of an xyz vectors.

xyz_line_line_bridge

lwdaq xyz_line_line_bridge line line

Determines the shortest vector from a one line to another. We specify each line with a point and a direction vector. The direction vector does not have to be a unit vector. We express the link as a point and a vector. We give the point in the first line that is closest to the second, and the vector that connects this point to the point in the second line that is closest to the first. The original two lines must be skewed. Parallel lines will return the origin for a point, and a zero vector.

xyz_line_plane_intersection

lwdaq xyz_line_plane_intersection line plane

Determines the point at which a line and a plane intersect. We specify the line with a point and a direction. We specify the plane with a point and a normal vector.

xyz_local_from_global_point

lwdaq xyz_local_from_global_point point local

Transforms a point in global coordinates to a point in local coordinates. It is the inverse of xyz_global_from_local_point. We pass the local coordinates of a point in the point string. We pass a description of the local coordinate system in the local string. The coordinate description consists of six numbers. The first three are the location in global coordinates of the local origin. The next three are the rotations about the global x, y, and z axes that transform the global axis unit vectors into the local axis unit vectors. The units of angle are radians. The routine returns the local coordinates of the point.

lwdaq xyz_local_from_global_point "0 1 0" "10 0 0 1.570796327 0 0"
-10.000000 -0.000000 -1.000000

We use bcam_coord_from_mount to obtain the pose of the mount coordinate systems of BCAM-style kinematic mounts.

lwdaq xyz_local_from_global_point "0 0 0" "10 0 0 0 0.1 0"
-9.950042 0.000000 -0.998334

In the example above, we have the local origin at x=10 in global coordinates. The local axes are rotated by 100 mrad about the global y-axis.

xyz_local_from_global_vector

lwdaq xyz_local_from_global_vector vector local

Transforms a vector in global coordinates to a vector in local coordinates. The routine takes two strings as parameters. The first is the xyz components of the vector in global coordinates. The second is the pose of the local coordinate system in the global coordinate system. By "pose" we mean the location and orientation of the local coordinates, where the locaion is the xyz-position of its origin in global coordinates and the orientation is the xyz-rotation we apply to the global coordinate axes to obtain the local coordinate axes. An "xyz-rotation" consists of three rotations by three angles about the x, y, and z axes in that order. The units of angle are radians. In the example below, the local coordinate system is at (10,0,0) and we obtain its axes by rotating the global axes by 90° about the x-axis.

lwdaq xyz_local_from_global_vector "0 0 1" "10 0 0 1.570796327 0 0"
0.000000 1.000000 -0.000000

When working with devices that sit on a BCAM-style kinematic mount, we obtain the pose of the sensor's mount coordinate system by passing the global coordinates of their three mounting balls to bcam_coord_from_mount.

lwdaq xyz_local_from_global_vector "5 0 0" "10 0 0 0 0.1 0"
4.975021 0.000000 0.499167

In the example above, we have the local origin at x=10 in global coordinates, but this has no effect upon the resulting vector. The local axes are rotated by 100 mrad about the global y-axis. Our vector is distance 5 in the global x-direction.

xyz_plane_plane_intersection

lwdaq xyz_plane_plane_intersection plane_1 plane_2

Determines the line along which two planes intersect. We specify each plane with a point in the plane and a normal to the plane, making six numbers for each plane.

xyz_point_line_vector

lwdaq xyz_point_line_vector point line

Determines the shortest vector from a point to a line. We specify the point with three coordinates. We specify the line with a point and a direction vector. The direction vector does not have to be a unit vector. The routine returns the three components of the shortest vector.

xyz_rotate

lwdaq xyz_rotate vector rotation

Rotate an xyz vector about the x, y, and z axes in that order by three angles rx, ry, and rz in radians.

xyz_rotation_from_axes

lwdaq xyz_rotation_from_axes x_axis y_axis z_axis

Search for a compound, three-dimensional rotation that produces the specified orthogonal, right-handed coordinate system vectors from the existing x, y, and z unit vectors. The rotation takes the form of three angles by which we rotate about x, y, and z. We pass the routine three vectors parallel to the new coordinate system. The routine returns the three rotations.

xyz_sum

lwdaq xyz_sum vector_a vector_b

Add two xyz vectors together as in a + b.

xyz_unit_vector

lwdaq xyz_unit_vector vector

Take a vector and divide it by its length to obtain a unit vector.

xyz_unrotate

lwdaq xyz_unrotate vector_a vector_b

Rotate an xyz vector about the z, y, z axes in that order by three angles rz, ry, and rx in radians. We specify the angles with three values in the order rx, ry, and rz, opposite to the order in which the angles will be applied to their respective axes, hence the name "unrotate".