#!/bin/sh
# \
exec oagwish -f "$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)]
APSDebugPath

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

APSApplication . -name SRAcquireMomboHistory -version $CVSRevisionAuthor \
  -overview {This application does configuration and acquisition for the storage ring mombo history facility.}

set apsOutputDir .
set outputRoot momboBH
set lastOutputRoot ""
set userComment ""
set outputIndex 0
set acquisitionMode stored
set setResynch 0
set acquireFullSets 0
set collectShortHistories 0
set convertInBackground 0
set lastOutputFile ""
set P0Count 1
set clipHead 0
set clipTail 0
set plotOptions ""
set fftPlotOptions ""

proc GiveShortHistoryWarning {} {
    setStatusText "** Note **"
    setStatusText "The short history mode is not fully tested."
    setStatusText "Use at your own risk."
    return
    set counter 5
    while {$counter} {
        incr counter -1
        bell
        after 200
    }
}

proc MakeFileEntryFrame {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -label "Output Specification"
    set w $parent$widget.frame
    global apsOutputDir outputFilename outputRoot outputIndex \
      lastOutputRoot userComment

    APSButton .daily -parent $w -text "Go to daily directory" \
      -packOption "-side top -anchor w" \
      -command "APSGoToDailyDirectory -subdirectory momboBH"

    APSLabeledEntry .dir -parent $w -textVariable apsOutputDir \
      -label "Directory: " -width 70 \
      -contextHelp "Enter the name of the directory in which data files will be written."
    APSLabeledEntry .comment -parent $w -textVariable userComment \
      -width 70 -label "Comment: " -contextHelp \
      "Enter a comment to be placed in the files with the data."

    frame $w.indexfr
    pack $w.indexfr -side bottom

    APSLabeledEntry .index -parent $w.indexfr -textVariable outputIndex \
      -label "Index: " -width 10 -packOption "-expand 1 -side left" \
      -contextHelp "Shows the file index for automatic filename generation for the history files. Incremented at the start of acquisition."

    APSButton .reset -parent $w.indexfr -text "RESET" -size small \
      -command "set outputIndex 0" -packOption "-side right" \
      -contextHelp "Use to reset the index counter for automatic filename generation."
    
}

proc MakeAcquisitionModeFrame {widget args} {
    global acquisitionMode setResynch convertInBackground acquireFullSets collectShortHistories
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -label "Acquisition Mode" -packOption "-side left"
    set w $parent$widget.frame
    APSRadioButtonFrame .xymode -parent $w -label "Mode" \
      -orientation vertical -variable acquisitionMode -gridPack "-row 0 -column 0" \
      -buttonList {"Tripped" "Stored"} \
      -valueList {tripped stored} \
      -contextHelp "Select acquisition mode, stored beam or tripped beam."
    APSRadioButtonFrame .resynch -parent $w -label "Resynch" \
      -orientation vertical -variable setResynch -gridPack "-row 0 -column 1" \
      -buttonList {"Disable" "Enable"} \
      -valueList {0 1} -contextHelp \
      "Select whether buffers are synchronized with the injection trigger or not."
    APSRadioButtonFrame .fullsets -parent $w -label "Full sets" \
      -orientation vertical -variable acquireFullSets \
      -gridPack "-row 0 -column 2" \
      -buttonList {No Yes} \
      -valueList {0 1} -contextHelp \
      "Select whether to acquire the full set of data or just the index and coordinate value."
    APSRadioButtonFrame .convert -parent $w -label "Convert to SDDS" \
      -orientation vertical -variable convertInBackground -gridPack "-row 0 -column 3" \
      -buttonList {Foreground Background} -valueList {0 1} -contextHelp \
      "Choose whether to convert the data to SDDS in the foreground or in the background.  If the latter is chosen, the data can be collected more rapidly but the workstation may experience a heavy load."
    APSRadioButtonFrame .short -parent $w -label "History Type" -gridPack "-row 0 -column 4" \
      -orientation vertical -variable collectShortHistories \
      -buttonList {Long Short} -valueList {0 1} -contextHelp \
      "Choose whether to collect the short waveforms.  These are downloaded via EPICS and are much more reliable, but have only 512 samples."
}

proc MakeClipEntryFrame {widget args} {
    global clipHead clipTail
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -label "Clip Control" \
      -contextHelp "Allows control of clipping of the history buffers.  Enter the number of samples to clip at each end of the buffer." \
      -packOption "-side left" 
    set w $parent$widget.frame
    APSLabeledEntry .le1 -parent $w -label "Head: " \
      -textVariable clipHead -contextHelp "Entry the number of samples to clip from the start of the buffer." \
      -width 5
    APSLabeledEntry .le2 -parent $w -label "Tail: " \
      -textVariable clipTail -contextHelp "Entry the number of samples to clip from the end of the buffer." \
      -width 5
    
}

