Tuesday, October 16, 2007

SDT Analysis in SPSS

This evening I was trying to figure out how to run signal detection analysis (SDT) using SPSS, rather than having to caculate SDT parameters (e.g., d') in Excel first and then do the statistical analysis in SPSS. Not that I have any concern about the accuracy of the output from Excel. I just don't trust myself to be able to calculate everything manually in Excel and not making a single mistake the entire time (even if I can do it once in a while, I don't think I can finish the process without any mistake everytime). I decided that if I can figure out how to calculate the SDT parameters in SPSS, it would greatly improve the accuracy of the analysis, and reduce the time needed to conduct the analysis and double check the accuracy.

The calculation of d' is pretty straight forward in theory. It's given by the distance between the center of the hypothesized distributions of signal and no signal (noise), divided by the spread of the distributions. This could then be further translated into this formula: d' = z(hit) - z(false alarm).

The main problem I encountered was that even though I know how to calculate the inversed culmulative normal distribution in in Excel (given by the function NORMSINV), I don't know how to do the same thing in SPSS. I tried google "sdt analysis in spss," "how to calculate d prime in spss," ... etc but didn't really find what I needed. Then I googled "NORMSINV equivalent in spss" and I came across this following document:

http://www.stat.auckland.ac.nz/~leila/07S2_SPSS_Excel_Workshop_II.pdf

Luckily this document is exactly what I was looking for: it introduces how to calculate culmulative normal districution functions in SPSS AND in Excel. To calculate d' and other SDT parameters in SPSS, you can use the following syntax (these are specifically for 2AFC tasks):

===================================
COMPUTE dprime = (IDF.NORMAL(HitRate,0,1) - IDF.NORMAL(FArate,0,1))/SQRT(2) .
EXECUTE .
COMPUTE c = -.5*(IDF.NORMAL(HitRate,0,1) + IDF.NORMAL(FArate,0,1)) .
EXECUTE .
COMPUTE cprime = c/(IDF.NORMAL(HitRate,0,1) - IDF.NORMAL(FArate,0,1)) .
EXECUTE .
===================================

In the context of a 2AFC task (let's say stimulus A and stimulus B), HitRate refers to the probablity of responding A when A is presented, and FArate refers to the probability of responding A when B is presented.

Because I started with the trial by trial data in the analysis, I had to aggregate and restructure the data several times in order to calculate the SDT parameters and then run the repeated measures ANOVA. However, once the syntax file is set up, if I want to run the same analysis again, all I need to do is change the file names that get retrieved and saved in the syntax, and then click on the run all icon. Then the entire analysis could be done within seconds :)

Labels: ,

Monday, October 15, 2007

AEEG Self Testing



This afternoon I was testing the AEEG recording by my self in the ERP lab. The idea is that you can have your EEG recorded while you are doing thing you normally do in real life. For this purpose, the system is made really small that people can carry it around while being recorded. The system that we are using is called TRACKIT. You can have an idea of its size from the picture.

The motage I used in the testing session is as follows:
Channel 1: Cz
Channel 2: on my left hand (added half way through the recording just for fun)
Referrence: Left mastoid (I used this for reference because it led to weaker eye-blink artifact)
Neutral: Fp1

To maximize the similarity between the recording settings of this session and our past AEP recording sessions, I also played the 2 vs 12 Hz sweep contrast (three 12 Hz sounds followed by one 2 Hz) in the background. I tried playing through earbud earphones, but that somehow screwed up the recording (my guess is that the potentials recorded from the reference site was too strong). So I played the sweeps at a much lower intensity then we had played for our prior participants because I didn't want to piss off people in the nearby rooms.

Other things I noticed that would influence the signals from the non-recording sites:

a. Where you place the amplifier (which connects the electrodes to TRACKIT). Perhaps this influences the electrical noises that get pick up from the empty connectors. For example, when the amplifier touched the desktop, the recording got screwed up.

b.When I touched the cord that connected the amplifier to TRACKIT (either directly with my figer or indirectly with a pen), the recording got messed up as well

c. When I tried to use my macbook (ran on battery) or use mighty mouse, the noises in non-recording channels increased dramatically (sometimes as bad as a and b). However when I reduced the contact surface (for example by covering most of my palm with my sleeve), that helped reduced the distortion in the signal

Labels:

Thursday, October 11, 2007

Painful (Elementary Level) Debugging

OMG.... I can't believe I made so many mistakes in such a simple script....

I was running data analysis in the library this afternoon, and need the last 2 digits of my 9-digit item number to recode some information (not the smartest item number scheme, I must admit). After I recoded all the variables necessary for the bias analysis, I then aggregated the raw data so that I could restructure the data format by subject for spss to run repeated measures ANOVA. When I opened the aggregated file, I found that for some subjects some of the recoded variables were lacking. This was when I found out that my item number had been messed up before they were imported to spss. If everything had worked correctly, there should be 8 possible values of the last two digits, and there should be equal number of cases for each possible values. However that was only true for my list 1 subjects.

Then I went back to inspect the Matlab script I used to extract the azk file. I tried everything I could imagine to save the mistake. Just to make a long story short, the problem (I think) was that I scanned the item numbers in the wrong number format. I used f32 to scan the 3 columns in the azk output. However, whereas f32 is good for scanning RT and COT values, it's not ideal for scanning item numbers. This is because the item number is always an integer, scanning them as floating point numbers would waste the precision on the none existent decimals.

In the end I just changed one small thing and the problem was saved. I feel really dumb because I actually used the correct format to scan the data in an earlier version of the script, but somehow I changed the format for some unknown reason afterwards, and created all these troubles for myself. The only thing that's conforting is that, I have learned my lesson, and I can confidently say that I know a bit better today and yesterday. I guess that's the most important thing :)

Labels: ,

Tuesday, October 09, 2007

textscan and textread

Last week I was trying to demonstrate to my RA Jenn how I used the Matlab script to extract data from DMDX azk files and pull the data from all lists into onecomplete file. I tried to demonstrate on the computer in Park 320, so that she will be able to do the same if I give her similar assignments.

However I forgot one important thing - the Matlab installed on computers in 320 is 6.5, whereas I composed the script in the Matlab 7 on my laptop. The main command I used in the script - textcan - does not come into existance until Matlab 7. The comparable command to use in Matlab 6.5 is textread, which has very similar argument structure to textscan. The main differece is the format of the data read in, and therefore how the data are referred to in the following scriptfor any manipulation. One main problem I have right now is that I cannot utilize the participant ID information from the read in matrix. I thought the format of this cell would be the same as when it's read in by textscan (string). But it doesn't seems to work this way. I'm puzzled exceedingly...

No wonder it didn't work when I demo the process in PC.... I swithced the demo to my laptop immediately, but it wasn't util several days later that I realized where the problem had came from.
I am hoping that other members in the lab can also benefit from the scripts I created, so I'm still trying to modify the scripts for Matlab 6.5. However, judging from the number of other random tasks that constantly fall on me, I serious doubt when I will have a big chunk of time to play with my scripts....

Labels: ,