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

#
# $Log: not supported by cvs2svn $
# Revision 1.7  1998/10/27 17:25:08  soliday
# Grided all the widgets so they can't disappear when the window is resized.
#
# Revision 1.6  1998/08/06 20:15:47  borland
# Added -retain=column,Time option to sddsconvert in time-range finding
# code, so it runs faster.
#
# Revision 1.5  1998/08/06 20:13:04  borland
# Added sddsconvert -recover ahead of sddsprocess command that gets the
# start and end time.  For some reason, this is needed because the file
# updates while it is being read.
#
# Revision 1.4  1998/07/30 01:25:16  borland
# Fixed problem that occured when the log file only has one row.
#
# Revision 1.3  1998/07/23 22:44:45  borland
# Added -nocomplain option to glob.
#
# Revision 1.2  1998/07/07 18:15:53  borland
# Now displays files in sorted list.
#
# Revision 1.1  1998/06/25 21:51:41  borland
# First version per R. Soliday.
#
#

set CVSRevisionAuthor "\$Revision: 1.8 $ \$Author: emery $"

proc changeList {Plane directory} {
    set line 0
    .userFrame.list.listbox delete 0 end
    foreach file [lsort -decreasing [glob -nocomplain "$directory/sr.$Plane*.stats"]] {
        .userFrame.list.listbox insert $line [file tail $file]
        incr line
    }
    update
}

proc getDate {SelFile doubleClick} {
    global directory
    if {$doubleClick == 1} {
        if {$SelFile != ""} {
            if {[file exists $directory/$SelFile]} {
                global startYear startMonth startDay\
                  startLongHours startTimeStamp startTotalSec endYear endMonth\
                  endDay endLongHours endTimeStamp endTotalSec selectedFile
                if [catch {eval exec sddsconvert $directory/$SelFile -pipe=out -recover=clip \
                             -retain=column,Time \
                             | sddsprocess -pipe -clip=1,1,invert \
                             | sdds2stream -pipe=in -columns=Time} result] {
                    puts stderr "$directory/$SelFile"
                    APSSetVarAndUpdate status "getDate (1): $result"
                    return
                }
                set selectedFile $SelFile
                APSSetVarAndUpdate status "Selected $SelFile"
                set startTotalSec [lindex $result 0]
                set endTotalSec [lindex $result 1]
                if ![string length [string trim $endTotalSec]] {
                    set endTotalSec [clock seconds]
                }
                if [catch "exec timeconvert -seconds=$startTotalSec -script=start" commands] {
                    APSSetVarAndUpdate status "getDate (2): $commands"
                    return
                }
                eval $commands
                set startLongHours [format %.2d:%.2d:%.2d $startHours $startMinutes $startSeconds]
                if [catch "exec timeconvert -seconds=$endTotalSec -script=end" commands] {
                    APSSetVarAndUpdate status "getDate (3): $commands"
                    return
                }
                eval $commands
                set endLongHours [format %.2d:%.2d:%.2d $endHours $endMinutes $endSeconds]
            }
        }
    }
}