proc MakeP0CountFrame {widget args} {
    global P0Count
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -label "P0 Count\nControl" \
      -contextHelp "Allows control of the P0 count process variables, which determine how many turns will elapse between successive readings of the BPMs." \
      -packOption "-side left" 
    set w $parent$widget.frame
    APSLabeledEntry .le -parent $w -label "Value: " \
      -textVariable P0Count -contextHelp "Enter the value for the P0 count here.  It controls how many turns will elapse between successive readings of the BPMs." -width 5
    APSButton .b1 -parent $w -text Send -command SetP0Count \
      -contextHelp "Sends the value above to the IOCs to be used as P0 count for all selected sectors."
    APSDisableButton $w.b1.button
}

proc SetP0Count {} {
    global P0Count BPMList
    if {$P0Count<0 || $P0Count>75} {
        setStatusText "P0Count is invalid---must be [1,75]"
        return
    }
    set sectorList [lindex [GetSectorBPMList] 0]
    if [llength $sectorList] {
        if [catch {exec cavput -list=S:bpm -list=[join $sectorList ,] \
        -list=:time.P0CT=$P0Count -pend=10} result] {
            setStatusText "$result"
            return
        }
    }
    setStatusText "P0 Count set to $P0Count for [llength $sectorList] sectors"
}

# returns list of sector-bpm pairs.
# the missing bpms should be excluded automatically 
# since momboS$sector$bpm would have values of 0.
proc GetSectorBPMList {} {
    global BPMList
    set selectedSector ""
    set selectedBPM ""
    for {set sector 1} {$sector<41} {incr sector} {
        foreach bpm $BPMList {
            global momboS$sector$bpm
            if [set momboS$sector$bpm] {
                set index [lsearch -exact $BPMList $bpm]
                if [expr $index > -1 ] {
                    lappend selectedSector $sector 
                    lappend selectedBPM $bpm
                }
            }
        }
    }
    return [list $selectedSector $selectedBPM]
}

proc SetHistoryTargets {} {
    global BPMList
    set data [GetSectorBPMList]
    set selectedBPMs ""
    foreach sector [lindex $data 0] bpm [lindex $data 1] {
        set index [lsearch -exact $BPMList $bpm]
        set index [expr 9 * (${sector} - 1) + $index]
        lappend selectedBPMs S:bpm${sector}=$index
    }
    if ![llength $selectedBPMs] {
        setStatusText "No BPM names given."
        return 0
    } else {
        eval exec cavput -list=[join $selectedBPMs ,] -list=:bh.BPMI -pendIoTime=10
    }
    return [llength $selectedBPMs]
}

# This works only for long histories.
proc ConfigureHistorySectors {} {
    global acquisitionMode setResynch BPMList
    set sectorList {}
    set selectedBPM {}

    set data [GetSectorBPMList]
    foreach sector [lindex $data 0] bpm [lindex $data 1] {
        lappend sectorList S:bpm$sector
        lappend selectedBPM S${sector}$bpm
    }
    if ![llength $selectedBPM] {
        setStatusText "No BPM names given."
        return 0
    } 
    # for tripped mode, configure before the beam is tripped
    if {![string compare $acquisitionMode tripped]} {
        # fifo read disable
        # fifo single shot
        # fifo continuous fill
        # fifo resynch
        if {[catch {exec cavput -list=[join $sectorList ,] \
                      -list=:bh. -list=BRDE=0,BRDM=0,FIM0=0,FIR0=$setResynch \
                      -pendIoTime=10} result] } {
            setStatusText "Error: $result"
            return 0
        }
    } elseif {![string compare $acquisitionMode stored]} {
        # fifo read enable
        # fifo single shot
        # fifo stop on full
        # fifo resynch
        if {[catch {exec cavput -list=[join $sectorList ,] \
                      -list=:bh. -list=BRDE=1,BRDM=0,FIM0=1,FIR0=$setResynch \
                      -pendIoTime=10} result] } {
            setStatusText "Error: $result"
            return 0
        }
        # G. Decker had a 3 second wait before resetting.
        after 1000
        # fifo reset
        if {[catch {exec cavput -list=[join $sectorList ,] \
                      -list=:bh. -list=FRST=1 \
                      -pendIoTime=10} result] } {
            setStatusText "Error: $result"
            return 0
        }
    }
    return [llength $BPMList]
}

