General Overview
You will find below the detail of an advanced analysis of a MEG experiment with the tools available at CENIR. These commands were used to analyze the AEMOS experiment (See S. Dubal and collaborators for more details).
Pre processing
Mean Head Position Computation
This first step uses dataHandler to compute a mean head position by averaging the initial had position of each run. This mean head position is then displayed using megDraw.
Code Block | ||||
---|---|---|---|---|
| ||||
## Compute mean head position by averaging initial head positions in all runs
dataHandler_dev -r -avg run??.fif -hp mean -time 0 -.1 meanhp.fif
## Generate *.hc files for each run
dataHandler_dev -r -hc run??.fif meanhp.fif
## Visualize each initial head position and computed mean position (this step is optional)
megDraw *.hc
|
:hcfig.png?250|Head positions example
tSSS Computation
We used maxfilter to correct for all the main non biological artifacts arising during the recording. maxfilter is configured here to check for bad channels on the entire dataset thanks to the duration computed with dataHandler. The head position for each run is transformed to the above computed mean head position and the MEG signals are recomputed accordingly. If needed you can add manualy bad channels with -bad option.
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run*.fif)
set log = `echo $run | sed "s/.fif/_sss.log/"`
set duration=`dataHandler -header $run | grep Duration | cut -d " " -f 2 `
maxfilter -gui -st $duration -trans meanhp.fif -f $run > $log
## In case of bad channels not detected
## maxfilter -gui -bad 0121 -st $duration -trans meanhp.fif -f $run > $log
end
|
Triggers Generation
You have to check the quality of the MaxFilter output before going further in your analysis.
First, we use dataHandler to generate the trigger list and add a new marker named "BAD". This marker will be used to mark artifacts and others part of the signals we do not want to use in the analysis.
Then you will use muse to double check the MaxFilter output.
Code Block | ||||
---|---|---|---|---|
| ||||
dataHandler -touchmarker BAD run*trans_sss.fif
muse_dev run01_trans_sss.fif
|
...
We then generate all the markers necessary to the signals analysis. This step depends heavily on your own setup.
The first step is to extract the triggers acquired during the experiment.
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run??_trans_tsss.fif)
dataHandler -r -triggers -ch STI101 $run
end
|
We then convert the acquisition triggers into something more readable (for the to be written triggers equations):
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run??_trans_tsss.fif)
## An alias to dataHandler command to simplify the coming call to dataHandler
alias dh "dataHandler_dev -r $run"
## Rename acquisition markers
dh -adm "T1=STI101_01"
dh -adm "T2=STI101_02"
dh -adm "T3=STI101_03"
dh -adm "T4=STI101_04"
dh -adm "T5=STI101_05"
dh -adm "T6=STI101_06"
dh -adm "T7=STI101_07"
dh -adm "T8=STI101_08"
## Optionally you can then delete STI101 marker
dh -delm_m STI101
end
|
The next step is to generate your markers of interest (to be used to compute Evoked Potential, Time-Frequency map, to perform localization …)
Code Block | ||||
---|---|---|---|---|
| ||||
set code = "T5 T6 T7 T8;"
foreach run (run??_trans_tsss.fif)
## An alias to dataHandler command to simplify the coming call to dataHandler
alias dh "dataHandler_dev -r $run"
# Fix, Stimulus and Task
dh -adm "Fixation=T1"
dh -adm "Prime=T2"
dh -adm "Target=T3"
dh -adm "Scale= T8"
dh -adm "Response=T4"
## (sub) Tasks (combination of T5, T6, T7 & T8 markers)
dh -adm "PCongruent=Prime & ($ |
...
5)"
dh -adm "PNoPrime=Prime & (($
Code Block |
---|
4) | ($ |
5))"
Subject response decoding (combination of T5, T6, T7 & T8 markers)
dh -adm "R1=Response & ($Code Block 1)" dh -adm "R2=Response & ($
2)"
dh -adm "R3=Response & ($Code Block 3)" dh -adm "R4=Response & ($
4)"
dh -adm "R5=Response & ($Code Block 5)" dh -adm "R6=Response & ($
6)"
dh -adm "R7=Response & ($Code Block 7)" dh -adm "R8=Response & ($
8)"
dh -adm "R9=Response & ($Code Block 9)" end
If you need an accurate timing with respect to your visual stimulation, you have to put a trigger on the signal coming from the photodiode (the threshold should be adapted, take a look with muse to choose the right one, and check the result of the detection and the corresponding delay in the log file!)
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run??_trans_tsss.fif)
## An alias to dataHandler command to simplify the coming call to dataHandler
alias dh "dataHandler_dev -r $run"
#Photodiode crossing including the threshold
dh -thd LIGHT 1 1 -ch MISC002
# display the synchronization between stimulus onset and the photodiode
dh -rt Target LIGHT > PhotoD_Sync_${run}.log
end
|
...
As a first step you to retreive the eyelinks files and to put them in a directory named eyelink. The dataHandler matches triggers channels from eyelink and meg recording to synchronize the files.
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run01 run02 run03 run04 run05 run06 run07 run08 run09 run10 run11)
## An alias to dataHandler command to simplify the coming call to dataHandler
alias dh "dataHandler_dev -r $run"
dh -edf eyelink/${run}.asc
end
|
Blink Detection
You can then run the blink detection using dataHandler. Check the results, if not enough blink is detected decrease maxvar option, if too many blinks are detected lower it and rerun the command. Of course your vertical EOG should be on BIO002 (standard location) and it should be reasonably clean (without artifacts bigger than the blinks amplitudes).
Code Block | ||||
---|---|---|---|---|
| ||||
dataHandler -tm BLINK maxvar -5 -ch BIO002 -time -.15 .6 -r run*trans_sss.fif > blinks.log
|
:blinkdetection.png?500|
QRS detection
Same thing for cardiac artifact, you should have a number of artifacts more or less equivalent to the number of seconds in your recordings (check the cardio.log file! you should find a line similar to this one: ExtractTemplate: corrected correlation: total points = 670 — we had a 10 minutes run so 670 fits well).
Code Block | ||||
---|---|---|---|---|
| ||||
dataHandler -r -tm CARDIO auto -.6 -hpf .3 -time 0 .6 -ch BIO003 run*trans_sss.fif > cardio.log
|
:cardioexample.png?500|
QRS Artifact correction
Once the cardiac artifacts are detected (please check the output of the previous dataHandler command!), run the following call to dataHandler to correct the cardiac artifacts. The output will be stored in cardiocor_run*.fif files.
Code Block | ||||
---|---|---|---|---|
| ||||
dataHandler -r -pcavg CARDIO 2 -time -.1 .6 -mag -grad *trans_sss.fif -new cardiocor_ > corrcardio.log
|
Adding markers based on eyelink markers and others artifact markers
Here we generate the final markers to be used for averaging and others processing by taking into account markers from the eyelink recordings and manually marked events (muscle activity).
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run (run??_trans_tsss.fif)
alias dh "dataHandler -r $run"
# defines EYE events as blinks and start of saccades > 5 degrees
dh -adm "EYE = EL_ESACC_L_5 |EL_SBLINK_L_ |EL_EBLINK_L_ | EL_ESACC_R_5 |EL_SBLINK_R_ |EL_EBLINK_R_ "
dh -adm "BLINK = EL_SBLINK_L_ |EL_EBLINK_L_ |EL_SBLINK_R_ |EL_EBLINK_R_"
# select targets without EYE events in given range
# one way is to define a fixed period "eyefree" around target
dh -adm "FixPost=Fixation+.4"
# defines FixOK in coincidence with FixPost
dh -adm "FixOK=FixPost[Prime]&EYE~"
# defines TargetOK in coincidence with Target, when immediately following a FixOK
dh -adm "PaintOK=Target[Scale]&EYE~"
dh -adm "TargetOK=PaintOK[-3 2.5]&FixOK"
dh -adm "BlinkTarget=Target[Scale]&BLINK"
# defines MUSCLE events indicated by bad markers
dh -adm "MUSCLE = BAD"
# select trials without MUSCLE events in given range
dh -adm "MuscleOK=Fixation[Scale]&MUSCLE~"
# select trials without clean baseline and target periods
dh -adm "TrialOK=TargetOK[-3 2.5]&MuscleOK" > selectevents_5deg_${run}.log
end
|
Basic Triggers manipulation & Basic Averaging
You can then start averaging steps to obtain your evoked potentials:
Code Block | ||||
---|---|---|---|---|
| ||||
foreach run in (cardiocor_*sss.fif)
alias dh "dataHandler -r -avg $run "
foreach cond (PCongruent PIncongruent PNoAction PNoPrimeBeginning PNoPrimeEnd)
# baseline is taken from FixOK (.3s after Fixation) to Priming.
dh -sync "TrialOK[-1.1 .5]&${cond}" -rbm FixOK 0 .2 -time -.1 1.1 CC_${cond}_5d.fif > averages.log
end
end
|
...