Neuroarchiver Tool

© 2008−2010, Kevan Hashemi Open Source Instruments Inc.

Contents

Description
Set-Up
Plots
Files
Channel Selection
Recording
Metadata
Play-Back
Overview
Analysis
Spectrum
Neuroarchiver Script

Description

The Neuroarchiver Tool is a program written in TclTk. It is a tool available in the LWDAQ Software. It is works with the LWDAQ Software's Recorder Instrument and data acquisition hardware such as the Data Receiver (A3018) and collections of Subcutaneous Transmitters (A3013). The Neuroarchiver acquires raw data continuously from the hardware and saves the data to disk. Independently from its data-storage activities, the Neuroarchiver reads raw data from disk, extracts signals from the raw data, displays the signals on the screen, and applies user-defined analysis to the signals.

The Neuroarchiver makes heavy use of disk files. The Recorder portion of the Neuroarchiver acquires data and stores it to disk immediately, without any analysis. The Player portion of the Neuroarchiver reads data from disk and analyses it. Both the Recorder and Player can run simultaneously, so that the Player can be reading data as it becomes available on disk.

To run the Neuroarchiver, download and install the LWDAQ Software for your Linux, Windows, or MacOS computer. Run the program and select the Neuroarchiver from the Tool menu. Before you proceed, however, we recommend you open the Recorder Instrument in the Instrument menu, and learn to use it with the help of the Recorder Instrument Manual. Before you acquire data with the Neuroarchiver from your own hardware, you must set up the Recorder Instrument to be the source of data. You are welcome to use the Recorder Instrument's default settings, which will acquire raw data from our demonstration hardware.


Figure: Neuroarchiver Tool on MacOS. The Recorder is recording data to disk. The Player is playing back data from another file. The Player can also read data from the recording file as the data becomes available. The Recorder controls are above the signal plots. The Player controls are below the plots. The analysis controls are just above the text window.

The Configure button opens an array of configuration parameters. The Help button offers some basic help. All the Browse buttons allow you to select the directory or file in a nearby text entry box.

In the figure above, the Recorder portion of the Neuroarchiver is downloading data in half-second intervals and storing them to an archive file whose name appears to the right of the Archive label. The Recorder state is Record. A yellow background means the Recorder is waiting for data. A white background means the Recorder is waiting for the Player to finish its analysis. Every 3600 seconds the Recorder will produce a new archive file. The archive files are in the NDF (Neuroscience Data Format) we describe here.

Meanwhile, the Player portion of the Neuroarchiver is reading from a different archive, which contains data from four Subcutaneous Transmitters (A3013A) implanted in live rats. The signals versus time are in the left plot. Amplitude versus frequency is in the right plot. The Player state is Play. A white background means the Player is waiting for the Recorder to finish acquiring data. A green background means that the Player is analyzing messages. If the background is yellow, the Player is waiting from data to be added to its archive. The Player will be waiting regularly if it is playing the same file to which the Recorder is writing new data. When the yellow background appears behind the Recorder state, the Recorder is waiting for data from the Recorder Instrument, which is in turn waiting for data from the data acquisition hardware. When the orange background appears, the Player is navigating through an existing archive file.

The Player displays channels seclected by the channel select string. In our example, the channel select string is "*", which selects all active channels in the time interval being displayed. We discuss channel selection in more detail below. All active channels are listed in the Channel Activity string, which gives the channel numbers and the number of messages received from each channel during the playback interval.

Set-Up

Here is how you start recording and simultaneous play-back with the Neuroarchiver. The Neuroarchiver uses the Recorder Instrument to acquire new data, so the first steps are to set up the Recorder Instrument to point to your Data Receiver (such as the A3018).

  1. Start LWDAQ
  2. Open the Recorder Instrument from the Instrument Menu.
  3. Set the Recorder Instrument's daq_ip_addr and daq_driver_socket to point to your data recorder.
  4. Press Acquire to see if you can get some data.
  5. Press Reset and then Loop. You are now acquiring live data from the data recorder. Look at the signals displayed in the Recorder Panel. Make sure that you have the correct set of transmitters turned on, and that they are all working. When you are satisfied, press Stop.
  6. Close the Recorder Panel.
  7. Open the Neuroarchiver Instrument from the Tool Menu.
  8. Select a Neuaroarchiver Directory and create a new archive with the Create button.
  9. Press Reset. The Recorder state indicator should turn red for a moment.
  10. Press Record. You should see the Recorder state indicator flashing yellow.
  11. With the Browse button in the Player section of the Neuroarchiver Panel, select your new archive.
  12. Press Play. You should see the Player state indicator flashing green, and after a while it will start flashing yellow as well.

