User:Penhunelab
Project in Li and Penhune's Lab
[edit]SAR:
[edit]Go to Labs:SAR
Yana's
[edit]Projects related software/hardware information:
[edit]* MOCAP - Motion Capture-Stimulus Synchronization using a DAQ box * fMRI Analysis under Windows using MNI Tools * Sound Glitches using .Net 2.0 async calls in SoundPlayer * Subversion (SVN) Client * Working with XML and XML Schemas in C#
Motion Capture-Stimulus Synchronization using a DAQ box
[edit]Since the motion capture signal is timed by the Mocap's own timer and the stimulus presentation is controlled by the PC timer, there is a need to synchronize both signals to know when the events in one (the stimulus presentations) happened relative to the other (motion signal)
Using a Data Acquisition Box we can combine both signals by means of a pulse in a channel that marks a stimulus presentation event and an End-Of-Frame (EOF) pulse generated by the special TCMs with a BNC connector in them at the end of every frame (after all active markers have been sampled)
To combine the two independent signals, we came up with 2 promessing methods: Method 1 (Using Digital IO Channels)
The easiest way to map the two channels is obviouly 1-to-1, which requires acquiring at the same rate in both channels. The key to have them synchronized is to start the acquisition at the same time. This can be acomplished by setting a common trigger (a single channel) to start the acquision in both channels. Then, by triggering that channel both digital input channels would start recording a binary stream that would be of the same length and that would have the advantage of being in sync with each other (e.g. sample #356 was acquired at the same time in both channels). I am not sure if recording in two channels uses a single sampling clock or not but even if they were separate clocks, because they run at the same frequency, on the same hardware, with (pressumably) the same physical configuration, their offset should be neglegible. Analysis
Since the result is 2 binary streams, the analysis, which is done offline, consists of finding changes in the stimulus signal (0 to 1 transition) and identifying the sample's index. With that information, we can go to the mocap EOF signal and count the number of pulses (blobs of 1s) from the beginning until the index identified in the stim signal. This gives us the mocap frame # closest to the stimulus presentation and also the delay from the mocap frame to the stimulus onset Example
Stim: 000000111000000111000 EOF: 001100110011001100110
The first stim appeared in index # 7. Counting the number of pulses (frames) in the mocap signal we can tell that the first stim appeared when the mocap finished acquiring the second frame with an offset of 0 samples (stim ON position coincides with EOF on position). The second stim appeared on index #16; again, counting on the EOF, that position correspondes to the 4th frame, but this time there is a delay between the EOF and the stim: 1 sample. This offset between a stim-ON sample and an EOF sample makes the resolution of this method tied to the sampling period of the digital signal, e.g. with a digital sampling frequency of 1MHz the resolution of this method would be 1us. Advantages
* The resolution of the measurements is better than in method 2
Disadvantages
* Eventhough the frequency of the EOF pulses is slow (e.g. 200Hz), the actual voltage drop that marks the end-of-frame is ~1.35us which means that we need to sample the signal at at least ~1.48MHz. This is not possible with our current DAQ, which has a max digital sampling rate of 1MHz. However, this problem can be overcome by using a circuit to widen that really short pulse in the EOF channel. The idea is to use the real EOF channel to trigger a circuit which creates a wider pulse, wide enough that it can be captured by the DAQ. This would increase the complexity of the setup by adding one more piece of hardware.
Method 2 (Using a Counter)
Using one of the counters in the DAQ we can count the number of frames (pulses in the EOF channel) that have been acquired at the moment of stimulus presentation. The key here is “at the moment of stimulus presentation”. The stimulus presentation event is working as a trigger to go and get the count of frames from the counter. This is achieved by using the second counter to generate pulses that mark a stimulus presentation. This pulse generator is used as an external sampling clock in the edge counter Task. This is the method currently used in our experiments
A key element here is making sure that the counter internally digitizes the signal fast enough to see the short pulse described in method 1. The good news is that the counter uses a 20MHz internal timebase (AFAIK a timebase is an internal oscillator in the DAQ). That means that the counter sees the EOF channel often enough to detect the pulses. Example
The mocap acquires 24 frames which makes the counter have a count of 24. Right after that 24th frame a stimulus is presented. This stimulus creates a pulse using the second counter in the box which is configured to be the same channel of the external clock for the counter task. Because we know the number of counting samples to expect (the number of stimuli in the trial) we can use a finite acquisition which allows us to reserve a buffer with that same number of placeholders for the counting samples. When the counter detects a tick in the external sampling clock it stores the current count in the buffer using one of the placeholders without interrupting the actual counting (this is unlike an “on-demand” acquisiton which is software based according to the manual). By the end of the trial, the buffer should be full with the count of frames right when each stimulus was presented. Advantages
* Since the goal is to find out when the stimulus was presented according to mocap frames, we need to count somehow to match one signal to the other. Using this method the counting is done by the hardware instead of having to detect pulses and counting in software. This results in a direct output of frame # where a stimulus appeared. In contrast, in method 1 the output is extensive since it is the actual signal sampled at a high frequency.
* Since the DAQ has a counter already we don't need an external circuit, unlike in method 1
Disadvantages
* Because the counter remains the same from n to n+1, we can't really tell more precisely where the stimulus appeared with respect to the frame; was it right after the EOF or right before it?. This limits the resolution of this method to that of the mocap sampling rate (EOF Frequency) which is usually 200Hz, i.e. we can't narrow the stim onset down to more than 5ms in the worst case scenario due to the discrete nature of the signal.
..................................................................................................................................
Sound Glitches using .Net 2.0 async calls in SoundPlayer
[edit]Background
Before .net 2.0, I wrote a library to play sounds. I was mostly using async calls and getting the data from memory streams. After some experiments with that library it was pretty consistent to encounter a glitch where the sound started playing correctly and somewhere in the middle it made a weird crackling noise. I updated to .net 2 and started using microsoft's SoundPlayer class instead of my classes and hoped that sound glitch would be fixed. It wasn't
I started investigating and other people reported this problem too: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93642 http://www.codeproject.com/cs/media/soundplayerbug.asp
In the first article of the list, they recommend using PerfMon to monitor what the garbage collector is doing. I always had a feeling it was the garbage collector since the glitch happened at different stimuli every time, sometimes not happening at all. Inconsistent bugs are often related to garbage collection since the GC is not very deterministic in its scheduling.
Pretty much the hypothesis is that while the sound is being played the GC moves (or deletes??) the memory location and the sound function ends up playing random garbage from the memory
The problem comes from the unmanaged calls to the API. When an unmanaged call is made, the unmanaged objects get pinned so that the GC doesn't move them, once the objects are used they get unpinned and become accesible (conceptually) to the GC. The problem is, in an async call the function returns right away, before the object is finished being used.
Subversion (SVN) Client
[edit]This is a general guide on how to use svn as a client with a pre-created server
For a complete documentation go to http://svnbook.red-bean.com/en/1.4/index.html Client frontends
Because most of the times it's easier to use a point-and-click interface, i recommend installing a frontend for svn; that way there's no need to learn the commands by heart.
Note: The implementation of the svn commands in the frontends is limited; sometimes, for not so common actions, the command line is still needed. The format in the command line is
svn <action>
for example, to see a quick help
svn help
So, back to the frontends…
For windows, the best available is tortoiseSVN. Check the Official site
For Mac OS X there is svnX or SCPlugin which integrates with Finder, similarly to the way tortoiseSVN does in windows
Importing files into the repository
The best way I've found is to create a temporary hierarchy of directories after some coding has been done (e.g. all the files have been created. if not they can always be added later) …/tmp/ProjectName/trunk/ …/tmp/ProjectName/tags/ …/tmp/ProjectName/branckes/
and then add the unversioned files to be versioned into the trunk directory
After that, import ProjectName (using tortoiseSVN) and using as destination folder \\svnserver/repo/ProjectName (…/tmp/ProjectName should be the source folder if right-clicked in it) Checking out files
To continue using the same directory as the unversioned code just checkout the code into the same directory where the code currently resides. MAKE SURE THE LATEST CHANGES HAVE BEEN COMMITTED before checking out on top of it. TortoiseSVN will complain that the directory is not empty but if the latest changes are already in the repository then it will override the files with the same version of it. Make sure that no programs using the files are open (e.g. visual studio)
After this you should have the same directory as before but now with version-controlled source files and still have the old unversioned files intact Committing files SVN in C#
When using Visual Studio 2003/2005 there's a plugin that integrates to the IDE. I have it installed but have to say that I usually still do everything using TortoiseSVN. The plugin is available here: AnkhSVN My Guidelines
To start a new project that is going to be versioned, probably the best approach I've encountered is the following.
1. Create project's folders in the repo; and trunk, tags and branches folders inside it using TortoiseSVN if you follow that structure 2. Create project in Visual Studio 3. Do an svn checkout to the visual studio project directory. TortoiseSVN will warn you that the directory is not empty, which leads me to believe this is not the optimal way maybe, ignore the warning. 4. Select the files you want to import to the repository (more on this shortly) 5. Use tortoiseSVN to add the files to the trunk of the project in the repo
Note that steps 1 and 2 can be interchanged
Which files to version? After some trial and error and reading what other people do online I decided to version the source code (of course) *.cs; *.csproj and *.sln. Other files like *.suo and *.csproj.user seem to change too often
Working with XML and XML Schemas in C#
[edit]This applies to .NET 2.0 or greater Creating the schema
You can use the VS2005 tool for this task Creating a class to read the XML file into
I use the xsd.exe tool that comes with vs2005 The command line to run it is
xsd.exe <inputSchema> /classes /language:CS /outputdir:<dirToOutput>
This will create a guide file of what the class will look like but it needs correction in some cases; especially in complexTypes
The class will need a parameter-less constructor. I think it misses it Reading XML files into classes
To read the xml files into an auto-generated-but-modified class Config in an object test I use
XmlSerializer deserializer = new XmlSerializer(typeof(Config)); Stream reader = new FileStream(<filePath>, FileMode.Open); Config test = (Config)deserializer.Deserialize(reader);
Reading XML files to process the data
To read an xml file while validating it with its schema and have access to the data without having to create a whole class for it I do
XmlReaderSettings xmlSettings = new XmlReaderSettings(); xmlSettings.CloseInput = true; //close the file reader when this xml reader is closed xmlSettings.ConformanceLevel = ConformanceLevel.Document; //i want to validate a whole document, not just a fragment xmlSettings.ValidationType = ValidationType.Schema; //using schemas to validate xmlSettings.ValidationFlags |= System.Xml.Schema.XmlSchemaValidationFlags.ProcessInlineSchema | System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings; xmlSettings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(xmlSettings_ValidationEventHandler); //handler called when there's a validation error xmlSettings.Schemas.Add(null, "<schema File>"); //add <schemaFile> xmlSettings.IgnoreWhitespace = true;
XmlReader coordinatesReader = XmlReader.Create("coordinatesReader.XmlLang", xmlSettings); //finally, create the reader
References
Differences between SimpleType and ComplexType When to use elements vs attributes
.........................................................................................................................
fMRI Analysis under Windows using MNI Tools
[edit]by Alejandro Endo (29/10/07)
The following are instructions to install fmri analysis tools under Windows. To see instruction on how to run the analysis please check Mike Ferrera's Guide
Traditionally, fmri analysis tools developed at the BIC ran under linux or under windows using a linux emulator like Cygwin. The latter was the recommended (and only) way to run a full analysis (preprocessing, linear modeling, contrasts, registration) under Windows that i knew of. I personally do not like emulators and went over the trouble of porting and recompiling all the tools that we needed to run natively under Windows. Since i thought this might be useful for others i decided to create some instructions on how to install everything from scratch easily. Keep in mind that the tools and functions within the tools that i have tested and sometimes fixed are just the ones needed in our lab. These are not completely tested tools in windows; therefore, some feedback would be welcomed. However, i can not take care of fixing bugs or porting other tools since i have other duties in our lab and it is not a brain-imaging-only lab. Requirements
* Matlab (i have run analyses with Matlab R2006a and newer but i would say that any version > Matlab 6 should work) * Windows (we use windows XP Pro in our lab; again, my guess is that anything newer than Windows 2000 should work) * Perl for Windows (Only if you want to run preprocessing such as Motion Correction and/or Blurring, more info on this later)
Steps
You should go through all of them if this is a fresh install. Of course, you can skip some of them if you know you don't need them; they are independent amongst each other
* Installing fmristat & Emma (for linear modeling, contrasts and most of the analyses) * Installing fmr_preprocess (for Data Preprocessing) * Installing register & Display (for data visualization/registration)
Installing fmristat & Emma
Emma is a Matlab toolbox to manipulate MINC files. Official Website fmristat is a set of matlab functions to do general statistical analysis for fMRI data. Official website
The versions available here are not *EXACTLY* the same versions available on the official websites. I have fixed some bugs and improved some issues with them running in Windows instead of Linux (like emma not removing the temp files from the temp directory due to the drive letter in windows “C:”) . I did not modify any of the logic of the code itself so the results should be the same.
* Download Modified Emma * Unzip it to you matlab toolbox directory (e.g. C:\Program Files\MATLAB\R2007a\toolbox\matlab) * Download Modified fmristat * Unzip it to your desired location (e.g. C:\Program Files\MATLAB\R2007a\work) * Download the MINC tools (v2.0.11) * Install the MINC tools * Open Matlab * Change Matlab's current directory to the directory where fmristat was unzipped. e.g. type in the Matlab Comand Window
cd 'C:\Program Files\MATLAB\R2007a\work\fmristat'
* Change the required packages' paths in the installation script.
In Matlab:
edit .\extras\install_fmristat_windows.m
and correct the paths at the beginning of the script
* Run the installation script
Installing register & display
Download the visualization package and unzip it
Optional: Download register.m and put it somewhere in the matlab path. This matlab script will take care of some cleaning of the filenames so that register can open them
To view a file do something like
register('C:\mnc\subj1.mnc'); or register('C:\mnc\anat1.mnc', 'C:\mnc\func1.mnc');
.....................................................................................................................