#!/bin/sh
# \
exec oagwish "$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.21 $ \$Author: sereno $"

APSApplication . -name "CTR Alpha Magnet and Scraper Scans" \
  -overview "Performs alpha magnet and scraper scans for CTR measurement." -version $CVSRevisionAuthor

set directory /home/helios/OAG/oagData/linac/ctrData

# This procedure sets the status variable used by the status widget.

set ControlStatus "Ready."

#Make application and status window widgets.  Returns 1 when completed.

proc MakeScanStatusWidget {widget args} {

    global ControlStatus
    set parent ""
    APSParseArguments {parent}
    
    set w $parent$widget
    APSScrolledStatus .status -parent $w -textVariable ControlStatus -width 65 -packOption {-side top}
    return 1
}

# Makes widgets used to perform the alpha magnet and scraper scans.

proc MakeScanWidgets {widget00 widget1 widget2 widget3 args} {

    global directory wa2 ws2 ws3 ws4 lowFreqLimit highFreqLimit totalCharge
    global uniqueFileLabelList fileLabelList fileRootname CTRSystem baseSubtract
    set parent ""
    APSStrictParseArguments {parent}

    set CTRSystem L2

    APSRadioButtonFrame ${widget00}a -parent $parent \
      -label "CTR System: " -orientation horizontal \
      -buttonList "L2 L3" -valueList "L2 L3" -variable CTRSystem

    APSFrame $widget00 -parent $parent \
      -height 30 -label "Data Processing Parameters" \
      -packOption {-side top -expand 1}
    
    set wdp $parent$widget00.frame

    APSFrame $widget1 -parent $parent \
      -height 30 -label "Alpha Magnet Current Scan" \
      -packOption {-side top -expand 1}
    
    set wa $parent$widget1.frame

    APSFrame .labelledEntryFrame -parent $wa \
      -height 30 \
      -packOption {-side top -expand 1}

    set wa1 ${wa}.labelledEntryFrame.frame 

    APSFrame .buttonFrame -parent $wa \
      -height 30 \
      -packOption {-side top -expand 1}

    set wa2 ${wa}.buttonFrame.frame 

    APSFrame $widget2 -parent $parent \
      -height 30 -label "Alpha Magnet Scraper Scan" \
      -packOption {-side top -expand 1}
    
    set ws $parent$widget2.frame

    APSFrame .labelledEntryFrame -parent $ws \
      -height 30 \
      -packOption {-side top -expand 1}

    set ws1 ${ws}.labelledEntryFrame.frame 

    APSFrame .buttonFrame -parent $ws \
      -height 30 \
      -packOption {-side top -expand 1}

    set ws2 ${ws}.buttonFrame.frame

    APSFrame $widget3 -parent $parent \
      -height 30 -label "Autocorrelation Scan" \
      -packOption {-side top -expand 1}

    set was $parent$widget3.frame

    APSFrame .labelledEntryFrame -parent $was \
      -height 30 \
      -packOption {-side top -expand 1}

    set ws3 ${was}.labelledEntryFrame.frame

    APSFrame .buttonFrame -parent $was \
      -height 30 \
      -packOption {-side top -expand 1}

    set ws4 ${was}.buttonFrame.frame

    APSLabeledEntry .integLimitFrame -parent $wdp -width 9 \
      -textVariable IntegLimit \
      -packOption {-side top -fill x} \
      -label "Integration Limit From CTR Waveform Peak (microseconds):" \
      -contextHelp "Integration limit after the maximum CTR signal."

    APSLabeledEntry .upFitLimitFrame -parent $wdp -width 9 \
      -textVariable UpperFitLimit \
      -packOption {-side top -fill x} \
      -label "Second order charge upper fit limit for scraper scan (nC):" \
      -contextHelp "Second order charge upper fit limit for scraper scan CTR signal vs current monitor charge data."

    APSLabeledEntry .lowFitLimitFrame -parent $wdp -width 9 \
      -textVariable LowerFitLimit \
      -packOption {-side top -fill x} \
      -label "Second order charge lower fit limit for scraper scan (nC):" \
      -contextHelp "Second order charge lower fit limit for scraper scan CTR signal vs current monitor charge data."

    APSLabeledEntry .alphaLowCurrentFrame -parent $wa1 -width 9 \
      -textVariable AlphaCurrentLowLimit \
      -packOption {-side top -fill x} \
      -label "Alpha Magnet Current Low Limit (Amperes):" \
      -contextHelp "Alpha magnet current low limit in amperes."

    APSLabeledEntry .alphaHighCurrentFrame -parent $wa1 -width 9 \
      -textVariable AlphaCurrentHighLimit \
      -packOption {-side top -fill x} \
      -label "Alpha Magnet Current High Limit (Amperes):" \
      -contextHelp "Alpha magnet current high limit in amperes."

    APSLabeledEntry .l1PhaseLowLimitFrame -parent $wa1 -width 9 \
      -textVariable  L1PhaseLowLimit \
      -packOption {-side top -fill x} \
      -label "Sector L1 Phase Low Limit (Volts):" \
      -contextHelp "Sector L1 phase low alpha magnet current limit (phase at -AlphaHalfRange)."

    APSLabeledEntry .l1PhaseHighLimitFrame -parent $wa1 -width 9 \
      -textVariable  L1PhaseHighLimit \
      -packOption {-side top -fill x} \
      -label "Sector L1 Phase High Limit (Volts):" \
      -contextHelp "Sector L1 phase high alpha magnet current limit (phase at +AlphaHalfRange)."

    APSLabeledEntry .alphaScanStepsFrame -parent $wa1 -width 9 \
      -textVariable AlphaScanSteps \
      -packOption {-side top -fill x} \
      -label "Steps:" \
      -contextHelp "Number of steps in the measurement."

    APSLabeledOutput .alphaFileRootFrame -parent $wa1 -width 50 \
      -textVariable  alphaFileRootnameTail \
      -packOption {-side top -fill x} \
      -label "File Rootname:" \
      -contextHelp "Data file and processed file rootname for alpha magnet scan."
     
    APSButton .scanButtonFrame -parent $wa2 \
      -text "Scan..." \
      -command {PerformAlphaMagnetScan -statusCallback SetStatus -steps ${AlphaScanSteps}} \
      -packOption {-side left -fill x} \
      -contextHelp "This button invokes a procedure that performs the alpha magnet current (along with L1 rf phase) scan."

    APSButton .plotButtonFrame -parent $wa2 \
      -text "Plot..." \
      -command {PlotAlphaMagnetScanRawAndProcessedData -statusCallback SetStatus} \
      -packOption {-side left -fill x} \
      -contextHelp "This button invokes a procedure that plots the processed alpha magnet scan data."

    APSButton .chooseAlphaMagnetFileButtonFrame -parent $wa2 \
      -text "Pick File..." \
      -command {PickAlphaMagnetScanRawAndProcessedDataFile -statusCallback SetStatus} \
      -packOption {-side left -fill x} \
      -contextHelp "This button allows one to choose a previously measured alpha magnet scan data file"

    APSLabeledEntry .scraperLowLimitFrame -parent $ws1 -width 9 \
      -textVariable ScraperPositionLowLimit \
      -packOption {-side top -fill x} \
      -label "Scraper Position Low Limit (cm):" \
      -contextHelp "Scraper position low limit in centimeters."

    APSLabeledEntry .scraperHighLimitFrame -parent $ws1 -width 9 \
      -textVariable ScraperPositionHighLimit \
      -packOption {-side top -fill x} \
      -label "Scraper Position High Limit (cm):" \
      -contextHelp "Scraper position high limit in centimeters."

    APSLabeledEntry .scraperStepsFrame -parent $ws1 -width 9 \
      -textVariable ScraperScanSteps \
      -packOption {-side top -fill x} \
      -label "Steps:" \
      -contextHelp "Number of steps in the scraper scan measurement."

    APSLabeledOutput .scraperFileRootFrame -parent $ws1 -width 50 \
      -textVariable  scraperFileRootnameTail \
      -packOption {-side top -fill x} \
      -label "File Rootname:" \
      -contextHelp "Data file and processed file rootname for scraper scan."
     
    APSButton .scanButtonFrame -parent $ws2 \
      -text "Scan..." \
      -command {PerformScraperScan -statusCallback SetStatus -steps ${ScraperScanSteps}} \
      -packOption {-side left -fill x} \
      -contextHelp "This button invokes a procedure that performs the scraper scan."

    APSButton .plotButtonFrame -parent $ws2 \
      -text "Plot..." \
      -command {PlotScraperScanRawAndProcessedData -statusCallback SetStatus} \
      -packOption {-side left -fill x} \
      -contextHelp "This button invokes a procedure that plots the results of the scraper scan."

    APSButton .chooseScraperFileButtonFrame -parent $ws2 \
      -text "Pick File..." \
      -command {PickScraperScanRawAndProcessedDataFile -statusCallback SetStatus} \
      -packOption {-side left -fill x} \
      -contextHelp "This button allows one to choose a previously measured scraper scan data file"

    APSRadioButtonFrame .baseline -parent $ws3 \
      -orientation horizontal \
      -packOption {-side top -fill x} \
      -label "Baseline:                                               " \
      -buttonList "Subtract Keep" -valueList "1 0" -variable baseSubtract

    APSLabeledEntry .lowFreqLimitFrame -parent $ws3 -width 9 \
      -textVariable lowFreqLimit \
      -packOption {-side top -fill x} \
      -label "Low Frequency Limit (1/microns):" \
      -contextHelp "Low Frequency Limit."

    APSLabeledEntry .highFreqLimitFrame -parent $ws3 -width 9 \
      -textVariable highFreqLimit \
      -packOption {-side top -fill x} \
      -label "High Frequency Limit (1/microns):" \
      -contextHelp "High Frequency Limit."

    APSLabeledEntry .totalChargeFrame -parent $ws3 -width 9 \
      -textVariable totalCharge \
      -packOption {-side top -fill x} \
      -label "Total Macropulse Charge (pC):" \
      -contextHelp "Total Macropulse Charge."

    APSLabeledEntry .totalMacroPulseLengthFrame -parent $ws3 -width 9 \
      -textVariable totalMacroPulseLength \
      -packOption {-side top -fill x} \
      -label "Total Macropulse Length (ns):" \
      -contextHelp "Total Macropulse Length."

    APSLabeledEntry .fileRootNameFrame -parent $ws3 -width 50 \
      -textVariable fileRootname \
      -packOption {-side top -fill x} \
      -label "Data file rootname:" \
      -contextHelp "Data file rootname."

    APSButton .daily -parent ${ws3}.fileRootNameFrame -size small -text "daily" \
      -command "set fileRootname [APSGoToDailyDirectory]AutoScanData01" -packOption "-side right"

    APSButton .acquireAutocorrelationFrame -parent $ws4 \
      -text "Acquire/Process..." \
      -command {AcquireAndProcessAutocorrelation -statusCallback SetStatus} \
      -packOption {-side left -fill x} \
      -contextHelp "This button is used to acquire and process the measured autocorrelation."

    APSButton .reprocessCurrentDistributionFrame -parent $ws4 \
      -text "Reprocess..." \
      -command Reprocess \
      -packOption {-side left -fill x} \
      -contextHelp "This button is used to reprocess the current distribution"

    APSButton .plotOnlyFrame -parent $ws4 \
      -text "Plot..." \
      -command {exec processCTRIFScan -fileRoot $fileRootname -plotOnly 1 -baseSubtract $baseSubtract} \
      -packOption {-side left -fill x} \
      -contextHelp "This button is used to plot the processed distribution."

    return 1
}

