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



set CVSRevisionAuthor "\$Revision: 1.11 $ \$Author: shang $"

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



#################################
#				#
#  	  DEFINE FUNCTIONS	#
#				#
#################################

# Widgets design: Power ON
proc PowerOnFrame {widget args} {
    APSStrictParseArguments {parent}

    set w $parent$widget.frame
    APSFrame $widget -parent $parent \
      -label "Turn on and warm up streak camera (5 minutes before use)" 
    
    APSLabeledEntry .onTime -parent $w \
      -label "Streak camera power-on time (in minutes, 1000 max):" -textVariable onTime \
      -contextHelp "Enter the maximum time for streak camera power to be on." -width 15

    APSLabeledEntry .timing -parent $w \
      -label "Timing for bunch length measurements (nanoseconds):" -textVariable timing \
      -contextHelp "Enter the timing for bunch length measurements." -width 15
    APSButton .set -parent $w.timing -packOption "-side right" -text set \
      -command {
          global timing 
          if [catch {exec cavput -list=S35ID:HamC1097_04aC=$timing -pend=30} result] {
              return -code error "$result"
          }
        }
    # executable command
    APSButton .powerOn -parent $w -text "Power ON" -packOption "-side left" \
      -command {PowerUpStreakCamera -onTime $onTime} 
    APSButton .powerOff -parent $w \
      -text "Turn off Streak Camera"  \
      -packOption "-side left" \
      -command {PowerDownStreakCamera} \
      -contextHelp "Turn off streak camera."
    
    APSButton .setupOps -parent $w -text "100mA beam SETUP" -packOption "-side left" \
      -command {setupStreakCamera -ringCurrent 100} \
      -contextHelp "Setup streak camera and optics for 100 mA measurements."

    APSButton .setupSingleBunch -parent $w \
      -text "Single bunch SETUP"  \
      -packOption "-side right" \
      -command {setupStreakCamera -ringCurrent 10} \
      -contextHelp "Setup streak camera and optics for 1 - 10 mA measurements."
    return
}

# Widgets design: Power OFF
proc PowerOffFrame {widget args} {
    APSStrictParseArguments {parent}

    set w $parent$widget.frame
    APSFrame $widget -parent $parent \
      -label "Power off the streak camera" 

    # executable command
    APSButton .powerOff -parent $w \
      -text "Turn off Streak Camera"  \
      -packOption "-side left" \
      -command {PowerDownStreakCamera -quitNow 0} \
      -contextHelp "Turn off streak camera."

    return
}


proc setROI {args} {
    global FrameGrabber 
    set area max
    set xFactor 3
    set yFactor 5
    set type ""
    APSParseArguments {area xFactor yFactor type}
     
    APSSetVarAndUpdate displayStatus "set $type ROI"
    
    # Frame grabber parameters
    set xMax 511
    set yMax 481
    switch $area {
        max {
            set xStart  150
            set yStart  20
            set xSize  200
            set ySize  440
        }
        auto {
            if [catch {exec cavget -list=${FrameGrabber}: -list=x,y -list=:fit: \
                       -list=centroidM,sigmaM \
                           -pend=10 -printErrors -label} valList] {
                return -code error $valList
            }
            array set videoData $valList
            
            set xCentroid  $videoData(${FrameGrabber}:x:fit:centroidM) 
            set yCentroid  $videoData(${FrameGrabber}:y:fit:centroidM) 
            set xSigma     $videoData(${FrameGrabber}:x:fit:sigmaM) 
            set ySigma    $videoData(${FrameGrabber}:y:fit:sigmaM) 
      
            if { $xSigma < 10 } {
                set xStart [expr $xCentroid - 25 ]
                set xSize 50
            } else {
                set xStart [expr $xCentroid - $xFactor * $xSigma ]
                set xSize  [expr 2 * $xFactor * $xSigma ]
            }
            if {$xStart < 0 } { set xStart 0 }
            if {[expr $xStart + $xSize ] > $xMax } { set xSize [expr $xMax - $xStart ] }
            
            if { $ySigma < 10 } {
                set yStart [expr $yCentroid - 25 ]
                set ySize 50
            } else {
                set yStart [expr $yCentroid - $yFactor * $ySigma ]
                set ySize  [expr 2 * $yFactor * $ySigma ]
            }
            if {$yStart < 0 } { set yStart 0 }
            if {[expr $yStart + $ySize ] > $yMax } { set ySize [expr $yMax - $yStart ] }
            set xStart [format %.0f $xStart]
            set yStart [format %.0f $yStart]
            set xSize [format %.0f $xSize]
            set ySize [format %.0f $ySize]
        }
        default {
            return -code error "Unknown area - $area given for setROI."
        }
    }
    APSSetVarAndUpdate displayStatus "set ROI to xStart=$xStart, xSize=$xSize, yStart=$yStart, ySize=$ySize"
    
    if [catch {exec cavput -list=${FrameGrabber}:roiXStartC=$xStart,${FrameGrabber}:roiYStartC=$yStart,${FrameGrabber}:roiXSizeC=$xSize,${FrameGrabber}:roiYSizeC=$ySize -pend=20} result] {
        return -code error "Unable to set ROI: $result"
    }
    APSSetVarAndUpdate displayStatus "done."
}

# Widgets design
proc SetupBunchLenFrame {widget args} {
    global videoMonitor FrameGrabberList FrameGrabber vDelay vDelayIncr nextVDelay
    
    APSStrictParseArguments {parent}
    
    # text input   
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Video / Timing Setup"

    # radio button for monitor selection
    set videoMonitorList {35BMA 35BMB 35IDA 35Lab 35CTRL MCR}
    set commandList {UpdateWithVideoMonitor UpdateWithVideoMonitor UpdateWithVideoMonitor UpdateWithVideoMonitor UpdateWithVideoMonitor UpdateWithVideoMonitor}
    APSRadioButtonFrame .videoMonitorChoiceFrame -parent $w \
      -orientation  horizontal \
      -packOption {-side top -fill x} \
      -label "Video Monitor  " \
      -variable videoMonitor \
      -buttonList $videoMonitorList \
      -valueList $videoMonitorList \
      -commandList $commandList \
      -contextHelp "This radio button is used to select a video monitor." 
    
    # radio button for frame grabber selection
    APSRadioButtonFrame .frameGrabberChoiceFrame -parent $w \
	-orientation  horizontal \
	-packOption {-side top -fill x} \
	-label "Frame Grabber  " \
	-variable FrameGrabber \
	-buttonList ${FrameGrabberList} \
	-valueList ${FrameGrabberList} \
	-contextHelp "This radio button is used to select a video frame grabber." \
	-commandList {"set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" \
			  "set inputFile [MakeInputFileName]" }
    
    # phase shift adjuster
    #vDelayFrame   .vDelay  -parent $w
    APSFrame .vdelay -parent $w
    set w1 $w.vdelay.frame
    $w1 configure -relief flat -bd 0
    APSLabeledEntryFrame .delay -parent $w1 \
      -label "Synchroscan delay  (set | inc => current, ns) " \
      -variableList {nextVDelay vDelayIncr vDelay } \
      -contextHelp "Enter the delay (changing step) of vertical trigger in unit of ns." \
      -orientation horizontal -width 6 -packOption "-side left" 
    APSButton .change -parent $w1 \
      -text "set"  \
      -packOption "-side right" \
      -command {SetVDelay -incr 0} \
      -contextHelp "Set vertical trigger delay (ns)."
    APSButton .down -parent $w1 \
      -text "down"  \
      -packOption "-side right" \
      -command { SetVDelay -incr -$vDelayIncr } \
      -contextHelp "Decrement vertical trigger delay (ns)."
    APSButton .up -parent $w1 \
      -text "up"  \
      -packOption "-side right" \
      -command { SetVDelay -incr $vDelayIncr } \
      -contextHelp "Increment vertical trigger delay (ns)."

    # executable command
    APSFrameGrid .grid -parent $w -yList {y1 y2}
    
    APSButton .setupVideo -parent $w.grid.y1  -text "Setup Video"  \
      -packOption "-side left"  -command {SetupVideo} \
     -contextHelp "Set frame grabber for video capture"

    APSButton .openShutter -parent $w.grid.y1   -text "Open Shutter"  \
        -packOption "-side left"  -command {OpenCloseStreakShutter Open} \
        -contextHelp "Open streak camera shutter"

    APSButton .closeShutter -parent $w.grid.y1   -text "Close Shutter"  \
        -packOption "-side left"  -command {OpenCloseStreakShutter Close} \
        -contextHelp "Close streak camera shutter"

    APSButton .restoreVideo -parent $w.grid.y1  -text "Restore Video"  \
      -packOption "-side left" -command {RestoreVideo} \
      -contextHelp "Restore frame grabber settings"

    APSButton .recover -parent $w.grid.y1  -text "Recover from HI Trip" \
      -packOption "-side left"  -command {TripRecover} \
      -contextHelp "Recover from high-intensity trip."
    
    APSButton .min -parent $w.grid.y2 -text "MinROI" \
        -command {setROI -area auto -yFactor 5 -type min} \
        -contextHelp "Set ROI according to beam image size."
    APSButton .medium -parent $w.grid.y2 -text "MediumROI" \
        -command {setROI -area auto -yFactor 7 -type medium } \
        -contextHelp "Set ROI according to beam image size."
    APSButton .max -parent $w.grid.y2 -text "MaxROI" \
        -command {setROI -area max -type max} \
        -contextHelp "Set maximum ROI to look for beam image."
    return
}


# Widgets design
proc MeasureBunchLenFrame {widget args} {
    global streakPhase
    global FrameGrabber
    global outputDir

    APSStrictParseArguments {parent}

    # text input   
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Bunch Length Measurement"

    # executable command
    APSButton .quickBunchLen -parent $w \
      -text "Quick Measurement"  \
      -command {QuickBunchLenMeas -abortVar abortRun} \
      -contextHelp "Quick automated bunch length measurement"

    APSButton .showPV -parent $w \
      -text "Show bunch length PV"  \
      -command {GetBunchLen} \
      -contextHelp "Display bunch length PV in ps units."
    
    APSButton .saveImages -parent $w \
      -text "Save/Display Images/Profiles"  \
      -command SaveImageFrame -contextHelp "Save streak camera images." 
    
    return
}


