#!/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)]

set ControlStatus "Ready."
set CVSRevisionAuthor "\$Revision: 1.14 $ \$Author: shang $"

set directory /home/helios/oagData/booster/BMagFFTData

set allowedAccountList "booster sereno juw hillmana pasky asdops"
# set directory ./
# Make the menu and status for the FFT monitor application.
set sparseInterval 5
proc MakeBoosterFFTMenuAndStatus {} {
        
    global ControlStatus CVSRevisionAuthor
    
    APSApplication . -name "Booster Magnet FFT Monitor" -version "$CVSRevisionAuthor (sereno)" \
      -overview "Booster magnet fft monitoring."
    
    APSScrolledStatus .status -parent .userFrame -textVariable ControlStatus -width 65 -packOption {-side top}
}

# Make the booster magnet control frame and associated widgets.

proc MakeBoosterMagnetControlFrameWidget {widget args} {

    global ControlStatus
    set parent ""
    APSParseArguments {parent}

    APSFrame $widget -parent $parent -label "Booster Magnet Output Voltage FFT Application." \
      -height 30 \
      -packOption {-side left -expand 1}
    
    set w $parent$widget.frame
    MakeBooMagFFTFrameWidget -parent $w
}

# Make widgets to acquire and plot the data.

proc MakeBooMagFFTFrameWidget {args} {

    global ControlStatus directory BM QF QD SF SD SFU SDU
    set parent ""
    APSStrictParseArguments {parent}
    set BM 1
    set QF 1
    set QD 1
    set SF 0 
    set SD 0
    set SFU 1
    set SDU 1

    APSButton .bm -parent $parent \
      -text "Acquire Voltage Waveform Data." \
      -command {BooMagFFTAnalysis -statusCallback SetStatus -BM $BM -QF $QF -QD $QD -SF $SF -SD $SD -SFU $SFU -SDU $SDU} \
      -packOption {-side top -expand 1} \
      -contextHelp "This button acquires booster magnet ramp data."

    APSButton .plotBetaFrame -parent $parent \
      -text "Plot Booster Magnet Voltage Waveform Data." \
      -command {PlotBoosterMagnetData -statusCallback SetStatus -BM $BM -QF $QF -QD $QD -SF $SF -SD $SD -SFU $SFU -SDU $SDU} \
      -packOption {-side top -expand 1} \
      -contextHelp "This button performs an fft on selected booster magnet voltage ramp data and plots the results."

    APSButton .setreferencewaveforms -parent $parent \
      -text "Set Reference Waveform File" \
      -command "setReferenceWaveforms -statusCallback SetStatus" \
      -packOption "-side top" \
      -contextHelp "This button is used to set and define the reference waveform file use for comparison purposes."
    global sparseInterval
    APSLabeledEntry .inteval -parent $parent -label "Sparse Interval:" \
      -textVariable sparseInterval -width 50 \
      -contextHelp "Interval to sparse the raw waveform (default is 5 point sparsing)."
    frame .selectMagnetsFrame 
    pack .selectMagnetsFrame -in $parent
    APSCheckButtonFrame .chooseMagnets -parent .selectMagnetsFrame \
      -label "Select Magnets" -orientation horizontal \
      -buttonList {"BM  " "QF  " "QD  " "SF  " "SD  " "SFU " "SDU "} -variableList "BM QF QD SF SD SFU SDU" \
      -allNone 1 -contextHelp "Click to choose which magnets to plot."
}

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

# Acquire booster magnet power supply voltage waveform data.

proc BooMagFFTAnalysis {args} {
        
    global ControlStatus directory sparseInterval
    APSStrictParseArguments {statusCallback BM QF QD SF SD SFU SDU}
        
    $statusCallback "Acquiring booster magnet data..."

    set dataFileUniqueLabel [APSOffsetDateInfo -today 1 -dateFormat Y-M-D]_[lindex [exec date] 3]
    
    if [catch {exec BRampWaveformMon -sparseInterval $sparseInterval -filename  ${directory}/BVoltData_${dataFileUniqueLabel}.sdds} result] {
	$statusCallback "Error in collecting waveform data: $result"
	return 0
    }
    if [catch {exec sddsconvert ${directory}/BVoltData_${dataFileUniqueLabel}.sdds -retain=col,*vout,time} result] {

    }
    catch {exec rm ${directory}/BVoltData_${dataFileUniqueLabel}.sdds~}
    $statusCallback "Done.  File is BVoltData_${dataFileUniqueLabel}.sdds."
    catch {exec gzip ${directory}/BVoltData_${dataFileUniqueLabel}.sdds}
    PlotBoosterMagnetData -dataFile ${directory}/BVoltData_${dataFileUniqueLabel}.sdds.gz \
      -statusCallback SetStatus -BM $BM -QF $QF -QD $QD -SF $SF -SD $SD -SFU $SFU -SDU $SDU
    return 1
}