# calls AcquireAllShortHistories
# or calls AcquireAllShortHistories
proc AcquireAllMomboHistoriesSelective {} { 
    set w [APSUniqueName .]
    global dialogDone doToggleGlobalResynch BPMList \
        abortAcquisition collectShortHistories
    set doToggleGlobalResynch 0
    set abortAcquisition 0
    set dialogDone 0
    APSDialogBox $w -name "Selection dialog" -okCommand "set dialogDone 1" \
        -cancelCommand "set dialogDone 2"
    for {set sector 1} {$sector<41} {incr sector} {
        lappend buttonList $sector
        lappend variableList AcquireSector$sector
        global AcquireSector$sector
        set AcquireSector$sector 0
    }
    APSCheckButtonFrame .cb -parent $w.userFrame -label "Select sectors" \
      -orientation horizontal -limitPerRow 10 -allNone 1 \
      -variableList $variableList -buttonList $buttonList 
    APSRadioButtonFrame .rb -parent $w.userFrame \
      -label "Toggle global resynch? (choose yes for synchronized data)?" \
      -variable doToggleGlobalResynch -buttonList {Yes No} -valueList {1 0}
    update
    tkwait variable dialogDone
    if $dialogDone!=1 return
    set sectorList ""
    for {set sector 1} {$sector<41} {incr sector} {
        if [set  AcquireSector$sector] {
            lappend sectorList $sector
        }
    }
    if [llength $sectorList] {
        UnsetAllBPMs
        setStatusText "Configuring histories for all BPMs in selected sectors..."
        ConfigureAllHistoriesInSectors -sectorList $sectorList
        set beamCurrent -1
        if $doToggleGlobalResynch {
            setStatusText "Toggling global resynch"
            exec cavput -list=Mt:Ddg2chan7.GATE=1
            # this takes 2 s, which is a necesary pause
            set beamCurrent [exec cavget -list=S-DCCT:CurrentM -repeat=number=10,pause=0.2,average]
            exec cavput -list=Mt:Ddg2chan7.GATE=0
            setStatusText "Data captured. Turn off kickers now if necessary."
            after 2000
        }
        setStatusText "Beginning data acquisition"
        if $collectShortHistories {
            GiveShortHistoryWarning
            if [catch {AcquireAllShortHistories -sectorList $sectorList \
                     -beamCurrent $beamCurrent} result] {
                exec cavput -list=Mt:Ddg2chan7.GATE=1
                return -code error "$result"
            }
        } else {
            if [catch {AcquireAllMomboHistories -sectorList $sectorList \
                     -beamCurrent $beamCurrent} result] {
                exec cavput -list=Mt:Ddg2chan7.GATE=1
                return -code error "$result"
            }
        }
    }
    setStatusText "Data acquisition completed.  Reseting gate."
    exec cavput -list=Mt:Ddg2chan7.GATE=1 
}

# this appears to configure only the long histories.
proc ConfigureAllHistoriesInSectors {args} {
    global BPMList BPMMissingList
    global acquisitionMode setResynch collectShortHistories
    for {set sector 1} {$sector<41} {incr sector} {
        lappend sectorList $sector
    }
    APSStrictParseArguments {sectorList}

    if {![string compare $acquisitionMode tripped]} {
        set FIM 0
    } else {
        set FIM 1
    }
    # do this for all 9 channels even if the number of monopulse bpms
    # have been reduced.
    for {set bpmNum 0} {$bpmNum<9} {incr bpmNum} {
        setStatusText "Configuring history of bpm number $bpmNum..."
        if !$collectShortHistories {
            set bpmNumList ""
            # Do this for each bpm number, as the history modules seem
            # to remember what the BPMs were set to when last selected.
            foreach sector $sectorList {
                lappend bpmNumList $sector:bh.BPMI=[expr ($sector-1)*9+$bpmNum]
            }
            if [catch {exec cavput -list=S:bpm -list=[join $bpmNumList ,] -pendIOTime=10} \
                  result] {
                return -code error "$result"
            }
            after 1000
            # do long histories
            if {[catch {exec cavput -list=S:bh -list=[join $sectorList ,] \
                          -list=:beamH. \
                          -list=FIMA=$FIM,FRRA=$setResynch \
                          -pendIoTime=10} result] } {
                setStatusText "ConfigureAllHistoriesInSectors: $result"
                return 0
            }
        } else {
            # do short histories 
            # fifo fill mode
            # fifo resynch
            # make list of good bpms:
            set goodBPMs ""
            foreach sector $sectorList {
                set bpm $sector[lindex $BPMList $bpmNum]
                if {[lsearch $BPMMissingList S$bpm] == -1} {
                    lappend goodBPMs $sector[lindex $BPMList $bpmNum]
                }
            }
            if [llength $goodBPMs] {
                if {[catch {exec cavput -list=S -list=[join $goodBPMs ,] \
                              -list=:bh. \
                              -list=FIR0=$setResynch,BRDE=1,BRDM=0,FIM0=$FIM \
                              -pend=15 \
                          } result]} {
                    setStatusText "ConfigureAllHistoriesInSectors: $result"
                    return 0
                }
            }
            after 1000
        }
    }
}

