#!/bin/sh  
# \
  exec oagtclsh "$0" "$@"

set auto_path [linsert $auto_path 0  /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]
APSStandardSetup

set usage "usage: subSeries -template <filename> -number <n> \[-priority <integer>\] \[-vary <varyList>\] \[-lvary <varyList>\] \[-series <series>\] \[-substitute <subList>\]  -rootname <string> \[-program <name>\] \[-overwrite 1\] \[-makeOnly 1\] \[-noEmail 1\] \[-hostList <name>\] \[-ckpt 0\]\nDefault program is elegant.\n\<varyList> is of the form <name>,<start>,<end>,...\n<subList> is of the form <name>,<value>\[<name>,<value>\]...\n<series> is of the form <name>,<value>,<value>,..."
set template ""
set priority 50
set number 0
set rootname ""
set program elegant
set overwrite 0
set makeOnly 0
set vary ""
set lvary ""
set substitute ""
set series ""
set noEmail 1
set ckpt 0
set hostList ""
set dedicated 0
set args $argv
if {[APSStrictParseArguments {priority template number rootname program vary lvary substitute overwrite makeOnly series noEmail hostList dedicated ckpt pause}] || \
      ![string length $template] || ![string length $rootname] || \
      ($number<1 && ![string length $series]) || $priority<0} {
    puts stderr $usage
    exit 1
}
set seed [expr int([clock seconds]/2)+1]
set priority [expr -abs($priority)]
if ![file exists $template] {
    puts stderr "not found: $template"
    exit 1
}
set dir [pwd]
set record $rootname.rec
if {[string length $record] && [file exists $record]} {
    return -code error "exists: $record"
}

set recordColumnList ""
set nVary 0
set seriesName ""
if [string length $series] {
    set seriesValueList [lrange [split $series ,] 1 end]
    if {![set number [llength $seriesValueList]]} {
        puts stderr "incorrect -series syntax\n$usage"
        exit 1
    }
    set seriesName [lindex [split $series ,] 0]
    set seriesIsNum 1
    foreach item $seriesValueList {
        if [catch {format %lf $item}] {
            set seriesIsNum 0
            break
        }
    }
    if [string length $record] {
        lappend recordColumnList $seriesName
        if $seriesIsNum {
            lappend recordTypeList SDDS_DOUBLE
        } else {
            lappend recordTypeList SDDS_STRING
        }
    }
}
if {[string length $vary] || [string length $lvary]} {
    if {[string length $vary] && [string length $lvary]} {
        puts stderr "Can't give -vary and -lvary"
        exit 1
    }
    if [string length $lvary] {
        set vary $lvary
    }
    if $number<2 {
        puts stderr "Can't have number of runs<2 if you are varying something."
        exit 1
    }
    set varyList [split $vary ,]
    if [expr [llength $varyList]%3] {
        puts stderr "Incorrect -vary syntax\n$usage"
        exit 1
    }
    set nVary [expr [llength $varyList]/3]
    for {set i 0} {$i<$nVary} {incr i} {
        set name [lindex $varyList [expr $i*3]]
        lappend varyName <$name>
        lappend varyStart [lindex $varyList [expr $i*3+1]]
        set varyEnd [lindex $varyList [expr $i*3+2]]
        if [string length $lvary] {
            lappend varyDelta \
              [expr pow((1.0*$varyEnd)/$varyStart, 1./($number-1))]
        } else {
            lappend varyDelta \
              [expr ($varyEnd-[lindex $varyStart end])/(1.0*$number-1.0)]
        }
        lappend recordColumnList $name
        lappend recordTypeList SDDS_DOUBLE
    }
}
set nSub 0
if [string length $substitute] {
    set subList [split $substitute ,]
    if [expr [llength $subList]%2] {
        puts stderr "Incorrect -substitute syntax\n$usage"
        exit 1
    }
    set nSub [expr [llength $subList]/2]
    for {set i 0} {$i<$nSub} {incr i} {
        set name [lindex $subList [expr $i*2]]
        lappend subName <$name>
        lappend subValue [lindex $subList [expr $i*2+1]]
        lappend recordColumnList $name
        if [catch {format %lf $subValue}] {
            lappend recordTypeList SDDS_STRING
        } else {
            lappend recordTypeList SDDS_DOUBLE
        }
    }
}

if [string length $record] {
    lappend recordColumnList FileName
    lappend recordTypeList SDDS_STRING
    set recordData(ColumnNames) $recordColumnList 
    foreach name $recordColumnList type $recordTypeList {
        set recordData(ColumnInfo.$name) "type $type"
    }
}

