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

# $Log: not supported by cvs2svn $

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)]

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: soliday $"

proc SetupParameters {args} {
    global parameterDescription parameterDefault parameterSetpoint parameterCategory

    set parameterDescription(ALF)    "momentum compation factor"
    set parameterDefault(ALF) 1.0D-4
    lappend parameterCategory(machine)  ALF
    set parameterDescription(BETAF)  "beam velocity factor"
    set parameterDefault(BETAF) 0.0
    lappend parameterCategory(basic) BETAF
    set parameterDescription(CH)     "centre harmonic"
    set parameterDefault(CH) 0.0
    lappend parameterCategory()  CH
    set parameterDescription(DELE)   "relative RMS energy spread for electrons, relative momentus spread half-width and half-height for protons"
    set parameterDefault(DELE) 1.0D-3
    lappend parameterCategory(beam)  DELE
    set parameterDescription(DELMAX) "maximum relative RMS energy spread for electrons"
    set parameterDefault(DELMAX) 0.0
    lappend parameterCategory(beam)  DELMAX
    set parameterDescription(DELMIN) "maximum relative RMS energy spread for electrons"
    set parameterDefault(DELMIN) 0.0
    lappend parameterCategory(beam)  DELMIN
    set parameterDescription(EKIN)   ""
    set parameterDefault(EKIN) 0.0
    lappend parameterCategory()  EKIN
    set parameterDescription(ELEC)   "electrons (true), protons (false)"
    set parameterDefault(ELEC) T
    lappend parameterCategory(beam)  ELEC
    set parameterDescription(ETOT)   ""
    set parameterDefault(ETOT) 1.0E9
    lappend parameterCategory()  ETOT
    set parameterDescription(EX)     "horizontal emittance"
    set parameterDefault(EX) 1.0D-6
    lappend parameterCategory(beam)  EX
    set parameterDescription(EZ)     "vertical emittance"
    set parameterDefault(EZ) 1.0D-6
    lappend parameterCategory(beam)  EZ
    set parameterDescription(FRF)    "RF frequency"
    set parameterDefault(FRF) 1.0D8
    lappend parameterCategory(machine)  FRF
    for {set i 1} {$i <= 20} {incr i} {
        set parameterDescription(FRL\($i\))    "longitudinal resonant frequencies"
        set parameterDefault(FRL\($i\)) 1.0D9
        lappend parameterCategory(ri)  FRL\($i\)
        set parameterDescription(FRT\($i\))    "transverse resonant frequencies"
        set parameterDefault(FRT\($i\)) 1.0D9
        lappend parameterCategory(ri)  FRT\($i\)
    }
    set parameterDescription(FVAR)   "varies FRS in NS steps on either side of input value over a total range or RS x fo"
    set parameterDefault(FVAR) F
    lappend parameterCategory(options)  FVAR
    set parameterDescription(GAMT)   "beam energy factor"
    set parameterDefault(GAMT) 0.0
#    lappend parameterCategory(basic)  GAMT
    lappend parameterCategory(machine)  GAMT
    set parameterDescription(HFULL)  "full chamber height"
    set parameterDefault(HFULL) 0.1
    lappend parameterCategory(chamber)  HFULL
    set parameterDescription(HRF)    "RF harmonic number"
    set parameterDefault(HRF) 0.0
#    lappend parameterCategory(basic)  HRF
    lappend parameterCategory(machine)  HRF
    set parameterDescription(I0)     "(average) total beam current"
    set parameterDefault(I0) 0.0
    lappend parameterCategory(beam)  I0
    set parameterDescription(I0MAX)  "used to make the current variable"
    set parameterDefault(I0MAX) 0.0
    lappend parameterCategory(beam)  I0MAX
    set parameterDescription(I0MIN)  "used to make the current variable"
    set parameterDefault(I0MIN) 0.0
    lappend parameterCategory(beam)  I0MIN
    set parameterDescription(INTRA)  "Intrabeam scattering computation"
    set parameterDefault(INTRA) F
    lappend parameterCategory(options)  INTRA
    set parameterDescription(JE)     "Energy damping partition number"
    set parameterDefault(JE) 2.0
    lappend parameterCategory(machine)  JE
    set parameterDescription(KB)     "number of bunches"
    set parameterDefault(KB) 1
    lappend parameterCategory(beam)  KB
    set parameterDescription(LASL)   "calculate Laslett tune shift"
    set parameterDefault(LASL) F
    lappend parameterCategory(options)  LASL
    set parameterDescription(LF)     "mode with the fastest growth rate"
    set parameterDefault(LF) F
    lappend parameterCategory(options)  LF
    set parameterDescription(LN)     "selected coupled-bunch mode numbers"
    set parameterDefault(LN) F
    lappend parameterCategory(options)  LN
    set parameterDescription(LONG)   "longitudinal instabilities (true), transverse (false)"
    set parameterDefault(LONG) T
    lappend parameterCategory(options)  LONG
    set parameterDescription(MAXTMC) "For longer bunches, it is possible to choose the number of sidebands with MINTMC and MAXTMC, as well as the number of radial modes with NRAD"
    set parameterDefault(MAXTMC) 3
    lappend parameterCategory()  MAXTMC
    set parameterDescription(MFMAX)  ""
    set parameterDefault(MFMAX) 2
    lappend parameterCategory()  MFMAX
    set parameterDescription(MFMIN)  ""
    set parameterDefault(MFMIN) 1
    lappend parameterCategory()  MFMIN
    set parameterDescription(MINOUT) "Permits the reduction of output to the summary lines only"
    set parameterDefault(MINOUT) T
    lappend parameterCategory(options)  MINOUT
    set parameterDescription(MINTMC) "For longer bunches, it is possible to choose the number of sidebands with MINTMC and MAXTMC, as well as the number of radial modes with NRAD"
    set parameterDefault(MINTMC) -3
    lappend parameterCategory()  MINTMC
    set parameterDescription(MMAX)   "Maximum multipoles"
    set parameterDefault(MMAX) 2
    lappend parameterCategory()  MMAX
    set parameterDescription(NB)     "Number of particles per bunch"
    set parameterDefault(NB) 0.0
    lappend parameterCategory(basic)  NB
    set parameterDescription(NBRL)   "Number of long. broad-band resonators (used in bunch lengthening)"
    set parameterDefault(NBRL) 1
    lappend parameterCategory()  NBRL
    set parameterDescription(NBRT)   "Number of trans. broad-band resonators (used in transv.mode couplg)"
    set parameterDefault(NBRT) 1
    lappend parameterCategory()  NBRT
    set parameterDescription(NCASE)  "natural values (0), turbulent bunch-lengthening (1), turbulent + potential well bunch-lengthening (2), input data (3)"
    set parameterDefault(NCASE) 2
    lappend parameterCategory(options)  NCASE
    set parameterDescription(NFMAX)  ""
    set parameterDefault(NFMAX) 1
    lappend parameterCategory()  NFMAX
    set parameterDescription(NFMIN)  ""
    set parameterDefault(NFMIN) 0
    lappend parameterCategory()  NFMIN
    set parameterDescription(NMIN)   "(integer) lowest coupled bunch mode"
    set parameterDefault(NMIN) 0
    lappend parameterCategory(options)  NMIN
    set parameterDescription(NPR)    "(integer) print every NPRth mode"
    set parameterDefault(NPR) 0
    lappend parameterCategory(options)  NPR
    set parameterDescription(NRAD)   "For longer bunches, it is possible to choose the number of sidebands with MINTMC and MAXTMC, as well as the number of radial modes with NRAD"
    set parameterDefault(NRAD) 1
    lappend parameterCategory()  NRAD
    set parameterDescription(NRL)    "number of longitudinal resonators"
    set parameterDefault(NRL) 3
    lappend parameterCategory(ri)  NRL
    set parameterDescription(NRT)    "number of transverse resonators"
    set parameterDefault(NRT) 3
    lappend parameterCategory(ri)  NRT
    set parameterDescription(NS)     "(integer) number of steps on eigher side"
    set parameterDefault(NS) 4
    lappend parameterCategory()  NS
    set parameterDescription(NSTEP)  "used to make the current variable"
    set parameterDefault(NSTEP) 10
    lappend parameterCategory()  NSTEP
    set parameterDescription(NTOT)   "total number of particles"
    set parameterDefault(NTOT) 1.0D9
    lappend parameterCategory()  NTOT
    set parameterDescription(PHIS)   "synchronous phase-angle"
    set parameterDefault(PHIS) 0.0
    lappend parameterCategory(machine)  PHIS
    set parameterDescription(PROTON) ""
    set parameterDefault(PROTON) F
    lappend parameterCategory(options)  PROTON
    for {set i 1} {$i <= 20} {incr i} {
        set parameterDescription(QRL\($i\))    "longitudinal quality factors"
        set parameterDefault(QRL\($i\)) 1.0
        lappend parameterCategory(ri)  QRL\($i\)
        set parameterDescription(QRT\($i\))    "transverse quality factors"
        set parameterDefault(QRT\($i\)) 1.0
        lappend parameterCategory(ri)  QRT\($i\)
    }
    set parameterDescription(RAD)    ""
    set parameterDefault(RAD) 100.0
    lappend parameterCategory()  RAD
    set parameterDescription(RESIST) "calculates the transverse resistive wall effect"
    set parameterDefault(RESIST) F
    lappend parameterCategory(options)  RESIST
    set parameterDescription(RESIV)  "chamber wall resistance"
    set parameterDefault(RESIV) 3.0D-8
    lappend parameterCategory(chamber)  RESIV
    set parameterDescription(RHO)    "bending radius"
    set parameterDefault(RHO) 100.0
    lappend parameterCategory(machine) RHO  
    set parameterDescription(RS)     "Value of the total range"
    set parameterDefault(RS) 0.0
    lappend parameterCategory()  RS
    set parameterDescription(SIGMAX) "max RMS bunch length"
    set parameterDefault(SIGMAX) 0.0
    lappend parameterCategory(beam)  SIGMAX
    set parameterDescription(SIGMIN) "min RMS bunch length"
    set parameterDefault(SIGMIN) 0.0
    lappend parameterCategory(beam)  SIGMIN
    set parameterDescription(SIGS)   "RMS bunch-length for electrons, half-width at half height for protons"
    set parameterDefault(SIGS) 0.0
    lappend parameterCategory(beam)  SIGS
    set parameterDescription(SPRL)   "relative synchrotron longitudinal frequency spread"
    set parameterDefault(SPRL) 0.0
    lappend parameterCategory(beam)  SPRL
    set parameterDescription(SPRT)   "relative synchrotron transverse frequency spread"
    set parameterDefault(SPRT) 0.0
    lappend parameterCategory(beam)  SPRT
    set parameterDescription(TAUX)   "horizontal damping time"
    set parameterDefault(TAUX) 1.0D9
    lappend parameterCategory(machine)  TAUX
    set parameterDescription(TF)     "mode with the fastest growth rate"
    set parameterDefault(TF) F
    lappend parameterCategory(options)  TF
    set parameterDescription(TMC)    "transverse mode coupling"
    set parameterDefault(TMC) F
    lappend parameterCategory(options)  TMC
    set parameterDescription(TMCBL)  "plot sigma vs current"
    set parameterDefault(TMCBL) T
    lappend parameterCategory(options)  TMCBL
    set parameterDescription(TMCPR)  "plot tuneshift vs current"
    set parameterDefault(TMCPR) F
    lappend parameterCategory(options)  TMCPR
    set parameterDescription(TN)     "selected coupled-bunch mode numbers"
    set parameterDefault(TN) F
    lappend parameterCategory(options)  TN
    set parameterDescription(TRANS)  "calcuates the stability of transverse coupled bunch modes"
    set parameterDefault(TRANS) F
    lappend parameterCategory(options)  TRANS
    set parameterDescription(TSPL)   "tune shift plots"
    set parameterDefault(TSPL) F
    lappend parameterCategory(options)  TSPL
    set parameterDescription(TUNMAX) "maximum tune"
    set parameterDefault(TUNMAX) 0.0
    lappend parameterCategory(machine)  TUNMAX
    set parameterDescription(TUNMIN) "minimum tune"
    set parameterDefault(TUNMIN) 0.0
    lappend parameterCategory(machine)  TUNMIN
    set parameterDescription(TUNX)   "horizontal tune"
    set parameterDefault(TUNX) 10.0
    lappend parameterCategory(machine)  TUNX
    set parameterDescription(TUNZ)   "vertical tune"
    set parameterDefault(TUNZ) 10.0
    lappend parameterCategory(machine)  TUNZ
    set parameterDescription(VRF)    "RF voltage"
    set parameterDefault(VRF) 1.0D6
    lappend parameterCategory(machine)  VRF
    set parameterDescription(WFULL)  "full chamber width"
    set parameterDefault(WFULL) 0.1
    lappend parameterCategory(chamber)  WFULL
    set parameterDescription(WTH)    "chamber wall thickness"
    set parameterDefault(WTH) 0.01
    lappend parameterCategory(chamber)  WTH
    set parameterDescription(XIMAX)  "maximum chromaticity"
    set parameterDefault(XIMAX) 0.0
    lappend parameterCategory(machine)  XIMAX
    set parameterDescription(XIMIN)  "minimum chromaticity"
    set parameterDefault(XIMIN) 0.0
    lappend parameterCategory(machine)  XIMIN
    set parameterDescription(XIX)    "horizontal chromaticity"
    set parameterDefault(XIX) 0.0
    lappend parameterCategory(machine)  XIX
    set parameterDescription(XIZ)    "vertical chromaticity"
    set parameterDefault(XIZ) 0.0
    lappend parameterCategory(machine)  XIZ
    set parameterDescription(ZN)     "low-frequency wall-impedance"
    set parameterDefault(ZN) 0.0
    lappend parameterCategory(chamber)  ZN
    for {set i 1} {$i <= 20} {incr i} {
        set parameterDescription(ZRL\($i\))    "longitudinal resonant impedance"
        set parameterDefault(ZRL\($i\)) 0.0
        lappend parameterCategory(ri)  ZRL\($i\)
        set parameterDescription(ZRT\($i\))    "transverse resonant impedance"
        set parameterDefault(ZRT\($i\)) 0.0
        lappend parameterCategory(ri)  ZRT\($i\)
    }
    
    foreach name [array names parameterDefault] {
        set parameterSetpoint($name) $parameterDefault($name)
    }
}