proc UnsetAllBPMs {} {
    global BPMList 
    for {set sector 1} {$sector<41} {incr sector} {
        foreach bpm $BPMList {
            global momboS$sector$bpm
            set momboS$sector$bpm 0
        }
    }
}

# called by AcquireAllMomboHistoriesSelective (once)
# for short histories.
# Uses the BPMMissingList properly.
proc AcquireAllShortHistories {args} {
    global outputIndex BPMList abortAcquisition BPMMissingList apsOutputDir
    for {set sector 1} {$sector<41} {incr sector} {
        lappend sectorList $sector
    }
    set beamCurrent 0
    APSStrictParseArguments {sectorList beamCurrent}

    foreach type $BPMList {
        foreach sector $sectorList {
            set bpm S$sector$type
            if {[lsearch $BPMMissingList $bpm] == -1} {
                lappend xWfList $bpm:bh:x_wf
                lappend yWfList $bpm:bh:y_wf
                lappend sumWfList $bpm:bh:sum_wf
                lappend fullBPMList $bpm
            }
        }
    }
    setStatusText "Enabling reading of short histories..."
    exec cavput -list=[join $fullBPMList ,] -list=:bh:wfDisable_bo=1 -pend=15 
    after 2000
    exec cavput -list=[join $fullBPMList ,] -list=:bh.SSEN=1 -pend=15 
    after 2000
    cd $apsOutputDir
    while 1 {
        set outputFile ShortWf-[format %03ld $outputIndex].sdds
        if ![file exists x-$outputFile] break
        incr outputIndex
    }

    setStatusText "Acquiring x plane short histories (3 seconds wait)..."
    if [catch {exec sddswmonitor -pvnames=[join $xWfList ,] x-$outputFile \
             } result] {
        setStatusText "Problem with sddswmonitor(x-plane): $result.\nPV argument: $xWfList"
        return -code error "Problem with sddswmonitor(x-plane): $result.\nPV argument: $xWfList"
    }
    setStatusText "Acquiring y plane short histories (3 seconds wait)..."
    if [catch {exec sddswmonitor -pvnames=[join $yWfList ,] y-$outputFile \
             } result] {
        setStatusText "Problem with sddswmonitor(y-plane): $result.\nPV argument: $yWfList"
        return -code error "Problem with sddswmonitor(y-plane): $result.\nPV argument: $yWfList"
    }
    setStatusText "Acquiring sum short histories (3 seconds wait)..."
    if [catch {exec sddswmonitor -pvnames=[join $sumWfList ,] \
                 sum-$outputFile \
             } result] {
        setStatusText "Problem with sddswmonitor(sum): $result.\nPV argument: $sumWfList"
        return -code error "Problem with sddswmonitor(sum): $result.\nPV argument: $sumWfList"
    }
    
    exec cavput -list=[join $fullBPMList ,] -list=:bh:wfDisable_bo=0 \
      -pend=15 
    incr outputIndex 1
}

set turnOffOtherBPMLevel -1
proc TurnOffOtherBPM {args} {
    global BPMList turnOffOtherBPMLevel
    if {$turnOffOtherBPMLevel != 0} {
        return
    } else {
        incr turnOffOtherBPMLevel
    }
    set sector 1
    set item ""
    APSParseArguments {sector item}
    foreach bpm $BPMList {
        global momboS$sector$bpm momboCBWidget
        if [string compare $bpm $item] {
            if {[set momboS$sector$bpm] != 0} {
#                set momboS$sector$bpm 0
                $momboCBWidget(S$sector$bpm) invoke
            }
        }
    }
    set turnOffOtherBPMLevel 0
}

