#! /usr/bin/gawk -f # Last edited on 2013-11-30 05:54:00 by stolfilocal BEGIN { # Extracts several segments from runs and concatenates them, and writes # the result to standard output. # # The segments are specified in the standard input. Each input line must have one # segment specification per line # # {SUBJID} {RUNID} {TINI} {TFIN} # # These parameters must be defined with the "-v" option: if (dir == "") { arg_error(("muet define {dir}")); } # The program reads the EEG data file "{dir}/s{SUBJID}_r{RUNID}.txt" and outputs # the lines (frames) in the time interval from {TINI} to {TFIN} # (in seconds, from the start of the file. # All files must have the same sampling frequency {fsmp}, number of channels # {nc}, number of electrodes {ne}, and channel names. abort = -1; # Specific for the 2013 128-electrode dataset ne = -1; # Number of electrodes. nc = -1; # Number of channels. fsmp = -1; # Sampling frequency. channels = ""; # Channel names separated by space. nsegs = 0; # Number of segments. nframes = 0; # Total frames written out. } (abort >= 0) { exit(abort); } # Remove comments: // { gsub(/[ ]*[#].*$/, "", $0); } # Skip blank lines: /^[ ]*$/ { next; } # process data lines: /^[ ]*[0-9]+[ ]+[0-9]+[ ]/ { if (NF != 4) { data_error(("invalid line format")); } sid = $1; rid = $2; tini = process_time($3, "tini"); tfin = process_time($4, "tfin"); fname = (dir "/s" sid "_r" rid ".txt"); extract_segment(fname, tini, tfin); nsegs++; next; } // { data_error(("invalid line format")); } function process_time(t, name) { if (t !~ /^[-+]?[0-9]+([.][0-9]+|)$/) { data_error(("invalid field " name " = \"" t "\"")); } t = t + 0.0; return t; } function extract_segment(fname,tini,tfin, nt,nts,nlin,lin,nfld,fld,t) { nt=0; # Number of data frames read from {fname}. nts=0; # Number of data frames written in this segment. nlin=0; # Number of lines (inc. header) while((getline lin < fname) > 0) { nlin++; if (match(lin, /^[ ]*([#]|$)/)) { # Commenth or blank, ignore. } else if (match(lin, /^[ ]*[a-zA-Z_.]+[ ]*[=]/)) { # Header line, check relevant fields: sub(/[ ]*[=][ ]*/, "=", lin); nfld = split(lin, fld, "="); if (fld[1] == "nc") { nc = check_int(fld[2],fname,nlin,"nc",nc); } else if (fld[1] == "ne") { ne = check_int(fld[2],fname,nlin,"ne",ne); } else if (fld[1] == "fsmp") { fsmp = check_float(fld[2],fname,nlin,"fsmp",fsmp); } else if (fld[1] == "channels") { channels = check_string(fld[2],fname,nlin,"channels",channels); } } else if (match(lin, /^[ ]*[-+]?[0-9]/)) { # Data line if (fsmp < 0) { segment_error(fname, nlin, "missing {fsmp} in header"); } t = (nt + 0.5)/fsmp; if ((t >= tini) && (t <= tfin)) { printf "%s\n", lin; nts++; nframes++; } nt++; } else { segment_error(fname, nlin, "invalid EEG data line format"); } } if ((ERRNO != "") && (ERRNO != "0")) { segment_error(fname, nlin, ERRNO); } close (fname); if (nlin == 0) { data_error(("file \"" fname "\" empty or missing")); } printf " %s extracted %d frames\n", fname, nts > "/dev/stderr" } function check_int(x,fname,nlin,name,oval, val) { gsub(/^[ ]+/, "", x); gsub(/[ ]+$/, "", x); if (x !~ /^[-+]?[0-9]+$/) { segment_error(fname,nlin,("invalid field " name " = \"" x "\"")); } val = x + 0; if (oval < 0) { # Write to header: printf "%s = %d\n", name, val; } else { if (val != oval) { segment_error(fname,nlin,("inconsistent field " name " = " oval " " val)); } } return val; } function check_float(x,fname,nlin,name,oval, val) { gsub(/^[ ]+/, "", x); gsub(/[ ]+$/, "", x); if (x !~ /^[-+]?[0-9]+([.][0-9]*|)$/) { segment_error(fname,nlin,("invalid field " name " = \"" x "\"")); } val = x + 0; if (oval < 0) { # Write to header: printf "%s = %f\n", name, val; } else { if (val != oval) { segment_error(fname,nlin,("inconsistent field " name " = " oval " " val)); } } return val; } function check_string(x,fname,nlin,name,oval, val) { gsub(/^[ ]+/, "", x); gsub(/[ ]+$/, "", x); gsub(/[ ][ ]+/, " ", x); if (x !~ /^[A-Za-z0-9_ ]+$/) { segment_error(fname,nlin,("invalid field " name " = \"" x "\"")); } val = x; if (oval == "") { printf "%s = %s\n", name, val; } else { if (val != oval) { segment_error(fname,nlin,("inconsistent field " name " = " oval " " val)); } } return val; } END { if (abort >= 0) { exit(abort); } printf "%d frames extracted from %d segments\n", nframes, nsegs > "/dev/stderr"; } function arg_error(msg) { printf "** %s\n", msg > "/dev/stderr"; abort = 1; exit(1); } function data_error(msg) { printf " «%s»\n", $0 > "/dev/stderr"; printf "%s:%d: ** %s\n", FILENAME, FNR, msg > "/dev/stderr"; abort = 1; exit(1); } function segment_error(f,n,msg) { printf "%s:%d: %s\n", f, n, msg > "/dev/stderr"; abort = 1; exit 1 }