#! /bin/sh
# (next line not seen by tcl) \
exec tclsh $0 ${1+"$@"}    # goto tcl

### alternate 3rd line: but breaks standalone
#DYLD_LIBRARY_PATH=$CSURF_LIBRARY_PATH exec tclsh $0 ${1+"$@"}  # goto my tcl

### mosaic2brik: marty sereno
#------------------------------------------------------------------------------
# 11/10/19 -- 0.1a: hack to unpack one of Antoine's 3D scans
# 11/10/30 -- 0.1b: check bins, renum'd OK, get reps, chk swap, error check
# TODO: get more parms from ASCCONV (how to get TR? 2D vs 3D?)
#------------------------------------------------------------------------------

### tmp
set dumpscript zzDUMPHEADER
set currhead zzCURRHEAD
set tmp zzz   ;# tmpfiles prefix

### parms
set ord simult    ;# also: altplus,alt+z2,altminus,alt-z2,seqplus,seqminus
set mosaicx 768   ;# may need to reset -- estimate by: sqrt(filebytes/2))
set mosaicy 768

### args
if { [llength $argv] != 7 } {
  puts ""
  puts "  use: mosaic2brik <stem> <scan> <xysize> <xymm> <slices> <thk> <TRsec>"
  puts ""
  puts "  example args:"
  puts ""
  puts "   MS280655.MR.FIL_ANTOINE   2     128     1.5     30      1.5   2.988"
  puts ""
  puts "  hack to un-mosaic Siemens 3D EPI *.IMA's currently unreadable by to3d"
  puts "  uses AFNI imcutup to de-mosaic and to3d to make BRIK"
  puts "  same args OK for already-renum'd-by-ima2brik: ..ANTOINE.02.0001. .."
  puts "  ignores DICOM header (imcutup reads from end)"
  puts ""
  puts "  edit mosaic2brik to change following assumed parameters:"
  puts "     mosaic size: ${mosaicx}x${mosaicy} pixels"
  puts "     geom: -xFOV \${halfwi}R-L -yFOV \${halfwi}A-P -zFOV \${halfth}I-S"
  puts "     slice order: \"simult\" (3D acquisition)"
  puts ""
  puts "                                                          vers=0.1b"
  exit
}
set stem    [lindex $argv 0]
set scan    [lindex $argv 1]
set ix      [lindex $argv 2]
set iy $ix
set inplane [lindex $argv 3]
set slices  [lindex $argv 4]
set thick   [lindex $argv 5]
set tr      [lindex $argv 6]

### check for AFNI binaries
foreach bin { to3d imcutup } {
  catch { exec which $bin } ret ;# no sh/bash which built-in -- use /bin/which
  if [string match "*no $bin*" $ret] {
    puts ""
    puts "ima2brik: ### required AFNI $bin not found on your \$path"
  }
}

### check firstfile there, check if renumbered to *.%02d.%04d.*
set renumflag 0
set firstfileorig [glob -nocomplain $stem.$scan.1.*.IMA]
set firstfilerenum \
  [glob -nocomplain $stem.[format "%02d" $scan].[format "%04d" 1].*.IMA]
set origs [llength $firstfileorig]
set renums [llength $firstfilerenum]
if { $origs == 1 && $renums == 0 } {
  set renumflag 0
  set reps [llength [glob $stem.$scan.*.*.IMA]]
  set firstfile $firstfileorig
} elseif { $origs == 0 && $renums == 1 } {
  set renumflag 1
  set reps [llength [glob $stem.[format "%02d" $scan].*.*.IMA]]
  set firstfile $firstfilerenum
} else {
  puts ""
  puts "mosaic2brik: ### first file not found (or non-unique), tried:"
  puts ""
  puts "   original:  $stem.$scan.1.*.IMA      ($origs matches)"
  puts " renumbered:  $stem.[format "%02d" $scan].0001.*.IMA  ($renums matches)"
  puts ""
  exit
}

### make tiny perl script to dump ASCII header, leave it there for user
#if ![file exists $dumpscript] {
#  set id [open $dumpscript w 0755]  ;# ugo+rx, u+w
#  puts $id "#!/usr/bin/perl"
#  puts $id "### marty: dump Siemens ASCII ima header (ASCCONV BEGIN/END can occur in dicom)"
#  puts $id "\$\\ = \"\\n\";"
#  puts $id "\$pr = 0;"
#  puts $id "\$fl = 0;"
#  puts $id "if (\$#ARGV < 0) { die(\"use: $dumpscript <siemens.IMA>\\n\"); }"
#  puts $id "open FILE, \$ARGV\[0\] or die \$!;"
#  puts $id "while (<FILE>) {"
#  puts $id "  chop;"
#  puts $id "  if (/### ASCCONV BEGIN ###/) { \$fl = 1; next; }"
#  puts $id "  if (/ulVersion                                = / && \$fl eq 1) { \$pr = 1; }"
#  puts $id "  if (/### ASCCONV END ###/ && \$pr eq 1) { exit; }"
#  puts $id "  if (\$pr) { print \$_; }"
#  puts $id "}"
#  close $id
#}
#exec $dumpscript $firstfile > $currhead