# called by AcquireAllMomboHistoriesSelective for
# long histories.
# calls AcquireMomboHistories 9 times
# Uses BPMMissingList to skip bpms that are not monopulse type
proc AcquireAllMomboHistories {args} {
    global outputIndex BPMList BPMMissingList abortAcquisition
    for {set sector 1} {$sector<41} {incr sector} {
        lappend sectorList $sector
    }
    set beamCurrent 0
    APSStrictParseArguments {sectorList beamCurrent}

    # loop over 9 types of bpms
    foreach type $BPMList {
        if $abortAcquisition break
        foreach sector $sectorList {
            global momboS${sector}$type
            # select only if bpm is "not missing", i.e monopulse type
            if {[lsearch $BPMMissingList S${sector}$type] == -1} {
                set momboS${sector}$type 1
                if $abortAcquisition break
                TurnOffOtherBPM -sector $sector -item $type
            }
            if $abortAcquisition break
        }
        update
        if $abortAcquisition break
        setStatusText "Doing $type bpms..."
        AcquireMomboHistories -configure 0 -beamCurrent $beamCurrent
        incr outputIndex -1
    }
    if $abortAcquisition {
        setStatusText "Aborted."
    } 
    incr outputIndex 1
}

# May be called by AcquireAllMomboHistories 9 times for long histories.
proc AcquireMomboHistories {args} {
    set configure 1
    set beamCurrent -1
    APSStrictParseArguments {configure beamCurrent}

    global userComment acquisitionMode apsOutputDir outputIndex \
      collectShortHistories
    global acquireFullSets clipHead clipTail convertInBackground \
      abortAcquisition
    set abortAcquisition 0

    if $beamCurrent<0 {
        set beamCurrent [exec cavget -list=S-DCCT:CurrentM]
    }
    scan $outputIndex %ld outputIndex
    incr outputIndex
    set outputIndexF [format %03ld $outputIndex]
    set selectedBPM {}
    set sectorList {}
    set data [GetSectorBPMList]
    if ![llength [lindex $data 0]] {
        # no bpm selected!
        setStatusText "No BPM given!"
        return
    }
    foreach sector [lindex $data 0] bpm [lindex $data 1] {
        lappend sectorList S:bpm$sector
        lappend selectedBPM S${sector}$bpm
    }
    
    setStatusText "Working....[exec date +%H:%M:%S]"
    if {![string compare $acquisitionMode stored]} {
        if {![SetHistoryTargets]} {
            setStatusText "Problem targeting."
            return
        }
        if $configure {
            setStatusText "Configuring histories and wait 2 seconds..."
            if ![ConfigureHistorySectors] {
                setStatusText "Problem configuring."
                return
            }
        }
        # default wait time for FIFO to fill
        after 2000
    }

    # save time of acquisition for use later
    set timeValue [exec timeconvert -break=now]
    set timeStamp [exec timeconvert -sec=$timeValue -text]

# for long histories, PV names are like S:bpm<sector>:bh.BRDE
# for short histories, PV names are like <bpm>:bh.BRDE

    if $collectShortHistories {
        GiveShortHistoryWarning
        
        setStatusText "FIFO buffer read enable and wait 2 seconds..."
        if [catch {exec cavput -list=[join $selectedBPM ,] \
                     -list=:bh.BRDE=1 -pend=10} result] {
            setStatusText "Problem triggering single shot read to IOC: $result"
            return
        }
        after 2000
        setStatusText "Triggering single shot read to IOC and wait 4 seconds..."
        if [catch {exec cavput -list=[join $selectedBPM ,] \
                     -list=:bh.SSEN=1 -pend=10} result] {
            setStatusText "Problem triggering single shot read to IOC: $result"
            return
        }
        after 4000

        foreach bpm $selectedBPM {
            lappend xWfList $bpm:bh:x_wf
            lappend yWfList $bpm:bh:y_wf
            lappend sumWfList $bpm:bh:sum_wf
        }
        exec cavput -list=[join $selectedBPM ,] -list=:bh:wfDisable_bo=1 -pend=15 
        after 2000
        exec cavput -list=[join $selectedBPM ,] -list=:bh.SSEN=1 -pend=15 
        after 2000
        cd $apsOutputDir
        while 1 {
            set outputFile ShortWf-[format %03ld $outputIndex].sdds
            if ![file exists x-$outputFile] break
            incr outputIndex
        }
        setStatusText "Acquiring data..."
        if [catch {exec sddswmonitor x-$outputFile \
                     -pvnames=[join $xWfList ,] -pendIOtime=20 \
                 } result] {
            setStatusText "Problem with sddswmonitor(x-plane): $result.\nPV argument: $xWfList"
            return
        }
        if [catch {exec sddswmonitor y-$outputFile \
                     -pvnames=[join $yWfList ,] -pendIOtime=20 \
                 } result] {
            setStatusText "Problem with sddswmonitor(y-plane): $result.\nPV argument: $yWfList"
            return
        }
        if [catch {exec sddswmonitor sum-$outputFile \
                     -pvnames=[join $sumWfList ,] -pendIOtime=20 \
                 } result] {
            setStatusText "Problem with sddswmonito(sum)r: $result.\nPV argument: $sumWfList"
            return
        }
        exec cavput -list=[join $selectedBPM ,] -list=:bh:wfDisable_bo=0 -pend=15

    } else {

        setStatusText "FIFO buffer read enable and wait 2 seconds..."
        if [catch {exec cavput -list=[join $sectorList ,] -list=:bh.BRDE=1 -pend=10} result] {
            setStatusText "Problem triggering single shot read to IOC: $result"
            return
        }
        after 2000
        setStatusText "Triggering single shot read to IOC and wait 4 seconds..."
        if [catch {exec cavput -list=[join $sectorList ,] -list=:bh.SSEN=1 -pend=10} result] {
            setStatusText "Problem triggering single shot read to IOC: $result"
            return
        }
        after 4000
        
        # regular mombo histories.
        # make a list of files for each BPM
        # the new file is the one that isn't in this list
        set bpmDir /home/helios4/srbpm/pub
        foreach sector [lindex $data 0] bpm [lindex $data 1] {
            set BPMName S${sector}${bpm}
            set BPMFileList($BPMName) [glob -nocomplain $bpmDir/${BPMName}_*.raw]
        }
        
        setStatusText "Dumping data to file system and wait 4 seconds."
        if [catch {exec cavput -list=[join $sectorList ,] \
                     -list=:bh:writeFile_sub.PROC=1 -pend=10} result] {
            setStatusText "Problem triggering single shot read to IOC: $result"
            return
        }
        after 4000

        cd $apsOutputDir
        # determine the presence of each file within a recent time period.
        foreach sector [lindex $data 0] bpm [lindex $data 1] {
            if $abortAcquisition break
            set BPMName S${sector}${bpm}
            setStatusText "Finding data for $BPMName"
            set waitLimit 10
            set fileFound 0
            while {!$fileFound && $waitLimit} {
                if $abortAcquisition break
                incr waitLimit -1
                set filelist [lsort -decreasing [glob -nocomplain $bpmDir/${BPMName}_*.raw]]
                if {[llength $filelist]!=[llength $BPMFileList($BPMName)]} {
                    if ![llength $BPMFileList($BPMName)] {
                        set fileFound 1
                        set file [lindex $filelist 0]
                        setStatusText "File found: $file"
                    } else {
                        foreach file $filelist {
                            if [lsearch -exact $BPMFileList($BPMName) $file]==-1 {
                                set fileFound 1
                                setStatusText "File found: $file"
                                break
                            }
                        }
                    }
                }
                if !$fileFound {
                    setStatusText "No file found for $BPMName. Waiting 4 seconds..."
                    after 4000
                }
            }
            if {$fileFound} {
                if [catch {file copy -force $file .
                    catch {file delete -force $file}} result] {
                    setStatusText "Problem copying data for $BPMName: $result"
                    update
                    continue
                }
                # remove the directory part of the filename
                set file [file tail $file]
                # create a csh script here so I can run it in the foreground or
                # background 
                set tmpFile /tmp/[APSTmpString].csh
                APSAddToTempFileList $tmpFile
                set fid [open $tmpFile w]
                puts $fid "\#!/bin/csh -f"
                puts $fid "set nonomatch"
                puts $fid "beamH2sdds $file"
                if !$acquireFullSets {
                    set xOption -retain=column,index,x
                    set yOption -retain=column,index,y
                } else {
                    set xOption -retain=column,*
                    set yOption -retain=column,*
                }
                puts $fid "rm $file"
                set root [file rootname $file]
                puts $fid "sddsprocess -nowarning ${root}-x.sdds ${BPMName}-${outputIndexF}-x.sdds \
                      -define=parameter,S35DCCT,$beamCurrent,units=mA \
                      $xOption -clip=$clipHead,$clipTail \
                      '-print=para,Comment,[APSMakeSafeQualifierString $userComment]' \
                      -define=param,Time,$timeValue,units=s \
                      '-print=param,TimeStamp,$timeStamp'"
                puts $fid "sddsprocess -nowarning ${root}-y.sdds ${BPMName}-${outputIndexF}-y.sdds \
                      -define=parameter,S35DCCT,$beamCurrent,units=mA \
                      $yOption -clip=$clipHead,$clipTail \
                      '-print=para,Comment,[APSMakeSafeQualifierString $userComment]' \
                      -define=param,Time,$timeValue,units=s \
                      '-print=param,TimeStamp,$timeStamp'"
                puts $fid "rm ${root}-x.sdds ${root}-y.sdds"
                flush $fid
                close $fid
                file attributes $tmpFile -permission ugo+rwx
                if $convertInBackground {
                    exec $tmpFile >& ${tmpFile}.log &
                } else {
                    setStatusText "Converting data for $BPMName"
                    if [catch {exec $tmpFile} result] {
                        setStatusText "Problem with conversion for $BPMName: $result"
                    }
                }
            } else {
                setStatusText "Problem finding file for $BPMName."
            }
        }
    }

    setStatusText "Disabling FIFO read."

    if $collectShortHistories {
        if [catch {exec cavput -list=[join $selectedBPM ,] \
                     -list=:bh.BRDE=1 -pend=10} result] {
            setStatusText ""Problem returning the FIFOs to read disable."
            return
        }
    } else {
        if [catch {exec cavput -list=[join $sectorList ,] -list=:bh. \
                     -list=BRDE=0 -pend=10} result] {
            setStatusText "Problem returning the FIFOs to read disable."
            return
        }
    }
    if $abortAcquisition {
        setStatusText "Aborted."
        bell
    } else {
        setStatusText "Done."
        bell
    }
}