# Widgets design
proc MonitorBunchLenFrame {widget args} {
    APSStrictParseArguments {parent}

    # text input   
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Monitor Bunch Length Data"

    APSLabeledEntry .inputdir -parent $w \
      -label "Input directory:" -textVariable inputDir \
      -contextHelp "Enter the directory for input monitor file." \
      -width 70
    APSButton .defaultdir -parent $w.inputdir -packOption "-side right" \
      -text "default" -size small \
      -command {set inputDir /home/helios/PHOTODIA/operations/s35apps/inputFiles }
  
    APSLabeledEntry .inputfilename -parent $w \
      -label "File name:" -textVariable inputFile \
      -contextHelp "Enter the name of the monitor file." \
      -width 70
    APSButton .defaultfile -parent $w.inputfilename -packOption "-side right" \
      -text "default" -size small \
      -command {set inputFile [MakeInputFileName] }

    APSLabeledEntry .steps -parent $w \
      -label "SDDS monitor steps:" -textVariable steps \
      -contextHelp "Enter the SDDS monitor steps." \
      -width 70

    APSLabeledEntry .interval -parent $w \
      -label "Monitor interval (s):" -textVariable interval \
      -contextHelp "Enter the SDDS monitor interval in seconds." \
      -width 70

    APSLabeledEntry .outputdirectory -parent $w \
      -label "Output dir:" -textVariable outputDir \
      -contextHelp "Enter the directory for output data file." \
      -width 70
    APSLabeledEntry .comment -parent $w \
      -label "Description: " -textVariable monitorDescription \
      -contextHelp "Enter the description for taking monitor data" \
      -width 70
    if {0} {
        APSButton .defaultOutDir -parent $w.outputdirectory -packOption "-side right" \
      -text "default" -size small \
      -command {set outputDir [MakeDefaultDir] }
    APSButton .daily -parent $w.outputdirectory -packOption "-side right" \
      -text "daily" -size small \
      -command {set outputDir [APSGoToDailyDirectory]}
    }
    if {0} {
        APSLabeledEntry .outputfilename -parent $w \
      -label "File name:" -textVariable outputFile \
      -contextHelp "Enter the full name of the output file." \
      -width 70
        APSButton .defaultOutFile -parent $w.outputfilename -packOption "-side right" \
      -text "default" -size small \
      -command {set outputFile [MakeOutputFileName]}
    }
    APSLabeledEntry .plotOption -parent $w \
      -label "Plot option:" -textVariable plotOptions \
      -contextHelp "Enter options for the plot." \
      -width 70
 
    # executable commands
    APSButton .datamonitor -parent $w \
      -text "Start SDDS monitor"  \
      -packOption "-side left" \
      -command {MonitorBunchLen} \
      -contextHelp "Start SDDS monitor for bunch length."
    if {0} {
    APSButton .checkprogressor -parent $w \
      -text "Check monitor progress"  \
      -packOption "-side left" \
      -command {ReportProgress -abortVar abortRun} \
      -contextHelp "Check SDDSmonitor progress."
    }
    # set plotOptions " 1"
    APSButton .plot -parent $w \
      -text "Plot Bunch Length"  \
      -packOption "-side left" \
      -command {PlotMonitorData} \
      -contextHelp "Plot bunch length data."

    APSButton .delete -parent $w \
      -text "Delete output file"  \
      -packOption "-side left" \
      -command {DeleteDataFile -filter Monitor} \
      -contextHelp "Delete the output file."
    if {0} {
        APSButton .abort -parent $w \
      -text "Abort"  \
      -command {AbortMonitor} \
      -contextHelp "Kills sdds monitor for bunch length."
    }
    return
}


# Widgets design
proc phaseScanFrame {widget args} {
    APSStrictParseArguments {parent}

    # text input   
    set w $parent$widget.frame
    APSFrame $widget -parent $parent -label "Delay Time (phase) Scans (use above file names)"
    if {0} {
    APSFrameGrid .fg -parent $w -xList {x1 x2 x3 x4}
    APSLabeledEntry .phaseStart -parent $w.fg.x1 \
      -label "Phase scan start:" -textVariable phaseStart \
      -contextHelp "Enter the starting point for quick scan." \
      -width 4

    APSLabeledEntry .phaseStop -parent $w.fg.x2 \
      -label "Phase scan stop:" -textVariable phaseStop \
      -contextHelp "Enter the end point for quick scan." \
      -width 4

    APSLabeledEntry .phaseSteps -parent $w.fg.x3 \
      -label "Phase scan steps:" -textVariable phaseSteps \
      -contextHelp "Enter the scan steps." \
      -width 4

    APSLabeledEntry .phaseInterval -parent $w.fg.x4 \
      -label "Phase interval (s):" -textVariable phaseInterval \
      -contextHelp "Enter the interval (s)." \
      -width 4
    }
    APSLabeledEntryFrame .phasePara -parent $w  -width 8 -orientation horizontal \
      -label "Phase scan start/stop/steps/interval(s): " \
      -variableList {phaseStart phaseStop phaseSteps phaseInterval} \
      -contextHelp "enter the value for phase scan start, phase scan stop, phase scan steps and phase scan interval in seconds, respectively."
    
    # executable commands
    APSButton .sddsFile -parent $w \
      -text "Use default files"  \
      -command {selectPhaseScanFiles} \
      -contextHelp "Select phase scan data files."

    APSButton .sddsPhaseScan -parent $w \
      -text "SDDSscan (save data)"  \
      -command {sddsPhaseScan} \
      -contextHelp "Scan phase and save data."

    APSButton .sddsPhasePlot -parent $w \
      -text "Plot data"  \
      -command {sddsPhasePlot -directory $outputDir -file $outputFile} \
      -contextHelp "Plot phase scan data."

    # executable commands
    APSButton .quickPhaseScan -parent $w \
      -text "Quick scan (save no data)"  \
      -command {quickPhaseScan} \
      -contextHelp "Quick scan to get the correct phase."

    APSButton .abortPhaseScan -parent $w \
      -text "Abort"  \
      -command {set abortRun 1} \
      -contextHelp "Kills phase scan."

    return
}


# ********************************************************************************************************
#	CONTROL PROCEDURES
# ********************************************************************************************************


proc PowerUpStreakCamera {args} {
    global VERBOSE    
    
    APSParseArguments {onTime}
    
    # check whether the power is already ON	
    if [catch {exec cavget -list=S35BMB:PwrBt5:AC1:pwrC.VAL -pend=30} powerStatus] {
        return -code error $powerStatus
    }
    if {$powerStatus == "?" } {
        return -code eorr "Unable to get the value of S35BMB:PwrBt5:AC1:pwrC.VAL PV"
    } elseif {$powerStatus == "On"} {
        APSSetVarAndUpdate displayStatus "Power is already on!"
    } else { 
	# check whether the camera was just turned off
        if [catch {exec cavget -list=S35BMB:PwrBt5:AC1:CALC.VAL -pend=30} powerWaitTime] {
            return -code error $powerWaitTime
        }
        if {$powerWaitTime=="?"} {
            return -code errro "Can not read value of PV - S35BMB:PwrBt5:AC1:CALC.VAL"
        }
        if $powerWaitTime {
            APSSetVarAndUpdate displayStatus "Power was just turned off. Wait for $waitTime seconds..."
        } else { 
 	    # turn on the streak camera power  
            APSSetVarAndUpdate displayStatus "Turning on the streak camera power now ..."
       	    if [catch {exec cavput -list=S35BMB:PwrBt5:AC1:OnSEQ.PROC=1 -pend=30} result] {
                return -code error "the power was not successfully turned on: $result!"
            }
       	}
    }

    # set maximum ON time (seconds)
    if {$onTime >= 1000} { set onTime 1000 }
    set time [format "%.0f" [expr 60 * $onTime] ]
    if [catch {exec cavput -list=S35BMB:PwrBt5:AC1:pwrC.HIGH=$time -pend=30} result] {
        return -code error " error occurred in setting the maximum power on time: $result!"
    }
    APSSetVarAndUpdate displayStatus "Power will be on for $onTime (minutes)."  
    APSSetVarAndUpdate displayStatus "Push SETUP button to set up streak camera and optics."  
    return
}


proc PowerDownStreakCamera {args} {
    set quitNow 0
    # turn off the streak camera power 
    APSParseArguments {quitNow}

    if [catch {OpenCloseStreakShutter Close} result] {
        return -code error $result
    }
    #setVar -var powerOff -value 1
    if [catch {exec cavput -list=S35BMB:PwrBt5:AC1:OffSEQ.PROC=1 -pend=30} result] {
        return -code error $result
    }
    if [catch {exec cavget -list=S35BMB:PwrBt5:AC1:CALC.VAL -pend=30} waitTime] {
        return -code error $waitTime
    }
    #set waitTime [ getVar -var powerWaitTime ]
    APSSetVarAndUpdate displayStatus "Streak camera is off. Wait $waitTime seconds before turning on again."
    
    # restore video settings before quitting 
    if $quitNow { 
        if [catch {RestoreVideo} result] {
            return -code error $result
        }
        exit 
    }
    return
}


proc setupStreakCamera {args} {
    global VERBOSE    
    
    APSParseArguments {ringCurrent}

    # Check vertical scan plug-in
    APSSetVarAndUpdate displayStatus "Testing vertical plug-in ..."
    if [catch {exec cavput -list=S35C5680:1:ConnectC.VAL=1 -pend=30} result] {
        return -code error "can not set streakconnect pv: $result!"
    }
    after 4000
    if [catch {exec cavput -list=S35C5680:1:SetUpDeviceX.PROC=1 -pend=30} result] {
        return -code error "can not setup streak device: $result"
    }
    #setVar -var streakInit -value 1
    after 4000
    if [catch {exec cavput -list=S35C5680:1:ReadInfoX.PROC=1 -pend=30} result] {
        return -code error "can not set streak info pv: $result"
    }
    #setVar -var streakReadInfo -value 1
    after 1000
    if [catch {exec cavget -list=S35C5680:1:VertModelM -pend=30} strBuffer] {
        return -code error "Error in reading streak buffer: $strBuffer"
    }
    #remove the first " and character-return and last "
    set str [string length $strBuffer]
    set strBuffer [string range $strBuffer 1 [expr $str-3]]
    if {$strBuffer=="?"} {
        return -code error "Can not get value of S35C5680:1:VertModelM!"
    }
    #set strBuffer [getVar -var streakVPlugIn]
    if {[string match *M5675* $strBuffer] < 1} {
       APSSetVarAndUpdate displayStatus "Incorrect vertical plug-in. Turn off and replace it: $strBuffer"
       return
    }
    APSSetVarAndUpdate displayStatus "Correct Plug-in $strBuffer used. Initializing streak camera ..."

    # keep testing communication with the camera every 5 seconds (10 cycles)
    for {set iteratn 1} {$iteratn <= 10} {incr iteratn} {
        if [catch {exec cavput -list=S35C5680:1:StatIn1M.VAL=1 -pend=30} result] {
            return -code error "Unable to set value of S35C5680:1:StatIn1M.VAL: $result"
        }
        #setVar -var streakStatus -value "  "
        after 4000
        if [catch {exec cavput -list=S35C5680:1:ConnectC.VAL=1 -pend=30} result] {
            return -code error $result
        }
        #setVar -var streakConnect -value "  "
        after 4000
        
        if [catch {exec cavget -list=S35C5680:1:StatIn1M.VAL -pend=30} streakStatus] {
            return -code error $strBuffer
        }
        if {$streakStatus=="?"} {
            return -code error "Unable to get value of S35C5680:1:StatIn1M.VAL  ($streakStatus)!"
        }
        #set strBuffer [getVar -var streakStatus]
    	if {[string length $streakStatus] > 20} {
            APSSetVarAndUpdate displayStatus "Power on communication successful."
            APSSetVarAndUpdate displayStatus "Setting up Camera..."
            # exec /home/helios/PHOTODIA/operations/s35apps/streakControl/bunchLenStreakInit
            #rewrite the above script as a procedure
            if [catch {BunchLenStreakInit} result] {
                return -code error $result
            }
            if [catch {PrepSynchroScan} result] {
                return -code error $result
            }
            APSSetVarAndUpdate displayStatus "Setting up Optics..."
            #exec /home/helios/PHOTODIA/operations/s35apps/streakControl/bunchLenOpticsSetup
            #the above script is replaced by proc BunchLenOptimcsSetup
            if [catch {BunchLenOpticsSetup} result] {
                return -code error $result
            }
            APSSetVarAndUpdate displayStatus "Setting up Timing..."
            #exec /home/helios/PHOTODIA/operations/s35apps/streakControl/bunchLenTimingSetup
            if [catch {BunchLenTimingSetup} result] {
                return -code error $result
            }
            # reduce absorber for lower ring current
            if {$ringCurrent < 20} {
                if [catch {exec cavput -list=S35BMB:StrkCam:Optic13C.VAL=0,S35BMB:StrkCam:Optic12C.VAL=1 -pend=30} result] {
                    return -code error $result
                }
               # setPV -pv [getPVName -var ndFilter1] -value 0
               # setPV -pv [getPVName -var ndFilter2] -value 1
            }
			
           APSSetVarAndUpdate displayStatus "Camera and optics are ready for measurements."
           APSSetVarAndUpdate displayStatus "Push SetupVideo button to prepare video system."  
           APSSetVarAndUpdate displayStatus "Please remember to Restore Video at end of experiment!"  
           return
        }
        APSSetVarAndUpdate displayStatus "Calling streak camera ..."
    }

    APSSetVarAndUpdate displayStatus "Power on communication failed! Turning streak off."  
    PowerDownStreakCamera -quitNow 0
    return
}


