-------------------------------------------------------------------

readana.m can't read Kazuo's high Fc analog files.

-------------------------------------------------------------------

Need to redo gen to be more general.

--------------------------------------------------------------------

Several things, among them opening the file browser window will cause 
xdphys/xdview to crash with:

Error: XtMakeGeometryRequest - parent not composite

Under Xfree86 4.0.1 (I have heard that this does not happen in newer
releases of Xfree86, e.g. 4.0.2)

In addition, xdview gives the same error, since it uses the file browser
widget directly in the main xdview window

The culprit is FileNom.c, line 733, activated via fdobj.c, line 123

XtVaSetValues(Child(fnw,viewport), XtNheight, height, NULL);

The error is probably due to this:

FileNominatorClassRec fileNominatorClassRec = {
  {
    /*** Core class part ***/
==>>    /* superclass	     */	(WidgetClass) &widgetClassRec,
    /* class_name	     */ "FileNominator",
    /* widget_size	     */ sizeof(FileNominatorRec),
    /* class_initialize      */ NULL,
    /* class_part_initialize */ NULL,
    /* class_inited          */	FALSE,
    /* initialize	     */	Initialize,
    /* initialize_hook       */	NULL,
    /* realize		     */	Realize,
    /* actions		     */	NULL,
    /* num_actions	     */	0,
    /* resources	     */	resources,
    /* num_resources	     */	XtNumber(resources),
    /* xrm_class	     */	NULLQUARK,
    /* compress_motion	     */	TRUE,
    /* compress_exposure     */	XtExposeCompressMultiple,
    /* compress_enterleave   */	TRUE,
    /* visible_interest	     */	FALSE,
    /* destroy		     */	Destroy,
    /* resize		     */	PositionChildren,
    /* expose		     */	NULL,
    /* set_values	     */	NULL,
    /* set_values_hook       */	NULL,			
    /* set_values_almost     */	XtInheritSetValuesAlmost,  
    /* get_values_hook       */	NULL,
    /* accept_focus	     */	NULL,
    /* version		     */	XtVersion,
    /* callback offsets      */	NULL,
    /* tm_table              */	NULL,
    /* query_geometry	     */	XtInheritQueryGeometry,
    /* display_accelerator   */	NULL,
    /* extension	     */	NULL,
  },
  {
    /*** FileNominator class part ***/
    /* extension	     */	NULL,
  }
};

Does this mean fileNominatorClass' only superclass is Core?
Core is the overall superclass.  FileNom's superclass should be
Composit, or Container.

No, this is not true.  I think what this means is that FileNom must be 
contained in a widget which is a sublcass of Composite, such as Form (?)

But it is a child of fdo->form, hmmm.


--------------------------------------------------------------------
From Hermann:

Now that we have the clicks and the short intervals in the
psth's, we have to measure latency. There are several algorithms around,
with one of the best being an algorith for Jeff Schall's lab at
Vanderbilt. He has a C-version on the internet, and I asked him whether we
could useit , and he happily agreed (I actually asked whether we could
also get the Matlab version, he also agreed, but never gave it to me).
So we have to implement something by ourselves. Could you, for Catherine
and on her payroll, please, implement the latency algorithm of Schall into
the analysis of XDphys or XDview or whereever it is necessary. 
I assume that you don't have an algorithm measuring latency in the
program. If you do already, please contact me first and tell me how to use
it.

-------------------
Dear Chris,
thanks for your mail. Here are my thought's on the algorithm (or what I
know about it, it is on the Web-site of J. Schall, and you can look it up
under:
www.vanderbilt.edu/AnS/psychology/WRC/VRGroups/SchallLab/Analysis%20Tools.html

> 

> 	*	I am assuming that the algorithm analyzes analog traces,
> 	 	and determines the start of the first spike by some heuristic.
> 		Is this true?  Thus in order to use the algorithm, you have
> 		to have recorded analog traces.

no it works on pulses, i.e. ttl pulses

> 
> 	*	How would data generated by this algorithm be displayed?  
> 		I'm thinking that you calculate the latency for each trial,
> 		and display the results in a histogram.

data could be displayed in the raster plots as a line or in a separate
histogram as you propose 
> 
> 	*	I am not sure where this algorithm should go: in xdphys/xdview
> 		or in MATLAB?  Over the past year Ben and I have pushed most of
> 		the analog trace analysis out of xdphys and into MATLAB.
> 		However, this seems like something that people might actually
> 		want to see often, so perhaps it makes sense to put it in
> 		xdview.

I think it could go into Matlab, but you can make this decision.
> 
> Please send me Jeff Schall's algorithm or tell me where I can get it,
> so that I can look it over.

see above. I shall write to Jeff again, and hopefully, he will send me the
Matlab code.

Best regards,
Hermann

Checklist

*	Add graph page to xdview on itd files only?
	* 	Have to ask hermann again what we agreed on as to display the
	  	latency data
	* 	Need to talk to Jeff Schall at Vanderbilt to get the C-code for 
		the latency algorithm