proc setStatusText {text} {
    global statusText 
    set statusText $text
    update
}

proc PlotLastMomboHistories {} {
    global apsOutputDir outputIndex plotOptions
    
    cd $apsOutputDir
    set xfilelist ""
    set yfilelist ""
    set data [GetSectorBPMList]
    scan $outputIndex %ld outputIndex
    set outputIndexF [format %03ld $outputIndex]
    foreach sector [lindex $data 0] bpm [lindex $data 1] {
        set BPMName S${sector}${bpm}
        set xfilelist [lappend xfilelist ${BPMName}-${outputIndexF}-x.sdds]
        set yfilelist [lappend yfilelist ${BPMName}-${outputIndexF}-y.sdds]
    }

    setStatusText "Plotting data ..."
    eval exec sddsplot -layout=1,2 -separate -grap=dots -filename \
      -title=@Comment \
      -group=fileindex \
      $plotOptions \
      -column=index,x $xfilelist  \
      -column=index,y $yfilelist  &
}

proc FFTPlotLastMomboHistories {} {
    global apsOutputDir outputIndex fftPlotOptions

    cd $apsOutputDir
    set xfileList ""
    set yfileList ""
    set xfftList ""
    set yfftList ""
    set data [GetSectorBPMList]
    setStatusText "FFTing..."
    scan $outputIndex %ld outputIndex
    set outputIndexF [format %03ld $outputIndex]
    foreach sector [lindex $data 0] bpm [lindex $data 1] {
        set BPMName S${sector}${bpm}
        set xfile    ${BPMName}-${outputIndexF}-x.sdds
        set yfile    ${BPMName}-${outputIndexF}-y.sdds
        set xfftfile ${BPMName}-${outputIndexF}-x.fft
        set yfftfile ${BPMName}-${outputIndexF}-y.fft
        lappend xfileList    $xfile   
        lappend yfileList    $yfile   
        lappend xfftfileList $xfftfile
        lappend yfftfileList $yfftfile
        if ![file exists $xfftfile] {
            catch {exec sddsfft $xfile $xfftfile -column=index,x -truncate \
                 -suppressaverage}
            exec sddsxref $xfftfile $xfile -transfer=para,Comment -noWarning -leave=*
            file delete $xfftfile~ 
        }
        if ![file exists $yfftfile] {
            catch {exec sddsfft $yfile $yfftfile -column=index,y -truncate \
                     -suppressaverage}
            exec sddsxref $yfftfile $yfile -transfer=para,Comment -noWarning -leave=*
            file delete $yfftfile~
        }
    }
    setStatusText "Plotting..."
    eval exec sddsplot -layout=1,2 -separate -grap=dots -filename \
      -title=@Comment \
      -group=fileindex \
      $fftPlotOptions \
      -column=f,FFTx $xfftfileList  \
      -column=f,FFTy $yfftfileList &
}