Look at your data recorder. The EMPTY light should be flashing regularly. If it is not flashing, your Neuroarchiver is not acquiring data as fast as the data is being recorded. This failure to keep up with the pace of recording may be due to your network connection being too slow to transport the data as it is created.

Once you get the recording and play-back working, you can try out various values of recording interval and play-back interval. For the most stable operation with up-to date signal display, the recording interval should be half the play-back interval. In stable operation, the Player is waiting for the Recorder to save data to disk. When the data is available, the Player displays it. While it waits, the Player state indicator is yellow.

You can look through previously-recorded archives even while you are recording a new archive. Stop the simultaneous playback and select a new archive. If you want to see an overview of an entire archive, select it in the Player and press the Overview button.

Plots

The two plots are drawn during playback of recorded data. Each plot has its own Enable check-box. Plotting can slow down play-back. Disable the plots by un-checking their enable check-boxes. Play-back will speed up.

The Value versus Time graph, which is on the left of the Neuroarchiver panel, shows signal voltage variation during the most recent playback interval. In the example display we see four traces. This plot is identical to the one generated by the Recorder Instrument. The traces are color-coded. For a table of channel numbers and their colors, see the Message Display section of the Recorder Instrument Manual, or this picture. The vertical axis is voltage, measured in ADC counts. Each transmitter converts its analog input into a sixteen-bit value. Sixteen-bit values run from 0 to 65535. In the example, the plot spans the range 0 to 65535. The bottom of the range is zero because the value of v_offset is 0. The top of the range is 65535 counts above the bottom because v_range is 65535. To convert between ADC counts and voltage at the transmitter input, consult the transmitter manual.

Example: The A3013A transmitter manual has a section called Analog Inputs. Here you will find that the gain of the transmitter from analog input to the ADC is 300. The voltage range 0 to 65535 corresponds to voltages 0 V to VBAT at the ADC input. For most of a transmitter's operating life, VBAT is 2.7 V, so each ADC count is 140 nV at the X input. The amplifier AC-couples the X input, placing its average value at 1.8 V. The dynamic range for signals at X is −6 mV to +3 mV. We can deduce the battery voltage, VBAT by looking at the average value of the signal in the plot. If A is the average value of X as a fraction of 65535, we have VBAT = 1.8 V / A. From the signal present in archive M1259065886.ndf, we estimate A is 0.64 for channels No1 and No2, 0.70 for channel No14, and 0.8 for channel No6. This implies VBAT of 2.8 V for No1 and No2, 2.6 V for No14, and only 2.2 V for No6. You can compare these voltages to this graph to estimate how much more operating life each transmitter has left.

The horizontal axis in the Value Versus Time graph is time. The full range from left to right covers the most recent playback interval. This interval is shown in the Interval selector beneath the graphs.

We can obtain a close-up of fluctuations in the analog signal by entering AC for v_coupling and changing v_range to a smaller value. With AC coupling, the Neuroarchiver places the average value of the signal half-way up the display.

The right-hand graph is the discrete fourier transform of the signals on the left-hand graph. The Player takes the discrete fourier transform of the interval data for each channel. It calculates all terms in the transform and plots those between f_min to f_max. The discrete fourier transform dictates frequency step from one discrete component to the next. We have f_step = 1/p, where p is the play interval. The transform amplitude range is zero to a_range in ADC counts.

Example: In the example plot, the amplitude range is 1000 counts. Each vertical division is 100 counts. We set f_min to 0 Hz and f_max to 256 Hz so that we can see the entire discrete fourier transform of the 512 samples taken in the 1-s play interval. The frequency step is 1 s because the play interval is 1 s. If we switch the play interval to 4 s, the Neuroarchiver will set the frequency step to 0.25 s.

If you set the range of the frequency plot outside the range zero to one half the sampling frequency, the spectrum will be blank.

Files