proc ValuesChanged {args} {
    global parameterSetpoint parameterDefault labelWidget
    set nameList [lsort -dictionary [array names parameterSetpoint]]
    foreach name $nameList {
        if {$parameterSetpoint($name) != $parameterDefault($name)} {
            $labelWidget($name) configure -fg blue
        } else {
            $labelWidget($name) configure -fg black
        }
    }
}

proc ReadInputFile {args} {

    set inputfile [APSFileSelectDialog .fsd \
                     -pattern "*.bbiin"]
    if {![llength $inputfile]} {
        return
    }

    global parameterSetpoint parameterDefault description labelWidget
    APSSetVarAndUpdate status "Default values loaded"
    foreach name [array names parameterDefault] {
        set parameterSetpoint($name) $parameterDefault($name)
    }

    if [catch {open $inputfile "r"} fid] {
        APSSetVarAndUpdate status "Can not read file $inputfile"
        bell
        return
    }
    set start 0
    set end 0
    set nameList ""

    set data [read $fid]
    catch {close $fid}
    set index [lsearch -glob $data {[$&]DATA}]
    if {$index == -1} {
        APSSetVarAndUpdate status "Invalid BBI input file"
        return
    }
    set description [lrange $data 0 [expr {$index - 1}]]
    incr index
    set data [lrange $data $index end]

    set index [lsearch -glob $data {[$&]END}]
    if {$index == -1} {
        APSSetVarAndUpdate status "Invalid BBI input file"
        return
    }
    incr index -1
    set data [lrange $data 0 $index]

    set data [split $data ,]
    foreach element $data {
        set element [split $element =]
        set name [string trim [lindex $element 0]]
        set value [string trim [lindex $element 1]]
        set parameterSetpoint($name) $value
    }
    if [info exists parameterSetpoint(DATEND)] {
        unset parameterSetpoint(DATEND)
    }
    ValuesChanged
    APSSetVarAndUpdate status "$inputfile read"
}