set statusText Ready.
APSScrolledStatus .status -parent .userFrame -textVariable statusText \
        -width 70 -height 10
MakeFileEntryFrame .output -parent .userFrame


#MakeBPMEntryFrame .bpm -parent .userFrame
set BPMList {A:P1 A:P2 A:P3 A:P4 B:P5 B:P4 B:P3 B:P2 B:P1}
set BPMMissingList [APSMpExcludedBPMList -excludeNbBPMs 1 -excludeIDBPMs 1 -excludeBMBPMs 1 -excludeFPGABPMs 1]
set momboBadBPMList $BPMMissingList

APSSRSectorButtons .bpmButtons -parent .userFrame -rootname mombo \
  -orientation horizontal \
  -label "BPM selections (Choose one per sector)" \
  -description "BPM selections (Choose one per sector)" \
  -itemList $BPMList -packOption "-side top" \
  -itemLabelList  $BPMList \
  -missingList $BPMMissingList \
  -command "TurnOffOtherBPM"

set apsContextHelp(.userFrame.bpmButtons)  "Choose no more than one bpm per sector. If more than one bpms per sector is selected through using the global sector and +all buttons, then only the last one in each sector will actually be used.\n\nSome bpms are missing and can never be highlighted. "

APSSetSRSectorButtons -mode all-off -rootname mombo \
  -itemList $BPMList