The Neuroarchiver works with NDF (Neuroscience Data Format) files. An NDF file contains a header, metadata string, and a data block to which we can append at any time without writing to the header or the data string (although the Neuroarchiver almost always writes to the metadata string whenever it adds data to a file). We define and describe the NDF image format in the Image Format section of the LWDAQ Manual. The Neuroarchiver manipulates these with a library of NDF-handling routines provided by LWDAQ. We list these routines below. These routines are declared in LWDAQ's Utils.tcl script, and you will find them described in the LWDAQ Command Reference. Their names begin with LWDAQ_ndf.

The Neuroarchiver works within a single directory, as named in the Directory entry box on the top of the Neuroarchiver Panel. All NDF archives, analyzer scripts, and results files must be contained in this same directory. If you attempt to use or specify a file outside the Neuroarchiver's directory, it will refuse and print a red error in its text window.

The Neuroarchiver's Player will roll over from one file to the next as the Recorder creates a new file automatically. Each data file is named with in the form "Mxxxxxxxxxx.ndf", where the ten x's are an integer giving the number of seconds since 1900 hours on 31st December, 1969. This number is the standard UNIX timestamp. From the name of each file, we can determine the time, to within a second, at which its first clock message occured. From there we can count clock messages and determine the time at which any other part of the data occured.

Channel Selection

The data processed by the Neuroarchiver takes the form of a list of data recorder messages, as we describe here. In general, the data will contain values from one or more channels. The Neuroarchiver selects which channels to display, transform, and store to disk using its channel_select parameter.

In its simplest form, channel_select is a single "*" character. With channel_select set to "*", the Neuroarchiver looks through the playback interval data and counts how many messages it contains from each of the 16 possible subcutaneous transmitter channels: No0 through No15. Of these, No0 is the clock message channel and No15 is the slow data channel. Transmitters like the A3013A use the fast data channels, No1 through No14. If a channel contains more than activity_threshold messages, the Neuroarchiver considers it active. It plots all active channels and lists them in the Channel Activity string in the format id:qty, where id is the channel number and qty is the number of messages. You will find the activity_threshold parameter in the configuration array (press Configure).

You can select particular channels with a specific channel_select string. You could enter "1 2 6 14" and the Neuroarchiver will attempt to display these channels, even if they have very few messages. You can specify the nominal sampling frequency and scatter extent for each channel. For a description of sampling frequency and scatter extent, see Analysis section of the Recorder Instrument Manual. If you list the channel numbers on their own, the Neuroarchiver assumes a the frequency and scatter given by default_frequency and default_scatter. You specify channel number, frequency, and scatter with three numbers in the form c:f:s. Thus "5:512:8" means channel 5 with sampling frequency 512 SPS and scatter extent 8.

The sampling frequency and scatter extent are used by the Neuroarchiver when it reconstructs an incoming message stream. The Neuroarchiver uses its clocks_per_second and ticks_per_clock parameter to convert samples per second into a sample period in units of data recorder clock ticks. The Neuroarchiver can then go through a channel's messages and identify places where messages are missing, and eliminate bad messages that occur in the message stream at random times.

By default, the Neuroarchiver applies reconstruction to all data during play-back. But you can disable the reconstruction by setting enable_reconstruct to zero in the configuration array. You may wish to disable reconstruction so you can get a better look at bad messages and other reception problems.

Recording

The Neuroarchiver uses the Recorder Instrument to obtain live data. First you set up the Recorder Instrument to read out streams of messages from a data-recording device, then you open the Neuroarchiver to store the live data. The Neuroarchiver does not display new data until after it has been stored to disk, so display and analysis are not part of data acquisition.

To capture live data, open the Recorder Instrument and configure it to read your data out of your data recorder. The Neuroarchiver will simply call the Recorder Instrument's data acquisition procedure when it captures new live data. You don't have to leave the Recorder Panel open after you set it up for data Recording, but you can leave it open if you like. By default, the Neuroarchiver turns off the Recorder Instrument's plotting and analysis of the incoming data. But you can turn on the plotting and analysis by setting enable_recorder_analysis to 1 in the Neuroarchiver's configuration panel, which you can open with the Configure button. With the plots turned off, you will see the raw data displayed as gray-scale pixels in the Recorder Instrument.