proc Reprocess {} {
    global fileRootname totalCharge totalMacroPulseLength lowFreqLimit highFreqLimit baseSubtract
    APSExecLog [APSUniqueName .] \
        -unixCommand "processCTRIFScan -fileRoot $fileRootname -totalCharge $totalCharge -lowFreqFitLimit $lowFreqLimit -highFreqFitLimit $highFreqLimit -totalMacroPulseLength $totalMacroPulseLength -plotOnly 0 -baseSubtract $baseSubtract"

}

# procedure to set the status display

proc SetStatus {text} {
    global ControlStatus
    set ControlStatus $text
    update
}

# Disable buttons once one is pressed.

proc DisableButtons {} {
    global wa2 ws2

    APSDisableButton ${wa2}.scanButtonFrame.button
    APSDisableButton ${wa2}.plotButtonFrame.button
    APSDisableButton ${wa2}.chooseAlphaMagnetFileButtonFrame.button
    APSDisableButton ${ws2}.scanButtonFrame.button
    APSDisableButton ${ws2}.plotButtonFrame.button
    APSDisableButton ${ws2}.chooseScraperFileButtonFrame.button
    return 1
}

# Enable buttons once one is pressed and its associated procedure finishes.

proc EnableButtons {} {
    global wa2 ws2 wb1

    APSEnableButton ${wa2}.scanButtonFrame.button
    APSEnableButton ${wa2}.plotButtonFrame.button
    APSEnableButton ${wa2}.chooseAlphaMagnetFileButtonFrame.button
    APSEnableButton ${ws2}.scanButtonFrame.button
    APSEnableButton ${ws2}.plotButtonFrame.button
    APSEnableButton ${ws2}.chooseScraperFileButtonFrame.button
    return 1
}

