DreamMon MEG Analysis Tools

Welcome to the documentation page on DreamMon project. You can browse it online or get dreammon.pdf, dreammon.ps or dreammon.info if you want to print it or watch from your favorite emacs's info.


Node:Top, Next:, Previous:(dir), Up:(dir)

Table of Contents


Node:Overview, Previous:Top, Up:Top

Overview

The DreamMon software suite is designed for the analysis and visualization of brain imaging data at the single-trial level using blind source separation and other advanced signal processing technique. Although designed for magnetoencephalography (MEG), it has proven flexible enough to be applied to EEG and other sorts of neuroscience data.

DreamMon is organized as an incoherent set of idiosyncratic programs.

The software is in a pre-alpha state, but we use it to produce lots of scientific papers anyway.


Node:Programs, Up:Top

Programs

This chapter describes some tricky aspects of running existing software. Necessity of such chapter occurs because of variety of command line parameters and switches present in many programs.

To get more profound information on command line parameters just run that program with -help.


Node:megtool, Up:Programs

megtool - main tool to access MEG data

Overview

megtool is developed to get low-level access to raw MEG data files. Next features list describes functionality of megtool. Features are mentioned in order in which they're done in megtool (So separating is applied before filtering)

Usage

This section gives examples of various ways to use the megtool program, especially tricky or unusual ways.

The -window option indices the "window of interest" around the lock event. However, the "before" and "after" lengths in the window may be negative. So for instance to define the window of interest to be the period from 20 to 35 samples following the lock, use -window -20,35

The -dump-means f option averages across trials. The output is a simple time series. It may be worth mentioning that, if the window of interest around a trial would extend outside the data file (eg before t=0) that missing data is not included in the mean.

 megtool -data 12 -dump-means foo.txt -window 0,100 -lock 2 \
         /home/neuro/megdata/ta/ta_trump_raw.raw

That example is stripped down, as it does not include options for getting sources instead of sensors, ie -W-file W -sources 122

The -response f switch finds the first point in each trial's window to exceed a threshold. The threshold MUST be supplied, using the "-response-threshold v" option. To find the first value below some threshold, start the threshold with a "+", as below.

The file output has one line for each trial in which a response was found. (Rejected trials are not included.) Each line has format described in see responses.

EXAMPLES:

find responses above 75,

megtool -data 12 -window 0,100 -lock 2 -response bar.txt \
   -response-thre 75  /home/neuro/megdata/ta/ta_trump_raw.raw

find responses below 53,

megtool -data 12 -window 0,100 -lock 2 -response baz.txt \
    -response-thre +53  /home/neuro/megdata/ta/ta_trump_raw.raw


Node:braintw, Up:Programs

braintw - Probabilistic word typing

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED


The Braintypewriter project at the Brain and Computation Lab

                           August, 2001

Overview:


Dependencies:
    dict-web1913 (copy web1913.index to directory of installation)
    > SDL-1.2
    SDL_image
    > freetype-2.0 (all available in debian package formt)
    additional fonts

Controls:

    Joystick left and right to scroll to the left or right of the
    letter row.  By default, '#' is the termination character
    and '<' is the backspace character.

    By default, button 1 increases shrinking speed, button 2 decreases
    the speed and button 4 exits the program.

Detailed command-line options:

    -h           The help message.

    -s num       Shrink speed. num is a float that specifies
		 for what percentage of the whole screen does the
		 focus area shrink every event loop. Default value is
                 0.001.

    -b           Name of the background image file

    -c           Clear the joystick event buffer so the program does
                 not abort prematurely.

    -f fn        Load color definitions of some or all letters from
		 file f.  See sample config file 'colorconfig' for
                 detailed syntax.

    -t 'c'       Specifies char c as the termination character to use
                 in the letter window. c must appear in quotes.

    -a 'c'       Specifies c as backspace character to use.

    -d num       Specifies the window sliding speed when a letter is
                 picked and we need to shift subwindows up to the top
		 row. i is an integer value. The bigger the value, the
		 faster and less smoother the windows slide. The
                 default value is 10.

    -w num       Specifies the window width in number of pixels. Default
                 value is 1280.

    -e num       Specifies the window height. Default value is 1024.

    -x num       Controls the speed at which the application runs. It
                 basically controls the shrink speed. Default value is 4.

    -k           Show special effects. When enabled, the program will
                 gradually zoom into child rows when they become
		 visible.  The special effect is here to minimize
		 interference with the experiment results.

How to run a close-loop live test with braintypewriter:

    The setup that is tested to work in the lab is to have 2 machines,
    one dedicated to braintypewriter, the other to
    sniffer+joycontrol. Remember that sniffer and joycontrol must be
    run on the same host to eliminate the network overhead.

    The following outlines the operation to be carried out in
    order.

  1.  Hook up the video output on machine 1 to the projector in MEG
      chamber.

  2.  On machine 1:
      Run ./braintw

  3.  On machine 2
      Run joycontrol:
      meg/control/scripts/run-sniffer-version
      The '-G' option in the script tells which host braintypewriter
      is running on. It also accepts an IP address.

  4.  <wait 5 seconds for joycontrol to initialize>

  5.  Run sniffit as root:
      ./sniffit -s blood -x -B 10 -v -D -C [-L] [-A n]
      The '-s' option specifies packets from this particular host are
      to be sniffed. In live test, 'blood' should be replaced by the
      MEG server.  '-C' has to be used to tell sniffer to check for
      the start of transmission. '-L' will tell sniffer to terminate
      when the termination string is met.  '-A n' activates the thread
      to report statistics at n seconds' intervals.

  6.  Now start the acquisition software to receive data from MEG
      machine.  You should see some movement on the braintypewriter
      screen.  If you use the verbose mode in sniffer, it will print
      "starting logging" when it sniffed data coming from the MEG
      server. Otherwise, you can tell sniffer is not working.

Files:

    colorconfig  A sample color definition file.


Node:cntxtica, Up:Programs

cntxtica - Contextual ICA

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED


# CVS version control block - do not edit manually
#  $RCSfile: README,v $
#  $Revision: 1.2 $
#  $Date: 2000/10/20 09:00:02 $
#  $Source: /home/cvs/meg/cntxtica_s/README,v $

