
proc APSChooseBestIDElementSetup {} {
    global elementNameList KEdgeEnergyList KEdge
    set elementNameList [list H He Li Be B C N O F Ne Na Mg Al Si P S Cl Ar K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe Cs Ba La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn Fr Ra Ac Th Pa U]

    set KEdgeEnergyList [list 1.36000004e+01  2.46000004e+01  5.47000008e+01  1.11500000e+02  1.88000000e+02  2.84200012e+02  4.09899994e+02  5.43099976e+02  6.96700012e+02  8.70229980e+02  1.07152002e+03  1.30332996e+03  1.55953003e+03  1.83913000e+03  2.14450000e+03  2.47162988e+03  2.82263989e+03  3.20613989e+03  3.60848999e+03  4.03834009e+03  4.48937012e+03  4.96488086e+03  5.46443018e+03  5.98916016e+03  6.53768018e+03  7.11085986e+03  7.70875000e+03  8.33100000e+03  8.98050000e+03  9.66070020e+03  1.03683096e+04  1.11036299e+04  1.18671504e+04  1.26567197e+04  1.34740996e+04  1.43271904e+04  1.52015000e+04  1.61055498e+04  1.70366406e+04  1.79962207e+04  1.89836094e+04  2.00005000e+04  2.10456699e+04  2.21179102e+04  2.32201406e+04  2.43509102e+04  2.55155098e+04  2.67129395e+04  2.79407207e+04  2.92009199e+04  3.04919902e+04  3.18150000e+04  3.31696914e+04  3.45651289e+04  3.59856016e+04  3.74400000e+04  3.89293008e+04  4.04446992e+04  4.19887617e+04  4.35718984e+04  4.51840000e+04  4.68376992e+04  4.85170117e+04  5.02433984e+04  5.19963984e+04  5.37861992e+04  5.56146016e+04  5.74863008e+04  5.93890000e+04  6.13308008e+04  6.33155195e+04  6.53503594e+04  6.74112422e+04  6.95247969e+04  7.16774062e+04  7.38763984e+04  7.61123828e+04  7.83987031e+04  8.07256016e+04  8.31045000e+04  8.55301016e+04  8.80047188e+04  9.05285938e+04  9.31072031e+04  9.57290000e+04  9.84040000e+04  1.01137000e+05  1.03920500e+05  1.06759000e+05  1.09648000e+05  1.12598398e+05 1.15596172e+05]

    foreach element $elementNameList KE $KEdgeEnergyList {
        set KEdge($element) [expr $KE/1e3]
    }
}

proc APSChooseBestMBAIDSetupGlobalVars {args} {
    global mainDataDirectory web subDirectory
    global resultsPlot1List resultsPlot2List resultsPrintList
    global dataDirectory current feType optimizationQuantity
    global straightType idMaximumLength scIdMaximumLength
    global idType gap periodOption periodFrac periodMin periodMax
    global defaultRangeLow defaultRangeHigh nBands
    global plotOutputType plotOutputRootname sortType ranks 
    global bandOn bandLow bandHigh referenceType 
    global latticeTag lattice
    global elementNameList KEdgeEnergyList KEdge elementFlag

    APSChooseBestIDElementSetup

    set lattice 3PW-V6
    set resultsPlot1List(none) ""
    set resultsPlot2List(none) ""
    set resultsPrintList(none) ""
    set dataDirectory(reference) $mainDataDirectory/reference
#    set dataDirectory(HPM,2013-047) $mainDataDirectory/AOP-TN-2013-047/HPM-Data
#    set dataDirectory(HPM,2013-055) $mainDataDirectory/AOP-TN-2013-055/HPM-Data
#    set dataDirectory(HPM,2014-009) $mainDataDirectory/AOP-TN-2014-009/HPM-Data
    set dataDirectory(HPM,3PW-V6) $mainDataDirectory/3PW-V6-brightness2/HPM-Data
#    set dataDirectory(Revolver2,2013-047) $mainDataDirectory/AOP-TN-2013-047/HPM-Data
#    set dataDirectory(Revolver2,2013-055) $mainDataDirectory/AOP-TN-2013-055/HPM-Data
#    set dataDirectory(Revolver2,2014-009) $mainDataDirectory/AOP-TN-2014-009/HPM-Data
    set dataDirectory(Revolver2,3PW-V6) $mainDataDirectory/3PW-V6-brightness2/HPM-Data
#    set dataDirectory(Revolver3,2013-047) ""
#    set dataDirectory(Revolver3,2013-055) ""
#    set dataDirectory(Revolver3,2014-009) $mainDataDirectory/AOP-TN-2014-009/HPM-Data
    set dataDirectory(Revolver3,3PW-V6) $mainDataDirectory/3PW-V6-brightness2/HPM-Data
#    set dataDirectory(SCU,2013-047) $mainDataDirectory/AOP-TN-2013-047/SCU-Data
#    set dataDirectory(SCU,2013-055) $mainDataDirectory/AOP-TN-2013-055/SCU-Data
#    set dataDirectory(SCU,2014-009) $mainDataDirectory/AOP-TN-2014-009/SCU-Data
    set dataDirectory(SCU,3PW-V6) $mainDataDirectory/3PW-V6-brightness2/SCU-Data
#    set latticeTag(2013-047) apsU-k10
#    set latticeTag(2013-055) apsU-k10
#    set latticeTag(2014-009) apsU-k0.1_N324_15mm
    set latticeTag(3PW-V6) apsU-k0.1_N324_15mm
    set current 200
    set feType HHL
    set optimizationQuantity Brightness
    set idMaximumLength 10.0
    set scIdMaximumLength 10.0
    set idType(HPM) 1
    set idType(Revolver3) 0
    set idType(Revolver2) 1
    set idType(SCU) 1
    set gap 9.0
    set periodOption All
    set periodFrac .?
    set periodMin 10.0
    set periodMax 56.0
    set defaultRangeLow 0
    set defaultRangeHigh 120
    set nBands 0
    set plotOutputType png
    set plotOutputRootname ""
    set sortType(ave) 1
    set sortType(min) 1
    set sortType(max) 1
    set sortType(dip) 0
    set ranks 1
    set referenceType None
    set straightType Normal

    foreach element $elementNameList {
        set elementFlag($element) 0
    }

    for {set i 0} {$i < 1} {incr i} {
	set bandOn($i) 1
	set bandLow($i) 3.3
	set bandHigh($i) 33.0
    }
    for {set i 1} {$i < 10} {incr i} {
	set bandOn($i) 0
	set bandLow($i) 0
	set bandHigh($i) 0
    }

    if {$web} {
	global cgi
	foreach varname "searching lattice current feType optimizationQuantity straightType idMaximumLength scIdMaximumLength gap periodOption periodFrac periodMin periodMax defaultRangeLow defaultRangeHigh ranks referenceType" {
	    set cgi($varname) ""
	}
        foreach element $elementNameList {
            set cgi(elementFlag$element) ""
        }
	foreach varname "idTypeHPM idTypeRevolver2 idTypeRevolver3 idTypeSCU" {
	    set cgi($varname) ""
	}
	foreach varname "sortTypeave sortTypemin sortTypemax sortTypedip" {
	    set cgi($varname) ""
	}
	for {set i 0} {$i < 10} {incr i} {
	    foreach varname "bandOn$i bandLow$i bandHigh$i" {
		set cgi($varname) ""
	    }
	}
	Cgi_Parse
	if {$cgi(searching) == 1} {
	    foreach varname "lattice current feType optimizationQuantity straightType idMaximumLength scIdMaximumLength gap periodOption periodFrac referenceType" {
		set $varname $cgi($varname)
	    }
	    foreach varname "periodMin periodMax defaultRangeLow defaultRangeHigh ranks" {
		if {[string trim [lindex $cgi($varname) 0]] != ""} {
		    set $varname [string trim [lindex $cgi($varname) 0]]
		}
	    }
            foreach element $elementNameList {
                set varname elementFlag$element
                set index $element
                if {$cgi($varname) == 1} {
		    set elementFlag($index) 1
		} else {
		    set elementFlag($index) 0
		}
            }
	    foreach varname "idTypeHPM idTypeRevolver2 idTypeRevolver3 idTypeSCU" index "HPM Revolver2 Revolver3 SCU" {
		if {$cgi($varname) == 1} {
		    set idType($index) 1
		} else {
		    set idType($index) 0
		}
	    }
	    foreach varname "sortTypeave sortTypemin sortTypemax sortTypedip" index "ave min max dip" {
		if {$cgi($varname) == 1} {
		    set sortType($index) 1
		} else {
		    set sortType($index) 0
		}
	    }
	    for {set i 0} {$i < 10} {incr i} {
		set bandOn($i) $cgi(bandOn$i)
		if {[string trim [lindex $cgi(bandLow$i) 0]] != ""} {
		    set bandLow($i) [string trim [lindex $cgi(bandLow$i) 0]]
		}
		if {[string trim [lindex $cgi(bandHigh$i) 0]] != ""} {
		    set bandHigh($i) [string trim [lindex $cgi(bandHigh$i) 0]]
		}
	    }
            if {($periodFrac != ".0")} {
                set periodFrac ".?"
            }
	}
    }
}