set turnOffOtherBPMLevel 0

APSFrameGrid .mode -parent .userFrame -yList {top bottom}
APSLabeledEntry .plotOptions -parent .userFrame.mode.top \
  -label "Plot Options:" \
  -width 80 -textVariable plotOptions  -contextHelp \
  "Enter plot options."
APSLabeledEntry .fftplotOptions -parent .userFrame.mode.top \
  -label "FFT Plot Options:" \
  -width 80 -textVariable fftPlotOptions  -contextHelp \
  "Enter plot options."
MakeAcquisitionModeFrame .acqmode -parent .userFrame.mode.bottom
# No longer needed as PV S:bpm*:time.P0CT no longer exist.
#MakeP0CountFrame .p0count -parent .userFrame.mode.bottom
MakeClipEntryFrame .clip -parent .userFrame.mode.bottom

APSFrame .f0 -parent .userFrame -relief flat -label ""
set w .userFrame.f0.frame

APSButton .target -parent $w -text TARGET \
  -contextHelp "Targets BPM histories to read, i.e. sets the value of the BPM index for each sector.\n\nFor stored beam mode, this done automatically by ACQUIRE and ACQUIRE ALL.\n\nFor tripped mode, press TARGET _before_ the beam is dumped." \
  -command SetHistoryTargets 

APSButton .configure -parent $w -text CONFIGURE \
  -contextHelp "Configures the BPMs to prepare for data acquisition.\n\nFor stored beam mode, this done automatically by ACQUIRE and ACQUIRE ALL.\n\nFor tripped mode, press CONFIGURE _before_ the beam is bumped." \
  -command ConfigureHistorySectors

APSButton .acquire -parent $w -text ACQUIRE \
  -contextHelp "For stored beam mode, configures BPMs and acquires data.\n\nFor tripped mode, simply acquires the data." \
  -command AcquireMomboHistories

APSButton .acquireAll -parent $w -text "ACQUIRE ALL..." \
  -contextHelp "Like ACQUIRE, but cycles through all the BPMs (i.e., 9 per sector!). For stored beam mode, configures BPMs and acquires data.\n\nFor tripped mode, simply acquires the data." \
  -command AcquireAllMomboHistoriesSelective

APSButton .abort -parent $w -text ABORT \
    -command {set abortAcquisition 1}

APSButton .plot -parent $w -text PLOT \
  -contextHelp "Plots the last set of data acquired, or the data named explicitly." \
  -command PlotLastMomboHistories

APSButton .fftplot -parent $w -text "FFT and PLOT" \
  -contextHelp "FFTs and plots the last set of data acquired, or the data named explicitly." \
  -command FFTPlotLastMomboHistories

APSFrame .f1 -parent .userFrame -relief flat -label ""
set w .userFrame.f1.frame
APSButton .resetresynch -parent $w -text "Enable Resynch Clock" \
    -contextHelp "This reenables the resynch clock. If this clock is left disabled, the beam histories won't work.  Script tries to do this when you exit, if you use File>Quit." \
    -command EnableResynchClock
APSButton .disableDumpConfig -parent $w -text "Disable Dump Config" \
    -contextHelp "This disables the automatic configuration of the beam histories by the MPS dump recorder." \
    -command "SetDumpConfig 0"
APSButton .enableDumpConfig -parent $w -text "Enable Dump Config" \
    -contextHelp "This enables the automatic configuration of the beam histories by the MPS dump recorder. Script tries to do this when you exit, if you use File>Quit." \
    -command "SetDumpConfig 1"

proc EnableResynchClock {} {
    exec cavput -list=Mt:Ddg2chan7.GATE=1 -pend=60
}

proc SetDumpConfig {state} {
    exec cavput -list=SR:DumpRecorder:ConfigBPMs=$state
}

dp_atexit append EnableResynchClock
dp_atexit append "SetDumpConfig 1"