Cntxtica (which stands for contextual independent components analysis for those
of you who are wondering) is a source-separation program. It is currently in
a functional, but extremely slow state.

Here are the possible command line options:

	   -help               this one is a little obvious....

	   -debug n            level of debugging.  This outputs
			       debugging messages to STDOUT.  It can
			       be any number 0-5, 5 being the highest
			       level of debugging output; 0 being the
 			       lowest.  It defaults to 0 (no debug output)

	  -generate-data       generate data internally (for testing purposes)

	 -test-gradient        calculate test gradient

         -use_stdin            take input from stdin.  A really poor
			       way to do this...on a TODO list to fix

	 -binary               binary data (default: ascii).  This one
			       is a little fussy.  At the moment, it
			       only takes binary data arranged in floats
			       (no .raw files).

	 -Nsens n              number of sensors.  Will default to 122

         -Msourc n             number of sources.  Will also default to 122.

	 -Tback n              depth of time dependency. defaults to 3

	 -Nouter n             number of outer iterations.  Defaults to 200
			       probably excessive, but not by too much

	 -Logistic_dens        Use logistic density function. This is not
			       actually functioning; I just put it there
			       to make me look good.

         -eta x                Learning rate (default: 1e-4)

	 -ReadTime n          sample size to read. defaults to 40000

	 -TotTime n           sample size for computation. defaults to
			      being equal to ReadTime

	 -Lsubsets n          Number of subsets in data. defaults to 1

	 -write_debug         Output the state of the seperation, including
			      the regression coefficients for each source

SO-to run it on a typical MEG file, foo.raw, that has about 120000 samples,
you would write

$ megtool -chunk 120000 -data-range 122 -dump_channel - foo.raw | cntxtica
  -ReadTime 120000 -use_stdin -Tback 50

Setting Tback to 50 is a somewhat arbitrary number; it should be much more than
the default (3), but how much is up to you.


Node:control, Up:Programs

control - Control suite

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED

Instructions on how to operate control project demonstration.

Introduction:
	This file has two parts: the first describes how to run the
control software suite, the second describes how to write schemes to
control particle movement.

Part 1 (how to run the control suite):
	The control suite is centered around the application
joy-control which acts as a client to any program that supplies
"channel" information.  Currently this information must be in 16 bit
integer format.  Right now there are three ways to serve the client
joy-control: using create-mouse-fifo, create-alpha-fifo, and sniffer.

	Since joy-control is the client you must run it first.  This
is done by executing a script file from the meg/control/scripts
directory.  The script file contains all necessary command line
switches for joy-control which are specified in detail via the
./joy-control --help command.

	1. Using create-mouse-fifo: Once you are running a joy-control
script in one terminal execute the command ./create-mouse-fifo in a
separate terminal on the local host.  The script file for joy-control
should look something like this:

exec ../joy-control \
    -dimension 2 \
    -back linen \
    -particles 1 \
    -squareColor red,ForestGreen \
    -schemeX ../schemes/scheme1.so \
    -optionsX 1.0 \
    -schemeY ../schemes/scheme1.so \
    -optionsY 1.0 \
    -graphics 1 \
    -fftRate .0001 \
    -samples 32\
    -windowY 748 \
    -windowX 1014 \
    -windowZ 500 \
    -channels 2
    $*

feel free to adjust whatever parameters you would like but the demo is
designed to work with the -dimension, -schemeX, -schemeY, -optionsX,
-optionsY, -graphics, and -channels switches set as they are.
	This demo takes channel information (in X and Y) from the
mouse running over a small window generated by create-mouse-fifo.  The
scheme switches tell joy-control not to process the channel
information in any special way but to translate the channel
information directly into particle movement.

	2. Using create-alpha-fifo: Once you are running a joy-control
script in one terminal execute the command ./create-alpha-fifo in a
separate terminal on a different host if possible (create-alpha-fifo
achieves accurate timing by polling very often and tends to bog down
the fastest of processors).  The host running create-alpha-fifo should
also be part of the bcomplab local network since it draws channel
information from a large raw file.  create-alpha-fifo expects the
joy-control script to be run on flake but this can easily be changed
by altering the host variable to the desired host name from within
create-alpha-fifo's code.  The script file for joy-control should look
something like this:

exec ../joy-control \
    -dimension 1 \
    -back linen \
    -samples 4 \
    -particles 1 \
    -squareColor red,ForestGreen \
    -schemeY ../schemes/scheme9.so \
    -optionsY 1.0 \
    -graphics 1 \
    -fftRate .0001 \
    -samples 32\
    -windowY 748 \
    -windowX 1014 \
    -windowZ 500 \
    -channels 122
    $*

Again, feel free to adjust these parameters as well but the demo is
designed to work with the -schemeY, -optionsY, -graphics, and
-channels switches set as they are.
	This demo takes channel information from an actual raw file
created during an unrelated meg experiment.  scheme9 is used to move
the particle according to the magnitude of the alpha frequency of
channel 95 (located at the back of the subjects head).  The alpha
rhythm is also plotted in a separate window using plotonline (if the
plot is not working then run make in the meg/plotonline directory then
make install).

	3.  Using sniffer: This application should be run in a
different terminal after the appropriate joy-control script has
already been executed.  While the particulars of running sniffer can
be found in Ting Li's documentation the joy-control script file should
look something like this:

exec ../joy-control \
    -dimension 2 \
    -back linen \
    -samples 4 \
    -particles 1 \
    -squareColor red,ForestGreen \
    -schemeX ../schemes/scheme9.so \
    -optionsX 1.0 \
    -schemeY ../schemes/scheme0.so \
    -optionsY 1.0 \
    -graphics 1 \
    -fftRate .0001 \
    -samples 32\
    -windowY 748 \
    -windowX 1014 \
    -windowZ 500 \
    -channels 122 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
    $*

Here you really should take the liberty of changing as many parameters
as you can to get an idea of joy-control's flexibility.  It's a good
idea to change schemes around to see what each will do.  Don't forget
to check each particular scheme's documentation before using it
though.  Some schemes are outdated and won't run properly with
joy-control's current implementation.  Only functional schemes will
actually compile with the makefile in meg/control/schemes so please
use those and whatever schemes you may write yourself.


