#!/usr/bin/perl -w
#3dPARtoANALYZE somefile.par
# This file is a modified version of this file
# http://www.cdfi.uab.edu/cdfi/Documents/6740FF06-1993-4EAE-8CF7-18CBCA3D78B6.html
use strict;
use Getopt::Std;
use Cwd;
my %Options = ();
my $ok = getopts("hsnvg24o:a", \%Options);
sub usage(){
print "3dPAR2ANFI\n";
print "Command line Options:\n";
print "-h This help message.\n";
print "-v Be verbose in operation.\n";
print "-s Skip the outliers test when converting 4D files\n";
print " The default is to perform the outliers test.\n";
print "-n Output NIfTI files instead of HEAD/BRIK.\n";
print " The default is create HEAD/BRIK files.\n";
print "-a Output ANALYZE files instead of HEAD/BRIK.\n";
print "-o The name of the directory where the created files should be\n";
print " placed. If this directory does not exist the program exits\n";
print " without performing any conversion.\n";
print " The default is to place created files in the same directory\n";
print " as the PAR files.\n";
print "-g Gzip the files created.\n";
print " The default is not to gzip the files.\n";
print "-2 2-Byte-swap the files created.\n";
print " The default is not to 2 byte-swap.\n";
print "-4 4-Byte-swap the files created.\n";
print " The default is not to 4 byte-swap.\n\n";
print "Sample invocations:\n";
print "3dPAR2AFNI subject1.PAR\n";
print " Converts the subject1.PAR file to subject1+orig.{HEAD,BRIK}\n";
print "3dPAR2AFNI -s subject1.PAR\n";
print " Same as above but skip the outlier test\n";
print "3dPAR2AFNI -n subject1.PAR\n";
print " Converts the file subject1.PAR file to subject1.nii\n";
print "3dPAR2AFNI -n -s subject1.PAR\n";
print " Same as above but skip the outlier test\n";
print "3dPAR2AFNI -n -s -o ~/tmp subject1.PAR\n";
print " Same as above but skip the outlier test and place the\n";
print " created NIfTI files in ~/tmp\n";
print "3dPAR2AFNI -n -s -o ~/tmp *.PAR\n";
print " Converts all the PAR/REC files in the current directory to\n";
print " NIfTI files, skip the outlier test and place the created\n";
print " NIfTI files in ~/tmp\n";
exit;
}
sub convertPar($) {
$,=" ";
$\="\n";
my $verbose = $Options{"v"};
my $skipOutliers = $Options{"s"};
my $nifti = $Options{"n"};
my $analyze = $Options{"a"};
my $gzip = $Options{"g"};
my $twoSwap = $Options{"2"};
my $fourSwap = $Options{"4"};
my $outputDirectory = $Options{"o"};
my $outliers="";
my $parFile = shift;
my ($rootname, $extension, %fov, %angulation, %origin, $slices, $tr, $volumes, $bitdepth, %reconres, $prefixargs);
my ($timeargs, $totalslices, $anterior, $posterior, $foot, $head, $right, $left, $FOVargs, $filespec, $session);
if ($outputDirectory){
if ( ! -d $outputDirectory ) {
print "$outputDirectory does not exist. Exiting!\n";
exit;
}
$outputDirectory = Cwd::abs_path($outputDirectory);
}
if ($verbose) {
print "Skipping outliers test\nOutput file will be NIfTI format\n";
}
if ($parFile =~ /([A-Za-z_0-9]+)\.([Pp][Aa][Rr])$/) {
$rootname=$1;
$extension=$2;
}
# parse PAR file.
my $lineCount=0;
open(PFH, $parFile) || die "Unable to open $parFile for reading: $!.\n";
my @buffer = ();
while (<PFH>) {
chomp; # strip record separator
push (@buffer, $_);
if ($#buffer > 2){
shift @buffer;
}
if ($lineCount <= 91 ) {
# file version
if (/# CLINICAL TRYOUT Research image export tool V([0-9])/) {
my $fileVersion = $1;
if ($fileVersion != 4 ) {
print "This program can only handle Version 4 PAR/REC files. Exiting.";
exit;
}
}
# field of view
if (/FOV \((..),(..),(..)\) \[.*\].*:\ *([0-9]+\.[0-9]+)\ *([0-9]+\.[0-9]+)\ *([0-9]+\.[0-9]+)/) {
$fov{$1}=$4;
$fov{$2}=$5;
$fov{$3}=$6;
}
# matrix size
# angulation
if (/Angulation midslice\((..),(..),(..)\)\[.*\].*:\ *(-?[0-9]+\.[0-9]+)\ *(-?[0-9]+\.[0-9]+)\ *(-?[0-9]+\.[0-9]+)/) {
$angulation{$1}=$4;
$angulation{$2}=$5;
$angulation{$3}=$6;
}
# distance from origin of FOV center
if (/Off Centre midslice\((..),(..),(..)\) \[.*\].*:\ *(-?[0-9]+\.[0-9]+)\ *(-?[0-9]+\.[0-9]+)\ *(-?[0-9]+\.[0-9]+)/) {
$origin{$1}=$4;
$origin{$2}=$5;
$origin{$3}=$6;
}
# number of slices
if (/number of slices.*:\ *([0-9]+)/) {
$slices=$1;
}
# TR
if (/Repetition time.*:\ *([0-9]+\.[0-9]+)/) {
$tr=$1;
}
# number of volumes
if (/number of dynamics.*:\ *([0-9]+)/) {
$volumes=$1;
}
if (/\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*([0-9]*)\s*[0-9]*\s*([0-9]*)\s*([0-9]*).*/) {
$bitdepth=$1;
$reconres{"x"}=$2;
$reconres{"y"}=$3;
}
}
$lineCount++;
} # end of while (<PFH>)
if (shift(@buffer) =~ /\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*[0-9]*\s*([0-9]*).*/){
my $numberOfImages = $1 + 1;
if ($verbose) {
print "*** Number of images is $numberOfImages";
}
if ($numberOfImages / $slices != $volumes) {
print "*** WARNING: The number of volumes from the PAR header does not match the number of slices times the number of images!";
$volumes = $numberOfImages / $slices;
print "*** WARNING: Resetting the number of volumes to be the number of slices times the number of images ($volumes).";
}
}
close(PFH);
if ($verbose) {
print "$rootname.$extension";
print "** Field of View ***";
print "ap=$fov{ap}";
print "fh=$fov{fh}";
print "rl=$fov{rl}";
print "*** Reconstruction Matrix ***";
print "x=$reconres{x}";
print "y=$reconres{y}";
print "*** Angulation ***";
print "ap=$angulation{ap}";
print "fh=$angulation{fh}";
print "rl=$angulation{rl}";
print "*** Origin ***";
print "ap=$origin{ap}";
print "fh=$origin{fh}";
print "rl=$origin{rl}";
print "*** Slices = $slices ***";
print "*** Bit Depth = $bitdepth ***";
print "*** TR = $tr ***";
}
# -----------calculate values and args for AFNI to3d to convert REC file
#
if ($outputDirectory) {
$session = "-session $outputDirectory/";
}
else {
$session = "";
}
if ($nifti) {
$prefixargs = "-prefix $rootname.nii";
}
else {
$prefixargs = "-prefix $rootname";
}
my $swap = "";
if ($twoSwap) {
$swap = "-2swap";
}
elsif ($fourSwap) {
$swap = "-4swap";
}
# generate time args for func or anat
$timeargs = "";
$totalslices = $slices;
if ($volumes > 1) {
if ($verbose) {
print "$volumes timepoints";
}
$timeargs = "-time:tz $volumes $slices ${tr}ms zero";
# $timeargs = "-time:zt $slices $volumes ${tr}ms zero";
$totalslices=$volumes*$slices;
if ($skipOutliers) {
$outliers="-skip_outliers";
}
}
#calculate FOV args
$anterior = abs($origin{ap}-$fov{ap}/2);
$posterior= abs($origin{ap}+$fov{ap}/2);
$foot = abs($origin{fh}-$fov{fh}/2);
$head = abs($origin{fh}+$fov{fh}/2);
$right = abs($origin{rl}-$fov{rl}/2);
$left = abs($origin{rl}+$fov{rl}/2);
$FOVargs = "-xFOV ${right}R-${left}L -yFOV ${anterior}A-${posterior}P -zFOV ${foot}I-${head}S";
#file specification
my $recextension="rec";
if ($extension =~ /PAR/) {
$recextension="REC";
}
$filespec = "3D:-1:0:$reconres{x}:$reconres{y}:$totalslices:$rootname.$recextension";
my $fileSize = -s "$rootname.$recextension";
if ( $fileSize > 0 ) {
# to3d command
print my $command="to3d $session $swap $outliers $prefixargs $timeargs $FOVargs $filespec";
system $command;
if ($analyze) {
print my $command="3dAFNItoANALYZE $rootname $rootname+orig.HEAD";
system $command;
print $command="rm -f $rootname+orig.{HEAD,BRIK}";
system $command;
}
if ($gzip) {
if ($nifti) {
$command="gzip -9v $rootname.nii";
}
elsif ($analyze) {
$command="gzip -9v $rootname.img";
}
else {
$command="gzip -9v $rootname+orig.BRIK";
}
print $command;
system $command;
}
}
else {
print "Skipping $parFile: The corresponding REC file is 0 bytes in length\n";
}
}
sub main() {
my $argCount = $#ARGV + 1;
usage() if $Options{"h"} or $argCount < 1;
foreach my $parFile (@ARGV) {
convertPar($parFile);
}
}
main();
syntax highlighted by Code2HTML, v. 0.9.1