The only thing that passes from the Recorder Instrument to the Neuroarchiver is the raw data acquired from the data acquisition hardware. The Recorder Instrument has a data acquisition parameter called daq_num_clocks. When you instruct the Recorder Instrument to acquire new data, it acquires a block of messages with exactly this number of clocks. The Recorder Instrument makes sure that first message in the block is always a clock message. The Neuroarchiver calculates daq_num_clocks from record_interval, which has units of seconds. In the example shown above, the recording time interval is 0.5 s, and is shown in the menu-button to the right of the Recorder controls.

As the Recorder saves data to a file, it also adds timestamp fields to the file's metadata string. We discuss timestamps and metadata below. You can view the recording file's metadata with the recorer's Metadata button.

Metadata

The NDF format contains a header, a metadata string, and a data block. Transmitter messages and clock messages are stored by the Recorder in the data block. New data is appended to the data block without any alteration of existing data. The metadata string has a fixed space allocated to it in the file, but is itself of variable length, being null-terminated. The Neuroarchiver makes use of the metadata string in three ways.

  1. Creation time and program version comments.
  2. Timestamps that aid in play-back.
  3. User-entered comments.
  4. Channel marks.

When the Recorder creates a new file, the metadata contains two comments. These fields are delimited by xml "c" tags.


<c>Date Created: Wed Nov 25 21:23:21 2009.</c>
<c>Creator: Neuroarchiver 37, LWDAQ_7.3.8.</c>

You can view, edit, and save the metadata for the recording file with the Metadata button in the Recorder section of the Neuroarchiver. You can do the same for the metadata in the playback file with the Player Metadata button. Users can enter their own comments in fields delimited by "c" tags.

A timestamp contains two numbers and is delimited by "t" tags. The first number is time in seconds. The second number is the index of the clock message that occured at that time after the first clock message in the file. The timestamp "t n" means that the clock message t seconds after the start of the archive is the n'th message in the archive.


<t>0 0</t>
<t>19.0 40575</t>
<t>28.0 58843</t>

Timestamps accelerate navigation through an archive. In the Player, we can jump to a new location in a file by entering a value in the Time box and pressing Step. The Neuroarchiver uses timestamps to get close to the requested time. Timestamps make the Overview button possible. Without timestamps, the Neuroarchiver does not bother to try to create an overview of an entire data file.

Files created by Neuroarchiver Version 35 and earlier contained no timestamps. You can generate new timestamps for a file with the New Timestamps button in any metadata viewing window. Generating new timestamps takes roughly a minute for every hour of data recorded.

The Recorder stores a new timestamp every time it writs a new block of data to disk. After a while, the timestamps, combined with all other fields, take up more than half the metadata space. The Recorder condenses the timestamp list by deleting every other timestamp and adds its new timestamp to the end of the list. The Recorder alters only the timestamps in the metadata string. All other fields will remain intact.

Channel marks are delimited by "m" tags. A channel mark has the form "t c "s"", where t is time since the start of the archive, c is a channel number, and s is a description string. The Overview button displays and prints out all a file's markers in its archive overview.


<m>1254.0 1 "possible seizure"</m>
<m>1258.0 1 "possible seizure"</m>
<m>1262.0 1 "possible seizure"</m>
<m>1266.0 1 "possible seizure"</m>

There are two ways to channel marks to the metadata. One is to insert them by hand using the metadata editor, which you obtain with the Metadata button. You can delete individual channel marks with keystrokes, or you can delete them all with the Clear Marks button. After you insert and delete marks, press the Save button to over-write the previous metadata string in the archive.

You can insert marks automatically from and analyzer script using the Neuroarchiver_analyzer_mark command. You pass a description of the mark to Neuroarchiver_analyzer_mark, and the routine marks the metadata for the current channel and the current play-time. The command is active only when the Marking checkbox is ticked. The Marking checkbox helps us avoid double-marking an archive in the metadata string. The Jump_to_Mark button allows you to jump to the next marker time after the current play time. When you press Jump_to_Mark, the Player disables marking by the Analysis script until you check the Marking box yourself.

Play-Back

The Neuroarchiver performs all its signal processing, plotting, and analysis when it reads data from disk. Both plots have their own enabling checkboxes because plotting is computationally intensive and yet not always necessary for signal analysis. If you want the Neuroarchiver to analyze archives with an analysis script and save the results to disk, you can accelerate the analysis by turning off both displays.