Part II (how to create new schemes):

What is a scheme?
	Schemes are individual files comprising different functions
that dictate how the particle they are assigned to will move.  They
are implemented as shared objects and are, therefore, capable of being
compiled separately from joy-control and linked to it dynamically.
	Basically, a scheme decides how a given particle will move in
a particular dimension given server side input.  For instance, if you
have two particles moving in two dimensions you will have to assign
four schemes in order to fully specify the particles' movement.  The
input to a schemes is always the same it basically consists of raw and
processed input from the server.  The output from a scheme is sent
though the argument virLoc (the particle dimension's virtual
location).  virLoc is given as a float from 0 to 1.  The actual
location of a particle is not assigned until the particle is about to
be displayed in joy-control.

What's different about implementing schemes as shared objects?
	There is really only one problematic aspect to implementing
schemes as shared objects.  Whenever the same scheme is assigned to
different particles and/or dimensions of a given particle, the same
function handle is assigned to both instances.  This means that and
global or static variables share the same variable space.  For
example, if you were to declare a static variable in the scheme that
is used more than once, all particles using this scheme would modify
the exact same variable.
	To get around the problem of "shared variables" we actually
pass in any variables that may differ from one instance of a scheme to
the other.  By convention static constants are passed in through the
array options and static variables are passed in through the array var
(with the first argument of options being the size of var).  It's
important to realize that truly local variables that are created each
time the function is called do not need to be passed in.  Only those
that need to be treated as static.
	The biggest drawback to this solution is that since both
options and var are double arrays you can only pass in data in double
format.

Writing a scheme:
	Always make sure to #include scheme.h and usually you'll need
to #include "meg/random.h"
	Another convention uses the first element of var as a flag
separating the first execution of the function from the others.  This
allows the function to initialize all the other elements of var and
write scheme information to the out file descriptor.  Typically, the
first few lines of a scheme will look like this:

Please look at original README - was cut due to formatting error.


Node:motion, Up:Programs

streamer - records subjects' head movements

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED



			Recording subjects' head movement

Build:

  make
  The executable is named streamer.

Important:

  Modify config.h according to your machine configuration.

Overview:

  Most of the code is borrowed from the streamer program in the
  xawtv-3.58 package.  The program will do a bit-wise comparison
  on two consecutive frames and only record both frames if their
  difference exceeds a certain threshold value (to be empirically
  determined in the MEG chamber).  Capture.c contains most of the
  frame  grabbing functionality.

  Changes were made in streamer.c, capture.h, capture.c.

Command-line options: (obtained from '-h' option)

  general options:
  -h          print this help text
  -M n        recording threshold
  -q          quiet operation
  -p n        use n compression threads    [1]
  -w seconds  wait before grabbing         [0]

video options:
  -o file     video/movie file name
  -f format   specify video format
  -c device   specify video4linux device   [/dev/video0]
  -r fps      frame rate                   [10.000]
  -s size     specify size                 [320x240]

  -t times    number of frames or hh:mm:ss [1]
  -b buffers  specify # of buffers         [16]
  -j quality  quality for mjpeg or jpeg    [75]
  -n tvnorm   set pal/ntsc/secam
  -i input    set video source

audio options:
  -O file     wav file name
  -F format   specify audio format
  -C device   specify dsp device           [/dev/dsp]
  -R rate     sample rate                  [44100]


movie writers:
  files - multiple image files
    video formats:
      ppm     24 bit TrueColor (BE: rgb)   [ppm]
      pgm     8 bit StaticGray             [pgm]
      jpeg    JPEG (JFIF)                  [jpeg]
    audio formats:
      mono8   8bit mono                    [wav]
      mono16  16bit mono (LE)              [wav]
      stereo  16bit stereo (LE)            [wav]

  raw - single file, raw video data
    video formats:
      rgb     24 bit TrueColor (BE: rgb)   [raw]
      gray    8 bit StaticGray             [raw]
      422     16 bit YUV 4:2:2 (packed)    [raw]
      422p    16 bit YUV 4:2:2 (planar)    [raw]
      4mpeg   yuv4mpeg (for mpeg2enc)      [yuv]

 audio formats:
      mono8   8bit mono                    [wav]
      mono16  16bit mono (LE)              [wav]
      stereo  16bit stereo (LE)            [wav]

  avi - Microsoft AVI (RIFF) format
    video formats:
      rgb15   15 bit TrueColor (LE)        [avi]
      rgb24   24 bit TrueColor (LE: bgr)   [avi]
      mjpeg   MJPEG (AVI)                  [avi]
      jpeg    JPEG (JFIF)                  [avi]
    audio formats:
      mono8   8bit mono                    [avi]
      mono16  16bit mono (LE)              [avi]
      stereo  16bit stereo (LE)            [avi]

  qt - Apple QuickTime format
    video formats:
      raw     24 bit TrueColor (BE: rgb)   [mov]
      yuv2    16 bit YUV 4:2:2 (packed)    [mov]
      yv12    12 bit YUV 4:2:0 (planar)    [mov]
      jpeg    JPEG (JFIF)                  [mov]
      mjpa    Motion JPEG-A                [mov]
      png     PNG images                   [mov]
    audio formats:
      mono8   8bit mono                    [mov]
      mono16  16bit mono (BE)              [mov]
      stereo  16bit stereo (BE)            [mov]

For example:

    ./streamer -f mjpeg -o video.avi -t 300 -M 35

  The above command will record 300 frames of avi video in motion jpeg
  format and the recording threshold is set to 35.

  Note that '-t' option is almost always necessary.

  Among the above, -M specifies an integer threshold value.  When the
  average difference(total_difference/(width*height)) between two
  frames is more than this value, the program will record both frames.

Output:

  The program will save the timestamps for all the frames into a file
  named "timestamps" in the following format:
    hh:mm:ss,msecond.
  msecond indicating how many microseconds have passed since the
  current second.


Dependencies:

  >X4.0
  X4.x-devel
  Corresponding codec libraries (avi,quicktime...)
  libXv
  libdl