# Procedure to perform the alpha magnet (along with phase) scan.
# Returns 1 when completed.

proc PerformAlphaMagnetScan {args} {
    global CTRSystem
    global directory AlphaCurrentLowLimit AlphaCurrentHighLimit L1PhaseLowLimit L1PhaseHighLimit
    global IntegLimit alphaFileRootname alphaFileRootnameTail

    APSStrictParseArguments {statusCallback steps}
    
    if {$steps<2} {
        if {$statusCallback!=""} {
            $statusCallback "Number of steps must be an integer > 1."
        }
        return 0
    }

    set steps [expr int(${steps}) / 1.0]

    DisableButtons

    set alphaFileRootname ${directory}/AlphaScan-[APSOffsetDateInfo -today 1 -dateFormat Y-M-D]_[lindex [exec date] 3]
    set alphaFileRootnameTail [file tail $alphaFileRootname]

    set phaseSlope [expr (${L1PhaseHighLimit} - ${L1PhaseLowLimit}) / (${AlphaCurrentHighLimit} - ${AlphaCurrentLowLimit})]
    set phaseIntercept [expr ${L1PhaseHighLimit} - (${phaseSlope} * ${AlphaCurrentHighLimit})]
    
    set alphaCurrent $AlphaCurrentLowLimit
    set alphaCurrentIncrement [expr (${AlphaCurrentHighLimit} - ${AlphaCurrentLowLimit}) / ${steps}]
    set dataFileList ""

    for {set index 1} {$index<=[expr ${steps} + 1]} {incr index} {
        set phaseValue [expr (${alphaCurrent} * $phaseSlope) + $phaseIntercept]
        exec cavput -list=L1:RG2:LFA:CurrentAO=$alphaCurrent -pendIoTime=20
        exec cavput -list=L1:PP:phaseAdjAO=$phaseValue -pendIoTime=20
        if {$index==1} {
            after 5000
        } else {
            after 3000
        }
        set AlphaI [exec cavget -list=L1:RG2:LFA:CurrentAO -pendIoTime=20]
        set L1Phase [exec cavget -list=L1:PP:phaseAdjAO -pendIoTime=20]
        if {$statusCallback!=""} {
            $statusCallback "Alpha Magnet Current = ${AlphaI} amperes."
            $statusCallback "Sector L1 rf phase = ${L1Phase} volts."
        }
        exec sddswmonitor -PVnames=${CTRSystem}:CTR:WF:timeScaleWF,${CTRSystem}:CTR:WF:scaledDataWF \
          ${alphaFileRootname}_${index}.sdds -step=1 -accumulate=average,number=10 -scalars=${directory}/${CTRSystem}CTRMonitor.mon -comment=CTRSystem,$CTRSystem
        lappend dataFileList ${alphaFileRootname}_${index}.sdds
        set alphaCurrent [expr $alphaCurrent + ${alphaCurrentIncrement}]
    }

    if {$statusCallback!=""} {
        $statusCallback "Alpha magnet scan completed.  Collecting and processing data..."
    }
    
    eval exec sddscombine $dataFileList ${alphaFileRootname}.sdds -overWrite
    eval exec rm $dataFileList

    if {$statusCallback!=""} {
        $statusCallback "Done."
    }

    # Process and plot the alpha magnet scan data.

    ProcessAlphaMagnetScanData -statusCallback SetStatus
    PlotAlphaMagnetScanRawAndProcessedData -statusCallback SetStatus
    
    EnableButtons

    return 1
}