If you check the Verbose box on the Neuroarchiver, the Player will report on its reading and analysis of data. You will see the loss in each channel, and the results of reconstruction and extraction of message from the playback interval's data. In the example display, you can see the Player telling us that it extracted two channels and reconstructed the other two.

You can navigate through archives by entering a new Time value and pressing Step. You will see the end time of the archive, which is the archive length in terms of the number of clock messages it contains, on the far right of the Player. If the archive has timestamps in its metadata, moving through the file will be fast. Otherwise, movement is slow. Try pressing Metadata and then New Timestsamps. Wait until you see the new timestamps appear and press Save. Now movement will be faster. The Back button steps back one playback interval. The Jump_to_Mark button jumps to the next channel mark listed in the metadata. When you press Jump_to_Mark, the Player disables marking by the analysis.

Overview

The Overview button opens the Player archive and creates a condensed view of its entire contents. The overview opens in a separate window and takes a few seconds to appear. The Neuroarchiver goes through the list of timestamp fields in the file's metadata and reads a small segment of data from the file at each moment specified in the timestamps. It finds the messages for each channel in this segment and adds them to a separate graph for each channel.

The overview shows the location of all channel marks from the file's metadata. Each mark appears as a vertical line in the channel color at the mark location. It prints the mark times and descriptions to its own text window.


Figure: File Overview. The active channels are listed below, with their color codes. The channel marks are drawn as vertical lines and printed below the plot.

The overview plot will follow the settings given in the Player for the Value vs. Time plot. It will include all channels that contain at least activity_threshold messages in the entire data block. You can leave the overview windows open and select a new playback archive for a new overview. Thus you can compare multiple overviews on the screen.

Analysis

In each playback step, the Neuroarchiver goes through each channel selected by channel_select and performs reconstruction, transformation, and analysis. The analysis is optional. We enable analysis with enable_analyze, which we can adjust with a checkbox in the Neuroarchiver window. The anlysis reads the file named by analyzer_file. This file must contain a TclTk script. The Neuroarchiver attempts to execute this script. If it encounters an error, it reports the error to the screen.

The analyzer script has access to the Neuroarchiver's configuration and information arrays with the construction config(element_name) and info(element_name) respectively. The configuration parameters are ones the user is free to modify. The info parameters are ones the Neuroarchiver sets automatically. The analysis script also has access to several temporary variables. We list some of the most useful variables in the following table.

VariableContents
num_clocksThe number of clock messages in the current playback interval
resultThe analysis results string, appended to the results file
config(results_file)File to which result string will be appended
config(play_file)The NDF archive being played back
config(play_time)Seconds from archive start to interval start
config(enable_vt)Voltage-time display is enabled
config(analyzer_file)The analysis script file
config(channel_select)The channel-selection string, if * then all channels chosen
config(play_interval)The playback interval in seconds
info(channel_num)The number of the channel just reconstructed and transformed
info(num_received)The number of messages received in this channel during this interval
info(num_messages)The number of messages in the reconstructed signal
info(signal)The reconstructed signal at sequence of timestamps and values
info(spectrum)The transform as sequence of amplitudes and phases
info(f_step)The separation in Hertz of the transform components, equal 1/play_interval
Table: Variables Useful to Analysis Scripts. The names are given as they must be quoted in an analysis script.

Other elements of the configuration array you can find by pressing the Configure button in the Neuroarchiver window. Each is available with config(element_name) in the analysis script. The information array elements you will have to seek out at the top of the Neuroarchiver script itself, where each is described in the comments.

If you select four channels for play-back, the analysis script will be called four times. Each time the Neuroarchiver calls the script, all variables that are specific to individual channels, such as num_received, signal and spectrum, will be set for the current channel. We obtain the current channel number through the channel_num parameter.

The first time the analysis is called, the results string is empty. Each call to the analysis should append some more values to the result string. After the final call to the analysis script, if the Neuroarchiver sees that $result is not an empty string, it appends $result to the results_file. Thus the results of analysis are accummulated in a text file for further analysis by some other program or process.

The following script records the number of messages received from each channel. This allows us to plot message reception versus time by importing the results file into a spreadsheet. Note how we detect the first call to anlaysis by noting that the result string will at that time be empty, and so we can begin our result line with the name of the file being played back, the number of seconds from the start of the file, and the number of clocks in the play interval. These three pieces of information apply equally to all channels, so we include them only once, at the start of the line.