Note:

  The program has been tested in the Brain and Computation Lab on pus
  (Athlon 700, 256MB, Haupauge WinTV, Debian 2.4.6, X4.1).  Only
  motion jpeg format has been tested.


Node:sniffer, Up:Programs

sniffit - grabs packets from network

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED


#Changelog
#   May 25,01   Added more notes on packet buffer in the "Buffer
#               mechanism" section.  Added format of dropout packet
#		warning in the "Dropout packet" section.


                             NOTES

This document explains the general workings of the sniffer program.

Here is a general discription of the whole program:
  The sniffit.c basically calls the low-level pcap API to
capture the TCP packets on the network and process these packets by
registering its own packet handler with the pcap functions.  To be
more specific, the program basically has an infinite loop, the only
thing in which is the calling of the pcap_dispatch() function, which
captures a single packet, be it TCP,UDP or ICMP,etc, and pass it to
the custom-specified packet handler.  The packet handler code is
contained in Control.c file, which reads the packet data into a buffer
and, when the buffer is filled up, assembles the packets in the raw
data format in the right order and sends the assembled data to either
a socket or a harddrive file.  Sendpacket.c is a program that reads the
data from the sending unit of sniffer, ie, Control.c, byte swaps the
data if necessary, and sends the data again to another socket. The
program can be made to ouput arbitrary channels.

Other files of interest are:
  packet.h      Packet structure, header and data buffer.
  socket.c      A small library by Brian Wiley for socket
                manipulations.

  sn_defines.h  Mainly defines the IPs and port numbers used in the
                program, also some TCP/IP related macros.

  sn_globle.h   All the global variables we need to keep track of,
                including some run-time options, sequence number
                tracking, etc.

The following is detailed explanation of interesting routines:

The packethandler

  The most import function in sniffit.c is packethandler(), which
is called every time a packet comes over the network.  First of all,
this function determine the packet type.  If it is TCP packet, which
is what we are interested in, it goes ahead and process it, otherwise
it returns DONT_EXAMINE.  Then it reads the packet header into the
(struct TCP_header)tcphead.  The processing mainly takes place in the
condition (finish<10&&LOGLEVEL==0).  One (struct Packet) is used to
store each TCP packet, including the header and actual data.  The max
data length is given by (max_packet_size-header_length)=1500-40=1460.
The whole packet is pointed to by (unsigned char *)sp that was passed in.
 But we want to skip the header, the size of which is given by
(info.IP_len+info.TCP_len+PROTO_HEAD).  Before memcpying the data into
the structure, the program uses IsValid() routine to check if this is
a packet we should be interested in,eg,if the src_ip is the meg
server, and if the src_port is from the communication port on the
server.  Also, the routine will not proceed to copy the data until it
sees the signal of acqusition start.  The checking is done by
comparing the packet data with a pre-specified string, defined in
sn_defines.h as a macro "start".  Similarly, end of aquisition is
characterized by the string defined in sn_defines.h "stop".  These two
characteristic strings are obtained by examining the raw dump of TCP
communication between the meg client and server.  After the routine
detects the "start" string, it will set the "isstart" flag to be true
and never bothers to check again.  Checking for termination works in
pretty much the same way.
NOTICE:  Both the header and the actual data passed in are big endian
and therefore it's necessary to do byte swapping when running the
program on a PC.  The sendpacket.c program takes care of this translation
before data is sent out to socket.

The buffer mechanism: (in sniffit.c)
  The user can specify a buffer size in terms of the number of TCP
packets.  This buffer is used to store the packets. When it's filled
up, ProcessData() routine will be called to process the whole buffer.
After the processing is done, the program will start filling the same
buffer again.  The reason for using it is we want to check for dropout
or out-of-order packets in the buffer and the buffer is a way to
minimize such problems. A global variable "COUNTER" is maintained to
keep track of the index into the packet buffer.  It will be set back to 0
whenever the processing is done.
  When the program starts, it will create the buffer by allocating
memory for n packets, where n is the number the user specified on
command line with '-B n'.  There is a global pointer (Packet *)packet
pointing to the start of this free memory.  packethandler() will keep
copying data sniffed, pointed to by (char*)sp, to the memory address
pointed to by packet[COUNTER], until COUNTER equals n.  Then the buffer
will be sent to ProcessData() for assembly, after which COUNTER will
be set to 0 and the program starts filling the piece of memory from the start
again.  The sniffed data will only be copied into one of the packet
structure in buffer if the packet actually contains the data we need
so that when the buffer is sent to ProcessData(), it contains all the
"good" data, that is, data that actually contain the channel
information.  At the stage of copying data into the packet structure,
the program doesn't check the sequence numbers, that is, the packets
are in whatever order they came in.  In ProcessData(), if REORDER
macro is defined, the program will use qsort() to reorder packets
according to their sequence numbers and return an order list of
pointers.  However, this way of reordering packets is limited.  It can
only sort the packets in the same buffer.  If an out-of-order packet
comes way after its normal order and becomes on packet in a different
buffer, then this way wouldn't work.



Actual packet processing:
  This is implemented in Control.c file.  For each packet in the
buffer, the program simply writes the data as is to the socket, but
adding a strictly incrementing 32-bit integer as the timestamp at
fixed interval.  This interval is defined as a constant "386" in the
Control.h file.  The number is obtained by (max_num_of_channels*2).
And max_num_of_channels is assumed to be all possible channels,
EEG,MEG,STIM and MISC.
This way, we have the artificial timestamps, which are not contained
in the network traffic.


Duplicate and Out-of-order packet checking:(in Control.c)
  Duplicate packet checking can be enabled by use -D DETAIL during
compile time. The Control.c maintains a bucket(called BUCKET) of all
the sequence numbers in the current buffer.  If it finds a sequence
number already in the bucket, it reports and error and simply discards
this packet.  The out-of-order packet test is implemented by simply
comparing the current sequence number with the last one, and if the
current one is smaller than the last one, then the current one must be
out of order.  If the user has enable "REORDER", then program will try
to reorder the packets in the buffer first, by sorting their sequence
numbers, and then process the buffer.


Dropout packet checking:(in Control.c)
  Checking for missing packet should always be enabled by defining