proc ReadTwissFile {args} {

    set inputfile [APSFileSelectDialog .fsd \
                     -pattern "*.twi"]
    if {![llength $inputfile]} {
        return
    }

    global parameterSetpoint parameterDefault description
    
    if {[catch {exec sdds2stream $inputfile -para=nux,nuy,dnux/dp,dnuy/dp,alphac,taux,Sdelta0,ex0,pCentral,Jdelta} results]} {
        APSSetVarAndUpdate status "Error: $results"
        return
    }

    set parameters "TUNX TUNZ XIX XIZ ALF TAUX DELE EX GAMT JE"
    foreach parameter $parameters value $results {
        set parameterSetpoint($parameter) $value
    }
    ValuesChanged
    APSSetVarAndUpdate status "$inputfile read"
}

proc SaveInputFile {args} {
    set inputfile ""
    set verbose 0
    APSStrictParseArguments {inputfile}
    if {![llength $inputfile]} {
        set inputfile [APSFileSelectDialog .fsd \
                         -checkValidity 0 \
                         -pattern "*.bbiin"]
        if {![llength $inputfile]} {
            return
        }
        set verbose 1
    }

    global parameterSetpoint parameterDefault description
    set nameList [lsort -dictionary [array names parameterSetpoint]]
    set data " [string trim $description]\n"
    append data " &DATA\n"
    set i 0
    foreach name $nameList {
        if {$parameterSetpoint($name) != $parameterDefault($name)} {
            append data " ${name}=$parameterSetpoint($name),"
            incr i
            if {$i == 4} {
                set i 0
                append data "\n"
            }
        }
    }
    append data "\n DATEND=F &END\n"
    append data " &DATA DATEND=T &END"
    
    if [catch {open $inputfile "w"} fid] {
        APSSetVarAndUpdate status "Cannot write to file $inputfile."
        return -code error "Cannot write to file $inputfile."
    }
    puts $fid $data
    catch {close $fid}
    if {$verbose} {
        APSSetVarAndUpdate status "$inputfile saved"
    }
}

