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. 

Reply via email to