"CHECK_MISSING" in the Makefile.  The program maintains a variable
that calculates (current_seq_num-last_seq_num-last_packet_length).
This variable should always be 0.  Otherwise, there must be dropout
packets, and the number of bytes we are missing is exactly this variable .
Then the program will print a warning to the standard output, giving
both the sequence numbers and the packet length of the current and
last packets, along with the number of missing bytes.  The program
does not take any action when such situation occurs.
  Whenever the program detects a missing packet, it prints a warning
to the standard error.  The format is "Packet loss between a and b at
c, amount: d sample e channel f - sample g channel h i samples",
where a and b are the last packet
processed and current packet, respectively, c the current packet's
index in the buffer, d is the total amount of bytes missing, e and f
and g and h are from which channel in which segment to which channel
in which segment is the data missing.  is the number of samples
completely missing.

NOTE: To make sure this checking mechanism works, we should try to
eliminate the data source as much as we can, in other words, this
mechanism works best when there are only packets going from a single
port on a host to a single port on another host.  This way, the
sequence numbers of packets from different sources will not mix up and
cause false alarms.  Actually, we must have this gurantee for the
checking to work properly.


RealProcess() routine:(in Control.c)
  After all the error checking has been done, the program calls this
routine to actually process the data buffer.  Its jobs includes
generating binary strings of timestamps and write them to socket at
fixed interval.  Two global variables are maintained in this routine:
"index_counter", which is essentially the timestamp and gets incremented
every segment; "ofset", which marks the place to add the first timestamp
in the current packet.  We need the variable "ofset" because the
positions of the segments in packets are not fixed.  The output will
be directed to a socket on port defined by "com_port" in "sn_defines.h".


Sendpacket.c
  This program is just a utility that reads the data from the sniffer
program, performs the byte swapping and formatting(which channels to
output), and sends the resulting data to another socket, on the other
end of which is some signal processing unit.


Test setup:

A. Hardware setup:
   First of all, make sure the ethernet interface connected to the
local net is brought up and set to promiscuous mode.  This interface
should be assigned an IP of 192.168.100.50 and the netmask should be
255.255.255.255.
   Connect this interface card to the LAN hub with a straight ethernet
cable.
   The actual meg acquisition can be just noise runs, or with
subjects.  It doesn't really matter to sniffer.

B. Software setup:
  Before the test, we should avoid running a lot of other processes
on this machine.
  The whole program will have two separate executables: sniffit and
sendpacket and a typical live test requires a particular sequence of
operations.  NOTICE that "sniffit" assumes all possible channels are
packed in the data, that is, EEG,MEG,STIM and MISC channels.  To only
transmit certain type of channels, the constant "INTERVAL" in
Control.h must be modified to correct value.  The "all_chan" variable
in sendpacket.c must also be modified to the actual number of channels.
The sniffit has to be run as root.  Sendpacket doesn't need to be root.

The correct sequence should be:
  1. start the sniffit, and tell it to write to socket(be root first)
  2. start sendpacket and tell it to write to socket.
  3. start meg acquisition.


  If debug messages are enabled, such as LDEBUG and CHECK_MISSING, you
might want to redirect the output of sniffit to a file.  The correct
command to start sniffit is:

       ./sniffit -B 20 -x -s 192.168.100.2 -F eth0 -C

See the README file for detailed explanation of command line options.
One thing to note is we specify only one source for sniffit to sniff,
which is 192.168.100.2, the HP server's IP on the localnet.  We should
always use this form for dropout packet checking to work properly.  If
you want to get a dump of what sniffit has captured, use "-d filename"
instead of "-x".  "-F" should be followed by which ever ethernet
interface hooked up to the local net. When the acquisition is started
on the HP machine, sniffit will report it has identified the start of
the transmission by saying "starting logging".  Before the meg is
started, "sendpacket" should be started by doing something like:

      ./sendpacket --output sock --data-chan 0 --data-range 122

Again, check README for detailed command options.  Now start the meg
acquisition.


C. Error checking:

   To check whether we have captured the right data, have the sniffit
program create a harddrive dump by using "-d filename" and save the
data of this acquisition on the HP machine.  Obtain the .raw file of
the data file on HP and copy it to the host we are running on.  Run:

   ./plot raw_file sniffer_dump 2

   This will plot the content of the two files in a window, raw file
in red and sniffer dump in blue.  Ignore the tail of the curves.  If
the body of the two curves overlap, that is, you can only see one
color showing on the screen, then we have the right data.  See README
file for detailed usage on plot.

   To simply debug the control loop, there is a way to do test runs
without the meg machine.  All we need to do is turn off the packet
validity checking and turn on our own fake machine, which outputs the
sine function of predictable numbers.  First, run sniffit like this:

   ./sniffit -B 20 -x -s server_ip

   "server_ip" is the IP of the host running fake meg machine.  You
must make sure sniffit and the fake meg run on different hosts,
otherwise sniffit wouldn't be able to sniff anything.  Now run fake
meg on a different host:

   ./meg

On another host, which can be the host on which sniffit is running,
run the cl program:

   ./cl server_ip

Again, "server_ip" is the IP of fake meg.  If the output of cl is not
redirected to a file, you should now see a whole bunch of garbage
bytes showing up on the cl's screen.  The sniffit should also begin to
write data to the socket.  Now run the sendpacket program on sniffit's host:

   ./sendpacket --output sock --no_byte_swap --data-chan 0 --data-range 122

The the sendpacket will relay the data to another socket.  We disable the
byte swapping calculation here because we are assuming we have little
endian architectures in the lab.


Output of statistics thread:

  Output for each time interval will be separated by dash lines.  The
  following fields will be show:(in the following order)

  Time elapsed: number of seconds elapsed since the start of the test.

  packets processed: total number of TCP packets processed, also in terms
                     of how many samples.

  packets ignored:  packets with different protocols than we are
                    interested

  Traffic:          total number of packets sniffed vs. seconds

  Processing rate:  packets processed vs. seconds, also
                    samples processed vs. seconds

  Number of dropout packets:  in number of packets and also in total
                              number of bytes.

Test result:

  All the tests done right now are 30-second noise runs with meg
machine.  During the whole process, we have no duplicate, out-of-order
or dropout packets and the data acquired, as shown by plot, is
correct.  The sniffit program is also tested for a frequency of 1 kilo
Hz and passed.  See BUGS.