proc PrepSynchroScan {args} {
    global VERBOSE    
    
    # Init the streak 
    if [catch {exec cavput -list=S35C5680:1:SetUpDeviceX.PROC=1 -pend=30} result] {
        return -code error "PrepSynchroScan1: $result"
    }
    #setVar -var streakInit -value 1
    after 4000

    # Init the streak 
    for {set iteratn 1} {$iteratn <= 10} {incr iteratn} {
        if [catch {exec cavput -list=S35C5680:1:StatIn1M.VAL=1 -pend=30} result] {
            return -code error "PrepSynchroScan: $result"
        }
        #setVar -var streakStatus -value "  "
        after 4000
        if [catch {exec cavput -list=S35C5680:1:ConnectC.VAL=1 -pend=30} result] {
            return -code error "PrepSynchroScan: $result"
        }
        #setVar -var streakConnect -value "  "
        after 4000
        #set strBuffer [getVar -var streakStatus]
        if [catch {exec cavget -list=S35C5680:1:StatIn1M.VAL -pend=30} streakStatus] {
            return -code error "PrepSynchroScan: $result"
        }
        APSSetVarAndUpdate displayStatus "prepSynchroScan: Reply Line 2 = $streakStatus"
    	if {[string length $streakStatus] > 20} {
            after 2000    	
            #exec /home/helios/PHOTODIA/operations/s35apps/streakControl/bunchLenStreakSetup
            if [catch {BunchLenStreakSetup} result] {
                return -code error "PrepSynchroScan: $result"
            }
            APSSetVarAndUpdate displayStatus "Streak synchroscan set up OK."
            return
        }
    }
    APSSetVarAndUpdate displayStatus "Streak synchroscan set up failed!"
    return
}

proc OpenCloseStreakShutter {state} {
    # open/colse streak camera shutter
    global displayStatus FrameGrabber
    if $state {
        set displayStatus "Open streak camera shutter..."
    } else {
        set displayStatus "Close streak camera shutter..."
    }
    if [catch {exec cavput -list=S35C5680:1:ShutterOpenC=$state -pend=30} result] {
        return -code error $result
    }
    #setPV -pv [getPVName -var shutterOpen] -value 1
    
    if [catch {exec cavget -list=S35C5680:1:ShutterStatusM -pend=30} shutterStatus] {
        return -code error $shutterStatus
    }
    #set shutterStatus [ getVar -var shutterStatus ]
    if {[string compare $shutterStatus $state]==0} {
        APSSetVarAndUpdate displayStatus "Streak camera shutter is $state."
    } else {
        APSSetVarAndUpdate displayStatus "Failed to $state streak camera shutter."
    }
    if [catch {exec cavget -list=${frameGrabber}:roi -list=X,Y -list=StartC,SizeC \
                   -pend=10 -printErrors -label} valList] {
        return -code error $valList
    }
    array set roiData $valList
    set displayStatus "ROI now is: xStart=$roiData(${FrameGrabber}:roiXStart, xSize=$roiData(${FrameGrabber}:roiXSize, yStart=$roiData(${FrameGrabber}:roiYStart, ySize=$roiData(${FrameGrabber}:roiXSize"
    set displayStatus "done."
    return
}

proc TripRecover {args} {
    if [catch {exec cavput -list=S35C5680:1:ShutterOpenC=0 -pend=30} result] {
        return -code error $result
    }
   # setVar -var shutterOpen -value 0
    after 1000
    if [catch {exec cavput -list=S35C5680:1:StatIn1M=1 -pend=30} result] {
        return -code error $result
    }
    # setVar -var streakStatus -value 1
    after 1000
    if [catch {exec cavput -list=S35C5680:1:ShutterOpenC=0 -pend=30} result] {
        return -code error $result
    }
  #  setVar -var shutterOpen -value 0
    APSSetVarAndUpdate displayStatus "Shutter is reset. Adjust gains / attenuation before opening it again."

    return
}


proc getVideoIndex { video } {
    global videoMonitorList
    global FrameGrabberList

    set videoIndex [lsearch $videoMonitorList $video]
    if {$videoIndex < 0} {
       set videoIndex [lsearch ${FrameGrabberList} $video]
    }
    return [expr $videoIndex+1]
}


proc SetupVideo { } {
    global VERBOSE videoMonitor FrameGrabber monitorCam grabberCam grabberCamIndex boxcarWidth numberAvg

    # Select control screens for monitor and frame grabber
    
    set monitorIndex [getVideoIndex $videoMonitor]
    set grabberIndex [getVideoIndex ${FrameGrabber}]
    set monitorPV "S35a1:VidSw:Mon${monitorIndex}:CamSelC"
    set grabberPV "S35a:VidSw:Mon${grabberIndex}:CamSelC"
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "monitorPV = $monitorPV"}
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "grabberPV = $grabberPV"}

	# save old settings
    global configSaved
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "configSaved = $configSaved"}
    APSSetVarAndUpdate displayStatus "Setup video ..."
    if {$configSaved == 0} {
        APSSetVarAndUpdate displayStatus "Saving frame grabber / monitor settings."
        if [catch {exec cavget -list=$monitorPV -pend=30} monitorCam] {
            return -code error $monitoCam
        }
        #set monitorCam [caget $monitorPV]
        if [catch {exec cavget -list=$grabberPV -pend=30} grabberCam] {
            return -code error $grabberCam
        }
        #set grabberCam [caget $grabberPV]
        if [catch {exec cavget -list=${FrameGrabber}:CAL:cameraIndexC -pend=30} grabberCamIndex] {
            return -code error $grabberCamIndex
        }
        #set grabberCamIndex [caget "${FrameGrabber}:CAL:cameraIndexC"]
        if [catch {exec cavget -list=${FrameGrabber}:boxcarWidthC -pend=30} boxcarWidth] {
            return -code error $boxcarWidth
        }
        #set boxcarWidth     [caget "${FrameGrabber}:boxcarWidthC"]
        if [catch {exec cavget -list=${FrameGrabber}:numToAvgC -pend=30} numberAvg] {
            return -code error $numberAvg
        }
        #set numberAvg       [caget "${FrameGrabber}:numToAvgC"]
        if {$VERBOSE} {APSSetVarAndUpdate displayStatus "monitorCam = $monitorCam"}
        if {$VERBOSE} {APSSetVarAndUpdate displayStatus "grabberCam = $grabberCam"}
    }
    set configSaved 1
    
    # Set monitor and frame grabber to Camera 3 (visible streak)
    if [catch {exec cavput -list=$monitorPV=3,$grabberPV=3,${FrameGrabber}:CAL:cameraIndexC=43 -pend=30} result] {
        return -code error $result
    } 
    
    # Set frame grabber ROI
    if [catch {exec cavput -list=${FrameGrabber} \
                   -list=:roiXStartC=50,:roiXSizeC=300,:roiYStartC=20,:roiYSizeC=460 \
                   -pend=30} result] {
        return -code error $result
    }
    
    # flush out the averager
    if [catch {exec cavput -list=${FrameGrabber}=0 \
                   -list=:baselineAvgC,:numToAvgC -pend=30} result] {
        return -code error $result
    }
    
    after 1000
    if [catch {exec cavput -list=${FrameGrabber} \
                   -list=:baselineAvgC=1,:numToAvgC=300 -pend=30} result] {
        return -code error $result
    }
    APSSetVarAndUpdate displayStatus "ROI: xStart=50, xSize=300, yStart=20, ySzie=460."
    APSSetVarAndUpdate displayStatus "Done."
    return
}


proc RestoreVideo { } {
    global VERBOSE videoMonitor FrameGrabber monitorCam grabberCam grabberCamIndex
    global boxcarWidth numberAvg

    # Select control screens for monitor and frame grabber
    set monitorIndex [getVideoIndex $videoMonitor]
    set grabberIndex [getVideoIndex ${FrameGrabber}]
    set monitorPV "S35a1:VidSw:Mon${monitorIndex}:CamSelC"
    set grabberPV "S35a:VidSw:Mon${grabberIndex}:CamSelC"
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "monitorPV = $monitorPV"}
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "grabberPV = $grabberPV"}

	# restore old settings
    global configSaved
    if {$VERBOSE} {APSSetVarAndUpdate displayStatus "configSaved = $configSaved"}
    if {$configSaved != 0} {
        APSSetVarAndUpdate displayStatus "Restoring frame grabber / monitor settings."
        if [catch {exec cavput -list=$monitorPV=$monitorCam,$grabberPV=$grabberCam -pend=30} result] {
            return -code error $result
        }
        #exec caput $monitorPV $monitorCam
        #exec caput $grabberPV $grabberCam
        if [catch {exec cavput -list=${FrameGrabber}: \
                     -list=CAL:cameraIndexC=$$grabberCamIndex,boxcarWidthC=$$boxcarWidth,numToAvgC=$numberAvg -pend=30} result] {
            return -code error $result
        }
      #  exec caput "${FrameGrabber}:CAL:cameraIndexC"  $grabberCamIndex
      #  exec caput "${FrameGrabber}:boxcarWidthC" $boxcarWidth
      #  exec caput "${FrameGrabber}:numToAvgC" $numberAvg
        if {$VERBOSE} {APSSetVarAndUpdate displayStatus "monitorCam = $monitorCam"}
        if {$VERBOSE} {APSSetVarAndUpdate displayStatus "grabberCam = $grabberCam"}
    }
    set configSaved 0

	# flush out the averager
    if [catch {exec cavput -list=${FrameGrabber}:baselineAvgC=0 -pend=30 
	exec cavput -list=${FrameGrabber}:numToAvgC=0 -pend=30 } result] {
        return -code error $result
    }
  #  exec caput "${FrameGrabber}:baselineAvgC"  0
  #  exec caput "${FrameGrabber}:numToAvgC"     0
    after 1000
    if [catch {exec cavput -list=${FrameGrabber}:baselineAvgC=1 -pend=30 
	exec cavput -list=${FrameGrabber}:numToAvgC=$numberAvg -pend=30} result] {
        return -code error $result
    }
  #  exec caput "${FrameGrabber}:baselineAvgC"  1
  #  exec caput "${FrameGrabber}:numToAvgC"     $numberAvg

    APSSetVarAndUpdate displayStatus "Done."
    return
}