proc APSChooseBestMBAIDSetupGUI {args} {
    global web elementNameList

    if {!$web} {
	APSApplication . -name chooseBestMBAID \
	    -version 1.0 -overview "Allows choosing the best insertion devices for a given application."
    } else {
	Cgi_Header "Allows choosing the best insertion devices for a given application." {BGCOLOR=white TEXT=black}
	set output "<form ACTION='http://ops.aps.anl.gov/cgi-bin/chooseBestMBAID.cgi' METHOD='GET' NAME='search' >"
    }

    if {!$web} {
	APSChooseBestMBAIDSetStatus Working...
	APSScrolledStatus .status \
	    -parent .userFrame \
	    -textVariable status \
	    -width 65 \
	    -packOption "-fill both -expand true"
    }
    
    set label "Lattice:"
    set variable lattice
    #set buttonList [list 2013-047(81pm) 2013-055(59pm) 2014-009(65pm-3PW)]
    #set valueList [list 2013-047 2013-055 2014-009]
    set buttonList [list 3PW-V6]
    set valueList [list 3PW-V6]
    if {!$web} {
	APSRadioButtonFrame .lattice -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList 
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Beam current (mA):"
    set variable current
    set buttonList [list 200 400]
    set valueList [list 200 400]
    if {!$web} {
	APSRadioButtonFrame .current -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList 
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Front end type:"
    set variable feType
    set buttonList [list Canted HHL VHHL EHHL]
    set valueList [list CFE HHL VHHL EHHL]
    if {!$web} {
	APSRadioButtonFrame .rbfe -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp "Choose the type of front end. The HHL (High Heat Load) front end has the highest existing power-handling capacity. VHHL has 50% higher capacity, while EHHL has 10x higher capacity."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Optimization quantity: "
    set variable optimizationQuantity
    set buttonList [list Brightness "Spectral flux density" "Spectral flux"]
    set valueList [list Brightness SpectralFluxDensity SpectralFlux]
    if {!$web} {
	APSRadioButtonFrame .mode -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp "Optimization can be performed for various quantities. The results typically don't depend strongly on this choice, but if you are interested in a particular quantity, this allows you to see plots of that quantity."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Maximum HPM ID length (m): "
    set variable idMaximumLength
    set buttonList [list None 2.4 4.8]
    set valueList [list 10.0 2.4 4.8]
    if {!$web} {
	APSRadioButtonFrame .rlength -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp "Specify the maximum allowed magnetic length for HPM devices, including revolvers."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Maximum SCU magnetic length: "
    set variable scIdMaximumLength
    set buttonList [list None 1.5 2.0 2.5 3.0 3.5 4.0 ]
    set valueList [list  10.0 1.5 2.0 2.5 3.0 3.5 4.0 ]
    if {!$web} {
	APSRadioButtonFrame .rlengthsc -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp "Specify the maximum allowed magnetic length for SCUs."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Undulator type: "
    set variable idType
    set variableIndexList [list HPM Revolver2 Revolver3 SCU]
    set variableList [list idType(HPM) idType(Revolver2) idType(Revolver3) idType(SCU)] 
    set buttonList [list HPM Revolver2 Revolver3 SCU]
    if {!$web} {
	APSCheckButtonFrame .utype -parent .userFrame -label $label \
	    -orientation horizontal \
	    -buttonList $buttonList \
	    -variableList $variableList
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList variableIndex $variableIndexList {
	    if {[set ${variable}($variableIndex)]} {
		append output "<input type=checkbox name=${variable}$variableIndex value=1 checked>$button "
	    } else {
		append output "<input type=checkbox name=${variable}$variableIndex value=1>$button "
	    }
	}
	append output "<br>"
    }

    set label "Magnetic gap (mm): "
    set variable gap
    set buttonList [list 9.0]
    set valueList [list 9.0]
    if {!$web} {
	APSRadioButtonFrame .gap -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp ""
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "Periods to consider: "
    set variable periodOption
    set buttonList [list Existing All]
    set valueList [list Existing All]
    if {!$web} {
	APSRadioButtonFrame .periods -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList \
	    -valueList $valueList \
	    -contextHelp "For revolvers, we restrict periods to 17 to 33 mm in 1 mm steps. Present APS undulators have periods of 18, 23, 27, 30, 33, 35, and 55 mm. APS-U is presently considering only these periods. However, this software can analyze the benefits of the full selection from 17 to 33 mm. For SCUs all periods are allowed."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set label "0.5mm period increments: "
    set variable periodFrac
    set buttonList [list Yes No]
    set valueList [list .? .0]
    if {!$web} {
	APSRadioButtonFrame .periodFrac -parent .userFrame -label $label \
	    -orientation horizontal -variable $variable \
	    -buttonList $buttonList -valueList $valueList \
	    -contextHelp "Select whether to consider periods with 0.5 mm increments. E.g., 32.5 in addition to 32.0"
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }
    
    set label "Minimum, maximum period (mm): "
    set variableList [list periodMin periodMax] 
    if {!$web} {
	APSLabeledEntryFrame .pMinMax -parent .userFrame -label $label \
	    -orientation horizontal \
	    -variableList $variableList \
	    -contextHelp "Enter the minimum and maximum period to allow."
    } else {
	append output "$label "
	foreach variable $variableList {
	    global $variable
	    append output "<input type=text size=10 name=$variable value=[set $variable]>"
	}
	append output "<br>"
    }

    set label "Optimize: "
    set buttonList [list "Band Ave." "Band Min." "Band Max." "Few Dips"]
    set variableList [list sortType(ave) sortType(min) sortType(max) sortType(dip)]
    set variable sortType
    set variableIndexList [list ave min max dip]
    if {!$web} {
	APSCheckButtonFrame .sort -parent .userFrame -label $label \
	    -orientation horizontal \
	    -buttonList $buttonList \
	    -variableList $variableList \
	    -contextHelp "Select which statistics to optimize in each band. \"Band Ave.\" is the average value in the band, etc. \"Few Dips\" refers to minimization of the number of dips in the spectrum that exceed 50%."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList variableIndex $variableIndexList {
	    if {[set ${variable}($variableIndex)]} {
		append output "<input type=checkbox name=${variable}$variableIndex value=1 checked>$button "
	    } else {
		append output "<input type=checkbox name=${variable}$variableIndex value=1>$button "
	    }
	}
	append output "<br>"
    }

    set label "Ranks to include: "
    set variable ranks
    if {!$web} {
	APSLabeledEntry .ranks -parent .userFrame -label $label \
	    -textVariable $variable -contextHelp "Enter the number of ranks to include (1 is the default)" 
    } else {
	append output "$label "
	global $variable
	append output "<input type=text size=10 name=$variable value=[set $variable]><br>"
    }

    set label "Default plot range (keV):"
    set variableList [list defaultRangeLow defaultRangeHigh]
    if {!$web} {
	APSLabeledEntryFrame .range -parent .userFrame -label $label \
	    -orientation horizontal -variableList $variableList 
    } else {
	append output "$label "
	foreach variable $variableList {
	    global $variable
	    append output "<input type=text size=10 name=$variable value=[set $variable]>"
	}
	append output "<br>"
    }

    set label "Reference: "
    set variable referenceType
    set buttonList None
    for {set period 17} {$period<34} {incr period} {
        lappend buttonList U$period.0 U${period}.5
    }
    set valueList  $buttonList
    if {!$web} {
        APSRadioButtonFrame .rbref -parent .userFrame -label $label \
          -orientation horizontal -variable $variable -limitPerRow 12 \
          -buttonList $buttonList -valueList $valueList -contextHelp \
          "Select the reference curve to display along with the optimum curves."
    } else {
	global $variable
	append output "$label "
	foreach button $buttonList value $valueList {
	    if {[set $variable] == $value} {
		append output "<input type=radio name=$variable value=$value checked>$button "
	    } else {
		append output "<input type=radio name=$variable value=$value>$button "
	    }
	}
	append output "<br>"
    }

    set elementVariableList ""
    set elementButtonList ""
    set Z 1
    foreach element $elementNameList {
        lappend elementButtonList "[format %5s ${element}/$Z]"
        incr Z
        lappend elementVariableList elementFlag($element) 
    }
    set label "K Edges: "
    set variable elementFlag
    set variableIndexList $elementNameList
    set variableList $elementVariableList
    set buttonList $elementButtonList
    if {!$web} {
	APSCheckButtonFrame .kedge -parent .userFrame -label $label \
	    -orientation horizontal -limitPerRow 12 \
	    -buttonList $buttonList \
	    -variableList $variableList -contextHelp "Choose elements for which to add K-edge lines. A region of +/-0.1 keV is added around each line."
    } else {
	global $variable
	append output "<br>$label "
	foreach button $buttonList variableIndex $variableIndexList {
	    if {[set ${variable}($variableIndex)]} {
		append output "<input type=checkbox name=${variable}$variableIndex value=1 checked>$button "
	    } else {
		append output "<input type=checkbox name=${variable}$variableIndex value=1>$button "
	    }
	}
	append output "<br>"
    }
    
    if {!$web} {
	APSChooseBestMBAIDAddPhotonBand -low 3.3 -high 33.0 -on 1
	
	APSFrame .buttons -parent .userFrame
	set w .userFrame.buttons.frame
	APSButton .addBand -parent $w -text "Add Band" -command APSChooseBestMBAIDAddPhotonBand 
	APSButton .search -parent $w -text "Search" -command APSChooseBestMBAIDRunSearch

	APSChooseBestMBAIDSetStatus Ready.
    } else {
	global bandOn bandLow bandHigh
	for {set i 0} {$i<1} {incr i} {
	    append output "<hr>Band $i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enable: "
	    if {$bandOn($i) == 1} {
		append output "<input type=radio name=bandOn$i value=1 checked>Yes "
		append output "<input type=radio name=bandOn$i value=0>No "
	    } else {
		append output "<input type=radio name=bandOn$i value=1>Yes "
		append output "<input type=radio name=bandOn$i value=0 checked>No "
	    }
	    append output "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "
	    append output "Low, High (keV): "
	    append output "<input type=text size=10 name=bandLow$i value=$bandLow($i)> "
	    append output "<input type=text size=10 name=bandHigh$i value=$bandHigh($i)> <br>"
	}
	for {set i 1} {$i<10} {incr i} {
	    append output "<hr>Band $i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Enable: "
	    if {$bandOn($i) == 1} {
		append output "<input type=radio name=bandOn$i value=1 checked>Yes "
		append output "<input type=radio name=bandOn$i value=0>No "
	    } else {
		append output "<input type=radio name=bandOn$i value=1>Yes "
		append output "<input type=radio name=bandOn$i value=0 checked>No "
	    }
	    append output "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "
	    append output "Low, High (keV): "
	    append output "<input type=text size=10 name=bandLow$i value=$bandLow($i)> "
	    append output "<input type=text size=10 name=bandHigh$i value=$bandHigh($i)> <br>"
	}
	append output "<hr><input type=hidden name=searching value=1>"
	append output "<input TYPE='submit' VALUE='Search'></form>"
	puts $output
    }

}

proc APSChooseBestMBAIDSetStatus {text} {
    global status web
    if {$web} {
	puts "[clock format [clock seconds] -format %H:%M:%S]: $text <br>"
    } else {
	set status "[clock format [clock seconds] -format %H:%M:%S]: $text"
	update
    }
}

proc APSChooseBestMBAIDAddPhotonBand {args} {
    set low 0
    set high 0
    set on 1
    APSStrictParseArguments {low high on}
    global nBands bandLow bandHigh bandOn
    
    if $nBands==0 {
	APSFrame .bands -parent .userFrame 
    }
    set bandLow($nBands) $low
    set bandHigh($nBands) $high
    set bandOn($nBands) $on
    APSFrame .band$nBands -parent .userFrame.bands.frame -label "Band $nBands"
    set w .userFrame.bands.frame.band$nBands.frame
    APSRadioButtonFrame .onoff -parent $w -label "Enable: " \
	-orientation horizontal -packOption "-side left" \
	-variable bandOn($nBands) -buttonList [list Yes No] -valueList [list 1 0]
    APSLabeledEntryFrame .lohi -parent $w -label "Low, High (keV): " \
	-orientation horizontal -packOption "-side left" \
	-variableList [list bandLow($nBands) bandHigh($nBands)] 
    incr nBands
}

proc APSChooseBestMBAIDRunSearch {} {
    global current feType optimizationQuantity straightType idType gap periodOption
    global nBands bandLow bandHigh bandIDs bandOn
    global dataDirectory idMaximumLength periodMin periodMax periodFrac scIdMaximumLength lattice
    global resultsPlot1List resultsPlot2List resultsPrintoutList resultsTag
    global ranks sortType referenceType defaultRangeLow defaultRangeHigh
    global elementFlag pickedElementList 
    set ranks [expr int($ranks)]
    if $ranks<1 {set ranks 1}

    set pickedElementList ""
    foreach element [array names elementFlag] {
        if {$elementFlag($element)} {
            lappend pickedElementList $element
        }
    }

    set resultsTag $current,$feType,$optimizationQuantity,$straightType,$gap,$periodOption,$nBands,$idMaximumLength,$scIdMaximumLength,$periodMin,$periodMax,$ranks,$sortType(ave),$sortType(min),$sortType(max),$sortType(dip),$referenceType,$defaultRangeLow,$defaultRangeHigh,$lattice,[join $pickedElementList ,]
    if [string compare $periodFrac .0]==0 {
	append resultsTag ,.0
    } else {
	append resultsTag ,.5
    }
    foreach name [list idType bandOn bandLow bandHigh] {
	foreach tag [array names $name] {
	    lappend resultsTag [set $name\($tag)]
	}
    }
    if [lsearch [array names resultsPlot1List] $resultsTag]!=-1 {
	APSChooseBestMBAIDSetStatus "Displaying cached results."
	eval exec sddsplot $resultsPlot1List($resultsTag) &
	eval exec sddsplot $resultsPlot2List($resultsTag) &
	set tmpW .[APSTmpString]
	eval APSFileDisplayWindow $tmpW $resultsPrintoutList($resultsTag) 
        APSButton .replot -parent $tmpW.buttonRow -text Replot -command "APSChooseBestMBAIDReplot \"$resultsTag\""
        APSButton .savePlot -parent $tmpW.buttonRow -text "Save Plots" -command "APSChooseBestMBAIDSavePlots \"$resultsTag\""
	return
    }

    APSChooseBestMBAIDSetStatus "Working..."
    set dataFileList [APSChooseBestMBAIDFindRelevantFiles]
    if [llength $dataFileList]==0 {
	APSChooseBestMBAIDSetStatus "No data matching your request."
	return 
    }

    APSChooseBestMBAIDSetStatus "[llength $dataFileList] files found"
    APSChooseBestMBAIDSetStatus "Analyzing..."

    set rootname /tmp/[APSTmpString]

    set bestFileList [APSChooseBestMBAIDFindBestFiles -dataFileList $dataFileList -rootname $rootname]
    APSChooseBestMBAIDSetStatus "Done."
}

proc APSChooseBestMBAIDReplot {tag} {
    global resultsPlot1List resultsPlot2List resultsPrintoutList
    eval exec sddsplot $resultsPlot1List($tag) &
    eval exec sddsplot $resultsPlot2List($tag) &
}

proc APSChooseBestMBAIDSavePlots {tag} {
    global resultsPlot1List resultsPlot2List resultsPrintoutList
    global plotOutputType plotOutputRootname savePlotsSem
    
    set tmpW .[APSTmpString]
    APSDialogBox $tmpW \
        -name "Save plots" \
        -okCommand "set savePlotsSem 1" \
        -cancelCommand "set savePlotsSem 0"
    APSRadioButtonFrame .type -parent $tmpW.userFrame -label "Type: " \
        -orientation horizontal -variable plotOutputType \
        -buttonList "PNG PDF Postscript" -valueList "png pdf ps" 
    APSLabeledEntry .rootname -parent $tmpW.userFrame \
        -textVariable plotOutputRootname \
        -label "Rootname: " -width 20 -type alpha 
    set savePlotsSem 0
    tkwait variable savePlotsSem
    if !$savePlotsSem {
        return
    }
    switch $plotOutputType {
        png {
            catch {eval exec sddsplot -device=hpng,onwhite,template=${plotOutputRootname}-%03ld.png -thick=2 -line=0,thick=2 \
                     $resultsPlot1List($tag) }
            catch {eval exec sddsplot -device=hpng,onwhite,template=${plotOutputRootname}-%03ldPower.png -thick=2 -line=0,thick=2 \
                     $resultsPlot2List($tag) }
        }
        ps {
            catch {eval exec sddsplot -device=cpost -output=${plotOutputRootname}.ps -thick=2 -line=0,thick=2 \
                     $resultsPlot1List($tag) }
            catch {eval exec sddsplot -device=cpost -output=${plotOutputRootname}-Power.ps -thick=2 -line=0,thick=2 \
                     $resultsPlot2List($tag) }
        }
        pdf {
            catch {eval exec sddsplot -device=cpost -output=${plotOutputRootname}.ps -thick=2 -line=0,thick=2 \
                     $resultsPlot1List($tag) }
            exec ps2pdf13 ${plotOutputRootname}.ps ${plotOutputRootname}.pdf
            catch {eval exec sddsplot -device=cpost -output=${plotOutputRootname}-Power.ps -thick=2 -line=0,thick=2 \
                     $resultsPlot2List($tag) }
            exec ps2pdf13 ${plotOutputRootname}-Power.ps ${plotOutputRootname}-Power.pdf
            file delete ${plotOutputRootname}.ps ${plotOutputRootname}-Power.ps
        }
    }
    APSChooseBestMBAIDSetStatus "Plots have been saved"
}

proc APSChooseBestMBAIDFindRelevantFiles {} {
    set dataFileList ""
    global current feType optimizationQuantity straightType idType gap periodOption lattice
    global dataDirectory idMaximumLength periodMin periodMax periodFrac scIdMaximumLength

    if {[string compare $feType LCFE]==0 && [string compare $straightType Short]==0} {
        APSChooseBestMBAIDSetStatus "Must choose Long straight for LSS Canted Front End"
        return 
    }
    foreach type [array names idType] {
	if !$idType($type) continue
        APSChooseBestMBAIDSetStatus "Searching for $type"
        switch $type {
            HPM {
                eval lappend dataFileList [APSChooseBestMBAIDFindDataFiles -type $type -dataDirectory $dataDirectory($type,$lattice) -straightType $straightType -feType $feType -current $current -gap $gap -periodOption $periodOption -maximumLength $idMaximumLength -periodMin $periodMin -periodMax $periodMax -periodFrac $periodFrac]
            }
            Revolver2 {
                eval lappend dataFileList [APSChooseBestMBAIDFindDataFiles -type $type -dataDirectory $dataDirectory($type,$lattice) -straightType $straightType -feType $feType -current $current -gap $gap -periodOption $periodOption -maximumLength $idMaximumLength -periodMin $periodMin -periodMax $periodMax -periodFrac $periodFrac]
            }
            Revolver3 {
                eval lappend dataFileList [APSChooseBestMBAIDFindDataFiles -type $type -dataDirectory $dataDirectory($type,$lattice) -straightType $straightType -feType $feType -current $current -gap $gap -periodOption $periodOption -maximumLength $idMaximumLength -periodMin $periodMin -periodMax $periodMax -periodFrac $periodFrac]
		}
            SCU {
                eval lappend dataFileList [APSChooseBestMBAIDFindScuDataFiles -dataDirectory $dataDirectory($type,$lattice) -straightType $straightType -feType $feType -current $current -gap $gap \
                                             -maximumLength $scIdMaximumLength -periodMin $periodMin -periodMax $periodMax -periodFrac $periodFrac]
            }
            default {
                APSChooseBestMBAIDSetStatus "Unknown undulator type \"$type\" !"
                return 
            }
	}
    }

    set dataFileList [lsort -unique $dataFileList] 
    return $dataFileList
}

proc APSChooseBestMBAIDFindBestFiles {args} {
    set dataFileList ""
    set rootname ""
    APSStrictParseArguments {dataFileList rootname}
    global nBands bandLow bandHigh bandIDs bandOn
    global optimizationQuantity straightType current feType gap
    global defaultRangeLow defaultRangeHigh ranks
    global sortType web referenceType dataDirectory latticeTag lattice pickedElementList mainDataDirectory
    
    set bandsOn 0
    foreach band [lsort [array names bandOn]] {
	if $bandOn($band) {
	    incr bandsOn
	}
    }
    if {$bandsOn==0 && [llength $pickedElementList]==0} {
	APSChooseBestMBAIDSetStatus "No bands defined or enabled, and no K-edges chosen."
	return
    }
    APSChooseBestMBAIDSetStatus "$bandsOn active bands, [llength $pickedElementList] chosen K-edges"
    switch [string tolower $optimizationQuantity] {
	brightness {
	    set quantity Brightness
	    set minimum 1e15
	    set plotMinimum 1e17
	    set units "ph/s/mm\$a2\$n/mrad\$a2\$n/0.1%BW"
	}
	spectralfluxdensity {
	    set quantity FluxDensity
	    set minimum 1e13
	    set plotMinimum 1e15
	    set units "ph/s/mrad\$a2\$n/0.1%BW"
	}
        spectralflux {
	    set quantity TotalFlux
	    set minimum 1e10
	    set plotMinimum 1e12
	    set units "ph/s/0.1%BW"
	}
	default {
	    APSChooseBestMBAIDSetStatus "Unknown optimization mode \"$optimizationQuantity\" !"
	    return
	}
    }
    
    set rangeLow $defaultRangeLow
    set rangeHigh $defaultRangeHigh
    foreach band [lsort [array names bandOn]] {
        if !$bandOn($band) continue
	set low  $bandLow($band)
	set high $bandHigh($band)

	lappend bandLowList  $low
	lappend bandHighList $high

	lappend bandListList "$low-$high"
    
	if [expr $low>$high] {
	    APSChooseBestMBAIDSetStatus "Error (1): band list has low > high ($low > $high)"
	    return
	}
	if [expr $low<$rangeLow] {
	    set rangeLow $low
	}
	if [expr $high>$rangeHigh] {
	    set rangeHigh $high
	}
        lappend bandRangeList $low-${high}keV 
    }

    global KEdge
    foreach element $pickedElementList {
        set low [expr $KEdge($element)-0.1]
        set high [expr $KEdge($element)+0.1]
	lappend bandLowList  $low
	lappend bandHighList $high

	lappend bandListList "$element"
        
	if [expr $low<$rangeLow] {
	    set rangeLow $low
	}
	if [expr $high>$rangeHigh] {
	    set rangeHigh $high
	}
        lappend bandRangeList $element
    }

    
    set rangeSpan [expr ($rangeHigh-$rangeLow)]
    set rangeMid  [expr ($rangeLow+$rangeHigh)/2.0]
    set rangeLow  [expr ($rangeMid-1.1*$rangeSpan/2.0)]
    set rangeHigh [expr ($rangeMid+1.1*$rangeSpan/2.0)]

    set sortCount 0
    foreach type [array names sortType] {
        if $sortType($type) {
            incr sortCount
        }
    }
    if $sortCount==0 {
        SetStatus "Error: No quantities selected for maximization."
        return 
    }


    set tmpRoot /tmp/[APSTmpString]
    set optList ""
    set plotOptList [list -mode=y=log,y=spec -limit=ymin=$plotMinimum -scale=$rangeLow,$rangeHigh,0,0 -same=global "-ylabel=$quantity ($units)"] 
    set band 0
    foreach low $bandLowList high $bandHighList bandRange $bandRangeList {
	# BrightnessGap<n> is the number of values in band <n> below $minimum.  Want to minimize
	# BrightnessMin<n> is the minimum brightness in band <n>.  Want to maximize
	# BrighntessAve<n> is the average brightness in band <n>.  Want to maximize
	lappend optList -print=parameter,BandRange$band,$bandRange
        lappend optList -process=${quantity},count,%sGap$band,functionOf=photonEnergy,lower=$low,upper=$high,top=$minimum
        lappend optList -process=${quantity},max,%sMax$band,functionOf=photonEnergy,lower=$low,upper=$high
        lappend optList -process=${quantity},min,%sMin$band,functionOf=photonEnergy,lower=$low,upper=$high
        lappend optList -process=${quantity},ave,%sAve$band,functionOf=photonEnergy,lower=$low,upper=$high
        if $band==0 {
            lappend optList "-define=col,${quantity}Delta,${quantity} Shifted${quantity} - ${quantity} 1e-300 +  /" 
        }
        lappend optList -process=${quantity}Delta,count,${quantity}Dips$band,functionOf=photonEnergy,lower=$low,upper=$high,bottom=0.5
	lappend optList -process=TotalPower,max,%s$band,functionOf=photonEnergy,lower=$low,upper=$high
	lappend optList -process=OnAxisPowerDensity,max,%s$band,functionOf=photonEnergy,lower=$low,upper=$high
	lappend onAxisPowerDensityList OnAxisPowerDensity$band
	lappend totalPowerList TotalPower$band

	lappend brightnessMinList ${quantity}Min$band
	lappend plotOptList -drawline=x0v=$low,x1v=$low,q0v=0,q1v=1,line=$band,thick=2
	lappend plotOptList -drawline=x0v=$high,x1v=$high,q0v=0,q1v=1,line=$band,thick=2
	lappend ndSortOptList1 -column=${quantity}Gap$band,min
	lappend sortOptList1 -column=${quantity}Gap$band,incr
        if $sortType(min) {
            lappend ndSortOptList2 -column=${quantity}Min$band,max
            lappend sortOptList2 -column=${quantity}Min$band,decr
        }
        if $sortType(max) {
            lappend ndSortOptList2 -column=${quantity}Max$band,max
            lappend sortOptList2 -column=${quantity}Max$band,decr
        }
        if $sortType(ave) {
            lappend ndSortOptList2 -column=${quantity}Ave$band,max
            lappend sortOptList2 -column=${quantity}Ave$band,decr
        }
        if $sortType(dip) {
            lappend ndSortOptList2 -column=${quantity}Dips$band,min
            lappend sortOptList2 -column=${quantity}Dips$band,incr
        }
#	lappend printOptList -column=BandRange$band -column=${quantity}*$band,format=%13.2e,end
	lappend printOptList($band) -column=BandRange$band -column=${quantity}*$band,format=%13.2e,end
	incr band 
    }
    if [expr $band!=($bandsOn+[llength $pickedElementList])] {
        APSChooseBestMBAIDSetStatus "Mismatch in band count"
        return
    }

    # Combine all the relevant brightness envelopes (photonEnergy, ${quantity})
    # Perform the processing as indicated above
    # Sort and keep first-rank configurations w.r.t. fewest points with ${quantity}<1e15
    # Sort and keep first-rank cnofigurations w.r.t. max values of band-min and band-average brightness
    # Make a plot for each of those configurations
    if {$web} {
	APSAddToTempFileList $rootname.best
	set tee1 ""
	set tee2 ""
    } else {
	APSAddToTempFileList $rootname.all $rootname.sort $rootname.best
	set tee1 "| tee $rootname.all"
	set tee2 "| tee $rootname.sort"
    }
    if $bandsOn==1 {
	if [catch {eval exec sddscombine $dataFileList -pipe=out \
                       | sddsshift -pipe -column=${quantity} -shift=1 \
		       | sddsprocess -pipe $optList -nowarning -process=photonEnergy,min,photonEnergyMin,functionOf=$quantity,lower=$minimum \
		       | sddscollapse -pipe \
		       $tee1 \
		       | sddsprocess -pipe -process=${quantity}Gap0,min,%sMin \
		       "{-test=column,${quantity}Gap0 ${quantity}Gap0Min ==}" \
		       | sddssort -pipe $ndSortOptList2 -nondom \
		       $tee2 \
		       | sddsprocess -pipe "{-redefine=col,Rank,Rank 0 == ? n_rows i_row - : Rank $,type=long}" -filter=column,Rank,1,$ranks -nowarning \
		       | sddsprocess -pipe \
	               -edit=column,Tag0,Filename,10Z/5dS/.bfnorm/10D \
	               -edit=column,Tag,Filename,10Z/5dS/.bfnorm/10DaS/-P/fZ- \
		       "{-define=column,BrightnessMinMin,$brightnessMinList}" \
		       "{-define=column,TotalPowerMax,$totalPowerList}" \
		       "{-define=column,OnAxisPowerDensityMax,$onAxisPowerDensityList}" \
		       | sddssort -pipe -column=Tag0 -unique \
		       | sddssort -pipe=in $rootname.best -column=BrightnessMinMin,decr $sortOptList1 $sortOptList2} result] {
	    APSChooseBestMBAIDSetStatus "Error (2): $result"
	    return
	}
    } else {
	if [catch {eval exec sddscombine $dataFileList -pipe=out \
                       | sddsshift -pipe -column=${quantity} -shift=1 \
		       | sddsprocess -pipe $optList -nowarning -process=photonEnergy,min,photonEnergyMin,functionOf=$quantity,lower=$minimum \
		       | sddscollapse -pipe \
		       | sddssort -pipe $ndSortOptList1 -nondom \
		       | sddsprocess -pipe -filter=column,Rank,1,$ranks -nowarning \
		       | sddsconvert -pipe -delete=col,Rank,CrowdingDistance,ConstraintsViolation \
		       | sddssort -pipe $ndSortOptList2 -nondom \
		       $tee2 \
		       | sddsprocess -pipe -filter=column,Rank,1,$ranks -nowarning \
		       | sddsprocess -pipe \
	               -edit=column,Tag0,Filename,10Z/5dS/.bfnorm/10D \
	               -edit=column,Tag,Filename,10Z/5dS/.bfnorm/10DaS/-P/fZ- \
		       "{-define=column,BrightnessMinMin,$brightnessMinList [llength $brightnessMinList] minn}" \
		       "{-define=column,TotalPowerMax,$totalPowerList [llength $totalPowerList] maxn}" \
		       "{-define=column,OnAxisPowerDensityMax,$onAxisPowerDensityList [llength $onAxisPowerDensityList] maxn}" \
		       | sddssort -pipe -column=Tag0 -unique \
		       | sddssort -pipe=in $rootname.best -column=BrightnessMinMin,decr $sortOptList1 $sortOptList2} result] {
	    APSChooseBestMBAIDSetStatus "Error (3): $result"
	    return
	}
    }

    set filenameList [exec sdds2stream -column=Filename $rootname.best]
    set rankList [exec sdds2stream -column=Rank $rootname.best]
    APSChooseBestMBAIDSetStatus "[llength $filenameList] rank-1 choices"
    APSChooseBestMBAIDSetStatus "[join $filenameList ,]"

    set i 1
    set plot2OptList -scale=$rangeLow,$rangeHigh,0,0
    foreach filename $filenameList rank $rankList {
	set tail [file tail $filename]
	set dirname [file dir $filename]
	if [string match "*-P??.?+P??.?+P??.?-L*-Rev3.*" $tail] {
	    # 3-revolver
	    set type Rev3
	    set fieldList [split $tail -]
	    set P1 [os editstring d [lindex [split [lindex $fieldList 4] +] 0]]
	    set P2 [os editstring d [lindex [split [lindex $fieldList 4] +] 1]]
	    set P3 [os editstring d [lindex [split [lindex $fieldList 4] +] 2]]
	    set L [os editstring d [lindex $fieldList 5]]
	    lappend plotOptList -column=photonEnergy,${quantity} $filename -graph=sym
	    lappend plotOptList "-title=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" 
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P1-L${L}-HPM.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=1,thick=2 -legend=spec=${P1}mm
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P2-L${L}-HPM.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=2,thick=2 -legend=spec=${P2}mm
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P3-L${L}-HPM.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=3,thick=2 -legend=spec=${P3}mm
            lappend plot2OptList -column=photonEnergy,TotalPower $filename 
            lappend plot2OptList "-topline=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" -end
            lappend plot2OptList -column=photonEnergy,OnAxisPowerDensity $filename  "-topline=${P1}mm + ${P2}mm + ${P3}mm" -end
        } elseif [string match "*-P??.?+P??.?-L*-Rev2.*" $tail] {
	    # 2-revolver
	    set type Rev2
	    set fieldList [split $tail -]
	    set P1 [os editstring d [lindex [split [lindex $fieldList 4] +] 0]]
	    set P2 [os editstring d [lindex [split [lindex $fieldList 4] +] 1]]
	    set L [os editstring d [lindex $fieldList 5]]
	    lappend plotOptList -column=photonEnergy,${quantity} $filename -graph=sym
	    lappend plotOptList "-title=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" 
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P1-L${L}-HPM.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=1,thick=2 -legend=spec=${P1}mm
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P2-L${L}-HPM.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=2,thick=2 -legend=spec=${P2}mm
            lappend plot2OptList -column=photonEnergy,TotalPower $filename 
            lappend plot2OptList "-topline=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" -end
            lappend plot2OptList -column=photonEnergy,OnAxisPowerDensity $filename  "-topline=${P1}mm + ${P2}mm" -end
	} elseif [string match "*-SCU.*" $tail] {
	    # SCU
	    set fieldList [split $tail -]
	    set P1 [os editstring d [lindex $fieldList 4]]
	    set L [os editstring d [lindex $fieldList 5]]
	    set type SCU
	    lappend plotOptList -column=photonEnergy,${quantity} $filename -graph=sym
	    lappend plotOptList "-title=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  $type" 
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P1-L${L}-${type}.bfnorm.envp 
	    lappend plotOptList -split=page -graph=line,type=1,thick=2 -legend=spec=${P1}mm

            lappend plot2OptList -column=photonEnergy,TotalPower $filename 
            lappend plot2OptList "-topline=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  $type" -end
            lappend plot2OptList -column=photonEnergy,OnAxisPowerDensity $filename "-topline=${P1}mm" -end
	} else {
	    # HPM
	    set fieldList [split $tail -]
	    set P1 [os editstring d [lindex $fieldList 4]]
	    set L [os editstring d [lindex $fieldList 5]]
	    set type HPM
	    lappend plotOptList -column=photonEnergy,${quantity} $filename -graph=sym
	    lappend plotOptList "-title=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" 
	    lappend plotOptList -column=photonEnergy,${quantity} $dirname/$latticeTag($lattice)-$feType-I${current}-P$P1-L${L}-${type}.bfnorm.envp
	    lappend plotOptList -split=page -graph=line,type=1,thick=2 -legend=spec=${P1}mm

            lappend plot2OptList -column=photonEnergy,TotalPower $filename 
            lappend plot2OptList "-topline=Rank:$rank FE:$feType  ${straightType}SS  I:${current}mA  L:${L}cm  gap:${gap}mm  $type" -end
            lappend plot2OptList -column=photonEnergy,OnAxisPowerDensity $filename "-topline=${P1}mm" -end
	}

        global refLabel
        set refLabel "None"
        if [string match U* $referenceType] {
            set LRef [FindReferenceLength -type $type -length $L -feType $feType]
            set refPeriod [os editstring %/U// $referenceType]
            set refFile $dataDirectory(reference)/G11.0/apsU-$feType-I100-G11.0-P${refPeriod}-L${LRef}-HPM.bfnorm.envp
            set refLabel APS/100mA/$referenceType/${LRef}cm
            lappend plotOptList -column=photonEnergy,${quantity} $refFile
            lappend plotOptList -split=page -graph=line,type=2,thick=2 -legend=spec=APS/100mA/$referenceType/${LRef}cm
            lappend plotOptList -end
        }
        lappend plotOptList -end

	incr i
    }

    global resultsPlot1List resultsPlot2List resultsPrintoutList resultsTag
    set resultsPlot1List($resultsTag) "$plotOptList"
    set resultsPlot2List($resultsTag) "-layout=1,2 $plot2OptList"
    if {$web} {
        puts "<hr>"
        foreach fnl $filenameList {
            file copy -force $fnl /net/epics-ops/web_roots/ops/logging/plots/
            puts "<a href=http://ops.aps.anl.gov/logging/plots/[file tail $fnl]>[file tail $fnl]</a><br>"
        }
	set sec [clock seconds]
	set latexOutput [APSChooseBestMBAIDLatexHeader]
	append latexOutput [APSChooseBestMBAIDLatexCalcValues]

	puts "<hr><pre>"
        if {[catch {exec sddsprocess $mainDataDirectory/AOP-TN-$lattice/$latticeTag($lattice).beam -pipe=out -clip=1,0,invert \
                      | sddsprintout -pipe=in "-title=Beam properties" -col=sigmax,format=%10.6f -col=sigmaxprime,format=%10.6f -col=emitx,format=%10.3g \
                      -col=sigmay,format=%10.6f -col=sigmayprime,format=%10.6f -col=emity,format=%10.3g \
                      -col=EnergySpread,format=%10.3g -col=current,format=%10.3f} results]} {
	    puts $results
	} else {
	    puts $results
	}

        if {[catch {exec sddsprocess $mainDataDirectory/AOP-TN-$lattice/$latticeTag($lattice).beam -pipe=out -clip=1,0,invert \
                      | sddsprintout -pipe=in -latex "-title=Beam properties" -col=sigmax,format=%10.6f -col=sigmaxprime,format=%10.6f -col=emitx,format=%10.3g \
                      -col=sigmay,format=%10.6f -col=sigmayprime,format=%10.6f -col=emity,format=%10.3g \
                      -col=EnergySpread,format=%10.3g -col=current,format=%10.3f} results]} {
            append latexOutput ${results}\n
	} else {
	    append latexOutput "${results}\n\\pagebreak\n"
	}

	if {[catch {eval exec sddsprintout "{-title=\n}" \
                      $rootname.best -width=600 -column=Tag0,format=%37s -col=Rank -col=TotalPowerMax -col=OnAxisPowerDensityMax -col=photonEnergyMin} results]} {
	    puts $results
	} else {
	    puts $results
	}
	if {[catch {eval exec sddsprintout $rootname.best "-title=" -latex -width=600 -column=Tag0,format=%37s -col=Rank -col=TotalPowerMax -col=OnAxisPowerDensityMax -col=photonEnergyMin} results]} {
	    append latexOutput ${results}\n
	} else {
	    append latexOutput "${results}\n\\pagebreak\n"
	}

	for {set i 0} {$i < $band} {incr i} {
	    if {[catch {eval exec sddsprintout $rootname.best "{-title=\nData for band $i}" -width=600 -column=Tag0,format=%37s $printOptList($i) } results]} {
		puts $results
	    } else {
		puts $results
	    }
	    if {[catch {eval exec sddsprintout $rootname.best -latex -width=600 -column=Tag0,format=%37s $printOptList($i) } results]} {
		append latexOutput ${results}\n
	    } else {
		append latexOutput "${results}\n\\pagebreak\n"
	    }
	}
	set i [string first photons/s/mm\$a2\$n/mrad\$a2\$n/0.1\\%BW $latexOutput]
	if {$i != -1} {
	    set j [string first \\begin\{table\} $latexOutput]
	    incr j
	    set k [string first \\begin\{table\} $latexOutput $j]
	    while {$k != -1} {
		set n [string first \n $latexOutput $k]
		set latexOutput [string replace $latexOutput $n $n "\\newline Brightness in units of photons/s/mm\$^2\$/mrad\$^2\$/0.1\\% BW \n"]
		set j [expr $k + 1]
		set k [string first \\begin\{table\} $latexOutput $j]
	    }
	}
	set i [string first photons/s/mm\$a2\$n/mrad\$a2\$n/0.1\\%BW $latexOutput]
	while {$i != -1} {
	    set latexOutput [string replace $latexOutput $i [expr $i + 35]]
	    set i [string first photons/s/mm\$a2\$n/mrad\$a2\$n/0.1\\%BW $latexOutput]
	}
	set i [string first photons/s/mrad\$a2\$n/0.1\\%BW $latexOutput]
	if {$i != -1} {
	    set j [string first \\begin\{table\} $latexOutput]
	    incr j
	    set k [string first \\begin\{table\} $latexOutput $j]
	    while {$k != -1} {
		set n [string first \n $latexOutput $k]
		set latexOutput [string replace $latexOutput $n $n "\\newline Spectral flux density in units of photons/s/mrad\$^2\$/0.1\\% BW \n"]
		set j [expr $k + 1]
		set k [string first \\begin\{table\} $latexOutput $j]
	    }
	}
	set i [string first photons/s/mrad\$a2\$n/0.1\\%BW $latexOutput]
	while {$i != -1} {
	    set latexOutput [string replace $latexOutput $i [expr $i + 27]]
	    set i [string first photons/s/mrad\$a2\$n/0.1\\%BW $latexOutput]
	}
	set i [string first photons/s/0.1\\%BW $latexOutput]
	if {$i != -1} {
	    set j [string first \\begin\{table\} $latexOutput]
	    incr j
	    set k [string first \\begin\{table\} $latexOutput $j]
	    while {$k != -1} {
		set n [string first \n $latexOutput $k]
		set latexOutput [string replace $latexOutput $n $n "\\newline Spectral flux in units of photons/s/0.1\\% BW  \n"]
		set j [expr $k + 1]
		set k [string first \\begin\{table\} $latexOutput $j]
	    }
	}
	set i [string first photons/s/0.1\\%BW $latexOutput]
	while {$i != -1} {
	    set latexOutput [string replace $latexOutput $i [expr $i + 17]]
	    set i [string first photons/s/0.1\\%BW $latexOutput]
	}
	puts "</pre><hr>"
	#append latexOutput "\n\\pagebreak\n"

        if {[catch {eval exec sddsplot $plotOptList -device=lpng,template=/net/epics-ops/web_roots/ops/logging/plots/plot${sec}_chooseBestMBAID_1-%03ld.png} results]} {
	}

	set i 1
	while {[file exists /net/epics-ops/web_roots/ops/logging/plots/plot${sec}_chooseBestMBAID_1-[format %03ld $i].png]} {
	    puts "<img src=http://ops.aps.anl.gov/logging/plots/plot${sec}_chooseBestMBAID_1-[format %03ld $i].png><hr>"
	    append latexOutput [APSChooseBestMBAIDLatexImage plot${sec}_chooseBestMBAID_1-[format %03ld $i].png]
	    incr i
	}

        if {[catch {eval exec sddsplot -layout=1,2 $plot2OptList -device=lpng,template=/net/epics-ops/web_roots/ops/logging/plots/plot${sec}_chooseBestMBAID_2-%03ld.png} results]} {
	}

	set i 1
	while {[file exists /net/epics-ops/web_roots/ops/logging/plots/plot${sec}_chooseBestMBAID_2-[format %03ld $i].png]} {
	    puts "<img src=http://ops.aps.anl.gov/logging/plots/plot${sec}_chooseBestMBAID_2-[format %03ld $i].png><hr>"
	    append latexOutput [APSChooseBestMBAIDLatexImage plot${sec}_chooseBestMBAID_2-[format %03ld $i].png]
	    incr i
	}

	set fid [open /net/epics-ops/web_roots/ops/logging/plots/plot${sec}_chooseBestMBAID.tex w]

	
	append latexOutput [APSChooseBestMBAIDLatexFooter]
	puts $fid $latexOutput
	close $fid
	set dir [pwd]
	cd /net/epics-ops/web_roots/ops/logging/plots
	global env
	#set env(TEXINPUTS) ".:/opt/local/share/texmf-dist/tex/latex//"
        #set pdflatex /usr/local/bin/pdflatex 
        set pdflatex /usr/local/texlive/2012/bin/x86_64-linux/pdflatex
	if {[catch {exec $pdflatex plot${sec}_chooseBestMBAID.tex} results]} {
	    puts "<br><br>ERROR: $results <br><br>"
	} else {
	    puts "<br><a href=http://ops.aps.anl.gov/logging/plots/plot${sec}_chooseBestMBAID.pdf>PDF output</a><br><br>"
	}
	cd $dir
    } else {
	eval exec sddsplot $plotOptList &
	eval exec sddsplot -layout=1,2 $plot2OptList &
        catch {exec sddsprocess $mainDataDirectory/AOP-TN-$lattice/$latticeTag($lattice).beam -pipe=out -clip=1,0,invert \
                 | sddsprintout -pipe=in "-title=Beam properties" -col=sigmax,format=%10.6f -col=sigmaxprime,format=%10.6f -col=emitx,format=%10.3g \
                 -col=sigmay,format=%10.6f -col=sigmayprime,format=%10.6f -col=emity,format=%10.3g \
                 -col=EnergySpread,format=%10.3g -col=current,format=%10.3f > $rootname.txt} 
	catch {eval exec sddsprintout $rootname.best "{-title=\n}" -width=600 -column=Tag0,format=%37s -col=Rank -col=TotalPowerMax -col=OnAxisPowerDensityMax  -col=photonEnergyMin >> $rootname.txt}
	for {set i 0} {$i < $band} {incr i} {
	    catch {eval exec sddsprintout "{-title=\nData for band $i}" $rootname.best -width=600 -column=Tag0,format=%37s $printOptList($i) >> $rootname.txt}
	}
	set tmpW .[APSTmpString]
	
	APSFileDisplayWindow $tmpW -fileName $rootname.txt -autoWidth 1 -autoWidthLimit 200
	APSButton .replot -parent $tmpW.buttonRow -text Replot -command "APSChooseBestMBAIDReplot \"$resultsTag\""
	APSButton .savePlot -parent $tmpW.buttonRow -text "Save Plots" -command "APSChooseBestMBAIDSavePlots \"$resultsTag\""
    }

    set resultsPrintoutList($resultsTag) "-fileName $rootname.txt -autoWidth 1"
}

proc APSChooseBestMBAIDFindDataFiles {args} {
    set dataDirectory ""
    set straightType ""
    set feType ""
    set current 150
    set gap 9.0
    set periodOption All
    set type HPM 
    set maximumLength 10.0
    set periodMin 10.0
    set periodMax 56.0
    set periodFrac .?
    APSStrictParseArguments {dataDirectory straightType feType current gap periodOption type maximumLength periodMin periodMax periodFrac}
    global latticeTag lattice

    set tag $latticeTag($lattice)
    set deduction 0
    switch $type {
	HPM {
	    set searchString $dataDirectory/G${gap}/${tag}-${feType}-I${current}-P??${periodFrac}-L
	    set periodValues 1
	}
	Revolver2 {
	    set searchString $dataDirectory/G${gap}/${tag}-${feType}-I${current}-P??${periodFrac}+P??${periodFrac}-L
	    set type Rev2
	    set periodValues 2
	}
	Revolver3 {
	    set searchString $dataDirectory/G${gap}/${tag}-${feType}-I${current}-P??${periodFrac}+P??${periodFrac}+P??${periodFrac}-L
	    set type Rev3
	    set periodValues 3
	}
	default {
	    APSChooseBestMBAIDSetStatus "Invalid type \"$type\" in APSChooseBestMBAIDFindDataFiles"
	    return 
	}
    }

    switch $feType {
        LCFE -
	CFE {
            set lengthList [expr 210-$deduction]
	    APSChooseBestMBAIDSetStatus "$lengthList"
            set dataFileList ""
	    foreach length $lengthList {
                if [expr $length<=100*$maximumLength] {
                    APSChooseBestMBAIDSetStatus "Search for $searchString${length}-${type}.bfnorm.env"
                    set dataFile0List [lsort [glob -nocomplain $searchString${length}-${type}.bfnorm.env]]
                    APSChooseBestMBAIDSetStatus "--- found [llength $dataFile0List] files"
                    eval lappend dataFileList $dataFile0List
                }
            }
	}
	EHHL -
	VHHL -
	HHL {
            set length0List [list 240 480]
	    foreach length $length0List {
                lappend lengthList [expr $length-$deduction]
            }
	    set dataFileList ""
	    foreach length $lengthList {
                if [expr $length<=100*$maximumLength] {
                    APSChooseBestMBAIDSetStatus "Search for $searchString${length}-${type}.bfnorm.env"
                    set dataFile0List [lsort [glob -nocomplain $searchString${length}-${type}.bfnorm.env]]
                    APSChooseBestMBAIDSetStatus "--- found [llength $dataFile0List] files"
                    eval lappend dataFileList $dataFile0List
                } else {
                    APSChooseBestMBAIDSetStatus "Ignoring $searchString${length}-${type}.bfnorm.env"
                }
	    }
	}
	default {
	    return 
	}
    }

    if [string compare $periodOption All]==0 {
        set existingPeriodList ""
    } else {
        set existingPeriodList [list 18.0 23.0 27.0 30.0 33.0 35.0 55.0]
    }


    set fileList ""
    switch $periodValues {
	1 {
	    foreach item $dataFileList {
		set partList [split $item -]
		set period [os editstring d [lindex $partList [expr [llength $partList]-3]]]
		if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period]==-1} continue
		if {[expr $period>=$periodMin] && [expr $period<=$periodMax]} {
		    lappend fileList $item
		}
	    }
	}
	2 {
	    foreach item $dataFileList {
		set partList [split $item -]
		set periodDataList [eval os editstring d [split [lindex $partList [expr [llength $partList]-3]] +]]
		set period1 [lindex $periodDataList 0]
		set period2 [lindex $periodDataList 1]
                if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period1]==-1} continue
                if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period2]==-1} continue
		if {[expr $period1>=$periodMin] && [expr $period1<=$periodMax] && \
			[expr $period2>=$periodMin] && [expr $period2<=$periodMax]} {
		    lappend fileList $item
		}
	    }
	}
	3 {
	    foreach item $dataFileList {
		set partList [split $item -]
		set periodDataList [eval os editstring d [split [lindex $partList [expr [llength $partList]-3]] +]]
		set period1 [lindex $periodDataList 0]
		set period2 [lindex $periodDataList 1]
		set period3 [lindex $periodDataList 2]
                if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period1]==-1} continue
                if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period2]==-1} continue
                if {[llength $existingPeriodList] && [lsearch -exact $existingPeriodList $period3]==-1} continue
		if {[expr $period1>=$periodMin] && [expr $period1<=$periodMax] && \
			[expr $period2>=$periodMin] && [expr $period2<=$periodMax] && \
			[expr $period3>=$periodMin] && [expr $period3<=$periodMax]} {
		    lappend fileList $item
		}
	    }
	}
    }
    return $fileList 
}