# Set the reference waveform file.

proc setReferenceWaveforms {args} {
    
    global refdirectory directory allowedAccountList

    APSParseArguments {statusCallback}

    set currentUserAccount [exec whoami]
    if {![string compare [lsearch -exact $allowedAccountList $currentUserAccount] -1]} {
        if {$statusCallback!=""} {
            $statusCallback "Account $currentUserAccount does not have permission to change\nthe reference ramp file."
            $statusCallback "Accounts with permission are $allowedAccountList."
        }
        return 0
    }

    if {$statusCallback!=""} {
        $statusCallback "Select a file to define as the waveform reference file."
    }

    set dataFile [APSFileSelectDialog .dataFileSelectWidget \
                    -path ${directory} \
                    -pattern BVoltData*.gz* \
                    -title "Voltage Waveform data file selection"]
    #modifed to use link for reference file instead of make new file
    if {[file exists $dataFile]} {
        set oldDir [pwd]
        cd $refdirectory
        if [file exist [file tail $dataFile]] {
            exec rm [file tail $dataFile]
        }
        exec cp $dataFile [file tail $dataFile]
        if [file exist BVoltDataReference.gz] {
            exec rm BVoltDataReference.gz
        }
        exec ln -s [file tail $dataFile] BVoltDataReference
        exec mv BVoltDataReference BVoltDataReference.gz
        if {$statusCallback!=""} {
            $statusCallback "Reference file was linked to [file tail $dataFile]."
        }
        cd $oldDir
    } else {
        if {$statusCallback!=""} {
            $statusCallback "No file selected.  Please select a valid file."
        }
    }

    return
    if {[file exists ${refdirectory}/BVoltDataReference-0001.gz]} {
        set referenceFileList [lsort [glob ${refdirectory}/BVoltDataReference-????.gz]]
        set currentReferenceFile [lindex $referenceFileList [expr [llength $referenceFileList] - 1]]
        set currentReferenceIndex [scan [lindex [split [lindex [split $currentReferenceFile "-"] 1] "."] 0] %ld]
        set newReferenceIndex [format %04ld [expr $currentReferenceIndex + 1]]
        set newReferenceFile ${refdirectory}/BVoltDataReference-${newReferenceIndex}.gz
    } else {
        set newReferenceFile ${refdirectory}/BVoltDataReference-0001.gz
    }

    if {[file exists ${refdirectory}/BVoltDataReference.gz]} {
        exec rm ${refdirectory}/BVoltDataReference.gz
    }

    if {[file exists $dataFile]} {
        exec cp $dataFile $newReferenceFile
        set newReferenceFileRoot [file tail $newReferenceFile]
        exec ln -s $newReferenceFileRoot BVoltDataReference
        exec mv BVoltDataReference ${refdirectory}/BVoltDataReference.gz
        if {$statusCallback!=""} {
            $statusCallback "Reference file $newReferenceFile created."
        }
    } else {
        if {$statusCallback!=""} {
            $statusCallback "No file selected.  Please select a valid file."
        }
    }
    return 1
}

# Plot selected booster magnet data for both time domain and fft.
# Return 1 when finished.  Return 0 if no file is selected.