proc plot {args} {
    APSStrictParseArguments {Col SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    APSSetVarAndUpdate status "Plotting $SelFile"
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    set passed ""
    upvar $Col Column
    foreach Col [array names Column] {
        if {$Column($Col) == 1} {
            append passed "-columnNames=Time,$Col $Dir/$SelFile "
        }
    }
    if {$passed != ""} {
        APSExec -unixCommand "sddsplot -filter=column,Time,$starttime,$endtime\
             -sever=xgap=15 -tickSettings=xTime\
             -groupBy=nameString -separate=nameString $passed "  
        APSSetVarAndUpdate status Done
    } else {
        APSSetVarAndUpdate status "No columns chosen"
        return
    }
}

proc analyzeTimes {args} {
    APSStrictParseArguments {SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    APSSetVarAndUpdate status "Analyzing correction times in $SelFile"

    set maxInterval 20
    set tempfile /tmp/[APSTmpString]
    set file $Dir/$SelFile
    exec sddsprocess $file -pipe=out \
      -filter=column,Time,$starttime,$endtime \
      | sddsconvert -pipe=in $tempfile \
      -retain=col,Time,ElapsedTime,Step 
    exec sddsderiv $tempfile -pipe=out \
      -differentiate=ElapsedTime  -versus=Step \
      | sddsprocess -pipe \
      -define=col,TimeInterval,ElapsedTimeDeriv,symbol=TimeInterval,units=s \
      -filter=col,TimeInterval,0,$maxInterval \
      | sddsxref -pipe $tempfile -noWarning \
      -take=Time -equate=Step \
      | tee $tempfile.intervals \
      | sddshist -pipe=in $tempfile.hist \
      -data=TimeInterval -sizeofbin=0.05
    
    exec sddsplot \
      "-topline=Analysis of OC time interval for $SelFile" \
      -col=Time,TimeInterval $tempfile.intervals \
      -grap=dots -tick=xtime -end \
      -col=TimeInterval,frequency $tempfile.hist \
      -grap=impulse -axes=x \
      &
    
    APSSetVarAndUpdate status Done
    return
}

proc export {args} {
    APSStrictParseArguments {Col SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    APSSetVarAndUpdate status "Exporting $SelFile"
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    if [catch "exec timeconvert -seconds=$starttime -script=S" commands] {
        APSSetVarAndUpdate status "export:: $commands"
        return
    }
    eval $commands
    if [catch "exec timeconvert -seconds=$endtime -script=E" commands] {
        APSSetVarAndUpdate status "export:: $commands"
        return
    }
    eval $commands
    set start "$SYear $SMonth $SDay $SHours:$SMinutes:$SSeconds"
    set end "$EYear $EMonth $EDay $EHours:$EMinutes:$ESeconds"
    APSExec -unixCommand "sddsExportData -dataDirectory $Dir -dataFileList $SelFile\
	    -timeFilterStart \"$start\"\
	    -timeFilterEnd \"$end\""   
    APSSetVarAndUpdate status Done
}

proc quick {args} {
    APSStrictParseArguments {Col SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    APSSetVarAndUpdate status "Plotting $SelFile"
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    if [catch "exec timeconvert -seconds=$starttime -script=S" commands] {
        APSSetVarAndUpdate status "quick:: $commands"
        return
    }
    eval $commands
    if [catch "exec timeconvert -seconds=$endtime -script=E" commands] {
        APSSetVarAndUpdate status "quick:: $commands"
        return
    }
    eval $commands
    set start "$SYear $SMonth $SDay $SHours:$SMinutes:$SSeconds"
    set end "$EYear $EMonth $EDay $EHours:$EMinutes:$ESeconds"
    APSExec -unixCommand "quickSDDSplot -dataDirectory $Dir -dataFileList $SelFile\
	    -timeFilterStart \"$start\"\
	    -timeFilterEnd \"$end\""   
    APSSetVarAndUpdate status Done
}

proc displaytext {args} {
    APSStrictParseArguments {Col SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    APSSetVarAndUpdate status "Displaying $SelFile"
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    set fileName /tmp/[APSTmpString]
    upvar $Col Column
    foreach Col [array names Column] {
        if {$Column($Col) == 1} {
            set ColName ${Col}Name
            set passed "-columns=TimeText,format=%-30s -columns=$ColName,format=%25s -columns=$Col,format=%12.3f"
            set Title "$ColName displayed from orbit controllaw stats file $SelFile between\
		    [exec timeconvert -seconds=$starttime -textOutput] and\
		    [exec timeconvert -seconds=$endtime -textOutput]"
            APSAddToTempFileList $fileName.$Col $fileName.$Col.1	    
            APSExec -unixCommand "sddsprocess $Dir/$SelFile -pipe=out -filter=column,Time,$starttime,$endtime \
		    | sddstimeconvert -pipe -breakdown=column,Time,text=TimeText \
		    | tee $fileName.$Col \
		    | sddsprintout -pipe=in $fileName.$Col.1 $passed \"-title=$Title\"" \
              -callback "displaytextfinish -FileName $fileName.$Col"
        }
    }
    if {![info exists passed]} {
        APSSetVarAndUpdate status "No columns chosen"
    }
}

proc displaytextfinish {args} {
    APSStrictParseArguments {FileName}
    APSFileDisplayWindow [APSUniqueName .] -fileName $FileName.1 \
      -sddsExportableFile $FileName -width 90 -deleteOnClose 1
    APSSetVarAndUpdate status Done
}

proc findoccurrences {args} {
    APSStrictParseArguments {Col SelFile Dir}
    set times [Check -SelFile $SelFile -Dir $Dir]
    APSSetVarAndUpdate status "Displaying occurrences in $SelFile"
    set starttime [lindex $times 0]
    set endtime [lindex $times 1]
    set fileName /tmp/[APSTmpString]
    upvar $Col Column
    foreach Col [array names Column] {
        if {$Column($Col) == 1} {
            set ColName ${Col}Name
            set passed "-columns=IdenticalCount,format=%3d,label=Occurrences -columns=$ColName,format=%25s"
            set Title "Number of occurrences of $ColName displayed from orbit controllaw stats file $SelFile between\
		    [exec timeconvert -seconds=$starttime -textOutput] and\
		    [exec timeconvert -seconds=$endtime -textOutput]"
            APSAddToTempFileList $fileName $fileName
            APSExec -unixCommand "sddsprocess $Dir/$SelFile -pipe=out -filter=column,Time,$starttime,$endtime \
		    | sddssort -pipe -column=$ColName -unique=count \
                    | sddssort -pipe -column=IdenticalCount,decreasing \
		    | sddsprintout -pipe=in $fileName.$Col $passed \"-title=$Title\""\
              -callback "displaycountfinish -FileName $fileName.$Col"
        }
    }    
    if {![info exists passed]} {
        APSSetVarAndUpdate status "No columns chosen"
    }
}

proc displaycountfinish {args} {
    APSStrictParseArguments {FileName}
    APSFileDisplayWindow [APSUniqueName .] -fileName $FileName \
      -width 45 -deleteOnClose 1
    APSSetVarAndUpdate status Done
}

proc Check {args} {
    set SelFile ""
    set Dir ""
    APSStrictParseArguments {SelFile Dir}
    if {![string length $SelFile]} {
        APSSetVarAndUpdate status "Check: no file chosen"
        return -code return
    }   
    if {![file exists $Dir/$SelFile]} {
        APSSetVarAndUpdate status "Check: $Dir/$SelFile does not exist"
        return -code return
    }
    global startYear startMonth startDay\
      startLongHours startTotalSec endYear endMonth\
      endDay endLongHours endTotalSec
    set startHours [APSConvertTimeToHours $startLongHours]
    set endHours [APSConvertTimeToHours $endLongHours]
    update
    if [catch "exec timeconvert -breakDown=year=$startYear,month=$startMonth,day=$startDay,hour=$startHours" starttime] {
        APSSetVarAndUpdate status "Check: $starttime"
        return -code return
    }
    if [catch "exec timeconvert -breakDown=year=$endYear,month=$endMonth,day=$endDay,hour=$endHours" endtime] {
        APSSetVarAndUpdate status "Check: $endtime"
        return -code return
    }
    if {$starttime >= $endtime} {
        APSSetVarAndUpdate status "Check: Ending time of interest is earlier than Starting time of interest"
        return -code return
    } 
    if {[expr $startTotalSec - $starttime] < 1 && [expr $startTotalSec -$starttime] > -1} {
        set starttime $startTotalSec
    } elseif {$starttime < $startTotalSec} {
        APSSetVarAndUpdate status "Check: Starting time of interest is earlier than actual starting time"
        return -code return
    }
    if {[expr $endtime - $endTotalSec] < 1 && [expr $endtime -$endTotalSec] > -1} {
        set endtime $endTotalSec
    } elseif {$endtime > $endTotalSec} {
        APSSetVarAndUpdate status "Check: Ending time of interest is later than actual ending time"
        return -code return
    }
    return "$starttime $endtime"
}

APSApplication . -name "Storage Ring Orbit Control Program Statistics Logs Viewer" -version $CVSRevisionAuthor \
  -overview "Storage Ring Orbit Control Program Statistics Logs Viewer allows easy viewing of the data from the\
	storage ring orbit control program statistics logs"

set w .userFrame
set directory /home/helios/oagData/controllaw/SRorbit/loggedData
set Plane x
set filelist ""
set selectedFile ""
set startTotalSec ""
set endTotalSec ""
set pass {-startYear $startYear -startMonth $startMonth -startDay $startDay\
            -startLongHours $startLongHours -startTotalSec $startTotalSec\
            -endYear $endYear -endMonth $endMonth -endDay $endDay\
            -endLongHours $endLongHours -endTotalSec $endTotalSec}

set status Ready
APSScrolledStatus .scrolledstatus -parent $w \
  -textVariable status -height 6 \
  -packOption "-expand true -fill x" -noPack 1
grid $w.scrolledstatus -column 0 -row 0 -sticky nsew

APSScrolledList .list -parent $w -height 10 \
  -itemList $filelist -callback "getDate" -selectMode "single" \
  -contextHelp "Double click log file to select it" -noPack 1
grid $w.list -column 0 -row 1 -sticky nsew

APSRadioButtonFrame .plane -parent $w -label Plane \
  -variable Plane -buttonList "x y" -valueList "x y" \
  -orientation horizontal -commandList {"changeList $Plane $directory" "changeList $Plane $directory"} \
  -contextHelp "Choose x or y plane" -noPack 1
grid $w.plane -column 0 -row 2 -sticky w

set startTimeStamp ""
APSLabeledOutput .starting -parent $w -label "Starting time:" \
  -width 25 -textVariable startTimeStamp -packOption "-anchor w" \
  -contextHelp "Starting time of selected file" -noPack 1
grid $w.starting -column 0 -row 3 -sticky w

set endTimeStamp ""
APSLabeledOutput .ending -parent $w -label "  Ending time:" \
  -width 25 -textVariable endTimeStamp -packOption "-anchor w" \
  -contextHelp "Ending time of selected file" -noPack 1
grid $w.ending -column 0 -row 4 -sticky w

set startDay 1
set startMonth 1
set startYear 1
set startLongHours 1
set wst $w.startTimeFrame
frame $wst
APSDateTimeAdjEntry .startentry -parent $wst -dayVariable startDay \
  -monthVariable startMonth -yearVariable startYear -hourVariable startLongHours \
  -label "Set starting time of interest"
grid $wst -column 0 -row 5 -sticky w

set endDay 1
set endMonth 1
set endYear 1
set endLongHours 1
set wet $w.endTimeFrame
frame $wet
APSDateTimeAdjEntry .endentry -parent $wet -dayVariable endDay \
  -monthVariable endMonth -yearVariable endYear -hourVariable endLongHours \
  -label "  Set ending time of interest"
grid $wet -column 0 -row 6 -sticky w

set allcol "readbackRMS readbackAve readbackMAD readbackLargest readbackDeltaRMS\
	readbackDeltaAve readbackDeltaMAD readbackDeltaLargest controlRMS\
	controlAve controlMAD controlLargest controlDeltaRMS controlDeltaAve\
	controlDeltaMAD controlDeltaLargest"
foreach i $allcol {
    set col($i) 0
}

APSCheckButtonFrame .plotcolumns -parent $w \
  -label "Choose columns to plot" -limitPerRow 8 \
  -buttonList {readbackRMS readbackAve readbackMAD readbackLargest\
                 readbackDeltaRMS readbackDeltaAve readbackDeltaMAD "readbackDeltaLargest        "\
                 controlRMS controlAve controlMAD controlLargest controlDeltaRMS\
                 controlDeltaAve controlDeltaMAD "controlDeltaLargest   "} \
  -variableList "col(readbackRMS) col(readbackAve) col(readbackMAD) col(readbackLargest)\
	col(readbackDeltaRMS) col(readbackDeltaAve) col(readbackDeltaMAD) col(readbackDeltaLargest)\
	col(controlRMS) col(controlAve) col(controlMAD) col(controlLargest) col(controlDeltaRMS)\
	col(controlDeltaAve) col(controlDeltaMAD) col(controlDeltaLargest)" \
  -orientation vertical -allNone 1 \
  -contextHelp "Click on the columns to see them in the output plot" -noPack 1
grid $w.plotcolumns -column 0 -row 7 -sticky nsew

set wb1 $w.buttonFrame1
frame $wb1

APSButton .plotdata -parent $wb1 -text Plot \
  -command {plot -Col col -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to plot columns selected"

APSButton .quicksddsplot -parent $wb1 -text "quickSDDSplot..." \
  -command {quick -Col col -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to launch quickSDDSplot"

APSButton .exportdata -parent $wb1 -text "Export..." \
  -command {export -Col col -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to export SDDS file"
grid $wb1 -column 0 -row 8 -sticky w

APSButton .analTimes -parent $wb1 -text "Analyze correction times" \
  -command {analyzeTimes -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to analyze the correction times."

set allcol "readbackLargest readbackDeltaLargest controlLargest controlDeltaLargest"
foreach i $allcol {
    set colText($i) 0
}

APSCheckButtonFrame .displaytext -parent $w \
  -label "Choose columns to display" -limitPerRow 2 \
  -buttonList {readbackLargestName "readbackDeltaLargestName   "\
                 controlLargestName controlDeltaLargestName} \
  -variableList "colText(readbackLargest) colText(readbackDeltaLargest)\
	colText(controlLargest) colText(controlDeltaLargest)"\
  -orientation vertical -allNone 1 \
  -contextHelp "Click on the columns to see them in the printout" -noPack 1
grid $w.displaytext -column 0 -row 9 -sticky nsew

set wb2 $w.buttonFrame2
frame $wb2
APSButton .showtext -parent $wb2 -text "Display columns" \
  -command {displaytext -Col colText -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to display printout of selected columns and values"

APSButton .occurrences -parent $wb2 -text "Number of occurrences" \
  -command {findoccurrences -Col colText -SelFile $selectedFile -Dir $directory} \
  -contextHelp "Click to display the number of occurrences for the selected columns"
grid $wb2 -column 0 -row 10 -sticky w

grid columnconfigure $w 0 -weight 1
grid rowconfigure $w 1 -weight 1


changeList $Plane $directory