proc APSChooseBestMBAIDFindScuDataFiles {args} {
    set dataDirectory ""
    set straightType ""
    set feType ""
    set current 150
    set gap 9.0
    set maximumLength 10.0
    set periodMin 10.0
    set periodMax 56.0
    set periodFrac .?
    APSStrictParseArguments {dataDirectory straightType feType current gap maximumLength periodMin periodMax periodFrac}
    global latticeTag lattice

    set tag $latticeTag($lattice)
    set deduction 110
    set type SCU

    set searchString $dataDirectory/G${gap}/${tag}-${feType}-I${current}-P??${periodFrac}-L
    set fileList ""
    switch $feType {
        CFE -
        LCFE {
            set lengthList [expr 210-$deduction]
	    APSChooseBestMBAIDSetStatus "$lengthList"
	    foreach length $lengthList {
                if [expr $length<=100*$maximumLength] {
                    APSChooseBestMBAIDSetStatus "Search for $searchString${length}-${type}.bfnorm.env"
                    set dataFile0List [lsort [glob -nocomplain $searchString${length}-${type}.bfnorm.env]]
                    APSChooseBestMBAIDSetStatus "--- found [llength $dataFile0List] files"
                    eval lappend fileList $dataFile0List
                }
            }
	}
	EHHL -
	VHHL -
	HHL {
            set lengthList [list 100 130 200 370]
	    APSChooseBestMBAIDSetStatus "$lengthList"
	    foreach length $lengthList {
                if [expr $length<=100*$maximumLength] {
                    APSChooseBestMBAIDSetStatus "Search for $searchString${length}-${type}.bfnorm.env"
                    set dataFile0List [lsort [glob -nocomplain $searchString${length}-${type}.bfnorm.env]]
                    APSChooseBestMBAIDSetStatus "--- found [llength $dataFile0List] files"
                    eval lappend fileList $dataFile0List
                }
            }
        }
    }

    set fileList1 ""
    foreach item $fileList {
	set partList [split $item -]
	set period [os editstring d [lindex $partList [expr [llength $partList]-3]]]
	if {[expr $period>=$periodMin] && [expr $period<=$periodMax]} {
	    lappend fileList1 $item
	}
    }
    return $fileList1
}