Meg test result:


Lab test result:
  These tests are conducted in the bcomplab with the fake_meg and
  fake_client programs:

  fake meg server: tears(K6, 32M)
  sniffit and fake meg client:  phlegm(Dual PIII 500 CPU, 256M)

Success:

  The threaded and sequential versions capture the same data.   These
  two do not really make a difference in performance, ie, threaded
  version fails all the tests that the sequential fails on.

  The threaded version of sniffer has no dropout packets when tested
  with 300Hz sampling rate for 5 minutes, while joy-control is running
  with on-line plotting enabled.  When the sampling rate is raised to
  600, there is no dropout packets,either.

  In the above condition, the threaded sniffer also runs with 1000Hz
  sampling rate with no dropout packets, but the statistics thread
  cannot be enabled('-A' option).

  Throttling on 'sendpacket' works but need a big number like
  "--sample-rate 1000" would work.

  Tests show that giving a big buffer size will stop dropout packets
  when testing against simulated bursting in the lab.
  Threaded version has to be used (-D USE_THREAD) and statistics
  thread must be disabled.  The following command have been tested and
  passed 300Hz, 600Hz and 1000Hz sampling rate:

     ./sniffit -s tears -x -B 130 -C -l 0

  The sending pieces uses this command:
  ./sendpacket --output eat --data-chan 0 --data-range 192 --no-byte-swap

  fake_meg:
  ./fake_meg 300 0

  fake_client:
  ./fake_client tears 0

  Giving '-B 130' will also work.

  To do a successful test with joy-control, some parameters under
  /proc need to be adjusted:

  Go to /proc/sys/net/core.
  Manually change wmem_default and wmem_max, which should be defaulted
  to 65535, to 524287(512k-1).  This will increase the read buffer
  size of each socket connection.  Then run the joy-control and
  sniffit with real-time priority enabled.  In this case, if we enable
  the statistics thread, we have to give '-A' a bigger interval, like
  20.  So this will work:

  ./sniffit -s 192.168.100.2 -x -B 20 -l 0 -A 30 -M

  ./sendpacket --output sock --data-chan 0 --data-range 192 --no-byte-swap --with-control

  I had dropout packets when giving 10 for statstics interval.  But
  the above ran with no problem for more than five minutes, when the
  fake sampling rate is 1000 and simulating the bursting problem.


Failure:
  When run under 1000 sampling rate with statistics thread enabled,
  the program drops a lot of packets.

FOLLOWING TEXT WASN'T FORMATTED PROPERLY. RAW TEXTUAL README FILE IS INCLUDED


	                                ReadMe

(See working_com for working commands in bcomplab)

  1.  How to build the programs:

    See INSTALL.
    Sniffit and sendpacket must run on the same host.
    The file sn_defines.h contains system defaults. You should modify
    it to suit your own need.

  2.  Command-line options:

    NOTE:  sniffit needs the user to be root to run.  sendpacket does not
           have this requirement.

    a) Options for the sniffit program

    To force sniffit to check for missing packets, append "-D
    CHECK_MISSING" to "CPPFLAGS" field in Makefile and 'make'. To have
    Sniffer give out warnings, append "-D DEBUG" to "CPPFLAGS field in
    Makefile and 'make'.

    -B n     Required option.  Specifies the buffer size to be used in
             the sniffit program.  n is the number of TCP packets to
             buffer before reordering and assembling raw data in these
             packets.

    -o fn    Tells sniffit to dump raw data to a disk file specified
             by fn.

    -x       Tells sniffit to dump raw data to a socket on the localhost.
	     In this case, sniffit establishes a socket by opening a
             pipe to "tcplisten" on port "com_port", which is
	     defined in "sn_defines.h".  The sendpacket program will
	     connect to this port to get the raw data.  The user must
	     specify either '-x' or '-o' on the command line to
	     specify the output mode.

    -C       Tells sniffit whether to verify the data or not.  If this
	     option is on the command line, whenever a packet is
	     captured, sniffit will discard those that are either not
	     from the MEG server, specified by "server_ip" in
	     "sn_defines.h", or not from the MEG server's
	     communication port, specified by "f_co_port" in
	     "sn_defines.h" .  Also, if data verification is required,
	     sniffit will not record data until it has found the
	     signal of start of transmission, by searching for the
	     string "200 Logging data" among packets from the server's
	     control port, specified by "f_ct_port" in
	     "sn_defines.h".  This option should only be turned on
	     during a live test with the MEG machine.  It doesn't work
	     with the fake raw data.

    -s str   Tells the program to only listen for packets from a
	     particular host "str".  "str" can be either a host name
	     or an IP address.  This option supports wild card; e.g.,

                "192.168.100.¨will process packets from hosts with IP
	        "192.168.100.xxx".

                "¨will process packets from all hosts on the
	        subnet.

    -t str   Similar to the above.  This tells sniffit to only check
	     packets destined toward certain host "str".

    -P proto Specifies the protocol to be used.  Possible options are:
	     IP,TCP,ICMP,UDP.  Sniffit uses TCP by default.

    -p port  Only checks packets going to port "port".

    -F dev   Forces sniffit to listen on device dev.  dev can be,eg., eth1,
             ppp0...  To run the program on meg370, it should listen
	     on NIC on the internal net.

    -v       Enable debug output.

    -l num   Enable real-time scheduling, num is the priority number.
             Giving a 0 will use the maximum priority allowed.

    -D       Enable checking for duplicate packets

    -r       Enable sorting packets within the buffer

    -L       Enable checking for end of transmission

    -A num   Create a thread that reports important network statistics
             at intervals of 'num' seconds.  num must be an integer.
             NOTE: Since there will be altogether 3 threads
             running(main thread, timer, statistics), the program will
             consume a lot of CPU time.  Make sure no other
             CPU-consuming processes are running, otherwise there will
             be dropout packets.

    -i num   Number of channels contained in a single segment.  The
             default is all the channels, 193.  So if we are using a
             different number of channels, be sure to use this option
             to specify the number.

    -n str   Specify the log file name to write the warning messages
             into.  If this option is not used, error messages will be
             written to standard error.

    -M       Adjust socket send buffer size via the proc file system.
             The default size under linux is 64k and this size will be
             adjusted to 512k(empirically determined) and the receive
             buffer size will remain the same.  This is to prevent the
             packet loss when the TCP connection has a bursting
             problem.   Socket buffer size will be restored to its
             original value after the program exits.

    -h       Print the help message.

  2.  Commands that work:

    To do a live test with the MEG machine on meg370 and show the raw data