if {$result == ""} {
	set result "$config(play_file) $config(play_time) $num_clocks "
}
append result "$info(channel_num) $info(num_received) "

Because the script is TclTk, it can do just about anything that TclTk can do. In theory, it can e-mail the finished result string to you, or upload it over the network to a server.

The reconstructed signal is available in $info(signal). The signal takes the form of a sequence of numbers separated by spaces. Each pair of numbers is the time and value of the signal. The time is in clock ticks from the start of the playback interval. The value is in sixteen-bit ADC counts. The timestamps are twenty-four bit numbers that give the number of data receiver ticks since the start of the playback interval. A twenty-four bit number is up to 16.8 million, and the tick frequency in the A3018 data receiver is 32.768 kHz. The maximum interval we can cover with these timestamps is 512 seconds. We usually specify intervals between 0.1 and 10 s. The sample values are sixteen-bit un-signed numbers.

The discrete fourier transform of the signal is available in $info(spectrum). The spectrum is a sequence of numbers separated by spaces. Each pair of numbers is an amplitude and a phase. The pairs are numbered 0 to n−1, where n is the number of samples in the signal, available in num_messages. The k'th pair of numbers describes the frequency component with frequency k×f_step. The amplitude is in sixteen-bit ADC counts and the phase is in radians.

The following analysis script calculates the total signal power in the 2−160 Hz frequency range, and appends the channel number and the power measurement to the result string. If the voltage-time plot is enabled, the analysis continues by plotting the 2−160 Hz band-pass filtered signal on the screen. It obtains the band-pass filtered signal by copying the original fourier transform, setting the components outside 2−160 Hz to zero, and obtaining the inverse transform.


if {$result == ""} {
	set result "$config(play_file) $config(play_time) "
}

set band_lo 2
set band_hi 160
set band_power 0.0
set f 0
foreach {a p} $info(spectrum) {
	if {($f >= $band_lo) && ($f <= $band_hi)} {
		set band_power [expr $band_power + ($a * $a)]
		incr count
	}
	set f [expr $f + $config(f_step)]
}

append result "$id $info(num_received) [format %.1f $band_power] "

if {$config(enable_vt)} {
	set new_spectrum ""
	set f 0
	foreach {a p} $info(spectrum) {
		if {($f >= $band_lo) && ($f <= $band_hi)} {
			append new_spectrum "$a $p "
		} {
			append new_spectrum "0 0 "
		}
		set f [expr $f + $config(f_step)]
	}
	set new_values [lwdaq_fft $new_spectrum -inverse 1]
	set new_signal ""
	set timestamp 0
	foreach {v} $new_values {
		append new_signal "$timestamp $v "
		incr timestamp
	}
	Neuroarchiver_plot_signal [expr $id + 32] $new_signal
}

The mean square value of the filtered signal is equal to the total power we obtain by adding together the squared fourier components. If the frequency band does not include zero, the filtered signal will have average value zero, because its zero-frequency, or DC, component has been removed. In order to see the filtered signal overlayed upon the original signal, we must use AC coupling in the display. The Neuroarchiver_band_power command does most of the work in the above code for you, and a bit more. The routine makes sure that the DC component of the filtered signal is included before plotting, so the filtered signal is always overlayed upon the original signal in the display.


if {$result == ""} {
	set result "$config(play_file) $config(play_time) "
}
set event_power [Neuroarchiver_band_power 3.0 30.0 $config(enable_vt)]
set transient_power [Neuroarchiver_band_power 0.2 2.0 0]
append result "$info(channel_num) \
	[format %.2f [expr 0.001*$event_power]] \
	[format %.2f [expr 0.001*$transient_power]]"

You will find Neuroarchiver_band_power defined in the Neuroarchiver script. The procedure takes three parameters: the low frequency, the high frequency, and a boolean flag to say whether or not we want the filtered signal plotted on the screen. The frequencies are in Herzt. The flag is 0 or 1. In our example, we plot the band 3.0×30.0 Hz on the screen only if the voltage-time display is enabled. The result string shows the power in both the 3.0-30.0 Hz and the 0.2-2.0 Hz bands. Power in the first band is associated with epileptic seizures. Power in the second band is a feature of step-like changes. One way to detect epileptic seizures is to look for power in the event band while there is far less power in the transient band.

Spectrum