set outputfile ""
proc SetOutputName {args} {
    global outputfile
    set of [APSFileSelectDialog .fsd \
                     -checkValidity 0 \
                     -pattern "*.bbiout"]
    if {![llength $of]} {
        return
    }
    set outputfile $of
    APSSetVarAndUpdate status "Output filename set to $of and [file rootname $outputfile].bbitop"
}

proc MakeBBIInputWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}

    global parameterSetpoint parameterDefault parameterDescription parameterCategory labelWidget


    set widgetList [APSTabFrame $widget -parent $parent -label "" \
                      -packOption "-side top -fill both -expand 1"\
                      -labelList [list "Machine Parameters" "Beam Parameters" "Chamber Parameters" "Resonant Impedances" "Options" "Basic Parameters" "Misc"] -width 1010 -height 570]
    
    option add *font -adobe-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
    set n 0
    foreach tab {machine beam chamber ri options basic ""} {
        APSFrame .one -parent [lindex $widgetList $n] -label ""
        set w [lindex $widgetList $n].one.frame
        incr n
        set count 5
        set xList ""
        for {set c 0} {$c < $count} {incr c} {
            set w$c $w.grid.x$c
            append xList "x$c "
        }
        APSFrameGrid .grid -parent $w -xList $xList

        set nameList [lsort -dictionary $parameterCategory($tab)]
        set names [llength $nameList]
        
        for {set i 0} {$i<$names} {incr i $count} {
            for {set j 0} {$j<$count} {incr j} {
                set index [expr $i + $j]
                set name [lindex $nameList $index]
                set contextHelp ""
                if [info exists parameterDescription($name)] {
                    set contextHelp [set parameterDescription($name)]
                }
                if [string length $name] {
                    if {([info exists parameterSetpoint($name)]) && (($parameterSetpoint($name) == "T") || ($parameterSetpoint($name) == "F"))} {
                        pack [frame [set w$j].par$index] -fill x
                        label [set w$j].par$index.label -text "${name}:"
                        pack [set w$j].par$index.label -side left
                        radiobutton [set w$j].par$index.true -text "   TRUE   " -variable parameterSetpoint($name) -value T -indicatoron 0
                        radiobutton [set w$j].par$index.false -text "   FALSE   " -variable parameterSetpoint($name) -value F -indicatoron 0
                        pack [set w$j].par$index.false [set w$j].par$index.true -padx 0 -ipadx 0 -side right
                        bind [set w$j].par$index.true <ButtonRelease-1> ValuesChanged
                        bind [set w$j].par$index.false <ButtonRelease-1> ValuesChanged
                        set labelWidget($name) [set w$j].par$index.label
                    } else {
                        APSLabeledEntry .par$index -parent [set w$j] \
                          -textVariable parameterSetpoint($name) \
                          -width 22 -label "${name}:" -contextHelp $contextHelp
                        bindtags [set w$j].par$index.entry "all . Entry [set w$j].par$index.entry"
                        bind [set w$j].par$index.entry <KeyPress> ValuesChanged
                        set labelWidget($name) [set w$j].par$index.label
                    }
                }
            }
        }
    }
    option add *font -adobe-courier-medium-r-normal-*-14-*-*-*-*-*-*-*
}

