Calling Maxfilter for multiple files using Perl

The script below will first run the MF on the first 20 second of data just to identify bad channels automatically using autobad. It will then pass the list onto the proper maxfilter with autobad turned off (as it does not seem to work properly anyway). The example here uses ST. The obvious disadvantage is that you only rely on a small portion of data for marking your bad channels, whereas they have been known showing up (and disappearing) randomly throughout the recording. It assumes all the raw files are conveniently stored in the same directory, and required a list of them (without the fif extention).

Save the text below where you like under a name you fancy (I called it preproc.pl), change the permission to executable (eg: chmod 740 preproc.pl) and run it from the directory where it sits by saying e.g. 'perl preproc.pl'. It's a quit and dirty perl code and I am thinking of changing it, but it is still a reasonably working one.

# a wrapper around maxfilter to get badchannels first
# and then get them to work in -bad option (needed due to MF broken functionality)
# Yury Shtyrov, MRC Cognition and Brain Sciences Unit Mar/2008


#setting the dir where the files are and a temp directory (create one manually first), on which
#we will operate

$dir = "/imaging/user/project/rawdata"; #replace with your raw data dir
$tmp_dir = "$dir/temp"; # remember to create one in the data dir

#setting the list of filenames for raw data files

@fifs = qw(filename1 filename2 filename3 ...); #list filenames without .fif extension here


#chaning to the working dir
chdir "$dir";

#then, going through each each individual file one by one
    foreach $fifs(@fifs) {

#getting the date and time in case we want to log it (for logging, use: perl preproc.pl > logfilename)
$stamp = readpipe ("date");
print "\n$stamp";

#moving files to a temp place to process
print "Moving $fifs.fif to $tmp_dir/temp.fif\n";
rename ("$dir/$fifs.fif",  "$tmp_dir/temp.fif") || die "cannot mv $fifs.fif to temp dir\n";

chdir "$tmp_dir";
#starting maxfilter with -autobad 20 to detect bad channels
print "Starting maxfilter on $fifs.fif to detect bad channels. Please, pray continuously.\n";
$error = eval{system '/opt/neuromag/bin/util/i686-pc-linux-gnu/maxfilter -v -f temp.fif -o temp_sss.fif -autobad 20 -skip 20 1200 -force > temp_logfile'}; #trying to fetch the system call output, too.
$error = $error / 256;
print "Maxfilter finished with code $error - whatever it means\n";

#scavenging through the log-file for a list of bad channels
$badch = readpipe ("cat temp_logfile | sed -n '/Static bad channels/p' | cut -f 5- -d ' ' | uniq"); #perhaps would be more elegant to do in perl rather than calling on cat|sed|cut|uniq. i'm lazy.
chomp $badch; #remove trailing new line
print "Bad channels identified: $badch \n";

#calling maxfilter with badchannels identified
print "Starting maxfilter to actually process $fifs.fif. Keep praying.\n";
$error = eval{system "/opt/neuromag/bin/util/i686-pc-linux-gnu/maxfilter -v -f temp.fif -o temp_sst.fif -bad $badch -st 4 -force > temp_logfile2"};
$error = $error / 256;
print "Maxfilter finished with code $error - see $fifs\_sst\_log.txt for details\n";

#moving the original fif and the real SSS-d file to where the stuff was before, removing the temp sss-file
print "Moving the original fif,the maxfiltered file and the log to the data dir. Removing the temp stuff.\n";
rename ("$tmp_dir/temp.fif", "$dir/$fifs.fif") || die "cannot mv $fifs.fif back from the temp dir\n";
rename ("$tmp_dir/temp_logfile2", "$dir/$fifs\_sst_log.txt") || warn "cannot mv temp_logfile2 from the temp dir\n";
rename ("$tmp_dir/temp_logfile", "$dir/$fifs\_badch_log.txt") || warn "cannot mv temp_logfile from the temp dir\n";
rename ("$tmp_dir/temp_sst.fif", "$dir/$fifs\_sst.fif") || die "cannot mv $fifs\_sst.fif form the temp dir\n";

unlink "$tmp_dir/temp_sss.fif" || warn "cannot remove the temp sss file\n";
}