External Email - Use Caution
I've attached a new version of dcmunpack. Try running this with
-keep-scouts and without -keep-scouts
Let me know if this runs successfully in both situations (I'm using you
as my tester:)
On 4/18/2023 10:51 AM, Proulx, Jean Sebastien wrote:
Sorry for the late follow-up.
Yes, that is what I’m doing. With dcmunpack -auto-runseq I convert
everything, then use the log/series-info.dat to do further renaming to
BIDS—at least that is what I am trying to, but this is another topic.
Thanks for the help and
Have a very good day!
Sébastien
#!/bin/tcsh -f
# dcmunpack
#
set VERSION = 'dcmunpack @FS_VERSION@';
set SeriesInfo = ();
set DoUnpack = 0;
set TargetDir = ();
set SrcInfo = ();
set SrcDirList = ();
set SrcPre = ();
set SrcPat = ();
set SrcExt = ();
set FSFAST = 1;
set DoInfoDump = 1;
set DoConvert = 1;
set DoCopy = 0;
set OnePerDir = 0;
set MGHDCM = 0;
set Key = ();
set DoBase = 0;
set infofile = ();
set itdicom = ();
set DoAutoRunSeq = 0;
set AutoRunSeqFmt = ""
set ExitOnError = 1;
@ ErrorsFound = 0;
set RunNoSkip = ()
set iid = ()
set ijd = ()
set ikd = ()
set UseDCM2NIIX = 1; # changed this to 1 on 4/06/2023
set CreateBIDS = 0
set DoPhase = 0;
set DoSiemensAscii = 1;
set KeepScouts = 0;
set ForceUpdate = 0;
set RunNos = ();
set SubDirs = ();
set Formats = ();
set FNames = ();
set NSkips = ();
set NDrops = ();
set DoFIPS = 0;
set Project = ();
set Site = ();
set BIRNID = ();
set VisitNo = ();
set RunPars = ();
set GetMax = 0;
set DoExtraInfo = 0;
set siemensBVecsCross = 0;
if($?FS_dcmGetDWIParamsSiemens_VoxelSpace) then
set siemensBVecsCross = $FS_dcmGetDWIParamsSiemens_VoxelSpace;
endif
set inputargs = ("$argv");
set PrintHelp = 0;
set LF = ();
set DoFirstDicom = 0;
if($#argv == 0) goto usage_exit;
set n = `echo "$argv" | grep -e -help | wc -l`
if($n != 0) then
set PrintHelp = 1;
goto usage_exit;
endif
set n = `echo "$argv" | grep -e -version | wc -l`
if($n != 0) then
echo $VERSION
exit 0;
endif
source $FREESURFER_HOME/sources.csh
goto parse_args;
parse_args_return:
goto check_params;
check_params_return:
# Create target dir, if necessary
if($#TargetDir) mkdir -p $TargetDir/log
# Create the log file
if($#LF == 0) then
if($#TargetDir) then
set LF = $TargetDir/log/dcmunpack.log
if(-e $LF) mv $LF $TargetDir/log/dcmunpack.$$.log
else
set LF = /dev/null
endif
endif
# Start populating the log file
echo ""| tee -a $LF
echo "cd `pwd`" | tee -a $LF
echo "$0 $inputargs"| tee -a $LF
echo ""| tee -a $LF
echo $VERSION >> $LF
ls -l $0 | tee -a $LF
uname -a >> $LF
date >> $LF
set StartTime = `date`;
set tSecStart = `date '+%s'`;
# Print out a summary
echo "---------------------------------------" | tee -a $LF
@ nth = 0;
foreach run ($RunNos)
@ nth = $nth + 1;
if(! $DoFIPS) then
echo " $nth $run $SubDirs[$nth] $FNames[$nth] $NSkips[$nth] $NDrops[$nth]"
| tee -a $LF
else
echo " $nth $run $RunPars[$nth] $RunParNos[$nth] $NSkips[$nth]
$NDrops[$nth]" | tee -a $LF
endif
end
echo "---------------------------------------" | tee -a $LF
if($OnePerDir) then
# This creates a list of all the subdirs in the tree
set SrcDirList2 = (`find -L $d -type d`);
else
set SrcDirList2 = ($SrcDirList)
endif
echo "Searching for matching files" | tee -a $LF
date | tee -a $LF
set flist = ();
foreach d ($SrcDirList2)
#echo "Searching $d" >> $LF
if($#SrcPre || $#SrcPat || $#SrcExt) then
set flist0 = (`find -L $d -name "$SrcPre*$SrcPat*$SrcExt"`)
else
set flist0 = (`find -L $d`)
endif
if($OnePerDir && $#flist0 > 0) then
set flist0 = ($flist0[1]);
endif
set flist = ($flist $flist0);
end
date | tee -a $LF
echo "Found $#flist total files." | tee -a $LF
if($#flist == 0) then
echo "ERROR: did not find any files"| tee -a $LF
exit 1;
endif
if($#flist > 100 && $#SrcInfo == 0) then
echo " Interrogating each and every one of them."
echo " Be patient."
endif
# Go through each file, create an info dump, extract params.
# This can be slow, esp for GE. In that case, try using the
# -one-per-dir functionality with -ext, -pat, and/or -pre.
if($#infofile == 0) then
if($#TargetDir) then
set infofile = $TargetDir/log/imagelist.dat
if($SrcInfo != $infofile) then
if(-e $infofile) mv $infofile $TargetDir/log/imagelist.$$.dat
endif
else
set infofile = `fs_temp_file`
endif
endif
if($#SrcInfo) then
if($SrcInfo != $infofile) then
# This may still fail if they are truly the same file but diff
# path spec, but that will not be important (it just might
# confuse people)
cp $SrcInfo $infofile
endif
else
rm -f $infofile
endif
set dumpfile = `fs_temp_file`
rm -f $dumpfile
@ nth = 0;
@ mth = 0;
foreach f ($flist)
@ nth = $nth + 1;
set filetype = `mri_probedicom --i $f --d filetype`
if($filetype == notdicom) continue;
@ mth = $mth + 1;
#echo "#@# $nth/$#flist `date`" >>& $LF
set cmd = (mri_probedicom --i $f)
if($DoSiemensAscii == 0) set cmd = ($cmd --no-siemens-ascii)
$cmd >& $dumpfile
if($status) then
cat $dumpfile | tee -a $LF
exit 1;
endif
set SeriesNo = `cat $dumpfile | awk '{if($1 == "SeriesNo") print $2}'`
if($status) then
echo "ERROR: cannot find series number in $dumpfile" | tee -a $LF
exit 1;
endif
set Patient = (`cat $dumpfile | awk '{if($1 == "PatientName") print $2}'`)
if($#Patient == 0) set Patient = 'unknown'
set Date = (`cat $dumpfile | awk '{if($1 == "StudyDate") print $2}'`)
if($#Date == 0) set Date = 'unknown';
set Time = (`cat $dumpfile | awk '{if($1 == "StudyTime") print $2}'`)
if($#Time == 0) set Time = 'unknown';
set Institution = (`cat $dumpfile | awk '{if($1 == "Institution") print
$0}'`)
if($#Institution == 0) set Institution = 'Institution unknown';
set EchoTime = (`cat $dumpfile | awk '{if($1 == "EchoTime") print $2}'`)
if($#EchoTime == 0) set EchoTime = 'unknown';
set TR = (`cat $dumpfile | awk '{if($1 == "RepetitionTime") print $2}'`)
if($#TR == 0) set TR = 'unknown';
set FlipAngle = (`cat $dumpfile | awk '{if($1 == "FlipAngle") print $2}'`)
if($#FlipAngle == 0) set FlipAngle = 'unknown';
#------------------------------------------------------------------------#
# Special case for PixSpace. Found a file where pixel spacing had some funny
# binary character in it, and it messed everything up
set PixSpace = (`cat $dumpfile | awk '{if($1 == "PixelSpacing") print $2}' |
strings`)
set tmpdat = `fs_temp_file --suffix .dat`
echo $PixSpace > $tmpdat
set PixSpace = (`cat $tmpdat`)
rm $tmpdat
if($#PixSpace == 0) set PixSpace = 'unknown';
#------------------------------------------------------------------------#
set PhaseEncDir = (`cat $dumpfile | awk '{if($1 == "PhaseEncDir") print
$2}'`)
if($#PhaseEncDir == 0) set PhaseEncDir = 'unknown';
set PixFreq = (`cat $dumpfile | awk '{if($1 == "PixelFrequency") print $2}'`)
if($#PixFreq == 0) set PixFreq = 'unknown';
set PhaseStr = ()
if($DoPhase) then
set ImageType = (`cat $dumpfile | awk '{if($1 == "ImageType") print $2}'`)
if($#ImageType == 1) then
if($ImageType == "ORIGINAL\PRIMARY\P\ND") set PhaseStr = "_phase"
endif
if($#PhaseStr == 0) set PhaseStr = NotPhase
endif
if($#SrcInfo) break;
echo "$Patient $SeriesNo $Date $Time $EchoTime $TR $FlipAngle $PixSpace
$PhaseEncDir $PixFreq $f $PhaseStr" >> $infofile
end
if($mth == 0) then
echo "ERROR: could not find any dicom files in"
echo " $SrcDirList2"
exit 1;
endif
set extra = ()
if($DoExtraInfo) then
set fieldstrength = `grep FieldStrength $dumpfile | awk '{print $2}' | sed
's/ /-/g'`
if($#fieldstrength == 0) set fieldstrength = unknown
set manufacturer = `grep Manufacturer $dumpfile | awk '{print $2}' | sed 's/
/-/g'`
if($#manufacturer == 0) set manufacturer = unknown
set scannermodel = `grep ScannerModel $dumpfile | awk '{print $2}' | sed 's/
/-/g'`
if($#scannermodel == 0) set scannermodel = unknown
set scannerserialno = `grep ScannerSerialNo $dumpfile | awk '{print $2}' |
sed 's/ /-/g'`
if($#scannerserialno == 0) set scannerserialno = unknown
set studydate = `grep StudyDate $dumpfile | awk '{print $2}' | sed 's/ /-/g'`
if($#studydate == 0) set studydate = unknown
set patient = `grep PatientName $dumpfile | awk '{print $2}' | sed 's/ /-/g'`
if($#patient == 0) set patient = unknown
set extra = ($patient $studydate $manufacturer $scannermodel $fieldstrength
$scannerserialno )
echo "ExtraInfo: $extra"
endif
rm -f $dumpfile
set SeriesNos = (`cat $infofile | awk '{print $2}' | sort -n | uniq`)
echo "Found $#SeriesNos unique series: $SeriesNos" | tee -a $LF
echo "Subject $Patient" | tee -a $LF
echo "Date $Date" | tee -a $LF
echo "Time $Time" | tee -a $LF
echo "$Institution" | tee -a $LF
# Print out one line for each series:
set AutoRunNos = ()
set AutoSubDirs = ()
set AutoFormats = ()
set AutoFNames = ()
set AutoNSkips = ()
set AutoNSkips = ()
set AutoNDrops = ()
if($#SeriesInfo == 0) then
if($#TargetDir) then
set SeriesInfo = $TargetDir/log/series-info.dat
if(-e $SeriesInfo) mv $SeriesInfo $TargetDir/log/series-info.$$.dat
else
set SeriesInfo = `fs_temp_file --suffix .dat`
endif
endif
rm -f $SeriesInfo
foreach series ($SeriesNos)
set r = `cat $infofile | awk -v s=$series '{if($2 == s) print $0;if($2 == s)
exit;}'`;
if($DoPhase == 0) set rexpected = 11
if($DoPhase == 1) set rexpected = 12
if($#r != $rexpected) then
echo $r
continue;
endif
if($DoPhase == 0) set f = $r[$#r];
if($DoPhase == 1) then
@ aa = $#r - 1;
set f = $r[$aa];
endif
set max = ();
if($GetMax) set max = (`mri_probedicom --i $f --max`)
# Create a trap in case tag 8 103e is not present (eg, in philips)
mri_probedicom --i $f --t 8 103e >& /dev/null
if($status) then
set descr = "unknown"
else
set descr = `mri_probedicom --i $f --t 8 103e | sed 's/ //g' | sed
's/\///g' | sed 's/(//g' | sed 's/)//g'| sed 's/\]//g'|sed 's/\[//g'`
endif
set fname = $r[11];
if($DoBase) set fname = `basename $f`
echo $Key $r[2] "$descr" $r[5-10] $fname $max $extra | tee -a $SeriesInfo
if($DoAutoRunSeq) then
if("$descr" == Localizer || "$descr" == localizer || "$descr" == AAHScout
|| \
"$descr" == AAHScout_sag || "$descr" == AAHScout_cor || \
"$descr" == AAHScout_tra || "$descr" == AAScout || \
"$descr" == T1w_setter || "$descr" == T2w_setter) then
if(! $KeepScouts) continue
endif
set AutoRunNos = ($AutoRunNos $series)
set AutoSubDirs = ($AutoSubDirs ".")
set AutoFormats = ($AutoFormats $AutoRunSeqFmt)
set FName = `printf %04d.$descr $series`
set AutoFNames = ($AutoFNames $FName)
set AutoNSkips = ($AutoNSkips 0)
set AutoNDrops = ($AutoNDrops 0)
endif
end
cat $SeriesInfo >> $LF
if($DoAutoRunSeq) then
set RunNos = ($AutoRunNos)
set SubDirs = ($AutoSubDirs)
set Formats = ($AutoFormats)
set FNames = ($AutoFNames)
set NSkips = ($AutoNSkips)
set NDrops = ($AutoNDrops)
endif
# If no runs have been specified, then just exit
if($#RunNos == 0) then
echo "" | tee -a $LF
echo "" | tee -a $LF
date | tee -a $LF
echo "dcmunpack done" | tee -a $LF
exit 0;
endif
# Unpack ---------------------------------------------------------
# Make sure all runs are represented
foreach run ($RunNos)
set ok = 0;
foreach series ($SeriesNos)
if($run == $series) then
set ok = 1;
break;
endif
end
if(! $ok) then
echo "ERROR: could not find run $run in data" | tee -a $LF
exit 1;
endif
end
# ------------------ Unpack --------------------------
@ nth = 0;
foreach run ($RunNos)
@ nth = $nth + 1;
set skipit = 0
foreach jj ($RunNoSkip)
if($run == $jj) set skipit = 1
end
if($skipit) then
echo "Skipping run $run" |& tee -a $LF
continue
endif
if($DoFIPS == 0) then
set SubDir = $SubDirs[$nth];
set Format = $Formats[$nth];
set FName = $FNames[$nth];
else
set fipsPar = $RunPars[$nth];
set fipsRun = $RunParNos[$nth];
set SubDir = $fipsPar;
set Format = "nii.gz"
set FName = f;
endif
set NSkip = $NSkips[$nth];
set NDrop = $NDrops[$nth];
if($FSFAST) then
set rundir = `printf %03d $run`
else
set rundir = ();
endif
set outdir = $TargetDir/$SubDir/$rundir
mkdir -p $outdir/log
if($DoConvert) then
set f = `cat $infofile | awk -v r=$run '{if($2 == r) print $11}' | head -n
1`
set PhaseStr = ()
if($DoPhase) then
set PhaseStr = `cat $infofile | awk -v r=$run '{if($2 == r) print $12}' |
head -n 1`
if($PhaseStr == NotPhase) set PhaseStr = ""
endif
set outfname = $outdir/$FName$PhaseStr.$Format
echo "" |& tee -a $LF
echo "#@# Run $run `date` ==================================" |& tee -a $LF
set ud = (`UpdateNeeded $outfname $f`)
if($ud || $ForceUpdate) then
set cmd = (mri_convert $f $outfname --nskip $NSkip --ndrop $NDrop
$itdicom)
if($#iid) set cmd = ($cmd -iid $iid);
if($#ijd) set cmd = ($cmd -ijd $ijd);
if($#ikd) set cmd = ($cmd -ikd $ikd);
if($DoFirstDicom) set cmd = ($cmd --first-dicom
$outdir/log/$FName.first.dicom.path)
if($UseDCM2NIIX) then
# environment variable FS_DCM2NIIX_OUTDIR
# this will be picked up in DICOMRead3(), and passed to
dcm2niix_fswrapper()
setenv FS_DCM2NIIX_OUTDIR $outdir
set cmd = ($cmd -dcm2niix)
if($CreateBIDS) then
set cmd = ($cmd -createBIDS)
endif
endif
if(! $UseDCM2NIIX) set cmd = ($cmd -no-dcm2niix)
if($siemensBVecsCross) set cmd = ($cmd -siemensBVecsCross)
if(! $siemensBVecsCross) set cmd = ($cmd -no-siemensBVecsCross)
echo $cmd |& tee -a $LF
$cmd |& tee -a $LF
if($status) then
if($ExitOnError) then
echo "ERROR: a conversion error was detected in Run $run" |& tee -a
$LF
echo "Either find out why, exclude this run, or run with
-no-exit-on-error to continue with other runs" |& tee -a $LF
exit 1;
endif
echo "ERROR: a conversion error was detected in Run $run, but
ExitOnError=1 so continuing to next run" |& tee -a $LF
@ ErrorsFound = $ErrorsFound + 1;
endif
else
echo "$outfname does not need updating" | tee -a $LF
endif
if($DoFirstDicom) then
set cmd = (cp `cat $outdir/log/$FName.first.dicom.path`
$outdir/$FName.first.dcm)
echo $cmd |& tee -a $LF
$cmd |& tee -a $LF
if($status) then
if($ExitOnError) then
echo "ERROR: an error was detected in Run $run copying firt dicom
file" |& tee -a $LF
echo "Either find out why, exclude this run, or run with
-no-exit-on-error to continue with other runs" |& tee -a $LF
exit 1;
endif
echo "ERROR: an error was detected in Run $run copying firt dicom file,
but ExitOnError=1 so continuing to next run" |& tee -a $LF
@ ErrorsFound = $ErrorsFound + 1;
endif
endif
endif
if($DoCopy) then
set flist = (`cat $infofile | awk -v r=$run '{if($2 == r) print $11}'`);
foreach f ($flist)
cp $f $outdir |& tee -a $LF
if($status) exit 1;
end
endif
if($DoInfoDump) then
set f = `cat $infofile | awk -v r=$run '{if($2 == r) print $11}' | head -n
1`
set dumpfile = $outdir/log/$FName-infodump.dat
set ud = (`UpdateNeeded $dumpfile $f`)
if($ud || $ForceUpdate) then
set cmd = (mri_probedicom --i $f)
if($DoSiemensAscii == 0) set cmd = ($cmd --no-siemens-ascii)
$cmd >& $dumpfile
if($status) cat $dumpfile | tee -a $LF
else
echo "$dumpfile does not need updating" | tee -a $LF
endif
endif
if($DoFIPS) then
set f = `cat $infofile | awk -v r=$run '{if($2 == r) print $11}' | head -n
1`
# Get full path
set fd = `dirname $f`;
pushd $fd > /dev/null
set fd = `pwd`
popd > /dev/null
set f = $fd/`basename $f`;
# Create XML File
set cmd = (fips-set --def-template --project $Project --site $Site \
--birnid $BIRNID --visit $VisitNo --studyname MRI --studyid 001 \
--datafile $f --run $fipsRun --paradigm $fipsPar \
--dicom-date --o $outdir/fips-process.xml --disacqs $NSkip)
# Note: spec --disacqs here. There is a skip above, but that is for
# when the dicom data are converted, and this applies to the dicom
# data itself. A skip should always be specified, even if it is 0.
# This can cause some confusion because the fips-process.xml file
# will be with the converted file but will not necessarily apply to it.
$cmd | tee -a $LF
if($status) exit 1;
endif
end
set tSecEnd = `date '+%s'`;
@ tSecRun = $tSecEnd - $tSecStart;
set tRunMins = `echo $tSecRun/60|bc -l`
set tRunMins = `printf %5.2f $tRunMins`
echo "Started at $StartTime " |& tee -a $LF
echo "Ended at `date`" |& tee -a $LF
echo "dcmunpack-Run-Time-Min $tRunMins" |& tee -a $LF
if($ErrorsFound > 0) then
echo "WARNING: $ErrorsFound errors during conversion, check logs" |& tee -a
$LF
endif
echo "" | tee -a $LF
echo "" | tee -a $LF
date | tee -a $LF
echo "dcmunpack done" | tee -a $LF
exit 0
###############################################
############--------------##################
parse_args:
set cmdline = ($argv);
while( $#argv != 0 )
set flag = $argv[1]; shift;
switch($flag)
case "-targ":
case "-trg":
if($#argv < 1) goto arg1err;
set TargetDir = "$argv[1]"; shift;
set DoUnpack = 1;
breaksw
case "-index-in":
if($#argv < 1) goto arg1err;
set SrcInfo = "$argv[1]"; shift;
if(! -e $SrcInfo) then
echo "ERROR: cannot find $SrcInfo"
exit 1;
endif
breaksw
case "-index-out":
if($#argv < 1) goto arg1err;
set infofile = "$argv[1]"; shift;
breaksw
case "-pre":
if($#argv < 1) goto arg1err;
set SrcPre = "$argv[1]"; shift;
breaksw
case "-pat":
if($#argv < 1) goto arg1err;
set SrcPat = "$argv[1]"; shift;
breaksw
case "-ext":
if($#argv < 1) goto arg1err;
set SrcExt = "$argv[1]"; shift;
breaksw
case "-key":
if($#argv < 1) goto arg1err;
set Key = "$argv[1]"; shift;
breaksw
case "-iid":
if($#argv < 3) goto arg3err;
set iid = ($argv[1] $argv[2] $argv[3]);
shift; shift; shift;
breaksw
case "-ijd":
if($#argv < 3) goto arg3err;
set ijd = ($argv[1] $argv[2] $argv[3]);
shift; shift; shift;
breaksw
case "-ikd":
if($#argv < 3) goto arg3err;
set ikd = ($argv[1] $argv[2] $argv[3]);
shift; shift; shift;
breaksw
case "-base":
set DoBase = 1;
breaksw
case "-itdicom":
# This adds -it dicom to the mri_convert cmd line
# This will force Seimens dicoms to be treated as generic
# which may be helpful for some applications (eg, PET)
set itdicom = ("-it dicom")
breaksw
case "-first-dicom":
# Copy first dicom in the series
set DoFirstDicom = 1
breaksw
case "-src":
case "-d":
if($#argv < 1) goto arg1err;
set d = "$argv[1]"; shift;
if(! -e $d) then
echo "ERROR: cannot find $d"
exit 1;
endif
if(! -r $d) then
echo "ERROR: $d exists but is not readable"
exit 1;
endif
set d = `getfullpath $d`
set SrcDirList = ($SrcDirList $d);
breaksw
case "-run":
if($#argv < 4) goto arg4err;
set RunNo = "$argv[1]"; shift;
set RunNos = ($RunNos $RunNo);
set SubDir = "$argv[1]"; shift;
set SubDirs = ($SubDirs $SubDir);
set Format = "$argv[1]"; shift;
if($Format != nii && $Format != nii.gz &&\
$Format != img &&\
$Format != mgh && $Format != mgz) then
echo "ERROR: format $Format not recoginzed"
echo "Valid values are nii, nii.gz, mgh, and mgz"
exit 1;
endif
set Formats = ($Formats $Format);
set FName = "$argv[1]"; shift;
# Strip extension from FName, if there
fname2stem $FName >& /dev/null
if($status == 0) set FName = `fname2stem $FName`;
set FNames = ($FNames $FName);
# Optional next argument is nskip
set NSkip = 0;
if($#argv != 0) then
set tmp = $argv[1];
set c = `echo $tmp | cut -c 1`
if("$c" != "-") then
set NSkip = $argv[1]; shift;
endif
endif
set NSkips = ($NSkips $NSkip)
# Optional next argument is ndrop
set NDrop = 0;
if($#argv != 0) then
set tmp = $argv[1];
set c = `echo $tmp | cut -c 1`
if("$c" != "-") then
set NDrop = $argv[1]; shift;
endif
endif
set NDrops = ($NDrops $NDrop)
set DoUnpack = 1;
breaksw
case "-auto-runseq":
if($#argv < 1) goto arg1err;
set AutoRunSeqFmt = $argv[1]; shift;
set DoAutoRunSeq = 1
set DoUnpack = 1;
set FSFAST = 0;
breaksw
case "-keep-scouts"
set KeepScouts = 1;
breaksw
case "-no-rescale-dicom"
setenv FS_RESCALE_DICOM 0
breaksw
case "-rescale-dicom"
# This is currently the default for mri_convert
setenv FS_RESCALE_DICOM 1
breaksw
case "-fips":
if($#argv < 4) goto arg4err;
set Project = "$argv[1]"; shift;
set Site = "$argv[1]"; shift;
set BIRNID = "$argv[1]"; shift;
set VisitNo = "$argv[1]"; shift;
set DoUnpack = 1;
set DoFIPS = 1;
breaksw
case "-fips-run":
if($#argv < 2) goto arg2err;
set RunNo = "$argv[1]"; shift;
set RunNos = ($RunNos $RunNo);
set RunPar = "$argv[1]"; shift;
set RunPars = ($RunPars $RunPar);
# Optional next argument is nskip
set NSkip = 0;
if($#argv != 0) then
set tmp = $argv[1];
set c = `echo $tmp | cut -c 1`
if("$c" != "-") then
set NSkip = $argv[1]; shift;
endif
endif
set NSkips = ($NSkips $NSkip)
# Optional next argument is ndrop
set NDrop = 0;
if($#argv != 0) then
set tmp = $argv[1];
set c = `echo $tmp | cut -c 1`
if("$c" != "-") then
set NDrop = $argv[1]; shift;
endif
endif
set NDrops = ($NDrops $NDrop)
set DoUnpack = 1;
set DoFIPS = 1;
breaksw
case "-no-convert":
case "-xml-only":
set DoConvert = 0;
breaksw
case "-copy-only":
set DoConvert = 0;
set DoCopy = 1;
breaksw
case "--dcm2niix":
case "-dcm2niix":
case "-dcr3":
set UseDCM2NIIX = 1;
set DoSiemensAscii = 0; # Newer dicoms do not have ascii
breaksw
case "--no-dcm2niix":
case "-no-dcm2niix":
case "-no-dcr3":
set UseDCM2NIIX = 1;
breaksw
case "--createBIDS":
case "-createBIDS":
set CreateBIDS = 1;
breaksw
case "-siemensBVecsCross"
set siemensBVecsCross = 1;
breaksw
case "-no-siemensBVecsCross"
set siemensBVecsCross = 0;
breaksw
case "-phase":
set DoPhase = 1;
breaksw
case "-no-phase":
set DoPhase = 0;
breaksw
case "-siemens-ascii":
set DoSiemensAscii = 1;
breaksw
case "-no-siemens-ascii":
# Newer dicoms do not have ascii and cause mri_probedicom to fail
set DoSiemensAscii = 0;
breaksw
case "-max":
set GetMax = 1;
breaksw
case "-extra-info":
set DoExtraInfo = 1;
breaksw
case "-no-extra-info":
set DoExtraInfo = 0;
breaksw
case "-generic":
set FSFAST = 0;
breaksw
case "-fsfast":
set FSFAST = 1;
breaksw
case "-noinfodump":
case "-no-infodump":
set DoInfoDump = 0;
breaksw
case "-log":
if($#argv < 1) goto arg1err;
set LF = "$argv[1]"; shift;
breaksw
case "-scanonly":
case "-series":
if($#argv < 1) goto arg1err;
set SeriesInfo = "$argv[1]"; shift;
breaksw
case "-oneperdir":
case "-one-per-dir":
set OnePerDir = 1;
breaksw
case "-old-bourget":
set SrcExt = "1.dcm"
breaksw
case "-mgh":
case "-martinos":
case "-bourget":
set SrcExt = "0001.dcm"
breaksw
case "-gedcm":
case "-one":
set SrcExt = ".dcm";
set OnePerDir = 1;
breaksw
case "-no-exit-on-error":
# continue to unpack data even if there is an error in coversion
set ExitOnError = 0;
breaksw
case "-force-update":
set ForceUpdate = 1
breaksw
case "-no-force-update":
set ForceUpdate = 0
breaksw
case "-run-skip":
if($#argv < 1) goto arg1err;
set RunNoSkip = ($RunNoSkip $argv[1]); shift
breaksw
case "-no-dwi":
setenv FS_LOAD_DWI 0 # turn off trying to read DWI parameters
breaksw
case "-debug":
set verbose = 1;
set echo = 1;
breaksw
default:
echo ERROR: Flag $flag unrecognized.
echo $cmdline
exit 1
breaksw
endsw
end
goto parse_args_return;
############--------------##################
############--------------##################
check_params:
if($#SrcDirList == 0) then
echo "ERROR: must specify an list of input directories"
exit 1;
endif
if($OnePerDir && $#SrcPre == 0 && $#SrcPat == 0 && $#SrcExt == 0) then
echo "ERROR: must spec -pre, -pat, and/or -ext with -one-per-dir"
exit 1;
endif
if($DoUnpack) then
if($#TargetDir == 0) then
echo "ERROR: need target directory"
exit 1;
endif
if($#RunNos != 0 && $DoAutoRunSeq) then
echo "ERROR: cannot use -run and -auto-runseq at the same time"
exit 1;
endif
if($#RunNos == 0 && ! $DoAutoRunSeq) then
echo "ERROR: need input runs"
exit 1;
endif
if($DoFIPS) then
if($#Project == 0) then
echo "ERROR: need project, etc, with FIPS"
exit 1;
endif
if($#SubDirs != 0) then
echo "ERROR: cannot spec -fips-run and -run"
exit 1;
endif
# Sort the list of run numbers in ascending order and get
# the run-within-paraidgm number
set tmp = `fs_temp_file`
#set tmp = dcmdir.tmp
rm -f $tmp
@ nth = 0;
foreach run ($RunNos)
@ nth = $nth + 1;
echo " $run $RunPars[$nth] $NSkips[$nth] $NDrops[$nth]" >> $tmp
end
# Sort by paradigm
set tmp2 = $tmp.2
cat $tmp | sort -k 2 > $tmp2
# Sort each paradigm by run
set tmp3 = $tmp.3
rm -f $tmp3
set ParList = (`cat $tmp | awk '{print $2}' | sort | uniq`)
foreach par ($ParList)
cat $tmp2 | sort -n -k 1 | \
awk -v p=$par 'BEGIN{n=1}{if($2 == p) print $0" "n; if($2 == p)n++}'
>> $tmp3
end
set RunNos = `cat $tmp3 | awk '{print $1}'`
set RunPars = `cat $tmp3 | awk '{print $2}'`
set NSkips = `cat $tmp3 | awk '{print $3}'`
set NDrops = `cat $tmp3 | awk '{print $4}'`
set RunParNos = `cat $tmp3 | awk '{print $5}'`
rm -f $tmp $tmp2 $tmp3
endif
# Make sure no runs specified twice
foreach run1 ($RunNos)
@ n = 0;
foreach run2 ($RunNos)
if($run1 == $run2) @ n = $n + 1;
end
if($n > 1) then
echo "ERROR: run $run1 is specified multiple times"
exit 1;
endif
end
endif
# This controls how the bvecs are computed. Previously, the function
# called dcmGetDWIParamsSiemens() would attempt to convert the bvecs
# to voxel space on a slice-by-slice basis; this was problematic
# because the slice normal was not known so it was computed using a
# cross product; but the cross product has a sign ambiguity that
# turned out to be wrong when det<0. Now, by default, this function
# will leave the bvecs in scanner space, then convert them to voxel
# space once the final vox2ras is known. If one wants to override this
# behavior and revert back to using the cross, then use
# -siemensBVecsCross. Note that if
# FS_dcmGetDWIParamsSiemens_VoxelSpace is already set,
# siemensBVecsCross will be set to that value (which can then be
# overridden with -siemensBVecsCross or -no-siemensBVecsCross)
if($siemensBVecsCross) then
setenv FS_dcmGetDWIParamsSiemens_VoxelSpace 1;
else
unsetenv FS_dcmGetDWIParamsSiemens_VoxelSpace
endif
goto check_params_return;
############--------------##################
############--------------##################
arg1err:
echo "ERROR: flag $flag requires one argument"
exit 1
############--------------##################
############--------------##################
arg3err:
echo "ERROR: flag $flag requires three arguments"
exit 1
############--------------##################
############--------------##################
arg4err:
echo "ERROR: flag $flag requires four arguments"
exit 1
############--------------##################
############--------------##################
usage_exit:
echo ""
echo "dcmunpack : run with -help for more info"
echo ""
echo "Required Arguments:";
echo " -src dcmdir <-src dcmdir>"
echo ""
echo "Other Arguments"
echo " -targ targetdir"
echo " -run run subdir format stemname <<nskip> ndrop>"
echo " -auto-runseq format : save all scans in the targetdir as
runo.seqname.format"
echo " -keep-scouts : unpack series with 'scout' or 'setter' in the name"
echo " -scanonly file : only scan the directory and put result in file"
echo " -one-per-dir : assume that there is only one dicom series in each
subdir"
echo " -gedcm : same as -one-per-dir -ext dcm"
echo " -ext extension : input extension (eg, dcm)"
echo " -pre prefix : input prefix (ie, input file name init string)"
echo " -pat pattern : input pattern (ie, string that occurs in the middle
of file name)"
echo " -no-infodump : do not create infodump.dat"
echo " -generic : do not use fs-fast hierarchy"
echo " -copy-only"
echo " -no-convert : do not convert to output format"
echo " -force-update : convert even if output is newer than the input dicom"
echo " -max : print out max in given dicom file"
echo " -base : report filename without path"
echo " -key keystring : put keystring before each run line (good for
searching)"
echo " -index-out index.out.dat : save index of files to index.out.dat (for
re-use)"
echo " this file will also be stored in targetdir/log/imagelist.dat"
echo " -index-in index.dat : read index of files (can make things much
faster on 2nd run) "
echo " -itdicom : add -it dicom to mri_convert cmd line"
echo " -no-exit-on-error : continue to unpack data even if there is an
error in coversion"
echo " -run-skip runno : skip a given run (good when using -auto-runseq)"
echo " -no-rescale-dicom : turn off DICOM rescaling based on tags
(0028,1052) (0028,1053)"
echo " -rescale-dicom : turn it on (default)"
echo " -no-dwi : turn off trying to read DWI parameters"
echo " -iid dcx dcy dcz : set -iid to mri_convert"
echo " -ijd dcx dcy dcz : set -ijd to mri_convert"
echo " -ikd dcx dcy dcz : set -ikd to mri_convert"
echo " -extra-info : add session info to each line of the info file (pat,
date, man, scan, field, serno)"
echo " -first-dicom : copy first dicom file into output folder. This was
implemented to "
echo " be able to have the pixel data from a dicom file with little or
no tissue in it"
if($UseDCM2NIIX) then
echo " -no-dcm2niix : Turn it off"
else
echo " -dcm2niix : use internal version of dcm2niix to convert (output
still user spec)"
echo " -createBIDS : generate a Brain Imaging Data Structure file in the
JSON text format."
endif
echo " -phase : add the string _phase to volumes that are phase images
based on ImageType"
echo ""
echo " -fips project site birnid visit"
echo " -fips-run run paradigm <<nskip> ndrop>"
echo " -xml-only : for fips, only create xml file, do not convert to output"
echo ""
echo " -log logfile"
echo " -debug"
echo " -help"
echo ""
if(! $PrintHelp) exit 1;
echo $VERSION
cat $0 | awk 'BEGIN{prt=0}{if(prt) print $0; if($1 == "BEGINHELP") prt = 1 }'
exit 1;
#---- Everything below here is printed out as part of help -----#
BEGINHELP
Sorts and converts a directory of DICOM files (Siemens, GE, Philips)
into an output hierarchy with nifti (nii), mgh, mgz, or analyze output
formats (will not create a series of 3D SPM files). This will
recursively search through all the subdirectories of the source
directory. To a large extent, this replaces unpacksdcmdir (the
Siemens-only unpacker) and will take most of its command-line
arguments. This program can often take a long time to run and usually
has to be run twice, once to get the list of runs and second to
specify which runs to unpack. There are two ways to make it run
faster. First, use -auto-runseq (see below) which will unpack all
runs. Alternatively, when you run it the first time to get a list of
runs, add -index-out index.dat. Then when you run it a second time,
use -index-in index.dat to make it run much faster.
-src dcmdir <-src dcmdir>
Dicom source directory. You can specify more than one. If you just specify
a source directory, it will give a summary of what it finds (like -scanonly
did for unpacksdcmdir). You should still give it -one-per-dir or -martinos
if applicable.
-targ targetdir
Output directory. Do not need to include when just getting information
about what is in the directory.
-run run subdir format stemname <<nskip> ndrop>
Specify unpacking rules for a given run (series), subdir is the
subdirectory under the target dir, format is the format extension
(nii, mgh, mgz, img), stemname is the base file name, nskip is the
number of time points to skip (optional, good for some fMRI), and
ndrop is the number of time points to drop from the end. The output
file will be targetdir/subdir/RRR/fname.format if using the FSFAST
output hierarchy (the default) or targetdir/subdir/fname.format with
-generic, where RRR is the 3-digit, zero-padded run number. Eg, "-run
3 bold nii f" would become targetdir/bold/003/f.nii in fsfast or
targetdir/bold/f.nii in generic. If the stemname has an extension,
that extension is ignored.
-auto-runseq format
Save all scans in the targetdir as runo.seqname.format. Eg,
-auto-runseq nii.gz would save files with names like
0002.mprage.nii.gz, 0003.ge_functionals.nii.gz, etc. This can be
easier than using the -run because you do not have to specify all the
runs on the command line and you only need to run this dcmunpack
once. It will exclude any sequneces named Localizer, localizer,
AAHScout, AHScout_sag, AAHScout_cor, AAHScout_tra, AAScout.
If you want to skip a run, then add -run-skip runno. If there are
errors in the conversion, then, by default, dcmunpack will exit with
error. If you want to convert all you can and deal with the errors
later, then add -no-exit-on-error.
-one-per-dir
Assume that the source directory (or subdirectory) contains only one
series. This is usually the case for GE, and this can speed things up
tremendously.
-martinos
-mgh
-bourget
Assume that the DICOM file names have the form produced at the MGH
Martinos Center when you "push something to bourget" from the scanner,
namely that each series will have one file that ends in "1.dcm", eg
397000-000007-000001.dcm. This can speed things up considerably.
Note: as of August, 2012, the naming convention that allows for fast
unpacking does not exist.
If you have to run this twice, it will be faster if you run it with
--index-out index.dat when you are getting a list of runs, then run it
again with --index-in index.dat when you go to unpack it.
-no-infodump
Do not create the fname-infodump.dat file
-generic
Do not use FSFAST hierarchy.
-no-convert
Do not actually run mri_convert
-copy-only
Only copy dicom files to output directory (implies -no-convert)
EXAMPLE
# CD into the dicom directory
cd Avanto-25096-20100325-162822-229000
# See what's there
dcmunpack -src . -martinos
---------------------------------------
Searching for matching files
Mon Jul 12 10:21:10 EDT 2010
Mon Jul 12 10:21:10 EDT 2010
Found 6 total files.
Found 6 unique series: 1 2 3 4 5 6
Subject Subj5
Date 20100325
Time 162822.229000
Institution Martinos Center Bay 2
1 Localizer 2.95 7 20 0.546875 ROW 285 ./229000-000001-000001.dcm
2 AAScout 1.23 2.6 0 2.5\2.5 ROW 1085 ./229000-000002-000001.dcm
3 ge_functionals 40 2000 90 3.125\3.125 COL 2300 ./229000-000003-000001.dcm
4 ge_functionals 40 2000 90 3.125\3.125 COL 2300 ./229000-000004-000001.dcm
5 ge_functionals 40 2000 90 3.125\3.125 COL 2300 ./229000-000005-000001.dcm
6 ge_functionals 40 2000 90 3.125\3.125 COL
---------------------------------------
# Now unpack it
dcmunpack -src . -martinos -targ /space/ProjectDir/subj5 \
-run 3 bold nii f.nii \
-run 4 bold nii f.nii \
-run 5 bold nii f.nii \
-run 6 bold nii f.nii
RELATIONSHIP TO UNPACKSDCMDIR
unpacksdcmdir is the Siemens-only unpacker. dcmunpack will take the
same command-line arguments except: -cfg, -seqcfg, -nspmzeropad,
-no-unpackerr (it unpacks everything), and -scanonly (you can still
get a scanonly-like summary of the data). dcmunpack does not accept
SPM as an output format. The seq.info file is not created (it is not
needed for newer versions of FSFAST). These features can be
programmed, I just have not gotten around to it. Unlike unpacksdcmdir,
dcmunpack searches subdirectories and can unpack GE data.
_______________________________________________
Freesurfer mailing list
Freesurfer@nmr.mgh.harvard.edu
https://mail.nmr.mgh.harvard.edu/mailman/listinfo/freesurfer
The information in this e-mail is intended only for the person to whom it is
addressed. If you believe this e-mail was sent to you in error and the e-mail
contains patient information, please contact the Mass General Brigham
Compliance HelpLine at https://www.massgeneralbrigham.org/complianceline
<https://www.massgeneralbrigham.org/complianceline> .
Please note that this e-mail is not secure (encrypted). If you do not wish to
continue communication over unencrypted e-mail, please notify the sender of
this message immediately. Continuing to send or respond to e-mail after
receiving this message means you understand and accept this risk and wish to
continue to communicate over unencrypted e-mail.