# Procedure to process the alpha magnet (along with phase) scan data.
# Returns 1 when completed.

proc ProcessAlphaMagnetScanData {args} {
    
    global directory AlphaCurrentLowLimit AlphaCurrentHighLimit L1PhaseLowLimit L1PhaseHighLimit
    global IntegLimit alphaFileRootname alphaFileRootnameTail CTRSystem

    APSStrictParseArguments {statusCallback}

    DisableButtons

    if [file exists ${alphaFileRootname}.sdds] {
        if {$statusCallback!=""} {
            $statusCallback "Processing alpha magnet scan data..."
        }
    } else {
        if {$statusCallback!=""} {
            $statusCallback "Pick a valid alpha magnet scan data file."
            EnableButtons
            return 0
        }
    }

    if [catch {exec sddsconvert ${alphaFileRootname}.sdds -pipe=out -topage=1 \
                 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    exec sddsprocess -pipe=out ${alphaFileRootname}.sdds \
      "-print=param,AlphaCurrSetString,%0.1f %s,Alpha1CurrentSetpoint,Alpha1CurrentSetpoint.units" \
      "-redefine=col,${CTRSystem}CTR:WF:timeScaleWF,${CTRSystem}CTR:WF:timeScaleWF,units=ms,symbol=Time" \
      "-redefine=col,${CTRSystem}CTR:WF:scaledDataWF,${CTRSystem}CTR:WF:scaledDataWF,units=Volts" \
      "-reprint=param,Filename,${alphaFileRootnameTail}.sdds,type=string" \
      | sddssmooth -pipe \
      -col=${CTRSystem}CTR:WF:scaledDataWF \
      -pass=0 -despike=neighbors=5,average=5,passes=5 \
      | sddsprocess -pipe=in ${alphaFileRootname}_Proc.sdds \
      -process=${CTRSystem}CTR:WF:scaledDataWF,baselevel,CTRBaselevel \
      "-redefine=col,${CTRSystem}CTR:WF:scaledDataWF,${CTRSystem}CTR:WF:scaledDataWF CTRBaselevel -,units=Volts" \
      -process=${CTRSystem}CTR:WF:scaledDataWF,maximum,CTRMax -nowarnings

    set CTRPeak [exec sdds2stream -param=CTRMax ${alphaFileRootname}_Proc.sdds]

    exec sddsprocess ${alphaFileRootname}_Proc.sdds ${alphaFileRootname}_Integ.sdds \
      -filter=col,${CTRSystem}:CTR:WF:timeScaleWF,${CTRPeak},${IntegLimit} \
      -process=${CTRSystem}:CTR:WF:scaledDataWF,sum,CTRSum -nowarnings \
      "-redefine=param,L1CM2,L1CM2 -1.0 *,units=nC" \
      "-redefine=param,L3CM1,L1CM2 -1.0 *,units=nC" \
      "-redefine=param,L5CM1,L1CM2 -1.0 *,units=nC"

    if {$statusCallback!=""} {
        $statusCallback "Done."
    }

    EnableButtons

    return 1
}

# Procedure to pick an alpha magnet scan file for processing and/or plotting.
# Returns 1 when completed.

proc PickAlphaMagnetScanRawAndProcessedDataFile {args} {

    global directory alphaFileRootname alphaFileRootnameTail CTRSystem

    APSStrictParseArguments {statusCallback}

    DisableButtons

    if {$statusCallback!=""} {
        $statusCallback "Pick alpha magnet scan data file for processing and/or plotting..."
    }

    set oldalphaFileRootname ${alphaFileRootname}
    set oldalphaFileRootnameTail ${alphaFileRootnameTail}

    set filename [APSFileSelectDialog .fileSelectWidget \
                    -path $directory \
                    -pattern AlphaScan-*:??.sdds \
                    -contextHelp "File select dialog to choose alpha magnet scan data file."]

    if {![string compare $filename ""]} {
        set alphaFileRootname $oldalphaFileRootname
        set alphaFileRootnameTail $oldalphaFileRootnameTail
    } else {
        set alphaFileRootname [file rootname ${filename}]
        set alphaFileRootnameTail [file tail ${alphaFileRootname}]
    }

    if {$statusCallback!=""} {
        $statusCallback "File $alphaFileRootname chosen."
    }

    if [catch {exec sddsconvert ${alphaFileRootname}.sdds -pipe=out -topage=1 \
                 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    EnableButtons

    return 1
}

# Procedure to perform the scraper scan.
# Returns 1 when completed.

proc PerformScraperScan {args} {
    global CTRSystem
    global directory ScraperPositionLowLimit ScraperPositionHighLimit scraperFileRootname
    global IntegLimit scraperFileRootnameTail
      
    APSStrictParseArguments {statusCallback steps}
    
    if {$steps<2} {
        if {$statusCallback!=""} {
            $statusCallback "Number of steps must be an integer > 1."
        }
        return 0
    }

    set steps [expr int(${steps}) / 1.0]

    DisableButtons

    set scraperFileRootname ${directory}/ScraperScan-[APSOffsetDateInfo -today 1 -dateFormat Y-M-D]_[lindex [exec date] 3]
    set scraperFileRootnameTail [file tail $scraperFileRootname]

    set dataFileList ""
    set scraperIncrement [expr (${ScraperPositionHighLimit} - ${ScraperPositionLowLimit}) / ${steps}]
    set scraperPosition ${ScraperPositionLowLimit}

    for {set index 1} {$index<=[expr ${steps} + 1]} {incr index} {
        exec cavput -list=L1:SCR:XL:motorSM=${scraperPosition} -pendIoTime=20
        if {$index==1} {
            after 5000
        } else {
            after 3000
        }
        set scraperPos [exec cavget -list=L1:SCR:XL:positionCC -pendIoTime=20]
        if {$statusCallback!=""} {
            $statusCallback "Scraper position = ${scraperPos} cm."
        }

        exec sddswmonitor -PVnames=${CTRSystem}:CTR:WF:timeScaleWF,${CTRSystem}:CTR:WF:scaledDataWF \
          ${scraperFileRootname}_${index}.sdds -step=1 -accumulate=average,number=10 -scalars=${directory}/${CTRSystem}CTRMonitor.mon -comment=CTRSystem,$CTRSystem
        lappend dataFileList ${scraperFileRootname}_${index}.sdds
        set scraperPosition [expr $scraperPosition + ${scraperIncrement}]
    }

    if {$statusCallback!=""} {
        $statusCallback "Scraper scan completed.  Collecting and processing data..."
    }
    
    eval exec sddscombine $dataFileList ${scraperFileRootname}.sdds -overWrite
    eval exec rm $dataFileList

    if {$statusCallback!=""} {
        $statusCallback "Done."
    }

# Process and plot the scraper scan data.

    ProcessScraperScanData -statusCallback SetStatus
    PlotScraperScanRawAndProcessedData -statusCallback SetStatus

    EnableButtons

    return 1
}

# Procedure to process the scraper scan data.
# Returns 1 when completed.

proc ProcessScraperScanData {args} {
 
    global directory ScraperPositionLowLimit ScraperPositionHighLimit scraperFileRootname scraperFileRootnameTail
    global IntegLimit UpperFitLimit LowerFitLimit CTRSystem
      
    APSStrictParseArguments {statusCallback}

    DisableButtons

    if {$statusCallback!=""} {
        $statusCallback "Processing scraper scan data..."
    }
    if [catch {exec sddsconvert ${scraperFileRootname}.sdds -pipe=out \
                 -topage=1 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    exec sddsprocess -pipe=out ${scraperFileRootname}.sdds \
      "-print=param,ScraperReadbackString,%0.2f %s,L1ScraperReadback,L1ScraperReadback.units" \
      "-redefine=col,${CTRSystem}:CTR:WF:timeScaleWF,${CTRSystem}:CTR:WF:timeScaleWF,units=ms,symbol=Time" \
      "-redefine=col,${CTRSystem}:CTR:WF:scaledDataWF,${CTRSystem}:CTR:WF:scaledDataWF,units=Volts" \
      "-reprint=param,Filename,${scraperFileRootnameTail}.sdds,type=string" \
      | sddssmooth -pipe \
      -col=${CTRSystem}:CTR:WF:scaledDataWF \
      -pass=0 -despike=neighbors=5,average=5,passes=5 \
      | sddsprocess -pipe=in ${scraperFileRootname}_Proc.sdds \
      -process=${CTRSystem}:CTR:WF:scaledDataWF,baselevel,CTRBaselevel \
      "-redefine=col,${CTRSystem}:CTR:WF:scaledDataWF,${CTRSystem}:CTR:WF:scaledDataWF CTRBaselevel -,units=Volts" \
      -process=${CTRSystem}:CTR:WF:scaledDataWF,maximum,CTRMax \
      -process=${CTRSystem}:CTR:WF:scaledDataWF,maximum,CTRMaxTime,functionOf=${CTRSystem}:CTR:WF:timeScaleWF,position

    exec sddscollapse -pipe=out ${scraperFileRootname}_Proc.sdds \
      | sddsprocess -pipe=in /tmp/Scraper_proc.sdds \
      -process=CTRMax,maximum,CTRPeakTime,functionOf=CTRMaxTime,position

    set CTRPeak [exec sdds2stream -param=CTRPeakTime /tmp/Scraper_proc.sdds]

    exec rm /tmp/Scraper_proc.sdds

    exec sddsprocess ${scraperFileRootname}_Proc.sdds ${scraperFileRootname}_Integ.sdds \
      -filter=col,${CTRSystem}:CTR:WF:timeScaleWF,${CTRPeak},${IntegLimit} \
      -process=${CTRSystem}:CTR:WF:scaledDataWF,sum,CTRSum \
      "-redefine=param,L1CM2,L1CM2 abs,units=nC" \
      "-redefine=param,L3CM1,L1CM2 abs,units=nC" \
      "-redefine=param,L5CM1,L1CM2 abs,units=nC"

    if {![string compare $CTRSystem L2]} {
        set currMonitor L1CM2
    } elseif {![string compare $CTRSystem L3]} {
        set currMonitor L3CM1
    } else {
        exec sddscollapse -pipe=out ${scraperFileRootname}_Integ.sdds \
          | sddsprocess -pipe -filter=col,L1CM2,${LowerFitLimit},${UpperFitLimit} \
          | sddspfit -pipe=in ${scraperFileRootname}_FitCTRInteg.sdds \
          -col=L1CM2,CTRSum -orders=1,2 -generate \
          -evaluate=${scraperFileRootname}_FitCTRIntegEval.sdds,begin=${LowerFitLimit},end=${UpperFitLimit},number=100
    }
    exec sddscollapse -pipe=out ${scraperFileRootname}_Integ.sdds \
      | sddsprocess -pipe -filter=col,${currMonitor},${LowerFitLimit},${UpperFitLimit} \
      | sddspfit -pipe=in ${scraperFileRootname}_FitCTRInteg.sdds \
      -col=${currMonitor},CTRSum -orders=1,2 -generate \
      -evaluate=${scraperFileRootname}_FitCTRIntegEval.sdds,begin=${LowerFitLimit},end=${UpperFitLimit},number=100

    if {$statusCallback!=""} {
        $statusCallback "Done."
    }

    EnableButtons

    return 1
}

# Procedure to pick a scraper scan file for processing and/or plotting.
# Returns 1 when completed.

proc PickScraperScanRawAndProcessedDataFile {args} {

    global directory scraperFileRootname scraperFileRootnameTail CTRSystem

    APSStrictParseArguments {statusCallback}

    DisableButtons

    if {$statusCallback!=""} {
        $statusCallback "Pick alpha magnet scan data file for processing and/or plotting..."
    }

    set oldscraperFileRootname ${scraperFileRootname}
    set oldscraperFileRootnameTail ${scraperFileRootnameTail}

    set filename [APSFileSelectDialog .fileSelectWidget \
                    -path $directory \
                    -pattern ScraperScan-*:??.sdds \
                    -contextHelp "File select dialog to choose scraper scan data file."]

    if {![string compare $filename ""]} {
        set scraperFileRootname $oldscraperFileRootname
        set scraperFileRootnameTail $oldscraperFileRootnameTail
    } else {
        set scraperFileRootname [file rootname ${filename}]
        set scraperFileRootnameTail [file tail ${scraperFileRootname}]
    }

    if {$statusCallback!=""} {
        $statusCallback "File $scraperFileRootname chosen."
    }
    
    if [catch {exec sddsconvert ${scraperFileRootname}.sdds -pipe=out \
                 -topage=1 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    EnableButtons

    return 1
}

# Procedure plots CTR waveform.
# Returns 1 when completed.

proc PlotAlphaMagnetScanRawAndProcessedData {args} {
    
    global directory alphaFileRootname IntegLimit CTRSystem
    global alphaFileRootnameTail

    APSStrictParseArguments {statusCallback}

    DisableButtons

    if [file exists ${alphaFileRootname}.sdds] {
        ProcessAlphaMagnetScanData -statusCallback SetStatus
        if {$statusCallback!=""} {
            $statusCallback "Plotting alpha magnet scan data..."
        }
    } else {
        if {$statusCallback!=""} {
            $statusCallback "Pick a valid alpha magnet scan data file."
        }
        EnableButtons
        return 0
    }
    
    if [catch {exec sddsconvert ${alphaFileRootname}.sdds -pipe=out -topage=1 \
                 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    catch {exec sddsplot -title=@Filename -graph=line,vary -split=page -legend=parameter=AlphaCurrSetString \
             "-yLabel=CTRMonitor Reading (Volts)" \
             ${alphaFileRootname}_Proc.sdds \
             "-topline=CTR Monitor Reading for Various Alpha Magnet Currents" \
             -col=${CTRSystem}:CTR:WF:timeScaleWF,${CTRSystem}:CTR:WF:scaledDataWF \
             "-string=\$s5\$e,x=$IntegLimit,y=0,scale=1,justify=rc,angle=90,linetype=4" \&}

    if {![string compare $CTRSystem L2]} {
        set currMonitor L1CM2
        set bpm L2P1
    } elseif {![string compare $CTRSystem L3]} {
        set currMonitor L3CM1
        set bpm L3P2
    } else {
        catch {exec sddsplot -title=@Filename -graph=symbol,scale=2,subtype=1 \
                 -param=Alpha1CurrentSetpoint,L2P1Sum ${alphaFileRootname}_Integ.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=L2:P1 Sum Signal (Amperes)" \
                 "-topline=L2:P1 Sum Signal vs Alpha Magnet Current" -end \
                 -param=Alpha1CurrentSetpoint,CTRSum ${alphaFileRootname}_Integ.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=CTR Integrated and Processed Signal (V ms)" \
                 "-topline=CTR Integrated and Processed Signal vs Alpha Magnet Current" -end \
                 -param=Alpha1CurrentSetpoint,CTRWFIntegral ${alphaFileRootname}_Proc.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=CTR Waveform Integrated Signal (Volts)" \
                 "-topline=CTR Waveform Integrated Signal vs Alpha Magnet Current" \&}
        return 1
    }
        catch {exec sddsplot -title=@Filename -graph=symbol,scale=2,subtype=1 \
                 -param=Alpha1CurrentSetpoint,${currMonitor} ${alphaFileRootname}_Integ.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=${currMonitor} Charge Signal (nC)" \
                 "-topline=${currMonitor} Charge Signal vs Alpha Magnet Current" -end \
                 -param=Alpha1CurrentSetpoint,${bpm}Sum ${alphaFileRootname}_Integ.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=${bpm} Sum Signal (Amperes)" \
                 "-topline=${bpm} Sum Signal vs Alpha Magnet Current" -end \
                 -param=Alpha1CurrentSetpoint,CTRSum ${alphaFileRootname}_Integ.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=CTR Integrated and Processed Signal" \
                 "-topline=CTR Integrated and Processed Signal vs Alpha Magnet Current" -end \
                 -param=Alpha1CurrentSetpoint,CTRWFIntegral ${alphaFileRootname}_Proc.sdds \
                 "-xLabel=Alpha Magnet Current (Amperes)" "-yLabel=CTR Waveform Integrated Signal (Volts)" \
                 "-topline=CTR Waveform Integrated Signal vs Alpha Magnet Current" \&}
    
if {$statusCallback!=""} {
        $statusCallback "Done."
    }
    
    EnableButtons

    after 5000
    eval exec rm [glob ${directory}/*Scan-*_*_*.sdds]
    return 1
}

# Procedure plots CTR waveform.
# Returns 1 when completed.

proc PlotScraperScanRawAndProcessedData {args} {
    
    global directory scraperFileRootname IntegLimit
    global scraperFileRootnameTail

    APSStrictParseArguments {statusCallback}

    DisableButtons

    
    if [file exists ${scraperFileRootname}.sdds] {
        ProcessScraperScanData -statusCallback SetStatus
        if {$statusCallback!=""} {
            $statusCallback "Plotting scraper scan data..."
        }
    } else {
        if {$statusCallback!=""} {
            $statusCallback "Pick a valid scraper scan data file."
        }
        EnableButtons
        return 0
    }

    if [catch {exec sddsconvert ${scraperFileRootname}.sdds -pipe=out -topage=1 \
                 | sdds2stream -pipe -parameter=CTRSystem} CTRSystem] {
        set CTRSystem LI
    }

    catch {exec sddsplot -title=@Filename -legend=parameter=ScraperReadbackString -graph=line,vary -split=page \
             "-yLabel=CTRMonitor Reading (Volts)" ${scraperFileRootname}_Proc.sdds \
             "-topline=CTR Monitor Reading for Various Scraper Positions" \
             -col=${CTRSystem}:CTR:WF:timeScaleWF,${CTRSystem}:CTR:WF:scaledDataWF \
             "-string=\$s5\$e,x=$IntegLimit,y=0,scale=1,justify=rc,angle=90,linetype=4" \&}
             
    if {![string compare $CTRSystem L2]} {
        set currMonitor L1CM2
        set bpm L2P1
    } elseif {![string compare $CTRSystem L3]} {
        set currMonitor L3CM1
        set bpm L3P2
    } else {
        catch {exec sddsplot -title=@Filename -graph=symbol,scale=2,subtype=1 \
                 -param=L1ScraperReadback,CTRSum ${scraperFileRootname}_Integ.sdds \
                 "-xLabel=Scraper Position (cm)" "-yLabel=Integrated CTR Signal (Volts)" \
                 "-topline=Integrated CTR Signal vs Scraper Position" -end \
                 -param=L1ScraperReadback,L2P1Sum ${scraperFileRootname}_Integ.sdds \
                 "-xLabel=Scraper Position (cm)" "-yLabel=L2P1 Sum Signal (Amperes)" \
                 "-topline=L2P1 Sum Signal vs Scraper Position" -end \
                 -param=L1ScraperReadback,L1CM2 ${scraperFileRootname}_Integ.sdds \
                 "-xLabel=Scraper Position (cm)" "-yLabel=L1CM2 Charge Signal (nC)" \
                 "-topline=L1CM2 Charge Signal vs Scraper Position" \&}
        catch {exec sddsplot -title=${scraperFileRootnameTail} \
                 -col=L1CM2,CTRSum ${scraperFileRootname}_FitCTRInteg.sdds -legend=specified=Data \
                 -graph=symbol,scale=2,subtype=1 \
                 -col=L1CM2,CTRSum ${scraperFileRootname}_FitCTRIntegEval.sdds -legend=specified=Fit \
                 "-xLabel=L1CM2 Charge Signal (nC)" "-yLabel=Integrated CTR Signal (Volts)" \
                 "-topline=Integrated CTR Signal vs L1CM2 Charge Signal" \&}
    }
    catch {exec sddsplot -title=@Filename -graph=symbol,scale=2,subtype=1 \
             -param=L1ScraperReadback,CTRSum ${scraperFileRootname}_Integ.sdds \
             "-xLabel=Scraper Position (cm)" "-yLabel=Integrated CTR Signal (Volts)" \
             "-topline=Integrated CTR Signal vs Scraper Position" -end \
             -param=L1ScraperReadback,${bpm}Sum ${scraperFileRootname}_Integ.sdds \
             "-xLabel=Scraper Position (cm)" "-yLabel=${bpm} Sum Signal (Amperes)" \
             "-topline=L2P1 Sum Signal vs Scraper Position" -end \
             -param=L1ScraperReadback,${currMonitor} ${scraperFileRootname}_Integ.sdds \
             "-xLabel=Scraper Position (cm)" "-yLabel=${currMonitor} Charge Signal (nC)" \
             "-topline=${currMonitor} Charge Signal vs Scraper Position" \&}
    catch {exec sddsplot -title=${scraperFileRootnameTail} \
             -param=${currMonitor},CTRSum ${scraperFileRootname}_Integ.sdds -legend=specified=Data \
             -graph=symbol,scale=2,subtype=1 \
             -col=${currMonitor},CTRSum ${scraperFileRootname}_FitCTRIntegEval.sdds -legend=specified=Fit \
             "-xLabel=${currMonitor} Charge Signal (nC)" "-yLabel=CTR Integrated and Processed Signal (V ms)" \
             "-topline=CTR Integrated and Processed Signal vs ${currMonitor} Charge Signal" \&}

    if {$statusCallback!=""} {
        $statusCallback "Done."
    }

    EnableButtons
    after 5000
    eval exec rm [glob ${directory}/*Scan-*_*_*.sdds]
    return 1
}

# Procedure to acquire and process the autocorrelation scan data.

proc AcquireAndProcessAutocorrelation {args} {

    global lowFreqLimit highFreqLimit fileRootname totalCharge totalMacroPulseLength CTRSystem baseSubtract

    APSStrictParseArguments {statusCallback}

    if {$statusCallback!=""} {
        $statusCallback "Acquiring autocorrelation data."
    }

    exec sddswmonitor -steps=1 -PVnames=${CTRSystem}:CTR:scanPositionsWF,${CTRSystem}:CTR:scanDataWF,${CTRSystem}:CTR:fftResultWF,${CTRSystem}:CTR:scanSC.D2DA,${CTRSystem}:CTR:scanSC.D3DA ${fileRootname}.sdds -comment=CTRSystem,$CTRSystem

    if $baseSubtract {
        if [catch {exec sddsbaseline ${fileRootname}.sdds ${fileRootname}.base -col=${CTRSystem}:CTR:scanDataWF \
                     -select=endpoints=5 -method=fit} result] {
            return -code error "error (1): $result"}
        if {$statusCallback!=""} {
            $statusCallback "Plotting raw autocorrelation data with baseline subtracted."
        }
        set baseFile ${fileRootname}.base
    } else {
        if {$statusCallback!=""} {
            $statusCallback "Plotting raw autocorrelation data."
        }
        set baseFile ${fileRootname}.sdds
    }

    catch {exec sddsplot -title=$fileRootname -col=${CTRSystem}:CTR:scanPositionsWF,${CTRSystem}:CTR:scanDataWF \
             -sep=nameIndex $baseFile \
             -col=${CTRSystem}:CTR:scanPositionsWF,${CTRSystem}:CTR:scanDataWF $baseFile \
             -graph=symbol,scale=2 "-topline=Raw AutoCorrelation Data" -end \
             -col=${CTRSystem}:CTR:scanPositionsWF,${CTRSystem}:CTR:scanSC.D2DA -graph=line,type=0 \
             -sep=nameIndex -legend=specified=L2P1 $baseFile \
             -col=${CTRSystem}:CTR:scanPositionsWF,${CTRSystem}:CTR:scanSC.D3DA -graph=line,type=1 \
             -legend=specified=L2P2 "-topline=BPM Data During Autocorrelation Scan" $baseFile \&}

    if {$statusCallback!=""} {
        $statusCallback "Processing autocorrelation data.  This will take a while."
    }
    
    APSExecLog [APSUniqueName .] \
      -unixCommand "processCTRIFScan -fileRoot $fileRootname -totalCharge $totalCharge -lowFreqFitLimit $lowFreqLimit -highFreqFitLimit $highFreqLimit -totalMacroPulseLength $totalMacroPulseLength -plotOnly 0 -baseSubtract $baseSubtract"
    
    return 1
}

set AlphaCurrentLowLimit 117
set AlphaCurrentHighLimit 137
set L1PhaseLowLimit 8.3
set L1PhaseHighLimit 6.3
set AlphaScanSteps 20
set alphaFilenameList [glob ${directory}/AlphaScan-*:??.sdds -nocomplain]
set alphaFileRootname [file rootname [lindex $alphaFilenameList [expr [llength ${alphaFilenameList}] - 1]]]
set alphaFileRootnameTail [file tail $alphaFileRootname]
set ScraperPositionLowLimit 9.5
set ScraperPositionHighLimit 12.0
set ScraperScanSteps 20
set IntegLimit 4
set UpperFitLimit 2.75
set LowerFitLimit 0.75
set scraperFilenameList [glob ${directory}/ScraperScan-*:??.sdds -nocomplain]
set scraperFileRootname [file rootname [lindex $scraperFilenameList [expr [llength ${scraperFilenameList}] - 1]]]
set scraperFileRootnameTail [file tail $scraperFileRootname]
set lowFreqLimit 0.002
set highFreqLimit 0.004
set baseSubtract 1
set totalCharge 3000.0
set totalMacroPulseLength 12.0
set fileRootname AutoScanData01
MakeScanStatusWidget .userFrame .
MakeScanWidgets .dataProcEntries .scanEntries .scraperEntries .removeEntries -parent .userFrame