channel by channel:

    first, run sniffit like this:(su to root first)

       ./sniffit -B 130 -x -s 192.168.100.2 -F eth0 -C -l 0

     then, run the sendpacket program on the same host:

       ./sendpacket --output sock --data-chan 0 --data-range 122

     then, start data transmission on the MEG machine;

    In this case, sniffit will only start sending data to sendpacket when
it finds the string "200 Logging data" in the incoming packets.
Sendpacket will separate data into channels and dump channels to another
socket.

    To do a test run within the lab:

	./sniffit -B 20 -x -s  
    run client:

        ./sendpacket --output sock --no_byte_swap --data-chan 0
        --data-range 122

    run the MEG data generator;

    The sniffit program can only be terminated by hitting Ctrl-C.

    For commands for the plot program, read "Test setup" section of
    NOTES.


  4. General workings:

     See NOTES for detail.

     Sniffit only starts sending data when there is a request on the
right port by the sendpacket program.

     The sniffit program does not touch the raw data at all. It only
assembles the raw data and send them to the socket as is.  The sendpacket
program does the byte swapping on data from the sniffit and encode
them back into binary 16-bit-integer stream.  The sendpacket program
doesn't output the timestamp for each slice but can do timestamp
verification if the user wants.

   5. Dependencies:
     Both programs make use of "tcplisten" and "tcpconnect" to
establish sockets.  So make sure you have these utilities in the system.
     Also, make sure you have libpcap and bpf(Berkley Packet Filter)
libraries installed in the system.

   6. Format of output
     The 'sendpacket' program is responsible for outputting data from
     sniffer.  If you wish to print the data to a socket, 'sendpacket'
     will print n 2-byte character strings, each string representing a
     value of the type int16_t.  n will be the number of output
     channels your specify with -data-chan and -data-range.

     If you are printing to standard output, the program will output n
     integers to stdout, each representing a single channel value.  n
     is defined the same way as above.


Node:showmeg, Up:Programs

showmeg - GUI for displaying MEG data

Summary

Idea behind showmeg was to create a small tool with features as

So now showmeg takes float data from stdin and presents it as a color image. Palette and other parameters can be changed dynamically. Sizes of image can be drawn from read data or provided at the beginning of data stream (Look Usage on showmeg).

Usage

Parameters for showmeg can be provided from command line as well as specified in its GUI (there some parameters which can be changed just from command line).

Help on all command line parameters can be achieved through invoking showmeg with -help.

showmeg tries to figure proper sizes if dealing with raw data without information about sizes. So if we specify either of dimensions (-[xy]size n) or ratio between them (-ratio n), showmeg computes the other one depending on size of data presented.

Here I want to describe just couple of parameters which can be not clear from small description of -help.

-input-raw

The -input-raw switches whether we're trying to get information about image from first 3 values which we meet in a stream. megtool dumps x, y and before(length of data before event) at the beginning of the image file. So if we get image from megtool, we can't specify -input-raw because it will consider then this information as data for displaying.

But if we created some information outside of our suite, like in Matlab and dumped it to simple ASCII file, we can use showmeg with this switch to avoid missing first 3 data points.

-just-generate

No GUI will appear. Depending on command line parameters, showmeg will generate an image and dump it to file with name specified in -i-file f parameter.

EXAMPLES

Show data obtained from megtool(see megtool).

megtool -sources 122 -data 27 -window 200,300 -lock 0/1 -gap 2/3/4 \
 -sort -W ~neuro/W/ta_el/joint/W -no-convert -i-file - \
 ~neuro/W/ta_el/data.raw \
 | showmeg -x 400 -colormap -5 -brightness 0.8 -contrast 0.5


Node:run_jade, Up:Programs

run_jade - JADE ICA

Summary