*   Anything left to do with the matlab stuff?
	*	Testing with Hermann's files
	*	Finish doing the documentation headers at the top of each .m
	 	file

-------------------

Project:
*  Finish and deliver Hermann's changes

*  Make xdphys record 2 channels of analog data
*  Figure out why readana can't read Kazuo's files

Four issues:
	(4) Reading the data
	
	With 3,4 comes designing file format changes, both to the text
	format, and to the intermediate binary format for analog data used
	by readana.m

	With 2 comes changing data structs, a change in the way that ttl based
	spike discrimination determines what channel to use


File format 
	Text file:
		Need to delimit different traces in the file.
		Need to record which channel the trace came from.
			Where to do this?  In the parms section? or with each trace?
			Probably more space efficient to do it in the parms section.
		Does mod_gawk need to be changed?
			probably not
		Delimit with TRACE, END_TRACE 
		Write a conversion program to update old files? or 
	Binary file used by readana.m:
		Header must change to contain 
			char nchans[15]
		Trace blocks must change to contain
			char channel[15] (channel # identifier)
		

Writing files:
	file writing is done in xdphys.c:appRun()
		WriteFileHeader
			writes ";; xdphys %s" string
			writes COMMENTS block
			writes PARAMS block
		WriteBeginRaster
			writes "RASTERDATA"
		mod_*.c:runScan() function records rasters
			getRaster retrieves the raster from the AD buffer
			writeRaster writes the raster
			writeAnalog writes the analog file
		WriteEndRaster
			writes "END_RASTERDATA"

	Conclusion:
		Only writeAnalog must be changed with respect to writing
		multiple analog traces.
		spiker_getADbuffer should be changed to return all an array of
			buffers, with another array indicating what each buffer conatins.

		int spiker_getADbuffer(int *nsamps, int *nbufs, int ***type, 
			xword ***bufs)

		spiker_getADbuffer:
			analogfns.c:writeAnalog()
			raster.c:getRaster_window()
			raster.c:getRaster_ss()
			raster.c:getRaster_ttl()
			unittrace.c:tracer_update()

Reading files:
	Within xdview:
		Files are read via fd.c:FD_read()
			fopen2.c:fopen2() 
				opens the file, returns FILE *fp
			The ";; ... ver" string is analyzed to determine what
				version of xdowl/xdphys wrote this file.
			readComments() 
					reads the comments
			fd.c:FD_new() 
					is called to allocate a new FILEDATA struct
			svars.c:fd_loadvars() 
					loads the svars from the PARAMS block
			fd.c:doFDreadMethod() 
				is called to read the raster data, and calculate summary info.
				This calls the function set by the appropriate pm_*.c file in 
				the pm_*_init() function of that file.  

				e.g. for ".iid" files, pm_iid.c:pm_iid_init() calls
					setFDreadMethod to set the set the appropriate read
					function for ".iid" files to be fd1.c:FD1_reader.
			fd1.c:FD1_reader()
				raster.c:readRaster() reads the raster
				*** if the (ana_flag) parameter to FD1_reader is 1,
					analogfns.c:readAnalog() reads the analog waveform
			
			*** FD1_reader is called with ana_flag set to 1 only in
				xdview.c:ana(), which is used to dump analog functions
				to a MATLAB readable format.	

		Conclusion: 
			(*) pm_ana.c must change?
			(a) the ana array in the FD1_RawData struct must change to
				be 3 dimensional (fd1.h:32)
DONE			fd1.c:FD1_sort() 
					must change, as it manipulates this array
DONE			fd1.c:FD1_freeRawData()
					must change, as it frees this array
DONE			fd1.c:FD1_get_ana() 
					the prototype must change to return xword ***
				xdview.c:ana() 
					change to deal with 3 dimensional ana array
DONE		(b) analogfns.c:readAnalog() must change
		
		readana.m:
			change to return an array of "data" structs, one
			per channel, and add the channel identifier to the header
			of the data struct.
	

User Interface
	
Add :
	

Most basic way to do this is to simply have a switch which turns on 
recording in the second channel.

Should there be support for doing 3 and 4 channels, if you have the
hardware?

How about this: instead of "ana_offset" we have "channel 1" and "channel 2" 
each of which can take the values "analog", "ttl", or "off"

"analog" means that data will be saved from that channel when "ana-save"
is 1
"off" means that data will not be saved from that channel when
"ana-save" is 1.

Remove "maxspikes" noone will ever change this.

"syncPulse" should really be in "Running Parameters".

Is there any way to combine all of this onto one window?

Hack out the spike sorter library.

FIX X related stuff!!! --> installing XFree86 4.0.2 fixes this

Problems: there should never be two ttl channels -- there is either 1 or
none.

Scale this to 3 and 4 channels by having

Could fix the first a/d channel to always be the same channel -- what's
the drawback of this?  If that channel breaks, the user can't change
a setting in xdphys to use a another channel.  What else?

So if we're saving analog data 

FD1_Reader skips over the analog data, mostly, except when xdview is
called with the "-ana" flag: see xdview.c:ana().  

Save an svar which says which channel the each of the traces belongs to.

the "ana" array now needs to be two dimensional (see fd1.c:1556)

AD pathway:

No need to change iserver, already returns two channels; it's xdphys
that interprets the channels.

Things to think about:
	
*	follow the path of the data in from iserver (is_getADbuffer) and
	determine how the channels get assigned
	*	Need better method for determining what each input analog channel
		will do in xdphys (UI)
	*	Generalize to many channels?
		Include generalizing iserver to many channels?

	Spikes are all gathered through getRaster()
	Analog data 

*	spike discrimination code will have to change, of course
	*	How do redo this sanely?

*	reading and writing analog waveforms 
	* 	How do I deal with writing two channels?
	* 	Backwards compatibility?  How can xdphys determine whether to read
	  	one of two channels? (THIS IS THE BIG ONE)

		1) 	Converter ... never done this before (maybe this is the easy
			way out)
		2) 	retain old code, how do I determine whether really really old
			(xdowl, which of course doesn't work now), really old (xdphys 
			before ascii ana blocks), old (xdphys with one ascii ana
			block) and new (xdphys with multiple ascii ana blocks)