proc RunBBI {args} {
    global outputfile
    if {![llength $outputfile]} {
        APSSetVarAndUpdate status "Please set the output file before running"
        bell
        return
    }
    set tmpDir /tmp/[APSTmpString]
    file mkdir $tmpDir
    if {[catch {SaveInputFile -inputfile ${tmpDir}/fort.15} result]} {
        file delete -force $tmpDir
        return -code error $result
    }
    file link -symbolic ${tmpDir}/core /dev/null

    set pwd [pwd]
    cd $tmpDir
    
    APSExecLog .execLog \
      -unixCommand bbi \
      -callback "RunBBIDone -tmpDir $tmpDir -pwd $pwd -state done" \
      -abortCallback "RunBBIDone -tmpDir $tmpDir -pwd $pwd -state aborted" \
      -cancelCallback "RunBBIDone -tmpDir $tmpDir -pwd $pwd -state canceled"

}

proc RunBBIDone {args} {
    set state ""
    set pwd ""
    set tmpDir ""
    APSStrictParseArguments {pwd state tmpDir}

    cd $pwd
    if {$state == "done"} {
        global outputfile
        if ![file exists [file dirname $outputfile]] {
            file mkdir [file dirname $outputfile]
        }
        if [file exists ${tmpDir}/fort.6] {
            file copy -force ${tmpDir}/fort.6 $outputfile
            APSSetVarAndUpdate status "$outputfile created"
        }
        if [file exists ${tmpDir}/fort.21] {
            file copy -force ${tmpDir}/fort.21 [file rootname $outputfile].bbitop
            APSSetVarAndUpdate status "[file rootname $outputfile].bbitop created"
        }
    }
    file delete -force ${tmpDir}/core ${tmpDir}/fort.6 ${tmpDir}/fort.15 ${tmpDir}/fort.21 $tmpDir
    APSSetVarAndUpdate status Done
}