proc APSChooseBestMBAIDLatexHeader {args} {
    return "\\documentclass\[11pt\]\{article\}
\\usepackage\{latexsym,html\}
\\usepackage\[pdftex\]\{graphicx\}
\\usepackage\[landscape\]\{geometry\}
\\usepackage\[justification=centering\]\{caption\}
\\usepackage\{enumerate\}

\\pagestyle\{plain\}
\\tolerance=10000
\\newenvironment\{req\}\{\\begin\{equation\} \\rm\}\{\\end\{equation\}\}
\\setlength\{\\topmargin\}\{0.15 in\}
\\setlength\{\\oddsidemargin\}\{0 in\}
\\setlength\{\\evensidemargin\}\{0 in\}
\\setlength\{\\textwidth\}\{6.5 in\}
\\setlength\{\\headheight\}\{-0.5 in\}
\\setlength\{\\textheight\}\{9 in\}
\\begin\{document\}\n"
}


proc APSChooseBestMBAIDLatexFooter {args} {
    return "\\end\{document\}\n"
}

proc APSChooseBestMBAIDLatexImage {filename} {
    return "\\begin\{figure\}\[htbp\!\]
\\centering\%
\\includegraphics\[width=8in\]\{${filename}\}
\\end\{figure\}
\\pagebreak\n"
}

