-
Notifications
You must be signed in to change notification settings - Fork 1
EV creation
Mandy Renfro edited this page Apr 9, 2018
·
15 revisions
The purpose of this script is to isolate specific trial types in order to generate the contrasts in Level 1 analysis. EV creation scripts are typically written using Jupiter Notebook -- this allows quick creation and manipulation of EV file output.
-
Navigate to the following folder:
/home/data/madlab/scripts/tools/sample_scripts
-
Open the sample script
create_ev.ipynb
Always make sure to create a Markdown cell to explain the nature of the present experiment. Keep it simple, but make sure to provide sufficient notes for future researchers/programmers. And always comment your code!
import os
from os.path import join
import numpy as np
import pandas as pd
from glob import glob
- Create arrays containing subject IDs and set/run information:
#subject ids
subs = ['WMAZE_001', 'WMAZE_002', 'WMAZE_004', 'WMAZE_005', 'WMAZE_006',
'WMAZE_007', 'WMAZE_008', 'WMAZE_009', 'WMAZE_010', 'WMAZE_012',
'WMAZE_017', 'WMAZE_018', 'WMAZE_019', 'WMAZE_020', 'WMAZE_021',
'WMAZE_022', 'WMAZE_023', 'WMAZE_024', 'WMAZE_026', 'WMAZE_027']
#three sets
stim_sets = ['set1', 'set2', 'set3']
- Create a loop to grab subject behavioral files:
#loop to grab correct 6 run text files for each subject
for sub in subs:
# Array containing path to behavior files
sub_dir = '/home/data/madlab/data/mri/wmaze/scanner_behav/{0}/'.format(sub)
# Array containing current sub's 6 behavior file runs
dir_file = glob(join(sub_dir, '{0}_wmazebl_2015*.txt'.format(sub)))
# Sort current sub's txt files in order of run
dir_file.sort()
- Create a loop to enumerate through set/run array. In this example, run1 and run2 will be processed in parallel for each set. Please note the removal of the last 3 trials from each run.
#loop through each of the set types
for i, curr_set in enumerate(stim_sets):
# Create dataframe for text files to extract EVS
run1 = pd.read_table(dir_file[i * 2])
run2 = pd.read_table(dir_file[i * 2 + 1])
#removal of the last 3 trials to avoid scanner artifact
run1 = run1[:-3]
run2 = run2[:-3]
- In the planned analysis, the contrast of interest was fixed before correct vs. incorrect conditional trials, so the following code was required to address the "before" part:
#convert dataframes into numpy arrays
run1_trialtype = run1['TrialType'].values
run1_correct = run1['Correct'].values
run1_resp = run1['Resp'].values
run2_trialtype = run2['TrialType'].values
run2_correct = run2['Correct'].values
run2_resp = run2['Resp'].values
# Shift TrialType column by 1 & insert dummy element into first index
run1_trial_shift = run1_trialtype[1:]
run1_trial_shift = np.insert(run1_trial_shift, -1, -1)
run2_trial_shift = run2_trialtype[1:]
run2_trial_shift = np.insert(run2_trial_shift, -1, -1)
# Shift Correct column up by 1 & insert dummy element into first index
run1_correct_shift = run1_correct[1:]
run1_correct_shift = np.insert(run1_correct_shift, -1, -1)
run2_correct_shift = run2_correct[1:]
run2_correct_shift = np.insert(run2_correct_shift, -1, -1)
-
In the above code, the newly created variables containing the values of the pandas data frame column are sliced to remove the first item, after which a "dummy element" is inserted in the last index of the now-converted numpy array. Depending on your unique analysis, this may not be necessary
-
The next step is to isolate the precise trials that will comprise each EV file type. You can do this in a number of ways... here you will see the use of np.where(), which grabs the indices of the targeted trials.
r1_all_b4_B_corr = np.where(((r1_trial_shift == 'B')
& (r1_correct_shift == 1))
& (r1_trialtype != 'BL'))
r1_all_b4_B_incorr = np.where(((r1_trial_shift == 'B')
& (r1_correct_shift == 0))
& (r1_trialtype != 'BL'))
r1_all_remain = np.where((r1_trial_shift != 'B')
& (r1_resp != 'NR')
| (r1_trialtype == 'BL'))
r1_nonresponse = np.where((r1_resp == 'NR'))
r2_all_b4_B_corr = np.where(((r2_trial_shift == 'B')
& (r2_correct_shift == 1))
& (r2_trialtype != 'BL'))
r2_all_b4_B_incorr = np.where(((r2_trial_shift == 'B')
& (r2_correct_shift == 0))
& (r2_trialtype != 'BL'))
r2_all_remain = np.where((r2_trial_shift != 'B')
& (r2_resp != 'NR')
| (r2_trialtype == 'BL'))
r2_nonresponse = np.where((r2_resp == 'NR'))
- The EV files are a 2-D matrix of (n,3) -- three columns of (1) onset time, (2) duration, and (3) amplitude
r1_onsets = run1['StimOnset']
r2_onsets = run2['StimOnset']
#obtain the onset time with indices from np.where()
#don't forget the [0] because np.where() returns a tuple
r1_b4_B_corr_onsets = r1_onsets.values[r1_all_b4_B_corr[0]]
r1_b4_B_incorr_onsets = r1_onsets.values[r1_all_b4_B_incorr[0]]
r1_remain_onsets = r1_onsets.values[r1_all_remain[0]]
r1_nonresponse_onsets = r1_onsets.values[r1_nonresponse[0]]
r2_b4_B_corr_onsets = r2_onsets.values[r2_all_b4_B_corr[0]]
r2_b4_B_incorr_onsets = r2_onsets.values[r2_all_b4_B_incorr[0]]
r2_remain_onsets = r2_onsets.values[r2_all_remain[0]]
r2_nonresponse_onsets = r2_onsets.values[r2_nonresponse[0]]
#use v-stack to create matrix containing *ALL* onsets,
# durations, and amplitudes in vertical columns
r1_mtrx = np.vstack((r1_onsets,
# Numpy array filled with 3's
np.ones(len(r1_onsets)) * 3.0,
# Numpy array filled with 1's
np.ones(len(r1_onsets)))).T
r1_b4_B_corr_mtrx = np.vstack((r1_b4_B_corr_onsets,
np.ones(len(r1_b4_B_corr_onsets))*3.0,
np.ones(len(r1_b4_B_corr_onsets)))).T
r1_b4_B_incorr_mtrx = np.vstack((run1_b4_B_incorr_onsets,
np.ones(len(r1_b4_B_incorr_onsets))*3.0,
np.ones(len(r1_b4_B_incorr_onsets)))).T
r1_all_remain_mtrx = np.vstack((r1_all_remain_onsets,
np.ones(len(r1_all_remain_onsets))*3.0,
np.ones(len(r1_all_remain_onsets)))).T
r1_nonresponse_mtrx = np.vstack((r1_nonresponse_onsets,
np.ones(len(r1_nonresponse_onsets))*3.0,
np.ones(len(r1_nonresponse_onsets)))).T
r2_mtrx = np.vstack((r2_onsets,
np.ones(len(r2_onsets))*3.0,
np.ones(len(r2_onsets)))).T
r2_b4_B_corr_mtrx = np.vstack((r2_before_B_corr_onsets,
np.ones(len(r2_b4_B_corr_onsets))*3.0,
np.ones(len(r2_b4_B_corr_onsets)))).T
r2_b4_B_incorr_mtrx = np.vstack((r2_b4_B_incorr_onsets,
np.ones(len(r2_b4_B_incorr_onsets))*3.0,
np.ones(len(r2_b4_B_incorr_onsets)))).T
r2_all_remain_mtrx = np.vstack((r2_all_remain_onsets,
np.ones(len(r2_all_remain_onsets))*3.0,
np.ones(len(r2_all_remain_onsets)))).T
r2_nonresponse_mtrx = np.vstack((r2_nonresponse_onsets,
np.ones(len(r2_nonresponse_onsets))*3.0,
np.ones(len(r2_nonresponse_onsets)))).T
- Now you only need to create a new directory and save the EV files you have created:
# If the output directory does not exist
if not os.path.exists(join(sub_dir, 'MRthesis/', 'model3_drop3/', 'EVs/')):
# Create it
os.makedirs(join(sub_dir, 'MRthesis/', 'model3_drop3/', 'EVs/'))
# Run 1 matrix
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}.txt'.format(i * 2 + 1),
r1_mtrx, delimiter='\t', fmt='%.4f')
# A before CORRECT B ONLY
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_before_B_corr.txt'.format(i * 2 + 1),
r1_before_B_corr_mtrx, delimiter='\t', fmt='%.4f')
# A before INCORRECT B ONLY
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_before_B_incorr.txt'.format(i * 2 + 1),
r1_before_B_incorr_mtrx, delimiter='\t', fmt='%.4f')
# All-remaining ONLY
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_all_remain.txt'.format(i * 2 + 1),
r1_all_remain_mtrx, delimiter='\t', fmt='%.4f')
# Nonresponse ONLY
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_nonresponse.txt'.format(i * 2 + 1),
r1_nonresponse_mtrx, delimiter='\t', fmt='%.4f')
# Run 2 files
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}.txt'.format(i * 2 + 2),
r2_mtrx, delimiter='\t', fmt='%.4f')
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_before_B_corr.txt'.format(i * 2 + 2),
r2_before_B_corr_mtrx, delimiter='\t', fmt='%.4f')
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_before_B_incorr.txt'.format(i * 2 + 2),
r2_before_B_incorr_mtrx, delimiter='\t', fmt='%.4f')
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_all_remain.txt'.format(i * 2 + 2),
r2_all_remain_mtrx, delimiter='\t', fmt='%.4f')
np.savetxt(sub_dir + '/MRthesis/' + 'model3_drop3/' + 'EVs/' +
'r{0}_nonresponse.txt'.format(i * 2 + 2),
r2_nonresponse_mtrx, delimiter='\t', fmt='%.4f')
- Once the script is complete, hit "Run" in Jupiter Notebook. Make sure to save when finished!
- Go the the output directory and open one of each type of EV file you have created.
- Compare the EV files' onset times to the original behavioral files to ensure that you grabbed the intended trials. This is the most likely point of error in your analyses, so take the extra time to double-check
- Each script to produce EV files will need to be customized to the precise analysis you wish to conduct.
- The EV files each represent a separate regressor for the general linear model in the Level 1 script.
- Moving DICOMs to HPC
- DICOM Conversion
- Freesurfer Recon_All, Quality Assurance, and Resubmission
- Preprocessing
- Normalization To Be Completed
- Creation of EV Files
- First Level Analysis
- Second Level Analysis To Be Completed
- Group Level Analysis To Be Completed
- DWI To Be Completed