set extension [file extension $template]
if $number>1 {
    set fnFormat [format $rootname-%%0%ldld$extension [expr int(log($number))]]
} else {
    set fnFormat $rootname$extension 
}

set ckptArg "-c n"
if $ckpt {
    set ckptArg "-ckpt condorCheckPt"
}


set j -1
set filename ""
for {set i 0} {$i<$number} {incr i} {
    incr seed -2
    set replNameList ""
    set replTagList ""
    set replValueList ""
    for {set iv 0} {$iv<$nVary} {incr iv} {
        lappend replNameList [lindex $varyName $iv]
        lappend replTagList [os editstring debd [lindex $varyName $iv]]
        if [string length $lvary] {
            set value [expr [lindex $varyStart $iv]*pow([lindex $varyDelta $iv], $i)]
        } else {
            set value [expr [lindex $varyStart $iv]+$i*[lindex $varyDelta $iv]]
        }
        lappend replValueList $value
        lappend dataList([os editstring debd [lindex $varyName $iv]]) $value
    }
    for {set is 0} {$is<$nSub} {incr is} {
        lappend replNameList [lindex $subName $is]
        lappend replTagList [os editstring debd [lindex $subName $is]]
        lappend replValueList [lindex $subValue $is]
        lappend dataList([os editstring debd [lindex $subName $is]]) [lindex $subValue $is]
    }
    if [string length $seriesName] {
        lappend replNameList <$seriesName>
        lappend replTagList $seriesName
        lappend replValueList [lindex $seriesValueList $i]
        lappend dataList($seriesName) [lindex $seriesValueList $i]
    }
    incr j
    set lastFilename $filename
    while 1 {
        set filename [format $fnFormat $j]
        if [string compare $filename $lastFilename]==0 {
            return -code error "in use: $filename"
        }
        if {[file exists $filename] && !$overwrite} {
            incr j
        } else break
    }
    lappend dataList(FileName) [os editstring e[string length $extension]b[string length $extension]d $filename]
    if [catch {exec replace $template $filename \
                 -original=[join $replNameList ,],<runName>,<seed> \
                 -replace=[join $replValueList ,],[file rootname $filename],$seed} result] {
        puts stderr $result
        exit 1
    }
    set record1(ColumnNames) "Tag ValueString"
    set record1(Column.Tag) [list $replTagList runName seed]
    set record1(Column.ValueString) [list $replValueList [file rootname $filename] $seed]
    if [catch {sdds save [file rootname $filename].subs record} result] {
        puts stderr "$result"
        exit 1
    }
    unset record1
    catch {file delete $filename.log}
    if !$makeOnly  {
        set tmpFile /tmp/[APSTmpString]
        set fd [open $tmpFile w]
        puts $fd "cd $dir"
        puts $fd "which $program"
        puts $fd "echo running $program $filename on `hostname`"
        if $ckpt {
            puts $fd "if (\$RESTARTED != 0  &&  -e $filename.ckpt) then"
            puts $fd "  $program -_condor_restart $filename.ckpt >>& $filename.log "
            puts $fd "else"
        }
        puts $fd "  $program $filename >& $filename.log"
        if $ckpt {
            puts $fd "endif"
        }
        close $fd
        if [llength $hostList] {
            catch {eval exec cat $tmpFile | qsub $ckptArg -p $priority -o $dir -e $dir -V -j y -N [file root [file tail $filename]] -hard -q [join $hostList ,]} result 
        } else {
            catch {eval exec cat $tmpFile | qsub $ckptArg -p $priority -o $dir -e $dir -V -j y -N [file root [file tail $filename]]} result 
        }
        puts stdout "$program $filename: $result"
    }
}
if !$makeOnly  {
    file delete $tmpFile
}

if [string length $record] {
    for {set iv 0} {$iv<$nVary} {incr iv} {
        set name [os editstring debd [lindex $varyName $iv]]
        set recordData(Column.$name) [list $dataList($name)]
    }
    for {set is 0} {$is<$nSub} {incr is} {
        set name [os editstring debd [lindex $subName $is]]
        set recordData(Column.$name) [list $dataList($name)]
    }
    if [string length $seriesName] {
        set recordData(Column.$seriesName) [list $dataList($seriesName)]
    }
    set recordData(Column.FileName) [list $dataList(FileName)]
    set recordData(ParameterNames) "CommandlineArgs"
    set recordData(Parameter.CommandlineArgs) [list "$argv"]
    if [catch {sdds save $record recordData} result] {
        return -code error "$result"
    }
}