run_jade idea was adopted from matlab/gen_utils/decor_ica.m. Both these codes are designed to implement Independent Component Analysis using JADE algorithm (for more information can check http://tsi.enst.fr/icacentral/algos.html).

run_jade was developed to gain some performance improvement. C implementation gave around 5 times speed up in comparison with matlab code. As well as matlab's code it reads data from raw MEG files with help of megtool through pipeline. This degrades performance a lot, so we will think about way to unify access to MEG files in our tools suite through some library.

Algorithm run_jade in nutshell is very straightforward

Usage

Almost all command line parameters described in Summary. Look also at examples. One important command line parameter can be -sens n which changes number of sensors from default 122 to provided value n.

EXAMPLES

Read all data from file, assumes default number of sensors 122:

run_jade  /home/mrgray/misc/backup/at/ta_tp_raw.raw

Read specified amount of data:

run_jade -skip 0 -read 139230 /home/mrgray/misc/backup/at/ta_tp_raw.raw

Previous example with speicified delays:

run_jade -skip 0 -read 139230 -taus 1,2:10,11:2:21,22:5:52 \
       /home/mrgray/misc/backup/at/ta_tp_raw.raw

Previous example with specified also thresholds to dump W file:

run_jade -skip 0 -read 139230 -taus 1,2:10,11:2:21,25:5:100  \
 -thresh 1e-1,1e-2,1e-3,1e-4,1e-5,1e-6:-1e-7:1e-7,9e-8:-1e-8:1e-8 \
  /home/mrgray/misc/backup/at/ta_tp_raw.raw


Node:File Formats, Up:Top

File Formats

This chapter describes file formats used some of the DreamMon MEG analysis tools.


Node:Original .raw, Up:File Formats

Original .raw file's structures

Formats of used data files didn't evolve for a long time. Mentioned in this section data structures defined in megtool/split.h.

timeslice_rec .raw Data Structure
This data structure describes single trial in the data. So every .raw file consists of records of this type.

Here channel is just a pointer to a slice of file/memory with data for all channels at the trial.

timestamp keeps timestamp of current trial.

struct timeslice_rec {
    u_int32_t timestamp;
    u_int16_t channel[1];
} __attribute__ ((packed));

Function open_rawfile defined in megtool/read.c opens a .raw file and map it to memory to make it possible later access it just like all timeslice_recs are in memory.

timeslice .raw Data Structure
Is used just a shortcut (typedef) for struct timeslice_rec

Because .raw data file doesn't keep any information about experiment (as number of sensors of each kind, sample rate etc), another data structure became involved.

rawfile_attributes .raw Data Structure

struct rawfile_attributes
{
  double samples_sec;	/* samples per second */

  int n_chan;		/* number of channels TOTAL */
  int n_meg;		/* number of MEG channels */
  int n_stim;		/* number of STIM channels */
  int n_eeg;		/* number of EEG channels */
  int n_misc;		/* number of misc channels */
  int rec_size;		/* size of each timeslice */
  int downsample;	/* how much should data be downsampled?*/
};

rawfile_attrib .raw Data Structure
Is used just a shortcut (typedef) for struct rawfile_attributes


Node:Aux files, Up:File Formats

Auxiliary Files

Here we mention formats of files which can be generated or fed into megtool.


Node:responses, Next:, Up:Aux files

Responses file

File contains detected responses. From a megtool.c's point of view it is a file which is generated with megtool.c and specific command line parameter -response f where f is a file name (usual name for a file can be 00x_resp.dat, where x can be a source number if we work with a single source).

Format of the file is simple, each number in each line has next meaning

1 2 3 4

  1. event number (ie trial number)
  2. timestamp of trial marking event
  3. absolute time (timestamp) of detected response
  4. relative time (latency) of detected response (relative to trial marking event)

Times are given as sample numbers, with the first sample considered time 0.


Node:events, Previous:responses, Up:Aux files

Events file

Default name for the file is inputfile.events, where inputfile is input file with data (like evoked.raw). Default value can be overriden with -event-file.

First line in a file keeps number of lines with events which follow.

Each line is just couple of numbers

1 2

  1. event time
  2. event type
Events Types

Numbers for events types varies from project to a project. Some times it is possible to get minor documentation on that in STIM_LINES files in the directory of the project.

So in plasticity project


Node:netcdf .ncmeg, Up:File Formats

netCDF based .ncmeg


----------------------------------------------------------------------
WARNING: .ncmeg format still is under development, so no
caching or storing in .ncmeg is done by now.
----------------------------------------------------------------------

Current format is designed under consideration of netMEG file format developed for MEGAN software

For more detailed description of netcdf library you can look at /usr/doc/netcdf-doc or go to the netcdf home page

All conventions on names of variables, attributes etc are defined in netcdf/megnetcdf.h.


Node:Global Attributes, Up:netcdf .ncmeg

Global Attributes

Global attributes are variable which defined for whole data file to give some additional information about experiment or stored data.

string Comments Global Attribute
different comments which can come from operator/user/...

string DateOfDataAcquisition Global Attribute
date when acquisition was done

string DateFileCreated Global Attribute
date when acquisition was done

string MontageName Global Attribute
Name of sensor system used

string PatientName Global Attribute
Name (can be just some kind of alias) of a patient

string netCDFfileType Global Attribute
comments about data acquired (if was averaged etc.)

string netCDFfileVersion Global Attribute
version of the file

string FiltersUsed Global Attribute
information (comments) if filters were used

string OriginalFileName Global Attribute
the name of the main file from which the data was read. Can be .meg file.

string OriginalFileDate Global Attribute
Modification time of source file - necessary to figure out if cached data in filtered and sources is valid

long SamplingRate Global Attribute
sampling rate of the device where data was acquired (default for MEG machine used was 300 Hz).


Node:Dimensions, Up:netcdf .ncmeg

Dimensions

Dimensions are defined to determine structure of other variables. For instance many variables will grow in time, so there is a reason to name a dimension time. Some data will be arranged depending on to which sensor it belongs, so there is a reason to create dimension sensors.

unlimited means that data in this dimension can grow. So if we're making an experiment we're accumulating data - so dimension dTime will grow and that is why it must be unlimited. Only single dimension within a file can be declared as of unlimited size.

dTime unlimited
Dimension of the time. Each time point is one set of experiment data

dSensors fixed
All sensors present in system

dSources fixed
All sources separated from raw data. By default (and for now) number of sources is equal to a number of sensors.

dStims fixed
Stimuluses which were present during an experiment

dCoord fixed
The three Cartesian coordinates XYZ for position of sensors and possibly localized sources


Node:Variables, Up:netcdf .ncmeg

Variables and Linked to Them Attributes

Most of variables defined in this section based on predefined dimensions (see Dimensions).

short raw (dTime, dSensors) Variables
raw data. date when acquisition was done

float filtered (dTime, dSensors) Variables
filtered data. Parameters of the filter used are listed in ????

float sources (dTime, dSources) Variables
data which was composed by applying unmixing matrix defined by unmixing.

double unmixing (dSensors, dSources) Variables
unmixing matrix which was applied to get sources from raw data

string matrixFile unmixing's Attribute
File name (including path) where unmixing matrix was taken from.

string matrixFileDate unmixing's Attribute
Date when this unmixing matrix's file was created

float SensorLocation (dSensors, dCoord) Variables
raw data. date when acquisition was done


Node:Cached .ncmeg.cached, Up:File Formats

.ncmeg.cached

Files of this format usually are just a temporary files for .ncmeg to .raw data files. They contains just intermediate computed data for speeding up the process, to avoid recomputing the same quantities over and over again, as it happens when we have separating matrix, or doing different manipulations with filtered data. So as far as parameters for current data file don't change we have valid cached data. .ncmeg can also keep all necessary caching data if it was configured for that or it was explicitly mentioned to don't create .cached file.

So variables in cached data file can be the ones which are missing in current .ncmeg file.


Node:Program Index, Up:Top

Program Index Index


Node:Sources Index, Up:Top

Sources Index Index


Node:Command Line Parameters Index, Up:Top

CL Parameters Index Index


Node:Data Types Index, Up:Top

Data Types Index


Node:Concept Index, Up:Top

Concept Index