Skip to content

Commit

Permalink
SART behavioural measures extraction
Browse files Browse the repository at this point in the history
- find all the correct GO and incorrect NO-GO events and calculate the response times via button press
- calculate descriptives for the response times and export
  • Loading branch information
teanijarv committed May 29, 2023
1 parent 10805cd commit cf33948
Showing 1 changed file with 65 additions and 45 deletions.
110 changes: 65 additions & 45 deletions templates/sart/sart_erp_preprocessing.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@
"\n",
"# Event names with IDs for GO and NO-GO trials\n",
"event_dict = {'GO trial': 4,\n",
" 'NO-GO trial': 8}\n",
" 'NO-GO trial': 8,\n",
" 'Button press': 16}\n",
"\n",
"# Button press ID\n",
"button_id = 16"
Expand Down Expand Up @@ -132,43 +133,90 @@
" .set_eeg_reference(ref_channels='average', verbose=False)\n",
" \n",
" # Filter the signal with bandpass filter and remove EOG artefacts with SSP\n",
" filt = prep.filter_raw_data(raw,filter_design, line_remove=None, eog_channels=eog_channels,\n",
" filt = prep.filter_raw_data(raw, filter_design, line_remove=None, eog_channels=eog_channels,\n",
" plot_filt=False, savefig=False, verbose=False)\n",
" \n",
" # Find events from the filtered EEG data and name them\n",
" events = mne.find_events(filt, stim_channel=stimulus_channel, consecutive=False, output='onset')\n",
" \n",
" # Create an array and dataframe of successful GO (followed with button press) and NO-GO trials (no button press)\n",
" success_go_nogo_events = []\n",
" success_events_total = []\n",
" success_go = []\n",
" unsuccess_nogo = []\n",
" df_success_temp = pd.DataFrame(index=[subject_names[i]],\n",
" data={'Total GO' : np.sum(events[:, 2] == event_dict['GO trial']),\n",
" 'Total NO-GO' : np.sum(events[:, 2] == event_dict['NO-GO trial']),\n",
" 'Correct GO': 0, 'Correct NO-GO': 0})\n",
" 'Correct GO': 0, 'Correct NO-GO': 0,\n",
" 'Incorrect GO': 0, 'Incorrect NO-GO': 0})\n",
" # Go through all events to check if they were successful or not\n",
" for m in range(len(events)):\n",
" if events[m][2] == event_dict['GO trial'] and events[m+1][2] == button_id:\n",
" success_go_nogo_events.append(events[m])\n",
" df_success_temp['Correct GO'] += 1\n",
" if events[m][2] == event_dict['NO-GO trial'] and events[m+1][2] != button_id:\n",
" success_go_nogo_events.append(events[m])\n",
" df_success_temp['Correct NO-GO'] += 1\n",
" success_go_nogo_events = np.asarray(success_go_nogo_events)\n",
" df_success_temp['Incorrect GO'] = df_success_temp['Total GO'] - df_success_temp['Correct GO']\n",
" df_success_temp['Incorrect NO-GO'] = df_success_temp['Total NO-GO'] - df_success_temp['Correct NO-GO']\n",
" # If event is a GO, check for button press\n",
" if events[m][2] == event_dict['GO trial']:\n",
" if events[m+1][2] == button_id:\n",
" # If there is a button press -> success\n",
" success_events_total.append(events[m])\n",
" success_events_total.append(events[m+1])\n",
" success_go.append(events[m])\n",
" success_go.append(events[m+1])\n",
" df_success_temp['Correct GO'] += 1\n",
" else:\n",
" # If there is no button press -> fail\n",
" df_success_temp['Incorrect GO'] += 1\n",
" # If event is a NO-GO, check for no button press\n",
" if events[m][2] == event_dict['NO-GO trial']:\n",
" if events[m+1][2] != button_id:\n",
" # If there is no button press -> success\n",
" success_events_total.append(events[m])\n",
" df_success_temp['Correct NO-GO'] += 1\n",
" else:\n",
" # If there is a button press -> fail\n",
" unsuccess_nogo.append(events[m])\n",
" unsuccess_nogo.append(events[m+1])\n",
" df_success_temp['Incorrect NO-GO'] += 1\n",
" success_events_total = np.asarray(success_events_total)\n",
" success_go = np.asarray(success_go)\n",
" unsuccess_nogo = np.asarray(unsuccess_nogo)\n",
"\n",
" # Calculate response times to button press for correct GO and incorrect NO-GO\n",
" if len(success_go)!=0:\n",
" rt_go = np.diff(success_go[:, 0])[0::2]/raw.info['sfreq']\n",
" else:\n",
" rt_go = 0\n",
" if len(unsuccess_nogo)!=0:\n",
" rt_nogo = np.diff(unsuccess_nogo[:, 0])[0::2]/raw.info['sfreq']\n",
" else:\n",
" rt_nogo = 0\n",
"\n",
" # Calculate descriptives for these response times\n",
" df_success_temp['Average RT (Correct GO)'] = np.mean(rt_go)\n",
" df_success_temp['Average RT (Incorrect NO-GO)'] = np.mean(rt_nogo)\n",
" df_success_temp['SD RT (Correct GO)'] = np.std(rt_go)\n",
" df_success_temp['SD RT (Incorrect NO-GO)'] = np.std(rt_nogo)\n",
" df_success_temp['Median RT (Correct GO)'] = np.median(rt_go)\n",
" df_success_temp['Median RT (Incorrect NO-GO)'] = np.median(rt_nogo)\n",
" df_success_temp['Minimum RT (Correct GO)'] = np.min(rt_go)\n",
" df_success_temp['Minimum RT (Incorrect NO-GO)'] = np.min(rt_nogo)\n",
" df_success_temp['Maximum RT (Correct GO)'] = np.max(rt_go)\n",
" df_success_temp['Maximum RT (Incorrect NO-GO)'] = np.max(rt_nogo)\n",
" df_success_temp['RTs (Correct GO)'] = str(rt_go)\n",
" df_success_temp['RTs (Incorrect NO-GO)'] = str(rt_nogo)\n",
"\n",
" # Merge the participant dataframe with the master dataframe\n",
" df_success = pd.concat([df_success, df_success_temp])\n",
" \n",
"\n",
" # Plot all the events\n",
" %matplotlib inline\n",
" fig, axs = plt.subplots(1, 1, figsize=(10, 5))\n",
" fig = mne.viz.plot_events(success_go_nogo_events, sfreq=filt.info['sfreq'],\n",
" fig = mne.viz.plot_events(success_events_total, sfreq=filt.info['sfreq'],\n",
" first_samp=filt.first_samp, event_id=event_dict,\n",
" axes=axs, show=False)\n",
" fig.subplots_adjust(right=0.7)\n",
" axs.set_title('Successful events ({})'.format(subject_names[i]))\n",
" plt.show()\n",
"\n",
" # Create epochs time-locked to successful GO and NO-GO events\n",
" # Create epochs time-locked to successful GO and NO-GO events (without including the button press events)\n",
" picks = mne.pick_types(filt.info, eeg=True, stim=False)\n",
" epochs = mne.Epochs(filt, success_go_nogo_events, event_id=event_dict,\n",
" epochs = mne.Epochs(filt, success_events_total[success_events_total[:, 2] != 16], event_id=event_dict,\n",
" tmin=tminmax[0], tmax=tminmax[1], baseline=baseline_correction,\n",
" picks=picks, preload=True)\n",
" \n",
Expand Down Expand Up @@ -207,34 +255,6 @@
"# Save the dataframe for task performance\n",
"df_success.to_excel('{}/{}/{}_task_performance.xlsx'.format(results_folder,exp_folder,exp_condition))"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Difference between unique events (just for checking)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"df_gotrials = pd.DataFrame(events[events[:,2]==4][:,0]/epochs.info['sfreq'])\n",
"df_gotrials['Event'] = 'GO'\n",
"df_nogotrials = pd.DataFrame(events[events[:,2]==8][:,0]/epochs.info['sfreq'])\n",
"df_nogotrials['Event'] = 'NO-GO'\n",
"\n",
"df_trials = pd.concat([df_gotrials, df_nogotrials]).sort_values(by=0).reset_index(drop=True)\n",
"df_trials = df_trials.rename(columns={0: 'Timepoint'})\n",
"\n",
"df_trials['Difference'] = df_trials['Timepoint'].diff()\n",
"\n",
"df_trials.describe()"
]
}
],
"metadata": {
Expand Down

0 comments on commit cf33948

Please sign in to comment.