@@ -8,25 +8,29 @@ cat("session started:", as.character(Sys.time()), "\n\n")
88# clear environment
99rm(list = ls())
1010
11+ # load required libraries
12+ library(tidyverse )
13+ library(jsonlite )
14+
1115# load configuration & functions
1216source(" config/paths.R" )
1317
1418# get repo root from paths
15- repo_root <- file.path(here :: here(), " .." , " .." , " .. " )
19+ repo_root <- file.path(here :: here(), " .." , " .." )
1620
1721source(" config/settings.R" )
1822source(" functions/load_behavioral_data.R" )
1923source(" functions/load_eeg_trial_info.R" )
2024source(" functions/apply_eeg_exclusions.R" )
2125source(" functions/apply_rt_trimming.R" )
2226source(" functions/check_inclusion_criteria.R" )
23- source(" functions/validate_against_eeg.R" )
2427source(" functions/generate_reports.R" )
2528
2629# === user input: define subject list ===
2730# slash-separated string of subject IDs to be processed in this run
2831# leave empty ("") to process all available subjects
29- subjects_to_process = " 390002/390003/390004/390005/390006/390007/390008/390009/390010/390011/390012/390013/390014/390015/390020/390021/390022/390023/390024/390025/390026/390027/390028/390030/390031/390032/390033/390034/390036/390037/390038/390039/390041/390042" ;
32+ # subjects_to_process = "390001/390002/390003/390004/390005/390006/390007/390008/390009/390010/390011/390012/390013/390014/390015/390020/390021/390022/390023/390024/390025/390026/390027/390028/390030/390031/390032/390033/390034/390036/390037/390038/390039/390041/390042/390043/390044";
33+ subjects_to_process = " 390035"
3034
3135# parse subject list
3236if (subjects_to_process == " " ) {
@@ -100,11 +104,94 @@ inclusion_file <- file.path(output_dir, "inclusion_summary.rds")
100104saveRDS(inclusion_summary , inclusion_file )
101105cat(" saved inclusion summary to:" , inclusion_file , " \n " )
102106
107+ processing_params <- list (
108+ rt_lower_bound = RT_LOWER_BOUND ,
109+ rt_outlier_threshold = RT_OUTLIER_THRESHOLD ,
110+ min_accuracy = MIN_ACCURACY ,
111+ min_trials_per_code = MIN_EPOCHS_PER_CODE
112+ )
113+
114+ # === SAVE CSV OUTPUTS FOR MATLAB ===
115+ cat(" \n === SAVING CSV OUTPUTS FOR MATLAB ===\n " )
116+
117+ # 1. save behavioral summary as CSV for MATLAB
118+ behavioral_summary_csv <- inclusion_summary %> %
119+ select(
120+ subject ,
121+ included ,
122+ exclusion_reason ,
123+ accuracy ,
124+ total_trials ,
125+ n_code_102 , n_code_104 , n_code_111 , n_code_112 , n_code_113 ,
126+ n_code_202 , n_code_204 , n_code_211 , n_code_212 , n_code_213
127+ ) %> %
128+ mutate(
129+ included = as.numeric(included ), # convert TRUE/FALSE to 1/0
130+ exclusion_reason = replace_na(exclusion_reason , " none" )
131+ )
132+
133+ behavioral_summary_file <- file.path(output_dir , " behavioral_summary.csv" )
134+ write_csv(behavioral_summary_csv , behavioral_summary_file )
135+ cat(" saved behavioral summary csv to:" , behavioral_summary_file , " \n " )
136+
137+ # 2. save trial-level data as CSV for MATLAB (if needed for future analyses)
138+ behavioral_trials_csv <- behavioral_with_rt %> %
139+ select(
140+ subject ,
141+ trial_idx ,
142+ code ,
143+ rt = flankerResponse.rt ,
144+ accuracy = responseType ,
145+ in_eeg ,
146+ eeg_analysis_ready ,
147+ eeg_exclusion_reason ,
148+ rt_exclusion_reason
149+ ) %> %
150+ mutate(
151+ in_eeg = as.numeric(in_eeg ),
152+ eeg_analysis_ready = as.numeric(eeg_analysis_ready ),
153+ accuracy = as.numeric(accuracy ),
154+ eeg_exclusion_reason = replace_na(eeg_exclusion_reason , " none" ),
155+ rt_exclusion_reason = replace_na(rt_exclusion_reason , " none" )
156+ )
157+
158+ behavioral_trials_file <- file.path(output_dir , " behavioral_trials.csv" )
159+ write_csv(behavioral_trials_csv , behavioral_trials_file )
160+ cat(" saved trial-level data csv to:" , behavioral_trials_file , " \n " )
161+
162+ # 3. save processing metadata as JSON for documentation
163+ metadata <- list (
164+ processing_date = Sys.time(),
165+ parameters = processing_params ,
166+ n_subjects_processed = n_distinct(behavioral_data $ subject ),
167+ n_subjects_included = sum(inclusion_summary $ included ),
168+ n_subjects_excluded = sum(! inclusion_summary $ included ),
169+ output_files = list (
170+ behavioral_summary = " behavioral_summary.csv" ,
171+ behavioral_trials = " behavioral_trials.csv" ,
172+ subject_summary_table = paste0(" subject_summary_table_" , format(Sys.time(), " %Y-%m-%d_%H-%M-%S" ), " .txt" )
173+ )
174+ )
175+
176+ metadata_file <- file.path(output_dir , " processing_metadata.json" )
177+ jsonlite :: write_json(metadata , metadata_file , pretty = TRUE )
178+ cat(" saved processing metadata to:" , metadata_file , " \n " )
179+
103180# generate reports
104181cat(" \n === GENERATING REPORTS ===\n " )
105182
106- # subject summary table
107- subject_table <- generate_subject_summary_table(
183+ # generate reports
184+ cat(" \n === GENERATING REPORTS ===\n " )
185+
186+ # generate both summary tables
187+ behavioral_table <- generate_behavioral_summary_table(
188+ behavioral_with_rt ,
189+ inclusion_summary ,
190+ output_dir ,
191+ verbose = TRUE
192+ )
193+
194+ erp_table <- generate_erp_summary_table(
108195 behavioral_with_rt ,
109196 inclusion_summary ,
110197 output_dir ,
@@ -119,36 +206,9 @@ processing_params <- list(
119206 min_trials_per_code = MIN_EPOCHS_PER_CODE
120207)
121208
122- cat(" \n === VALIDATION ===\n " )
123-
124- # validate against most recent eeg postprocessing
125- # find most recent eeg postprocessing date
126- eeg_dates <- list.dirs(derivatives_dir ,
127- full.names = FALSE , recursive = FALSE )
128- eeg_dates <- eeg_dates [grepl(" _erp-postprocessing$" , eeg_dates )]
129-
130- if (length(eeg_dates ) > 0 ) {
131- most_recent_eeg <- sort(eeg_dates , decreasing = TRUE )[1 ]
132- eeg_date <- gsub(" _erp-postprocessing" , " " , most_recent_eeg )
133-
134- cat(" \n validating against eeg postprocessing from:" , eeg_date , " \n " )
135-
136- eeg_summary <- load_eeg_summary_table(eeg_date , derivatives_dir )
137- validation_results <- validate_trial_counts(inclusion_summary , eeg_summary , verbose = TRUE )
138-
139- # save validation results
140- validation_file <- file.path(output_dir , " validation_results.rds" )
141- saveRDS(validation_results , validation_file )
142- cat(" \n saved validation results to:" , validation_file , " \n " )
143- } else {
144- cat(" \n warning: no eeg postprocessing folders found, skipping validation\n " )
145- }
146-
147- # generate final summary report (needs validation results)
148209summary_report <- generate_postprocessing_summary(
149210 behavioral_with_rt ,
150211 inclusion_summary ,
151- validation_results ,
152212 output_dir ,
153213 processing_params ,
154214 verbose = TRUE
0 commit comments