We calculate the spectrum of each channel signal using the lwdaq_fft routine, which is available to you at the LWDAQ command line. The lwdaq_fft routine takes the sequence of sample values produced by reconstruction and returns the complete discrete fourier transform. If we pass N terms to the transform, we get N/2 terms back.

The routine insists upon a number of samples that is an exact power of two. So we can pass it 16, 32, 256, 512, or 1024 samples. Otherwise the outine gives us an error. Signal reconstruction ensures that we have a suitable number of samples. If you turn off reconstruction by setting enable_reconstruct to zero, the Neuroarchiver adds or subtracts samples to or from the signal so as to satisfy the fourier transform's requirements.

When a signal's end value differs greatly from its start value, the fourier transform sees a sharp step at the end of what it assumes is a periodic function represented by the signal interval. Such a step generates power at all frequencies of the spectrum, rendering the spectrum less useful for detecting events such as epileptic seizures. The Neuroarchiver applies a window function to the signal before it applies the fourier transform. The window_extent element in the Neuroarchiver's configuration array gives the fraction of the signal that should be subject to the window-function at the start and at the end of the sequence of available samples. We like to use window_extent 0.05 for EEG signals. The window function is provided as an option in the lwdaq_fft routine.

Data from transmitters like the A3013 will occasionally contain bad messages. Signal reconstruction attempts to eliminate these messages, and almost always succeeds in doing so, but we find that we still get several bad messages per hour on each signal channel. These appears as spikes, or glitches, in the data. The Neuroarchiver can eliminate almost all of these bad messages with a glitch filter, which is provided as an option by lwdaq_fft. The glitch_threshold element in the configuration array specifies a threshold for glitch recognition. Any sample that differs by more than glitch_threshold from the previous sample will be over-written by the previous sample. This algorithm works well unless the first sample in the interval is itself a bad message, in which case the entire interval will most likely be over-written by the bad message value. With glitch_threshold = 10000, we observed several glitches per hour from implanted A3013A transmitters, each lasting one or two samples. With 4-s intervals each containing 2048 samples, we expect to lose one 4-s interval because of a poorly-placed glitch once every two thousand hours, which is less than 4 s of lost data during the operating life of the transmitter.

The following graphs show how the power in frequency range 2−160 Hz, as recorded from four implanted A3013A transmitters, varies as we apply the window function and the glitch filter. Our data is M1262395837 (recorded Sat Jan 2 01:30:37 2010), with active channels 1, 2, 3, and 7. We measured the power with an Analyzer script, and recorded the power to a file. Our play interval was 4 s.


Figure: Power in the 2−160 Hz Range. No window function applied, no glitch filter. We see power spikes from glitches and from steps, as well as the power rise due to a genuine seizure in channel No1.

We now applied window_extent = 0.05 and recorded power again.


Figure: Power in the 2−160 Hz Range. Window function with extent 0.05, so that 100 samples at the start and end of the signal were smoothed into the average signal value, leaving no step from start to end. We disabled the glitch filter.

Now we applied glitch_threshold = 10000 (ten thousand) and recorded power again.


Figure: Power in the 2−160 Hz Range. We used window function extent 0.2 and glitch filter threshold 10,000.

In the final graph, the seizure on channel No1 stands out more. But we still have several events in the hour-long period that require investigation. These turn out to be real steps in the signal, perhaps associated with electrode problems. The following graph shows the signal from No3 at time 2200 s, which shows power 13000 counts sq.


Figure: 4-s Interval of Channel No3 at 2200 s. This signal passes through the window function and the glitch filter, and still produces high power in the 2−160 Hz band. The orange trace is the original signal. The blue trace is the inverse-transform after removing components outside the 2−160 Hz band.

We believe the above plot represents something other than a seizure. On channel No1, we see a sustained seizure starting at time 1250 s. Here is a fragment of the seizure.


Figure: 1-s Interval of Channel No1 at 1250 s. Green is the original signal, purple is the inverse-transform signal.

You will find our work on detecting seizures with the help of the spectrum in Neuroarchiver Experiments.

Neuroarchiver Script

The Neuroarchiver Script is the TclTk program that defines the Neuroarchiver process. The name of the file is Neuroarchiver.tcl, and you will find it in the Tools directory of your LWDAQ distribution. We have added extensive comments to the script. We intend these comments to act as an introduction to TCLTK and LWDAQ programming.