APSApplication . -name ComputeBunchBeamInstability -version $CVSRevisionAuthor \
      -overview {This application provides the inferace for computing bunched beam instabitiies, the executable is a fortran program -- bbi written by cern lab.}

set status "You can get context help for each of the input parameters by double right clicking on them."
APSScrolledStatus .status -parent .userFrame -textVariable status -width 95 \
    -withButtons 1 -packOption "-fill x"
#set directory [APSGoToDailyDirectory]
#APSLabeledEntry .dir -parent .userFrame -label "Main directory:" -textVariable directory -width 60 -contextHelp "The directory for creating bbi input file and storing bbi output files."
#set rootname aps
#APSLabeledEntry .rootname -parent .userFrame -label "Rootname:" -textVariable rootname -width 60 -contextHelp "The rootname bbi input and output files, the extension of input file is .bbiin and the extension of output file is .bbiout, and the SDDS output files is .bbisdds."
set description "Default BBI Input Parameters"

SetupParameters

APSLabeledEntry .description -parent .userFrame -label "Description:" -textVariable description -packOption "-fill x -expand true"
MakeBBIInputWidget .bbiInput -parent .userFrame
#ReadAPSDefaults

APSButton .readInput -parent .userFrame -text "Read Input File" -command "ReadInputFile"
APSButton .readTwiss -parent .userFrame -text "Read Elegant Twiss File" -command "ReadTwissFile"
APSButton .saveInput -parent .userFrame -text "Save Input File" -command "SaveInputFile"
APSButton .setOutputName -parent .userFrame -text "Set Output Name" -command "SetOutputName"
APSButton .run -parent .userFrame -text "Run" -command "RunBBI"