proc QuickBunchLenMeas {args} {
    global VERBOSE videoMonitor FrameGrabber monitorCam grabberCam grabberCamIndex 
    global boxcarWidth numberAvg       

	# Open streak shutter
    #openStreakShutter
    if [catch {OpenCloseStreakShutter Open} result] {
        return -code error $result
    }
	# Set up frame grabber and save old settings
    #setupVideo 
    if [catch {SetupVideo} result] {
        return -code error $result
    }
    
    # Wait for the averaged data to stabilize and record the bunch length
    set bunchLenPV "${FrameGrabber}:y:fit:cal:sigmaAvgM"
    APSSetVarAndUpdate displayStatus "Measuring bunch length ... "
    for {set iteratn 1} {$iteratn <= 5} {incr iteratn} {
        after 2000
        if [catch {exec cavget -list=$bunchLenPV -pend=30} bunchLen] {
            return -code error $bunchLen
        }
        #set bunchLen [caget $bunchLenPV]
        APSSetVarAndUpdate displayStatus "Bunch length = $bunchLen (ps)"
    }
    APSSetVarAndUpdate displayStatus "The average bunch length = $bunchLen (ps)"

    # Close streak shutter
    if [catch {OpenCloseStreakShutter Close} result] {
        return -code error $result
    }
    #closeStreakShutter

    # Restore old settings
    if [catch {RestoreVideo} result] {
        return -code error $result
    }
    #restoreVideo 
    
    APSSetVarAndUpdate displayStatus "Done."
    return
}



proc SetVDelay {args} {
    global vDelay

    set incr 0.1
    APSParseArguments {incr}
    
    # set new vDelay value
    set value $vDelay
    if {$incr} { 
        set value [format "%0.2f" [expr $value + ($incr)] ] 
        #setPV -pv [getPVName -var vDelay] -value $nextValue
    }
    if [catch {exec cavput -list=S35ID:HamC1097_04aC=$value -pend=30} result] {
        return -code error $result
    }
    set vDelay $value
    return
}


proc MonitorBunchLen {args} {
    global inputDir inputFile interval steps  abortRun mainDir FrameGrabber videoMonitor outputDir outputFile
    global monitorDescription
    
    if {![string length $inputDir] || ![string length $inputFile]} {
        return -code error "monitorBunchLen: Invalid syntax for input dir/file."
    }
    if ![file exists $inputDir] {
        return -code error "monitorBunchLen: Can't find directory $inputDir."
    }
    if ![file exists $inputDir/$inputFile] {
        return -code error "monitorBunchLen: Can't find file $inputFile."
    }
    #set time [clock format [clock seconds] -format "%H:%M:%S"]
   # set outputDir [MakeDefaultDir]
    if ![file exists $outputDir] {
        APSSetVarAndUpdate displayStatus "Create dir: $outputDir"
        if [catch {exec mkdir $outputDir} result] {
            return -code error "Error making directory $outputDir: $result"
        }
        #exec setfacl -m mask:rwx $outputDir 
      #  exec /home/helios/OAG/bin/setFACL-oagPlus bxyang,emery,borland,sr,asdops $outputDir
    }
    regexp {:(.*)} $FrameGrabber a frame
    set name ${videoMonitor}_${frame}_Monitor.0000
    if ![file exist $outputDir/$name] {
        set outputFile $name
    } else {
        set outputFile [APSNextGenerationedName -directory $outputDir -name $name -separator .]
    }
    OpenCloseStreakShutter Open
    # Set up frame grabber and save old settings
    SetupVideo
    
    APSSetVarAndUpdate displayStatus "Start taking data ..."
    global monitorDone
    set monitorDone 0
    APSExecLog [APSUniqueName .] -width 80 \
      -unixCommand "sddsmonitor $inputDir/$inputFile $outputDir/$outputFile -append -interval=$interval,s -steps=$steps -verbose -getunits=force" \
      -callback "set monitorDone done" -abortCallback "set monitorDoone aborted" \
      -cancelCallback "set monitorDone canceled"
    tkwait variable monitorDone
    if [string length $monitorDescription] {
        set tmpfile /tmp/[APSTmpString]
        set monitorDescription [APSMakeSafeQualifierString $monitorDescription]
        if [catch {exec sddsprocess $outputDir/$outputFile $tmpfile\
                     "-print=par,Description,$monitorDescription" } result] {
            return -code error $result
        }
        exec mv $tmpfile $outputDir/$outputFile
    }
    APSSetVarAndUpdate displayStatus "monitoring data $monitorDone"
    return
}


proc ReportProgress {args} {
    global VERBOSE  outputDir outputFile  steps 

    # Check the progres
    set pList 	[APSGetSDDSColumn -fileName $outputDir/$outputFile -column TimeOfDay]
    set nptsList [llength $pList]
    set nptsToGo [expr $steps - $nptsList]
    APSSetVarAndUpdate displayStatus "Data set length = $nptsList. Remaining # of points = $nptsToGo."

    # Restore old settings and Close streak shutter if scan complete
    if {$nptsList >= $steps} {
        if [catch {RestoreVideo} result] {
            return -code error $result
        }
        if [catch {OpenCloseStreakShutter Close} result] {
            return -code error $result
        }
    }
    return
}