*	rewrite readana to be able to handle multiple traces per trial
	*	xdview ana dumping script

SaveTraceCB (xdphys.c)
	-> is_getADbuffer (iserver)

SaveTraceWaveform (xdphys.c)
	-> is_getADbuffer (iserver)

calcRMS (xdphys.c)
	-> is_getADbuffer (iserver)

plottrace (xcalibur.c)
	-> is_getADbuffer (iserver)
	
ResetAllAction (unittrace.c)
	-> is_getADbuffer (iserver)

ResetAction (unittrace.c)
	-> is_getADbuffer (iserver)

ss_user_initialize (ss_user.c)
	-> is_getADbuffer (iserver)

spiker_getADbuffer (raster.c)
	Called by:
		writeAnalog (analogfns.c)
		getRaster_window (raster.c)
		getRaster_ss (raster.c)
		getRaster_ttl (raster.c)
		tracer_update (unittrace.c)

		
single_step (misc.c)
	-> is_getADbuffer (iserver)
	
view_input (iviewer.c)
	-> is_getADbuffer (iserver)

SaveCB (iviewer.c)
	-> is_getADbuffer (iserver)

view_input and SaveCB (iviewer.c)
	iviewer handles the input/output examiniation windows
	Always presumes that there are two input and two output channels

view_input (iviewer.c)
	Called by:
		runScan in the following files
			mod_bam.c
			mod_beats.c
			mod_bja.c
			mod_bw.c
			mod_cal.c
			mod_cal.c
			mod_cf.c
			mod_click.c
			mod_fiid.c
			mod_fr.c
			mod_gen.c
			mod_int.c
			mod_rig.c

writeAnalog (analogfns.c)
	-> spiker_getADbuffer (raster.c)
			-> is_getADbuffer (iserver)

useSS (raster.c)
	-> getRaster_ttl (raster.c)
		-> spiker_getADbuffer (raster.c)

getRaster (raster.c)
	-> getRaster_ttl (raster.c)
		-> spiker_getADbuffer (raster.c)
			-> is_getADbuffer (iserver)

getRaster (raster.c)
	-> getRaster_window (raster.c)
		-> spiker_getADbuffer (raster.c)
			-> is_getADbuffer (iserver)

getRaster (raster.c)
	-> getRaster_ss (raster.c)
		-> spiker_getADbuffer (raster.c)
			-> is_getADbuffer (iserver)

getRaster (raster.c)
	-> tracer_update (unittrace.c)
		-> spiker_getADbuffer (raster.c)
			-> is_getADbuffer (iserver)

writeAnalog (analogfns.c)
	void writeAnalog(FILE * fp)
	Called by: 
		mod_bam.c:runScan
		mod_beats.c:runScan
		mod_cf.c:runScan
		mod_click.c:runScan
		mod_fiid.c:runScan
		mod_gen.c:runScan

	Writes analog data in ascii to the file pointer passed to it

spike_getADbuffer()
	int spiker_getADbuffer(
		int *nsamps_p, 
		xword ** ttlbuf_p, 
		xword ** analogbuf_p)
	
	-> is_getADbuffer()

	spiker.ttl_offset |____ one of these must be 1, the other 0
	spiker.ana_offset |

	sets ttlbuf_p to channel spiker.ttl_offset
	sets analogbuf_p to channel spiker.ana_offset

xcalibur related: 
	runScan (mod_int.c)
		-> is_getADbuffer (iserver)

	runScan (mod_fr.c)
		-> is_getADbuffer (iserver)

	runScan (mod_cal.c)
		-> is_getADbuffer (iserver)

	runScan (mod_bw.c)
		-> is_getADbuffer (iserver)