proc APSChooseBestMBAIDLatexCalcValues {args} {
    append output "\\begin\{description\}
\\setlength\{\\itemsep\}\{1pt\}
\\setlength\{\\parskip\}\{0pt\}
\\setlength\{\\parsep\}\{0pt\}\n"

    append output "\\item\[Today's date:\] [clock format [clock seconds]]\n"

    global current
    append output "\\item\[Beam current (mA):\] ${current}\n"

    global feType
    if {$feType == "CFE"} {
	set feTypeString Canted
    } else {
	set feTypeString $feType
    }
    append output "\\item\[Front end type:\] ${feTypeString}\n"

    global optimizationQuantity
    if {$optimizationQuantity == "SpectralFluxDensity"} {
	set optimizationQuantityString "Spectral flux density"
    } elseif {$optimizationQuantity == "SpectralFlux"} {
	set optimizationQuantityString "Spectral flux"
    } else {
	set optimizationQuantityString $optimizationQuantity
    }
    append output "\\item\[Optimization quantity:\] ${optimizationQuantityString}\n"

    global straightType
    append output "\\item\[Straight section type:\] ${straightType}\n"

    global idMaximumLength
    if {$idMaximumLength == "10.0"} {
	set idMaximumLengthString "None"
    } else {
	set idMaximumLengthString $idMaximumLength
    }
    append output "\\item\[Maximum ID magnetic length (m):\] ${idMaximumLengthString}\n"

    global scIdMaximumLength
    if {$scIdMaximumLength == "10.0"} {
	set scIdMaximumLengthString "None"
    } else {
	set scIdMaximumLengthString $scIdMaximumLength
    }
    append output "\\item\[Maximum SCU magnetic length (m):\] ${scIdMaximumLengthString}\n"

    global idType
    set idTypeString ""
    if {$idType(HPM)} {
	lappend idTypeString "HPM"
    }
    if {$idType(Revolver2)} {
	lappend idTypeString "Revolver2"
    }
    if {$idType(Revolver3)} {
	lappend idTypeString "Revolver3"
    }
    if {$idType(SCU)} {
	lappend idTypeString "SCU"
    }
    append output "\\item\[Undulator type:\] [join $idTypeString ", "]\n"

    global gap
    append output "\\item\[HPM and revolver gap (mm):\] ${gap}\n"

    global periodOption
    append output "\\item\[Periods to consider:\] ${periodOption}\n"

    global periodFrac
    if {$periodFrac == ".?"} {
	set periodFracString "Yes"
    } else {
	set periodFracString "No"
    }
    append output "\\item\[0.5mm period increments:\] ${periodFracString}\n"

    global periodMin
    append output "\\item\[Minimum period (mm):\] ${periodMin}\n"

    global periodMax
    append output "\\item\[Maximum period (mm):\] ${periodMax}\n"

    global sortType
    set sortTypeString ""
    if {$sortType(ave)} {
	lappend sortTypeString "Band Ave"
    }
    if {$sortType(min)} {
	lappend sortTypeString "Band Min"
    }
    if {$sortType(max)} {
	lappend sortTypeString "Band Max"
    }
    if {$sortType(dip)} {
	lappend sortTypeString "Few Dips"
    }
    append output "\\item\[Optimize:\] [join $sortTypeString ", "]\n"

    global ranks
    append output "\\item\[Ranks to include:\] ${ranks}\n"

    global defaultRangeLow defaultRangeHigh
    append output "\\item\[Default plot range (keV):\] $defaultRangeLow to $defaultRangeHigh \n"
    
    global referenceType refLabel
    append output "\\item\[Reference:\] ${refLabel}\n"

    global bandOn bandLow bandHigh
    for {set i 0} {$i<10} {incr i} {
	if {$bandOn($i) == 1} {
	    append output "\\item\[Band $i range (keV):\] $bandLow($i) to $bandHigh($i) \n"
	}
    }

    global elementNameList elementFlag
    set kedgesString ""
    set Z 1
    foreach element $elementNameList {
        if {$elementFlag($element)} {
            lappend kedgesString "[format %5s ${element}/$Z]"
        }
        incr Z
    }
    append output "\\item\[K Edges:\] [join $kedgesString ", "]\n"

    append output "\\end\{description\}
\\pagebreak\n"

    return $output

}