### TODO: get xysize/xymm/slices/thk/TRsec
## ASCCONV: 1st two scans (192/128 = 1.5)
#sSliceArray.asSlice[0].dThickness        = 45
#sSliceArray.asSlice[0].dPhaseFOV         = 192
#sSliceArray.asSlice[0].dReadoutFOV       = 192
#sKSpace.lBaseResolution                  = 128
#sKSpace.lPhaseEncodingLines              = 128
#sKSpace.lPartitions                      = 36
#sKSpace.lImagesPerSlab                   = 30
## ASCCONV: 2nd two scans (211/128 = 1.6484375)
#sSliceArray.asSlice[0].dThickness        = 45
#sSliceArray.asSlice[0].dPhaseFOV         = 211
#sSliceArray.asSlice[0].dReadoutFOV       = 211
#sKSpace.lBaseResolution                  = 128
#sKSpace.lPhaseEncodingLines              = 128
#sKSpace.lPartitions                      = 36
#sKSpace.lImagesPerSlab                   = 30

### HOWTO get ASCCONV parm
#set patt sSliceArray.asSlice\\\[0\\\].dThickness ;#3slash:2=1togrep,3rd=tclbrak
#if {![catch {exec grep "$patt" $currhead} ret]} {set blockthk [lindex $ret 2]}

### setup/assume AFNI geometry
set halfwi [expr $inplane * $ix.0 / 2.0]
set halfth [expr $thick * $slices.0 / 2.0]   ;# 3D EPI: z is FOV, not SLAB
set geom "-xFOV ${halfwi}R-L -yFOV ${halfwi}A-P -zFOV ${halfth}I-S"

### check swap (assume Intel/LSBfirst short inp; arg:3d=short,3Ds=short+swap)
set afnitype 3D
set syst [exec uname -s]  ;# Darwin,Linux,IRIX,IRIX64
set proc [exec uname -p]  ;# powerpc,i386,i686,athlon,x86_64,mips,Ubun->unknown
if { $syst == "Darwin" && $proc == "powerpc" } { set afnitype 3Ds }
if { $syst == "IRIX" || $syst == "IRIX64" } { set afnitype 3Ds }

### check output overwrite, directory writable
set outpref scan[format "%02d" $scan]
set outbrik $outpref+orig.BRIK
if [file exists $outbrik] {
  puts ""
  puts "mosaic2brik: ### outfile $outbrik exists  ...first rm, or mv aside"
  puts ""
  exit
}
if ![file writable ..] {
  puts ""
  puts "mosaic2brik: ### permissions prevent writing outfile   ...quitting"
  puts ""
  exit
}

### ready to convert, wait for user OK
puts ""
puts "Ready to convert:"
puts ""
if {$renumflag} {
  puts "   scannum:  $scan (re-numbered)"
} else {
  puts "   scannum:  $scan (not re-numbered)"
}
puts " IMA files:  $reps (time points)"
puts "    xysize:  $ix pixels"
puts "   inplane:  $inplane mm"
puts "    slices:  $slices"
puts " thickness:  $thick mm"
puts "        TR:  $tr sec"
puts ""
puts "  assuming Siemens ${mosaicx}x${mosaicy} pix mosaics"
puts "  assuming AFNI geometry: $geom"
puts "  assuming AFNI acquisition order: $ord"
puts ""
puts "  OK to create scan[format "%02d" $scan]+orig.BRIK?"
puts "    -- ctrl-D to go"
puts "    -- ctrl-C to quit"
set resp [read stdin]

### manually cut up mosaics into a zillion files
set t 1
while {$t <= $reps} {
  if {$renumflag} {
    set stem2 [glob $stem.[format "%02d" $scan].[format "%04d" $t].*.IMA]
  } else {
    set stem2 [glob $stem.$scan.$t.*.IMA]
  }
  set fnamefmt $afnitype:-1:0:$mosaicx:$mosaicy:1:$stem2 ;# -1 => read from end
  set cmd "imcutup -prefix $tmp.$t $ix $iy $fnamefmt"
  puts $cmd
  catch { eval exec $cmd } ret
  if {"$ret" != ""} { puts $ret }
  incr t
}

### make image list (ignore blank slices at end of mosaic)
set imlist ""
for {set t 1} {$t <= $reps} {incr t} {
  for {set z 1} {$z <= $slices} {incr z} {
    set im $tmp.$t.[format "%03d" $z]
    set imlist "$imlist $im"
  }
}

### make BRIK
set cmd "to3d -prefix $outpref $geom -time:zt $slices $reps ${tr}s $ord $imlist"
puts $cmd
catch { eval exec $cmd } ret
puts $ret

### cleanup
eval exec rm -f [glob $tmp.*.???]