proc PlotBoosterMagnetData {args} {

    global ControlStatus refdirectory directory

    set dataFile ""
    APSStrictParseArguments {dataFile statusCallback BM QF QD SF SD SFU SDU}

    set referenceFile ${refdirectory}/BVoltDataReference.gz

    if {![string compare $dataFile ""]} { 
        set fileLabelList [lsort [glob -nocomplain ${directory}/BVoltData_*]]
	set fileTailList ""
	foreach fileLabel $fileLabelList {
	    append fileTailList "[string range [file tail $fileLabel] 10 28] "
	}
        set dataFileList [APSChooseItemFromList \
                            -name "File Label Selection" \
                            -itemList $fileTailList \
                            -returnList $fileLabelList \
                            -returnIndices 0 \
                            -multiItem 1 \
                            -contextHelp "Selected data file for plotting."]
    } else {
        set dataFileList $dataFile
    }
    
    set deleteColumns ""
    set deleteColumns2 ""
    set yList ""
    set yFFTList ""
    foreach var {BM QF QD SF SD SFU SDU}  magnet {BM QF QD SF SD SF-U SD-U} {
	if {![set $var]} {
	    set deleteColumns "| sddsconvert -pipe -delete=columns"
	    append deleteColumns2 ",${magnet}vout"
	} else {
	    if {[string compare $yList ""]==0} {
		append yList "${magnet}vout"
		append yFFTList "FFT${magnet}vout"
	    } else {
		append yList ",${magnet}vout"
		append yFFTList ",FFT${magnet}vout"
	    }
	} 
    }
    if {[string compare $yList ""]==0} {
	$statusCallback "No magnets selected."
        return 0
    }
    foreach dataFile $dataFileList {
	$statusCallback "Plotting data in file [file tail $dataFile]..."
    }
    if {[llength $dataFileList]==0} {
	$statusCallback "No file selected.  Select a file to plot."
	return 0
    }

    set tempFile /tmp/[APSTmpString]
    APSAddToTempFileList $tempFile ${tempFile}1 ${tempFile}2 ${tempFile}3 ${tempFile}4
   
    if [catch {eval exec sddscombine $dataFileList -pipe=out ${deleteColumns}${deleteColumns2} \
                 | sddsprocess -pipe=in $tempFile -edit=parameter,FileNameTime,Filename,1Z_S/.sdds/5k } result] {
        return -code error "PlotBoosterMagnetData(1): $result"
    }
    
    set opt ""
    lappend opt "-redefine=col,BMvout,BMvout BMvSlope time * BMvIntercept + -"
    lappend opt "-redefine=col,QFvout,QFvout QFvSlope time * QFvIntercept + -"
    lappend opt "-redefine=col,QDvout,QDvout QDvSlope time * QDvIntercept + -"
    lappend opt "-redefine=col,SFvout,SFvout SFvSlope time * SFvIntercept + -"
    lappend opt "-redefine=col,SDvout,SDvout SDvSlope time * SDvIntercept + -" 
    set oldOpt $opt
    lappend opt "-redefine=col,SF-Uvout,SF-Uvout SF-UvSlope time * SF-UvIntercept + -"
    lappend opt "-redefine=col,SD-Uvout,SD-Uvout SD-UvSlope time * SD-UvIntercept + -" 
   
    if [catch {eval exec sddsprocess $tempFile -pipe=out -filter=col,time,25,250  $opt \
                 | sddsprocess -pipe \
                 \"-redefine=col,time,time 1.0e-3 *,units=s\" \
                 | sddsfft -pipe "-col=time,*vout" -suppress -window -truncate \
                 | sddsprocess -pipe -filter=col,f,50,1000 \
                 | sddsxref -pipe=in $tempFile ${tempFile}1 -transfer=parameter,FileNameTime -leave=* } result] {
        return -code error "PlotBoosterMagnetData(2): $result"
    }
    set cols [exec sddsquery -col $referenceFile]
    if [lsearch -exact $cols "SF-Uvout"]>=0 {
        set option $opt
    } else {
        set option $oldOpt
    }
   
    if [catch {eval exec sddsprocess  $referenceFile -pipe=out -filter=col,time,25,250 \
                 $option \
                 | sddsprocess -pipe \
                 \"-redefine=col,time,time 1.0e-3 *,units=s\" \
                 | sddsfft -pipe "-col=time,*vout" -suppress -window -truncate  \
                 | sddsprocess -pipe -filter=col,f,50,1000 \
                 | sddsxref -pipe=in $referenceFile ${tempFile}3 -transfer=parameter,FileNameTime -leave=* } result] {
        return -code error "PlotBoosterMagnetData(3): $result"
    }
    
    if [catch {eval exec sddsprocess $tempFile -pipe=out $opt \
                 | sddsprocess -pipe \
                 \"-redefine=col,time,time 1.0e-3 *,units=s\" \
                 | sddsfft -pipe "-col=time,*vout" -suppress -window -truncate \
                 | sddsprocess -pipe -filter=col,f,50,1000 \
                 | sddsxref -pipe=in $tempFile ${tempFile}2 -transfer=parameter,FileNameTime -leave=* } result] {
        return -code error "PlotBoosterMagnetData(4): $result"
    }
    if [catch {eval exec sddsprocess $referenceFile -pipe=out $option \
                 | sddsprocess -pipe \
                 \"-redefine=col,time,time 1.0e-3 *,units=s\" \
                 | sddsfft -pipe "-col=time,*vout" -suppress -window -truncate \
                 | sddsprocess -pipe -filter=col,f,50,1000 \
                 | sddsxref -pipe=in $referenceFile ${tempFile}4 -transfer=parameter,FileNameTime -leave=* } result] {
        return -code error "PlotBoosterMagnetData(5): $result"
    }
    
    if {[llength $dataFileList]==1} {
	exec sddsplot -groupBy=page,nameString -sep=nameString -split=page \
          "-topline=Full Time-range Booster Magnet Output Voltage FFT and Reference" \
          -graph=line,vary \
          "-col=f,($yFFTList)" ${tempFile}4 -legend=specified=Reference \
          -replicate=match=page \
          "-col=f,($yFFTList)" ${tempFile}2 -legend=specified=Selection \
          -title=@FileNameTime -topTitle \&
	
	exec sddsplot -groupBy=page,nameString -sep=nameString -split=page \
          "-topline=Booster 25 to 250 ms Ouput Voltage linear error FFT" \
          -graph=line,vary \
          "-col=f,($yFFTList)" ${tempFile}3 -legend=specified=Reference \
          -replicate=match=page \
          "-col=f,($yFFTList)" ${tempFile}1 -legend=specified=Selection \
          -title=@FileNameTime -topTitle \&
	
	exec sddsplot -groupBy=page,nameString -sep=nameString -split=page \
          "-topline=Booster Magnet Output Voltage and Reference" \
          -graph=line,vary \
          "-col=time,($yList)" $referenceFile -legend=specified=Reference \
          -replicate=match=page \
          "-col=time,($yList)" -title=@FileNameTime \
          -topTitle $tempFile -legend=specified=Selection \&
    } else {
	exec sddsplot -groupBy=nameString,page -sep=page -split=page \
          "-topline=Booster Magnet Output Voltage FFT and Reference" \
          -graph=line,vary \
          "-col=f,($yFFTList)" ${tempFile}4 -legend=specified=Reference \
          -replicate=match=page \
          "-col=f,($yFFTList)" ${tempFile}2 -legend=specified=Selection \
          -title=@FileNameTime -topTitle \&

	exec sddsplot -groupBy=nameString,page -sep=page -split=page \
          "-topline=Booster Magnet Output Voltage FFT for 0 to 250 ms and Reference" \
          -graph=line,vary \
          "-col=f,($yFFTList)" ${tempFile}3 -legend=specified=Reference \
          -replicate=match=page \
          "-col=f,($yFFTList)" ${tempFile}1 -legend=specified=Selection \
          -title=@FileNameTime -topTitle \&
	
	exec sddsplot -groupBy=nameString,page -sep=page -split=page \
          "-topline=Booster Magnet Output Voltage and Reference" \
          -graph=line,vary \
          "-col=time,($yList)" $referenceFile -legend=specified=Reference \
          -replicate=match=page \
          "-col=time,($yList)" $tempFile -legend=specified=Selection \
          -title=@FileNameTime -topTitle \&
    }

	
    $statusCallback "Done"
    return 1
}

# Build Application

MakeBoosterFFTMenuAndStatus
MakeBooMagFFTFrameWidget -parent .userFrame
set refdirectory /home/helios/oagData/booster/BMagFFTData/Reference
if {(![string compare $apsNetworkDomain "accel.ntw0rk"]) || (![string compare $apsNetworkDomain "aps4.anl.gov"])} {
    set directory /home/helios/oagData/booster/BMagFFTData
} else {
    set directory /tmp
}