proc GetFilesInMainDir {args} {
    global mainDir 
    set filter ""
    APSParseArguments {filter}
    set oldDir [pwd]
    cd $mainDir
    set directories [glob -nocomplain *]
    set files ""
    if [llength $directories] {
        set directories [lsort -decreasing $directories]
    }
    foreach dir $directories {
        set newfiles [glob -nocomplain $dir/*${filter}*]
        foreach file $newfiles {
            lappend files $file
        }
    }
    cd $oldDir
    return $files
}

proc GetPlotFile {args} {
    set filter ""
    APSParseArguments {filter} 
    set filter $filter
    set files [GetFilesInMainDir -filter $filter]
    if ![llength $files] {
        return -code error "No $filter files found in mainDir!"
    }
    global Fileselection
    APSScrolledListWindow .process -name "Plot data file selection" \
      -label "select a data file" \
      -itemList $files -selectionVar Fileselection
    tkwait variable Fileselection
    if ![string length $Fileselection] {
        return -code error "No files chosen!"
    }
    return $Fileselection
}
proc PlotMonitorData {args} {
    global mainDir
    set plotOption ""
    APSParseArguments {plotOption}
    
    set plotFile [GetPlotFile -filter Monitor]
    set optionLen [string length $plotOption]
    if {[string length $plotOption] > 3} {
        exec sddsplotM ${mainDir}/${plotFile} \
          -col=TimeOfDay,streakSigmaYavg -topTitle -title=${plotFile} ${plotOption} & 
    } else {
        exec sddsplotM ${mainDir}/${plotFile} -col=TimeOfDay,streakSigmaYavg -topTitle -title=${plotFile} & 
    }
    return
}

proc DeleteDataFile {args} {
    set filter ""
    APSParseArguments {filter}
    global fileList
    
    set files [GetFilesInMainDir -filter $filter]
    if ![llength $files] {
        return -code error "No $filter files found!"
    }
    global FileSelection
    set Fileselection ""
    APSScrolledListWindow .process -name "File Selection" -acceptButton 0 \
      -label "Select a data file" \
      -itemList $files -selectionVar Fileselection
    set fileList $files
    APSDialogBoxAddButton .delete -parent .process -text "Delete" -command "DeleteChosenFile"
    tkwait variable Fileselection
    return
}

proc DeleteChosenFile {args} {
    global fileList mainDir
    set action ""
    APSParseArguments {files}
    set chosenList [.process.userFrame.sl.listbox curselection]
    if ![llength $chosenList] {
        return -code error "No files are chosen!"
    }
    set viewList ""
    foreach index $chosenList {
        set file [lindex $fileList $index]
        if [APSYesNoPopUp "Are you sure to delete file $mainDir/$file"] {
            file delete -force $mainDir/$file 
        }
    }
}


proc quickPhaseScan {args} {
    global abortRun  phaseStart phaseStop phaseSteps phaseInterval FrameGrabber

	# Wait for the averaged data to stabilize and record the bunch length
    set deltaPhase [expr ($phaseStop-$phaseStart)/($phaseSteps-1.0)]
    set waitInterval  [format "%.0f" [expr 1000 * $phaseInterval]]
    APSSetVarAndUpdate displayStatus "Scanning delay time. Make sure that the VID is set up correctly "
    APSSetVarAndUpdate displayStatus "Scanning ... "
    APSSetVarAndUpdate displayStatus "deltaPhase = $deltaPhase"
    for {set iSteps 0} {$iSteps <= $phaseSteps} {incr iSteps} {
        set thisPhase [expr $phaseStart + $iSteps * $deltaPhase]
        if [catch {exec cavput -list=S35ID:HamC1097_04aC=$thisPhase -pend=30} result] {
            return -code error $result
        }
        after $waitInterval
        if [catch {exec cavget -list=S35ID:HamC1097_04aSU -pend=30} truePhase] {
            return -code error $truePhase
        }
        if [catch {exec cavget -list=${FrameGrabber}:x:raw:peakM -pend=30} xProfile] {
            return -code error $xProfile
        }
        if [catch {exec cavget -list=${FrameGrabber}:y:fit:cal:centroidM -pend=30} yCentroid] {
            return -code error $yCentroid
        }
        APSSetVarAndUpdate displayStatus \
         [format "Delay = %.3f, xProf = %.0f, y0 = %.3f" $truePhase $xProfile $yCentroid]
        if {$abortRun} {
           APSSetVarAndUpdate displayStatus "Phase scan aborted."
            set abortRun 0
            return
        }
    }
    APSSetVarAndUpdate displayStatus "Done."
    return
}


proc selectPhaseScanFiles {args} {
    global inputDir inputFile outputDir outputFile FrameGrabber

    set inputDir "/home/helios/PHOTODIA/operations/s35apps/inputFiles"
    set inputFile [MakeInputFileName]
   # set inputFile "streakCam_${FrameGrabber}.mon"
    set outputDir "/home/helios/OAG/oagData/sr/streakCamera/setup"
    set outputFile [clock format [clock seconds] -format bmbStreakPhase-%Y-%j-%m%d-%H%M%S]

    return
}


proc sddsPhaseScan {args} {
    global inputDir inputFile outputDir outputFile phaseStart phaseStop phaseSteps phaseInterval
    global FrameGrabber

    if ![file exists $inputDir] {
        return -code error "monitorBunchLen: Can't find directory $inputDir."
    }
    if ![file exists $inputDir/$inputFile] {
        return -code error "monitorBunchLen: Can't find file $inputFile."
    }

    if ![file exists $outputDir] {
        return -code error "monitorBunchLen: Can't find directory $outputDir."
    }
    
    # Open streak shutter
    APSSetVarAndUpdate displayStatus "Open streak sutter."
    if [catch {OpenCloseStreakShutter Open} result] {
        return -code error $result
    }
    
    # Set up frame grabber and save old settings
    APSSetVarAndUpdate displayStatus "Setup video."
    if [catch {SetupVideo} result] {
        return -code error $result
    }
    
    # Move to the center of the scan range
    set centerDelay [expr 0.5 * ($phaseStart + $phaseStop) ]
    if [catch {exec cavput -list=S35ID:HamC1097_04aC=$centerDelay -pend=30} result] {
        return -code error $result
    }
    APSSetVarAndUpdate displayStatus "Center of delay scan = $centerDelay."
    
    # make an exp file from template and get its name
    set expFileName bmStreakPhaseScan_${FrameGrabber}.exp
    if [file exists $outputDir/$expFileName] {
        exec rm -f $outputDir/$expFileName
    }
    set template "$inputDir/bmbStreakPhaseScanTemplate.exp"
    exec replaceText $template $outputDir/$expFileName \
      -original=<monitorFile>,<limit1>,<limit2>,<npts>,<interval> \
      -replace=$monitorFile,$phaseStart,$phaseStop,$phaseSteps,$phaseInterval
    
    
    #####   Take data   #####
    global monitorProcess
    set monitorProcess [exec sddsexperiment $outputDir/$expFileName $outputDir/$outputFile & ]
    APSSetVarAndUpdate displayStatus "Start taking data (processID = $monitorProcess) ..."
    return
}


proc sddsPhasePlot {args} {
    APSParseArguments {directory file}
    if ![file exists $directory/$file] {
        return -code error "Can't find file $file in $directory."
    }
    exec sddsplot $directory/$file -col=delayTime1097,streakXProfile -filenamesOnTopline &
    exec sddsplot $directory/$file -col=delayTime1097,streakY0 -scales=0,0,-450,450 -filenamesOnTopline &
    return
}


proc AbortMonitor {args} {
    global monitorProcess abortRun

    # Kill the sdds process
    if $monitorProcess { exec kill $monitorProcess & }
    
    # Close streak shutter
    if [catch {OpenCloseStreakShutter Close} result] {
        return -code error $result
    }
    # Restore old settings
    if [catch {RestoreVideo} result] {
        return -code error $result
    }
    APSSetVarAndUpdate displayStatus "Monitor process aborted."
    set abortRun 0
    return
}


#########################################################
#	Define and initialize important global vars	#
#########################################################

##########################################
#Initial Streak camera before measurement#
##########################################
proc BunchLenStreakInit {args} {
    
    APSSetVarAndUpdate displayStatus "Init streak camera before measurements"

    # Flush GPIB buffer
    if [catch {exec cavput -list=S35C5680:1:RawReadM.PROC=1 -pend=30} result] {
        return -code error "BunchLenStreakInit1: $result"
    }
    after 1000
    
    # Push Init Button
    if [catch {exec cavput -list=S35C5680:1:SetUpDeviceX.PROC=1 -pend=30} result] {
        return -code error "BunchLenStreakInit2: $result"
    }
    after 8000

    # Disable local controller
    if [catch {exec cavput -list=S35C5680:1:ControllerEnbC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit3: $result"
    }
    after 1000
    
    # Turn off response
    if [catch {exec cavput -list=S35C5680:1:ResponseEnbC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit4: $result"
    }
    after 1000

    # Close shutter
    if [catch {exec cavput  -list=S35C5680:1:ShutterOpenC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit5: $result"
    }
    after 1000

    # Turn down gain
    if [catch {exec cavput  -list=S35C5680:1:MCPgainC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit6: $result"
    }
    after 1000
    
    # Turn off scan
    if [catch {exec cavput  -list=S35C5680:1:VertSweepC=1 -pend=30} result] {
        return -code error "BunchLenStreakInit7: $result"
    }
    after 1000
    
    if [catch {exec cavput  -list=S35C5680:1:VertSweepC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit8: $result"
    }
    after 1000

    # Turn off gated mode
    if [catch {exec cavput  -list=S35C5680:1:Sy:GateModeC=1 -pend=30} result] {
        return -code error "BunchLenStreakInit9: $result"
    }
    after 1000
    if [catch {exec cavput  -list=S35C5680:1:Sy:GateModeC=0 -pend=30} result] {
        return -code error "BunchLenStreakInit10: $result"
    }
    after 1000
    
    # Turn to focus mode
    if [catch {exec cavput -list=S35C5680:1:VertSweepC=1 -pend=30} result] {
        return -code error "BunchLenStreakInit11: $result"
    }
    after 1000
    if [catch {exec cavput -list=S35C5680:1:VertSweepC=0  -pend=30} result] {
        return -code error "BunchLenStreakInit12: $result"
    }
    after 1000
    
    # Turn off vertical scan
    if [catch {exec cavput -list=S35C5680:1:HSweepRngC=0   -pend=30} result] {
        return -code error "BunchLenStreakInit13: $result"
    }
    after 1000
    if [catch {exec cavput -list=S35C5680:1:S:HSweepRngC=0  -pend=30} result] {
        return -code error "BunchLenStreakInit14: $result"
    }
    after 1000
    if [catch {exec cavput -list=S35C5680:1:Sy:HSweepRng1C=1  -pend=30} result] {
        return -code error "BunchLenStreakInit15: $result"
    }
    after 1000
    if [catch {exec cavput -list=S35C5680:1:Sy:HSweepRng2C=0  -pend=30} result] {
        return -code error "BunchLenStreakInit: $result"
    }
    after 1000
    
    # set horizontal trigger level
    if [catch {exec cavput -list=S35C5680:1:HTrigLvlC=1.0  -pend=30} result] {
        return -code error "BunchLenStreakInit16: $result"
    }
    after 1000

    # set delay steps 
    if [catch {exec cavput -list=S35C5680:1:DelayC=0  -pend=30} result] {
        return -code error "BunchLenStreakInit17: $result"
    }
    after 1000
    
    # set time over 
    if [catch {exec cavput -list=S35C5680:1:TimeOvrC=1  -pend=30} result] {
        return -code error "BunchLenStreakInit18: $result"
    }
    after 1000
    
    # Flush GPIB buffer
    if [catch {exec cavput -list=S35C5680:1:RawReadM.PROC=1  -pend=30} result] {
        return -code error "BunchLenStreakInit18: $result"
    }
    after 1000
    
    # Get plug-in info from main frame
    if [catch {exec cavput -list=S35C5680:1:ReadInfoX.PROC=1  -pend=30} result] {
        return -code error "BunchLenStreakInit19: $result"
    }
    after 1000
}

proc BunchLenStreakSetup {args} {
    
    APSSetVarAndUpdate displayStatus "Setup 35-BM-B streak camera for bunch length measurements"
    
    # close shutter
    if [catch {exec cavput -list=S35C5680:1:ShutterOpenC=0 -pend=30} result] {
        return -code error "BunchLenStreakSetup1: $result"
    }
    after 1000
    
    # set vetical scan range to range 4 (PV = 3)
    if [catch {exec cavput -list=S35C5680:1:Sy:VSweepRngC=4 -pend=30} result] {
        return -code error "BunchLenStreakSetup: $result"
    }
    after 1000
    
    # turn on vetical scan before setting range! 
    if [catch {exec cavput -list=S35C5680:1:VertSweepC=1 -pend=30} result] {
        return -code error "BunchLenStreakSetup: $result"
    }
    after 1000
    
    # set vetical scan range to range 3 (PV = 2)
    if [catch {exec cavput -list=S35C5680:1:Sy:VSweepRngC=3 -pend=30} result] {
        return -code error "BunchLenStreakSetup: $result"
    }
    #note that caput behaves differently, if we want S35C5680:1:Sy:VSweepRngC to be 3,
    #use caput S35C5680:1:Sy:VSweepRngC 2
    #if want S35C5680:1:Sy:VSweepRngC to be 4, use caput S35C5680:1:Sy:VSweepRngC 3
    #I do not know why (have to ask programmer of caput)
    after 1000
}

proc BunchLenOpticsSetup {args} {
    APSSetVarAndUpdate displayStatus "Setup 35-BM-B optics for bunch length measurements"
    
    # close shutter (0 = IN, 1 = OUT)
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic6C.VAL=0 -pend=30} result] {
        return -code error "BunchLenOpticsSetup1: $result"
    }
    
    # Position the aperture slits
    if [catch {exec cavput -list=S35BMB:CamOp1:M3MT.VAL=31.5,S35BMB:CamOp1:M4MT.VAL=33 -pend=30} result] {
        return -code error "BunchLenOpticsSetup2: $result"
    }
    
    # Position the ND filter slides
    if [catch {exec cavput -list=S35BMB:CamOp1:M5MT.VAL=20 -pend=30} result] {
        return -code error "BunchLenOpticsSetup3: $result"
    }
    
    # Position the steering lens
    if [catch {exec cavput -list=S35BMB:CamOp1:M6MT.VAL=34,S35BMB:CamOp1:M7MT.VAL=24 -pend=30} result] {
        return -code error "BunchLenOpticsSetup4: $result" 
    }
    
    # Rotator OUT
    if [catch {exec cavput -list=S35BMB:CamOp1:M8MT.VAL=0 -pend=30} result] {
        return -code error "BunchLenOpticsSetup5: $result"
    }
    
    # select focusing lens (0 = selected, 1 = unselected)
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic0C.VAL=0 -pend=30} result] {
        return -code error "BunchLenOpticsSetup6: $result"
    }
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic -range=begin=1,end=7 \
                 -list=C.VAL=1 -pend=30} result] {
        return -code error "BunchLenOpticsSetup7: $result"
    }
    
    # select BP filter 633 x 10 nm (0 = selected, 1 = unselected)
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic -list=8C=0,9C=1,10C=1 -list=.VAL \
                 -pend=30} result] {
        return -code error "BunchLenOpticsSetup8: $result"
    }
    # select ND filter (11=4.0 OD, 12 = 2.0 OD, 13 = 1.0 OD) 
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic -list=11C=1,12C=0,13C=0 -list=.VAL \
                 -pend=30} result] {
        return -code error "BunchLenOpticsSetup9: $result"
    }
    # reserved optics OUT (14-15 =1.0 OD)
    if [catch {exec cavput -list=S35BMB:StrkCam:Optic -list=14C,15C -list=.VAL=1 \
                 -pend=30} result] {
        return -code error "BunchLenOpticsSetup10: $result"
    }
}

proc BunchLenTimingSetup {args} {
    global timing
    
    APSSetVarAndUpdate displayStatus "Setup Timing for bunch length measurements"
    
    # Select vertical source (0 = OFF, 1 = spare, 2 = P0, 3 = 117.3 MHz, 4 = 176 MHz)
    if [catch {exec cavput -list=S35TMux0:1MO=3 -pend=30} result] {
        return -code error "BunchLenTimingSetup1: $result"
    }
    
    # Select vertical trigger output (0 = OFF, 1 = BMA, 2 = BMB, 3 = BMC, MHz, 4 = Spare)
    if [catch {exec cavput -list=S35TMux0:0MO=2 -pend=30} result] {
        return -code error "BunchLenTimingSetup2: $result"
    }
    
    # Select delay unit in nanoseconds (used 6/11/2003 -- )
    if [catch {exec cavput -list=S35ID:HamC1097_04aC=$timing -pend=30} result] {
        return -code error "BunchLenTimingSetup3: $result"
    }
    
    # Select delay unit in nanoseconds (used 4/18/2003 -- )
    #caput S35ID:HamC1097_04aC 6.9
    # Select delay unit in nanoseconds (used 11/1/2002 -- )
    #caput S35ID:HamC1097_04aC 5.0
    # Select delay (used 6/25/2002 -- 8/25/2002 )
    # caput S35ID:HamC1097_04aC 0.5
    # Select delay (used 5/30/2002 -- 6/25/2002 )
    # caput S35ID:HamC1097_04aC 0.1
    # The following was used for 2/5/02 till end of run
    # caput S35ID:HamC1097_04aC 3.9
    
    # Select delay (used for 12/2001 to 1/2002)
    # caput S35ID:HamC1097_04aC 3.5

}

proc GetBunchLen {} {
    global FrameGrabber
    
    if [catch {exec cavget -list=${FrameGrabber}:y:fit:cal:sigmaAvgM -pend=30} bunchLen] {
        return -code error "GetB$bunchLen1:$bunchLen"
    }
    APSSetVarAndUpdate displayStatus "Bunch length PV =${FrameGrabber}:y:fit:cal:sigmaAvgM, value=$bunchLen " 

}

proc SaveImageFrame {args} {
    global OutputDir ImageRootname ProfileRootname nFrames interval FrameGrabber VideoRegion ProfilePlane
    
    set frameWidth 80
    APSFrame .image -packOption "-expand 1 -fill x"
    .image.frame configure -bd 0
    APSFrame .save -parent .image.frame -label "Save Image/Profiles" -packOption "-expand 1 -fill x"
    set w0 .image.frame.save.frame
    APSFrame .option -parent $w0 -label "Options" -packOption "-expand 1 -fill x" -width $frameWidth
    set w $w0.option.frame
    set grabberList {S:VID1 S:VID2 S:VID3 S:VID4 S:VID5 S:VID6 LI:VD1}
    set commandList {"MakeDefaultRootname -type All" "MakeDefaultRootname -type All" "MakeDefaultRootname -type All" "MakeDefaultRootname -type All" "MakeDefaultRootname -type All" "MakeDefaultRootname -type All" "MakeDefaultRootname -type All" }
    global PlotDir
    APSRadioButtonFrame .grabber -parent $w -label "Frame Grabber: " -orientation horizontal \
      -variable FrameGrabber -buttonList $grabberList -commandList $commandList \
      -valueList $grabberList -contextHelp "select a video frame grabber." 
                       
    APSLabeledEntry .interval -parent $w -label "Number of Frames: " -textVariable nFrames \
      -width 65 -contextHelp "number of frame for capture/sum/save image"
    APSLabeledEntry .num -parent $w -label "Interval (sec) between frames: " -textVariable interval \
      -width 65 -contextHelp "interval between capture/sum frames"
    APSLabeledEntry .dir -label "Output Directory:" -parent $w -width 65 -textVariable OutputDir \
      -contextHelp "The output directory for saving images." -packOption "-expand 1 -fill x"
    bind $w.dir.entry <Leave> "UpdatePlotDirectory"
    APSButton .default -text "default" -size small -parent $w.dir -packOption "-side right" \
      -command {set OutputDir [MakeDefaultDir]}
    APSButton .daily -text "daily" -size small -parent $w.dir -packOption "-side right" \
      -command {set OutputDir [APSGoToDailyDirectory]}
    APSLabeledEntry .comment -parent $w -width 65 -textVariable imageDescription -label "Description:" \
      -contextHelp "the description for saving images/profiles." -packOption "-expand 1 -fill x"

    APSFrameGrid .fg -parent $w0 -xList {x1 x2}
    set w1 $w0.fg.x1
    set w2 $w0.fg.x2
    APSFrame .saveImage -parent $w1 -label "Save/Sum Images"
    set w $w1.saveImage.frame
    APSRadioButtonFrame .region -parent $w -label "Video Region:" -orientation horizontal \
      -variable VideoRegion -buttonList {Entire_Image ROI_Only Soft_ROI} -valueList {Enter_Image ROI_Only Soft_ROI} \
      -contextHelp "The video region for saving images."
    APSLabeledEntry .rootname -parent $w -label "File root name:" -textVariable ImageRootname \
      -width 30
    APSButton .default -parent $w.rootname -text "default" -size small -packOption "-side right" \
	-command "MakeDefaultRootname -type Image"
    global ROI_xStart ROI_yStart ROI_xSize ROI_ySize
    APSLabeledEntryFrame .spec -parent $w -label "ROI X1/Y1/xSize/ySize:" \
      -variableList {ROI_xStart ROI_yStart ROI_xSize ROI_ySize} \
      -orientation horizontal -width 4 \
      -contextHelp "Soft ROI specifications: ROI_xStart/ROI_yStart/ROI_xSize/ROI_ySize."
    APSButton .update -parent $w.spec -packOption "-side right" \
      -text "default" -command UpdateROI \
      -contextHelp "Load hardware ROI as default softROI values."
    
    APSButton .saveimage -parent $w -text "Capture Image" -command {CaptureVideoData} \
      -contextHelp "capture and save first several frames images."
    APSButton .abort -parent $w -text "Abort" -command {set abortRun 1} \
      -contextHelp "Stops image capture."
    APSButton .delete -parent $w -text "Delete Output Files" -command {DeleteDataFile -filter Image} \
      -contextHelp "delete the output files that were just created."
    APSFrame .prof -parent $w2 -label "Save Profiles" 
    set w $w2.prof.frame
    global ProfilePlane ProfRootname
    APSRadioButtonFrame .plane -parent $w -label "Plane:" -buttonList {x y both} -valueList {x y both} \
      -variable ProfPlane -orientation horizontal -contextHelp "choose the plane for saving profiles."
    APSLabeledEntry .rootname -parent $w -label "File root name:" -textVariable ProfRootname \
      -width 25
    APSButton .default -parent $w.rootname -text "default" -size small -packOption "-side right" \
	-command "MakeDefaultRootname -type Prof"
    APSButton .save -parent $w -text "Save Profiles" -command "SaveProfileData"
    APSButton .delete -parent $w -text "Delete Data File" -command "DeleteDataFile -filter Prof"

    global PlotDir PlotVideoMonitor
    APSFrame .review -parent .image.frame 
    set w0 .image.frame.review.frame
    APSFrame .plot -parent $w0 -label "Display Images/Plot Profiles"
    set w $w0.plot.frame
    $w configure -bd 0
    APSRadioButtonFrame .monitor -parent $w -label "Video Monitor: " -variable PlotVideoMonitor \
      -buttonList {35BMA 35BMB 35IDA 35Lab 35CTRL MCR} -valueList {35BMA 35BMB 35IDA 35Lab 35CTRL MCR} \
      -contextHelp "choose the video monitor type for plots, since the data is saved by the type of montior." \
      -orientation horizontal
          
    APSLabeledEntry .dir -parent $w -label "Input Directory: " -width 70 -textVariable PlotDir \
      -contextHelp "The directory of the plotting files."
    APSButton .d -parent $w.dir -packOption "-side right" -text D -size small \
      -command {set PlotDir [MakeDefaultDir]}
    APSButton .pick -parent $w.dir -packOption "-side right" -text P -size small \
      -command {set PlotDir [FindDir]} \
      -contextHelp "pick a directory from a list for corresponding video monitor type."
    APSButton .image -parent $w -text "View Image" -command {ViewImage}
    APSButton .imagesum -parent $w -text "View Sum Image" -command {ViewImage -sum 1}

    APSFrame .prof -parent $w0
    set w $w0.prof.frame
    $w configure -bd 0
    global profXLabel profPlotOption profPlotFile profPlotMethod
    
    APSRadioButtonFrame .xLabel -parent $w -label "xLabel:      " \
      -buttonList {x(um) x(mm) xp(urad) y(um) y(mm) yp(urad) t(ps)} \
      -valueList {x(um) x(mm) xp(urad) y(um) y(mm) yp(urad) t(ps)} \
      -variable profXLabel -contextHelp "xLabel for plotting profiles." -orientation horizontal
    APSRadioButtonFrame .method -parent $w -label "Plot method: " \
      -buttonList {waterfall separate one_plot sum_plot sum_png} \
      -valueList {waterfall separate one_plot sum_plot sum_png}  \
      -variable profPlotMethod -orientation horizontal
    APSLabeledEntry .option -parent $w -label "Plot option for profiles:" -textVariable profPlotOption \
      -width 50
    APSButton .clear -parent $w.option -packOption "-side right" \
      -text "clear" -size small \
      -command {set profPlotOption ""}
    APSButton .scales -parent $w.option -packOption "-side right" \
      -text "scales" -size small \
      -command {set profPlotOption "-scales=0,0,0,0"}
    APSButton .stagger -parent $w.option -packOption "-side right" \
      -text "stagger" -size small \
      -command {set profPlotOption "-stagger=yInc=15"}
    APSButton .plot -parent $w -command PlotProfFile -text "Plot Profile"
    
}

proc FindFile {args} {
    set directoryVar ""
    set filter ""
    APSParseArguments {directoryVar filter} 
    global $directoryVar
    set directory [set $directoryVar]
    if ![file exist $directory] {
        return -code error "$directory does not exist"
    }
    set oldDir [pwd]
    cd $directory
    set files [glob -nocomplain ${filter} ]
    cd $oldDir
    if ![llength $files] {
        return -code error "No $filter files found in directory $PlotDir!"
    }
    global selectionFile
    APSScrolledListWindow .filesel \
      -name "Directory selection" \
      -label "Select a directory" \
      -itemList $files \
      -selectionVar selectionFile
    tkwait variable selectionFile
    return $selectionFile
}

proc FindDir {args} {
    global dirSelection PlotVideoMonitor mainDir
    
    set dirList [lsort -decreasing [glob -nocomplain $mainDir/*]]
    
    if ![llength $dirList] {
        return -code error "No data found for $PlotVideoMonitor monitor!"
    }
    APSScrolledListWindow .dirsel \
      -name "Directory selection" \
      -label "Select a directory" \
      -itemList $dirList \
      -selectionVar dirSelection
    tkwait variable dirSelection
    return $dirSelection
}

proc SaveProfileData {args} {
    global abortRun  VERBOSE FrameGrabber ProfPlane OutputDir ProfRootname nFrames interval imageDescription
    
    # Determine x/y actions
    switch $ProfPlane {
        x {
            set xScanDone 0
            set yScanDone 1
        }
        y {
            set xScanDone 1
            set yScanDone 0
        }
        both {
            set xScanDone 0
            set yScanDone 0
        }
    }
    if ![file exist $OutputDir] {
        if [catch {exec mkdir $OutputDir} result] {
            return -code error "Error making directory $OutputDir: $result"
        }
        # exec setfacl -m mask:rwx $OutputDir 
        #exec /home/helios/OAG/bin/setFACL-oagPlus emery,borland,bxyang,sr,asdops $OutputDir
    }
    set ProfRootname [MakeDefaultRootname -type Prof]
    set template /home/helios/BXYANG/operations/s35apps/inputFiles/saveProfileTemplate.wmon
    # Prepare x-scan
    if !$xScanDone {
        set xFile [file root $ProfRootname]-xProf
        set xMonFile  [file root $ProfRootname]-xProf.wmon 
        if [catch {exec cavget -list=${FrameGrabber}:roiXSizeC -pend=30} xSize] {
            return -code error $xSize
        }
        exec replaceText $template $OutputDir/$xMonFile \
          -original=<VIDn>,<axis>,<length> \
          -replace=$FrameGrabber,x,$xSize
    }
    if !$yScanDone {
        set yFile [file root $ProfRootname]-yProf
        set yMonFile  [file root $ProfRootname]-yProf.wmon 
        if [catch {exec cavget -list=${FrameGrabber}:roiYSizeC -pend=30} ySize] {
            return -code error $ySize
        }
        exec replaceText $template $OutputDir/$yMonFile \
          -original=<VIDn>,<axis>,<length> \
          -replace=$FrameGrabber,y,$ySize
    }

    #################
    #   Take data   #
    #################
    APSSetVarAndUpdate displayStatus "Start taking data."
    set extraPVFile ""
    set morePV [file exists $extraPVFile]
    
    # Start x-scan
    if !$xScanDone {
      APSSetVarAndUpdate displayStatus "Saving x-profiles in $OutputDir/$xFile."
      if $morePV { 
          APSExecLog [APSUniqueName .] \
            -unixCommand "sddswmonitor $OutputDir/$xMonFile $OutputDir/$xFile -interval=$interval -steps=$nFrames -verbose" \
            -callback "set xScanDone 1" -cancelCallback "set xScanDone 1" -abortCallback "set xScanDone -1" \
            -width 80 -height 15 -scalars=$extraPVFile 
      } else {
         APSExecLog [APSUniqueName .] \
           -unixCommand "sddswmonitor $OutputDir/$xMonFile $OutputDir/$xFile -interval=$interval -steps=$nFrames -verbose" \
           -callback "set xScanDone 1" -cancelCallback "set xScanDone 1" -abortCallback "set xScanDone -1" \
           -width 80 -height 15 
      }
    }
    # Start y-scan
    if !$yScanDone {
        APSSetVarAndUpdate displayStatus "Saving y-profiles in $OutputDir/$yFile."
        if $morePV { 
            APSExecLog [APSUniqueName .] \
              -unixCommand "sddswmonitor $OutputDir/$yMonFile $OutputDir/$yFile -interval=$interval -steps=$nFrames -verbose" \
              -callback "set yScanDone 1" -cancelCallback "set yScanDone 1" -abortCallback "set yScanDone -1" \
              -width 80 -height 15  -scalars=$extraPVFile 
        } else {
         APSExecLog [APSUniqueName .] \
           -unixCommand "sddswmonitor $OutputDir/$yMonFile $OutputDir/$yFile -interval=$interval -steps=$nFrames -verbose" \
           -callback "set yScanDone 1" -cancelCallback "set yScanDone 1" -abortCallback "set yScanDone -1" \
           -width 80 -height 15 
      }
    }
    if !$xScanDone {
        tkwait variable $xScanDone
    }
    if !$yScanDone {
        tkwait variable $yScanDone
    }
    if {[file exist $OutputDir/$xFile] && [string length $imageDescription]} {
        set tmpfile /tmp/[APSTmpString]
        if [catch {exec sddsprocess $OutputDir/$xFile \
                     "-reprint=par,Description,$imageDescription in x plane" } result] {
            return -code error $result
        }
        exec mv $tmpfile $OutputDir/$xFile
    }
    if {[file exist $OutputDir/$yFile] && [string length $imageDescription]} {
        set imageDescription [APSMakeSafeQualifierString $imageDescription]
        set tmpfile /tmp/[APSTmpString]
        if [catch {exec sddsprocess $OutputDir/$yFile \
                     "-reprint=par,Description,$imageDescription in y plane" } result] {
            return -code error $result
        }
        exec mv $tmpfile $OutputDir/$yFile
    }
    APSSetVarAndUpdate displayStatus "Done."
    return
}

proc CaptureVideoData {args} {
    global FrameGrabber interval VideoRegion RIO_xStart ROI_xSize ROI_yStart ROI_ySize ImageRootname nFrames
    global OutputDir abortRun fileIndexLen VERBOSE videoMonitor imageDescription
    set sum 0
    APSParseArguments {sum}
   # set OutputDir [MakeDefaultDir]
    if ![file exist $OutputDir] {
        if [catch {exec mkdir $OutputDir} result] {
            return -code error "Error making directory $OutputDir: $result"
        }
        #exec setfacl -m mask:rwx $OutputDir 
       # exec /home/helios/OAG/bin/setFACL-oagPlus emery,borland,bxyang,sr,asdops $OutputDir
    }
    
    APSSetVarAndUpdate displayStatus "Start taking data."
    set ImageRootname [MakeDefaultRootname -Image]
    
    # write temperary image directory
    switch $FrameGrabber {
        LI:VD1   { set subdir linac }
        S:VID1   { set subdir VID1 }
        S:VID2   { set subdir VID2 }
        S:VID3   { set subdir VID3 }
        S:VID4   { set subdir VID4 }
        S:VID5   { set subdir VID5 }
        S:VID6   { set subdir VID6 }
    }
    set tempImageDir /home/helios4/image_data/$subdir
    if [catch {exec cavput "-list=${FrameGrabber}:imageFilePath=$tempImageDir" -pend=30} result] {
        return -code error $result
    }
    APSSetVarAndUpdate displayStatus $tempImageDir
    if [catch {exec cavput -list=${FrameGrabber}:fileIndexEnableC=0 -pend=30} result] {
        return -code error $result
    }
    if [catch {exec cavget -list=${FrameGrabber}:imageFileName -pend=30} tempImageFile] {
        return -code error $tempImageFile
    }
    if { $VideoRegion == "ROI_Only" } {
        set value 1
    } else { set value 0} 
    if [catch {exec cavput -list=${FrameGrabber}:writeImageFileC=$value -pend=30} result] {
        return -code error $result
    }
    set fileList ""
    set a $tempImageFile
    if [regexp {(.*)\-} $a b c] {
	while {[regexp {(.*)\-} $a b c]} {
	    set a $c
	}
	set name $c
    } else {
	set name $a
    }
    for {set fIndex 0} {$fIndex < $nFrames} {incr fIndex} {
        # check abortRun
        if {$abortRun} {
            APSSetVarAndUpdate displayStatus "Image capture aborted."
            set abortRun 0
            return
        }
        # write temperary image filename and check it
	if ![file exist $tempImageDir/${name}-0000] {
	    set tempFile ${name}-0000
	} else {
	    set tempFile [APSNextGenerationedName -name $name-0000 -directory $tempImageDir \
			      -separator - -newFile 1]
	}
       # setVar -var imageFileName -value $tempFile
        if [catch {exec cavput -list=${FrameGrabber}:imageFileName=$tempFile -pend=30} result] {
            return -code error $result
        }
        
        # Save file
        APSSetVarAndUpdate displayStatus "Saving frame No. $fIndex in $tempFile"
        if [file exists "$tempImageDir/$tempFile"] {exec rm -f "$tempImageDir/$tempFile"}
        #setVar -var grabSaveButton -value 1
        if [catch {exec cavput -list=${FrameGrabber}:saveImageToFileC=1 -pend=30} result] {
            return -code error $result
        }
        # wait for file writing to complete
        for {set checkIndex 0} {$checkIndex < 30} {incr checkIndex} {
            #set frameGrabberMessage [getVar -var frameGrabberMessage]
            if [catch {exec cavget -list=${FrameGrabber}:image:seqMsg1 -pend=30}  frameGrabberMessage] {
                return -code error $frameGrabberMessage
            }
            if $VERBOSE {APSSetVarAndUpdate displayStatus "frameGrabberMessage = $frameGrabberMessage"}
            if {[string match "*successfully*" $frameGrabberMessage]} { break }
            if {[string match "*Ready*" $frameGrabberMessage]} {
                if [catch {exec cavput -list=${FrameGrabber}:writeImageFileC=1 -pend=30} result] {
                    return -code error $result
                }
                #setVar -var saveButton -value 1
            }
            update
            after 1000            
        }
        
        # copy if the file exist
        after 500
        if [file exists "$tempImageDir/$tempFile"] {
            set error 0
            set file [file root $ImageRootname]-[format "%0${fileIndexLen}.0f" $fIndex][file extension $ImageRootname] 
            if $VERBOSE {APSSetVarAndUpdate displayStatus "Copying $tempFile to $file"}
            if { $VideoRegion == "Soft_ROI" } {
                if [catch {sddsMatrixSubmatrix -inputFile $tempImageDir/$tempFile \
                             -outputFile $OutputDir/$file -columnRoot HLine \
                             -row1 $ROI_xStart -row2 [ expr $ROI_xStart + $ROI_xSize ] \
                             -col1 [expr 484 - $ROI_yStart - $ ROI_ySize ] -col2 [expr 484 - $ROI_yStart]  } result] {
                    APSSetVarAndUpdate displayStatus "$result"
                    set error 1
                }
                if [catch {APSClipROI -input $tempImageDir/$tempFile -output $OutputDir/$file \
                             -imageColumns HLine -formatString "%03.0f" \
                             -xSpotMin $ROI_xStart -xSpotMax [ expr $ROI_xStart + $ROI_xSize ] \
                             -ySpotMin [expr 484 - $ROI_yStart - $ROI_ySize ] -ySpotMax [expr 484 - $ROI-yStart] } result] {
                    APSSetVarAndUpdate displayStatus "$result"
                    set error 1
                }
            } else {
                if [catch {file copy -force $tempImageDir/$tempFile $OutputDir/$file } result] {
                    APSSetVarAndUpdate displayStatus "$result"
                    set error 1
                }
            }
            if $error {
                APSSetVarAndUpdate displayStatus "Error transferring file $tempFile to $file"
                set fIndex [expr $fIndex - 1]
            } else {
                if [string length $imageDescription] {
                    set imageDescription [APSMakeSafeQualifierString $imageDescription]
                    set tmpfile /tmp/[APSTmpString]
                    if [catch {exec sddsprocess $OutputDir/$file \
                                 "-reprint=par,Description,$imageDescription" } result] {
                        return -code error $result
                    }
                    exec mv $tmpfile $OutputDir/$file
                }
                lappend fileList $OutputDir/$file
                APSSetVarAndUpdate displayStatus "Succeeded in transferring file $tempFile to $file"
                file delete -force $tempImageDir/$tempFile 
            }
        } else {
            set fIndex [expr $fIndex - 1] 
        }
        # Wait additional time specified
        after [format "%0.0f" [expr 1000 * $interval ] ]
    }
    APSSetVarAndUpdate displayStatus "Summing images to $OutputDir/${ImageRootname}-SUM"
    if [catch {eval exec sddscombine $fileList -pipe=out \
                 | sddsenvelope -pipe -copy=VLineName -copy=Index -sum=1,HLine??? \
                 | sddsprocess -pipe -define=col,%s,%sSum,select=HLine*,edit=%/Sum// \
                 | sddsconvert -pipe=in -delete=col,*Sum $OutputDir/${ImageRootname}-SUM } result] {
        return -code error $result
    }
    APSSetVarAndUpdate displayStatus "Done."
    return
}


proc UpdateROI {args} {
    global ROI_xStart ROI_yStart ROI_xSize ROI_ySize FrameGrabber
    
    catch {exec cavget -list=${FrameGrabber}:roiXStartC -pend=30} ROI_xStart
    catch {exec cavget -list=${FrameGrabber}:roiXSizeC -pend=30} ROI_xSize
    catch {exec cavget -list=${FrameGrabber}:roiYStartC -pend=30} ROI_yStart
    catch {exec cavget -list=${FrameGrabber}:roiYSizeC -pend=30} ROI_ySize
    APSSetVarAndUpdate displayStatus "softROI for $FrameGrabber: X = $ROI_xStart + $ROI_xSize, Y = $ROI_yStart + $ROI_ySize"
}

proc GetDefaultDir {monitor} {
    switch $monitor {
        35BMA {set dir 35BM/BMA }
        35BMB {set dir 35BM/BMB }
        35IDA {set dir 35ID/divCam }
        35Lab {set dir 35Lab }
        35CTRL {set dir 35CTRL }
        MCR {set dir mcr}
        default {return -code error "Unknown video monitor given!" }
    }
    return /home/helios/PHOTODIA/DeviceData/SR/S35/$dir/StreakCam
}

proc MakeInputFileName {args} {
    global FrameGrabber
    
    if {$FrameGrabber=="LI:VD1"} {
	set name VID0
    } elseif ![regexp {:(.*)} $FrameGrabber a name c] {
        return -code error "Invalid frame grabber name: $FrameGrabber"
    }
    return streakCam_${name}.mon
}

proc MakeDefaultDir {args} {
    set monitor ""
    APSParseArguments {monitor}
   # set defaultDir [GetDefaultDir $monitor]
    set seconds [clock seconds]
    set year [clock format $seconds -format "%Y"]
    set month [clock format $seconds -format "%m%d"]
    set time [clock format $seconds -format "%H%M%S"]
    return /home/helios/oagData/sr/bunchLength/$year-$month
}

proc MakeDefaultRootname {args} {
    global videoMonitor FrameGrabber
    set type ""
    APSParseArguments {type}
    set time [clock format [clock seconds] -format "%H%M%S"]
    global ProfRootname ImageRootname
    regexp {:(.*)} $FrameGrabber a frame
    if {$type=="All"} {
        set ImageRootname S${videoMonitor}_${frame}_Image-${time}
        set ProfRootname S${videoMonitor}_${frame}_Prof-${time}
    } else {
        set ${type}Rootname S${videoMonitor}_${frame}_${type}-${time}
    }
}

proc UpdateWithVideoMonitor {args} {
    global PlotVideoMonitor videoMonitor ProfRootname VideoRootname FrameGrabber
    set time [clock format [clock seconds] -format "%H%M%S"]
    set PlotVideoMonitor $videoMonitor
    MakeDefaultRootname -type All
}
proc UpdatePlotDirectory {args} {
    global  OutputDir PlotDir
    set PlotDir $OutputDir
}
proc ViewImage {args} {
    set sum 0
    APSParseArguments {sum}
    global PlotDir PlotVideoMonitor
    
    if $sum {
        set filter *${PlotVideoMonitor}*SUM
    } else {
        set filter *${PlotVideoMonitor}*
    }
    set file [FindFile -directoryVar PlotDir -filter $filter]
    APSSetVarAndUpdate displayStatus "Show imaged from $PlotDir/$file"
    exec sddscontour $PlotDir/$file -shade=16 -col=Index,HLine* -equalaspect \
       -topTitle -title=$file -ystrings=sparse=20 &
    
}

proc PlotProfFile {args} {
    global  profXLabel profPlotOption profPlotFile PlotDir profPlotMethod
    
    set profPlotFile [FindFile -directoryVar PlotDir -filter *Prof]
    if ![string length $profPlotFile] {return}
    if ![file exists $PlotDir/$profPlotFile] {return -code error "$PlotDir/$profPlotFile does not exist."}
    
    set file $PlotDir/$profPlotFile
    # look for x or y
    set columnList [exec sddsquery $file -col]
    if { [lsearch -exact $columnList xCoord] >=0 } {
       set xVar xCoord
    } elseif { [lsearch -exact $columnList yCoord] >= 0 } {
       set xVar yCoord
    } else {
       return -code error "xCoord or yCoord is not found."
    }
    APSSetVarAndUpdate displayStatus "Plot against coordinate xVar = $xVar"
    
    set yLabel "-yLabel=Counts"
    set title  "-title=$profPlotFile"

    APSSetVarAndUpdate displayStatus "Plot profiles in $file"
    switch $profPlotMethod {
        one_plot  {
           eval exec sddsplot $file -col=${xVar},profileData \
              -xLabel=$profXLabel $yLabel -topTitle $title \
              -split=page -graphic=line,vary \
              $profPlotOption &      
        }
        separate  {
            eval exec sddsplot $file -col=${xVar},profileData \
              -xLabel=$profXLabel $yLabel -topTitle $title \
              -split=page -separate=page -samescale \
              $profPlotOption &      
            
        }
        sum_plot {
            set sumFile $PlotDir/${profPlotFile}-sum.sdds
            if ![file exist $sumFile] {
                if [catch {exec sddsenvelope $PlotDir/$profPlotFile $sumFile -copy=$xVar -sum=1,profileData } result] {
                    return -code error $result
                }
            }
            eval exec sddsplot $sumFile -col=${xVar},profileDataSum \
              -xLabel=$profXLabel $yLabel -topTitle $title -split=page \
              $profPlotOption &
        }
        sum_png {
            set sumFile $PlotDir/${profPlotFile}-sum.sdds
            if ![file exist $sumFile] {
                if [catch {exec sddsenvelope $PlotDir/$profPlotFile $sumFile -copy=$xVar -sum=1,profileData } result] {
                    return -code error $result
                }
            }
            set pngFile $PlotDir/${profPlotFile}.png
            eval exec sddsplot $sumFile -col=${xVar},profileDataSum \
              -xLabel=$profXLabel $yLabel -topTitle $title -split=page \
              -device=png,onwhite -output=$pngFile \
              $profPlotOption & 
        }
        waterfall {
            #streak plot
            set colRoot Prof
            set streakFile $PlotDir/${profPlotFile}-WF
            set tmpfile /tmp/[APSTmpString]
            set sddsDescription "Stacked profiles of $PlotDir/${profPlotFile}"
            APSAddToTmpFileList -ID 1 -fileList "$tmpfile.0 $tmpfile.1"
            if [catch {exec sddsconvert $file $tmpfile.0 -delete=col,profileData } result] {
                return -code error $result
            }
            if [catch {exec sddsconvert  $PlotDir/$profPlotFile -pipe=out -retain=col,profileData \
                         | sddstranspose -pipe -root=A -digit=3 \
                         | sddscombine -pipe -merge  \
                         | sddstranspose -pipe -root=$colRoot -digit=3 -oldColumnName=oldRowName \
                         | sddsxref -pipe=in $tmpfile.0 $tmpfile.1
                exec sddsprocess $tmpfile.1 $streakFile -delete=col,oldRowName \
                         -description=text=$sddsDescription } result] {
                return -code error $result
            }
            eval exec sddscontour $streakFile -col=$xVar,$colRoot* \
              -xLabel=$profXLabel -yLabel=Delay_Time(Turns) -shade=16 -topTitle $title \
              $profPlotOption &    
        }
    }
    APSSetVarAndUpdate displayStatus "Done"
    return
}

#################################
#				#
#  	  MAIN PROGRAM		#
#				#
#################################
# Initialize global data
#initGlobalVars

# Process command line arguments
set powerOn 0
set PowerUser 0
set action 0
set args $argv
APSParseArguments { PowerUser action }

# Imediate action to be designed
if {$action=="something"} {
   exit
} elseif {$action=="something else"} {
   exit
}

set VERBOSE 0
set ProfilePlane y
set configSaved 0
set videoMonitorList {35BMA 35BMB 35IDA 35Lab 35CTRL MCR}
set VideoRegion ROI_Only
set profiles yProfile
set xLabel t(ps)
set nFrames 4
set interval 1
set FrameGrabber S:VID4
set ROI_xStart 130
set ROI_yStart 160
set ROI_xSize 250
set ROI_ySize 160
set fileIndexLen 4
set SumImage 1
set ProfPlane y
set videoMonitor 35BMA
set PlotVideoMonitor $videoMonitor
set outputDir [MakeDefaultDir]
set OutputDir [MakeDefaultDir]
set PlotDir $OutputDir
set profXLabel t(ps)
set profPlotFile ""
set profPlotMethod waterfall
set phaseStart 0.0
set phaseStop 9.0
set phaseSteps 46
set phaseInterval 0.5
set noInit 1
set abortRun 0
set VERBOSE 0
set authorizedUser 1
set DRYRUN 0
set steps 10
set onTime 240
set timing 4.50
set FrameGrabberList {S:VID1 S:VID2 S:VID3 S:VID4 S:VID5 S:VID6 LI:VD1}
#set FrameGrabberValueList {VID0 VID1 VID2 VID3 VID4 VID5 VID6}
set monitorCam 25
set grabberCam 17
set grabberCamIndex 117
set boxcarWidth 15
set numberAvg 300
set vDelayIncr 0.1
set inputDir /home/helios/PHOTODIA/operations/s35apps/inputFiles
set inputFile [MakeInputFileName]
set outputDir [MakeDefaultDir]
set outputFile S${videoMonitor}_${FrameGrabber}_Monitor.0000
if [catch {exec cavget -list=S35ID:HamC1097_04aC -pend=30} vDelay] {
    return -code error $vDelay
}
set nextVDelay $vDelay
set mainDir /home/helios/oagData/sr/bunchLength
set monitorDescription ""
set imageDescription ""
MakeDefaultRootname -type Image
MakeDefaultRootname -type Prof

#########################
#    INTERACTIVE MODE	#
#########################

# Menu bar

if {$PowerUser} {
   set appName "srBunchLen: Streak Camera SynchroScan Setup"
   set PowerUser 1
} else {
   set appName "srBunchLen: Streak Camera SynchroScan Operation"
   set PowerUser 0
}


APSApplication . -name $appName -version $CVSRevisionAuthor \
    -overview "Measure the storage ring bunch length with Hamamatsu streak camera."

# message window output "stdout"
set displayStatus "PowerUser = $PowerUser"
APSScrolledStatus .status -parent .userFrame -width 80 -height 6 -textVariable displayStatus 
APSSetVarAndUpdate displayStatus "Push the Power button to turns on streak camera"


PowerOnFrame         .poweron   -parent .userFrame
SetupBunchLenFrame   .setup     -parent .userFrame
MeasureBunchLenFrame .bunchLen  -parent .userFrame
MonitorBunchLenFrame .monitor   -parent .userFrame
#if {$PowerUser >= 10} {phaseScanFrame .quickscan -parent .userFrame}


.menu.help.menu add command -label "HTML info file" -command {
    exec netscape "/home/helios/PHOTODIA/DeviceInfo/SR/Sector35/35BM/35BMB/Streak_Camera/bmbStreakBunchLenApp.html" &
    # exit
}
.menu.help.menu insert 5 separator

.menu.file.menu delete 2
.menu.file.menu add command -label "Quit" -command { 
    APSMenuFrameClose .userFrame.mf
    PowerDownStreakCamera -quitNow 1
}

.menu.help.menu add command -label "Toggle verbose mode" -command {
    set VERBOSE [expr 1 - $VERBOSE]
    APSSetVarAndUpdate displayStatus "set VERBOSE = $VERBOSE"
}
.menu.help.menu add command -label "Toggle DRYRUN mode" -command {
    set DRYRUN [expr 1 - $DRYRUN]
    APSSetVarAndUpdate displayStatus "set DRYRUN = $DRYRUN"
}
.menu.help.menu insert 7 separator







