#!/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.14 $ \$Author: soliday $"

set dataDir /home/helios/oagData/monitoring/SRH2O
cd $dataDir

proc AbsorberWaterReviewOverview {} {
    return "This is a utility for simple processing and display of data from the absorber water system."
        }

APSApplication . -name AbsorberWaterReview -version $CVSRevisionAuthor \
        -overview [AbsorberWaterReviewOverview]
set statusText "Ready."
APSScrolledStatus .status -parent .userFrame -textVariable statusText -width 60 \
    -height 3

proc SetStatusText {text} {
    global statusText 
    set statusText  "$text"
    update
}

proc MakeDateTimeFrame {widget args} {
    set parent .
    set rootname ""
    APSStrictParseArguments {parent rootname glitchMode}
    set label "Date/Time Range of Interest"

    APSFrame $widget -parent $parent -label $label
    set w $parent$widget.frame

    APSDateTimeAdjEntry .startDate -parent $w \
      -yearVariable ${rootname}StartYear \
      -monthVariable ${rootname}StartMonth \
      -dayVariable ${rootname}StartDay \
      -hourVariable ${rootname}StartHour \
      -label "Starting date/time (year, month, day, hour): " -defaultHour 0 \
      -command ResetDataFileList -buttonSize small
    APSDateTimeAdjEntry .endDate -parent $w \
      -yearVariable ${rootname}EndYear \
      -monthVariable ${rootname}EndMonth \
      -dayVariable ${rootname}EndDay \
      -hourVariable ${rootname}EndHour \
      -label "Ending date/time (year, month, day, hour):   " -defaultHour 24 \
      -command ResetDataFileList -buttonSize small

    SetDateTimeToToday -rootname ${rootname}Start -hour 0
    SetDateTimeToToday -rootname ${rootname}End  -hour 24
}

proc SetDateTimeToToday {args} {
    set rootname ""
    set hour 0
    ResetDataFileList
    APSStrictParseArguments {rootname hour}

    global ${rootname}Month ${rootname}Year ${rootname}Day ${rootname}Hour
    
    APSDateBreakDown -dayVariable ${rootname}Day -yearVariable ${rootname}Year \
      -monthVariable ${rootname}Month -twoDigitYear 0 -leadingZeros 0
    set ${rootname}Hour $hour
}

set dataFileList ""
set dataFileListIsOld 1
proc ResetDataFileList {} {
    global dataFileList  dataFileListIsOld
    set dataFileList ""
    set dataFileListIsOld 1
}

    
proc MakeSmoothWidget {widget args} {
    global doSmooth smoothPasses
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame ${widget} -parent $parent -label "" \
          -contextHelp "Controls for smoothing of data before display" -relief flat
    APSFrameGrid .fg -parent $parent${widget}.frame -xList {f1 f2}
    set w $parent${widget}.frame.fg
    APSRadioButtonFrame .onoff -parent $w.f1 -label Smooth \
          -variable doSmooth -buttonList {on off} -valueList {1 0} \
          -contextHelp "Turns smoothing on and off." -orientation horizontal
    APSLabeledEntry .passes -parent $w.f2 -label Passes: -width 4 \
          -textVariable smoothPasses -packOption "-expand 1 -side top" \
          -contextHelp "Enter the number of times the smoother will pass over the data."

}

proc MakeButtonRow {widget args} {
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label ""
    APSButton .plottemp -parent $parent$widget.frame \
      -text "Plot Temp." -command "PlotData Temp" \
      -contextHelp "Plots temperature data and beam current for the range of days specified."
    APSButton .plotdtemp -parent $parent$widget.frame \
      -text "Plot Temp. Rise" -command "PlotData TempRise" \
      -contextHelp "Plots temperature rise data and beam current for the range of days specified."
    APSButton .plotdtempnorm -parent $parent$widget.frame \
      -text "Plot Norm. Temp. Rise" -command "PlotData TempRiseNorm" \
      -contextHelp "Plots temperature rise data normalized to the beam current for the range of days specified."
    #APSButton .plotpres -parent $parent$widget.frame -text "Plot Diff Pres." -command "PlotData DiffPres" -contextHelp "Plots differential pressure data for the range of days specified."
    APSButton .plotheadtemp -parent $parent$widget.frame \
      -text "Plot Header Temp." -command "PlotData HeaderTemp" \
      -contextHelp "Plots header temperature data for the range of days specified."
}

proc MakeSectorsWidget {widget args} {
    set parent ""
    APSStrictParseArguments {parent}
    for {set sector 1} {$sector<41} {incr sector} {
        global Do[format %02ld $sector]
    }
    APSFrame $widget -parent $parent -label "Sector selection"
    set w $parent$widget.frame
    APSCheckButtonFrame .cb1 -parent $w -label "" \
      -buttonList {01 02 03 04 05 06 07 08 09 10} \
      -variableList {Do01 Do02 Do03 Do04 Do05 Do06 Do07 Do08 Do09 Do10} \
      -orientation horizontal -allNone 1 -relief flat
    APSCheckButtonFrame .cb2 -parent $w -label "" \
      -buttonList {11 12 13 14 15 16 17 18 19 20} \
      -variableList {Do11 Do12 Do13 Do14 Do15 Do16 Do17 Do18 Do19 Do20} \
      -orientation horizontal -allNone 1 -relief flat
    APSCheckButtonFrame .cb3 -parent $w -label "" \
      -buttonList {21 22 23 24 25 26 27 28 29 30} \
      -variableList {Do21 Do22 Do23 Do24 Do25 Do26 Do27 Do28 Do29 Do30} \
      -orientation horizontal -allNone 1 -relief flat
    APSCheckButtonFrame .cb4 -parent $w -label "" \
      -buttonList {31 32 33 34 35 36 37 38 39 40} \
      -variableList {Do31 Do32 Do33 Do34 Do35 Do36 Do37 Do38 Do39 Do40} \
      -orientation horizontal -allNone 1 -relief flat
}


lappend typeList C2:W2 C4 EA1 EA3:PBD EA5:PBD EA6:TR6:ID6 TR5:ID5 W4
lappend typeVarList C2W2 C4 EA1 EA3PBD EA5PBD EA6TR6ID6 TR5ID5 W4

proc MakeTypeWidget {widget args} {
    global typeList typeVarList
    set parent ""
    APSStrictParseArguments {parent}
    APSFrame $widget -parent $parent -label "Absorber type selection"
    set w $parent$widget.frame
    eval global $typeVarList
    foreach var $typeVarList {
        set $var 1
    }
    APSCheckButtonFrame .cb1 -parent $w -label "" \
      -buttonList $typeList \
      -variableList $typeVarList \
      -orientation horizontal -allNone 1 -relief flat
}

set existingDataFile ""
set lastFileList ""
set fileListUpdateTime 0
proc FindFiles {} {
    global StartMonth StartYear StartDay StartHour
    global EndMonth EndYear EndDay EndHour existingDataFile lastFileList fileListUpdateTime dataDir
    global dataFileListIsOld StartTime EndTime
    set Rootname SRH2O

    foreach item $lastFileList {
        set mtime [file mtime $item]
        if {$mtime>$fileListUpdateTime} {
            set dataFileListIsOld 1
            break
        }
    }

    if !$dataFileListIsOld {
        return $existingDataFile
    }

    set dataFileList  \
      [APSFindFilesBetweenDates -tailsOnly 1 \
         -rootname ${Rootname}- \
         -directory $dataDir \
         -startDateList [APSFormatDate -year $StartYear -month $StartMonth \
                           -day $StartDay -dateFormat list] \
         -endDateList [APSFormatDate -year $EndYear -month $EndMonth \
                         -day $EndDay -dateFormat list] ]
    SetStatusText "[llength $dataFileList] files found."
    set lastFileList $dataFileList
    set fileListUpdateTime [exec timeconvert -now | token -last]
    set tmpFile /tmp/[APSTmpString]
    set existingDataFile $tmpFile
    switch [llength $dataFileList] {
        0 {
            return ""
        }
        1 {
            if [string compare [file extension $dataFileList] .gz]==0 {
                set tmpFile $tmpFile.gz
                set existingDataFile $tmpFile
            }
            APSAddToTempFileList $tmpFile
            if [catch {exec cp $dataFileList $tmpFile} result] {
                SetStatusText "copy problem: $result"
                return ""
            }
        }
        default {
            APSAddToTempFileList $tmpFile
            SetStatusText "Merging..."
            if [catch {eval exec sddscombine -merge $dataFileList -overwrite $tmpFile} result] {
                SetStatusText "Processing problem: $result"
                return ""
            }
        }
    }

    if [catch {APSConvertTimeToHours $StartHour} hour] {
        SetStatusText "Invalid starting hour: $StartHour"
        return
    }
    set StartTime \
      [exec timeconvert \
         -breakDown=year=$StartYear,day=$StartDay,month=$StartMonth,hour=$hour]
    if [catch {APSConvertTimeToHours $EndHour} hour] {
        SetStatusText "Invalid ending hour: $EndHour"
        return
    }
    set EndTime \
      [exec timeconvert \
         -breakDown=year=$EndYear,day=$EndDay,month=$EndMonth,hour=$hour]
    set dataFileListIsOld 0
    return $tmpFile
}

proc PlotData {plotChoice} {
    global dataFileList
    SetStatusText "Working..."
    set file [FindFiles]
    if ![string length $file] {
        SetStatusText "No data found."
        return
    }
    switch $plotChoice {
        Temp -
        TempRiseNorm {
            SetStatusText "Computing temperature rises..."
            set data [ComputeTempRise -fileName $file]
            APSAddToTempFileList $data
            set file $data
            MakePlots -fileName $data -plotChoice $plotChoice
        }
        default {
            MakePlots -fileName $file -plotChoice $plotChoice
        }
    }
}

proc MakePlots {args} {
    global sparsingInterval plotDevice sameScaleY layoutChoice printerName labelSizeOption 
    global env groupMode plotTitle
    global StartTime EndTime
    global doSmooth smoothPasses

    set fileName ""
    set plotChoice  ""
    APSStrictParseArguments {fileName title plotChoice}
    if ![file exists $fileName] {
        return
    }

    if [string compare $groupMode type]==0 {
        lappend extraOptions -groupby=inamestring -separate=inamestring
    }
    lappend extraOptions "-topline=[APSMakeSafeQualifierString $plotTitle]"
    lappend extraOptions $layoutChoice 
    lappend extraOptions -presparse=$sparsingInterval
    lappend extraOptions -device=$plotDevice
    lappend extraOptions $labelSizeOption
    if $sameScaleY {
        lappend extraOptions -same=x,y,global
    } else {
        lappend extraOptions -same=x,global
    }

    global typeList typeVarList
    eval global $typeVarList
    set typesToDoList ""
    set index 0
    foreach elem $typeVarList {
        if [subst \$$elem] {
            lappend typesToDoList [lindex $typeList $index]
        }
        incr index
    }

    switch $plotChoice {
        Temp {
            set columnList *TActual
            set units degF
            set withDCCT 1
            set title "Temperature data along with beam current"
        }
        TempRiseNorm {
            set columnList *TRiseNorm
            set units degF/mA
            set withDCCT 0
            set title "Beam-current normalized temperature rise data"
        }
        DiffPres {
            set columnList ""
            set units PSI
            for {set sector 1} {$sector<41} {incr sector} {
                set var Do[format %02ld $sector]
                global $var
                if [subst \$$var] {
                    foreach type $typesToDoList {
                        lappend columnList [format H2O:%02ld:%s:P $sector $type]
                    }
                }
            }
            set withDCCT 0
            set title "Differential pressure data"
        }
        TempRise {
            set columnList ""
            set units degF
            for {set sector 1} {$sector<41} {incr sector} {
                set var Do[format %02ld $sector]
                global $var
                if [subst \$$var] {
                    foreach type $typesToDoList {
                        lappend columnList [format H2O:%02ld:%s:T $sector $type]
                    }
                }
            }
            set withDCCT 1
            set title "Temperature rise data with beam current"
        }
        HeaderTemp {
            set columnList ""
            set units degF
            for {set sector 2} {$sector<41} {incr sector 2} {
                set headerSector($sector) 0
            }
            for {set sector 1} {$sector<41} {incr sector} {
                set var Do[format %02ld $sector]
                set SHSector [expr 2*int(($sector+1)/2)]
                global $var
                if {[subst \$$var] && !$headerSector($SHSector)} {
                    lappend columnList [format H2O:%02ld:PW:SH:T $SHSector]
                    set headerSector($SHSector) 1
                }
            }
            set withDCCT 0
            set title "Header temperature data"
        }
    }
    if [llength $columnList]==0 {
        SetStatusText "Nothing selected to plot."
        return
    }

    if $doSmooth {
        SetStatusText "Smoothing..."
        if ![SmoothData -fileName $fileName -passes $smoothPasses \
               -columnList [join $columnList ,]] {
            return
        }
    }

    if [string compare $plotDevice motif] {
        set commandTail "| lpr -P$printerName"
    } else {
        set commandTail ""
    }

    if $withDCCT {
        eval exec sddsplot -filter=column,Time,$StartTime,$EndTime \
          {-title=$title} \
          -device=$plotDevice -separate $extraOptions $fileName -ticks=xtime \
          -column=Time,([join $columnList ,]) \
          -legend=spec=$units \
          -column=Time,S35DCCT -yscale=id=1 -omni -graph=line,type=1 \
          -legend=spec=Current $commandTail &
    } else {
puts "sddsplot -filter=column,Time,$StartTime,$EndTime -separate $extraOptions $fileName -ticks=xtime \"-column=Time,([join $columnList ,])\""
        eval exec sddsplot -filter=column,Time,$StartTime,$EndTime \
          {-title=$title} \
          -separate $extraOptions $fileName -ticks=xtime \
          -column=Time,([join $columnList ,]) \
          -legend=spec=$units {{-ylabel=use=name}} $commandTail &
    }
    SetStatusText "Plots launched."
}

proc SmoothData {args} {
    set fileName ""
    set columnList ""
    set passes 1
    APSStrictParseArguments {fileName passes columnList}
    if ![file exists $fileName] {
        return 0
    }
    set tmpfile /tmp/[APSTmpString]
    SetStatusText "Smoothing in progress..."
    if [catch \
          {exec sddssmooth $fileName $tmpfile -columns=$columnList -passes=$passes} result] {
        SetStatusText "Error smoothing data: $result"
        return 0
    }
    if [catch {exec mv $tmpfile $fileName} result] {
        Setstatustext "Error: $result"
        return 0
    }
    return 1
}

proc ComputeTempRise {args} {
    set fileName ""
    set lowerTime 0
    set upperTime 24
    APSStrictParseArguments {fileName lowerTime upperTime}
    if ![file exists $fileName] {
        return ""
    }
    set dataOutput /tmp/[APSTmpString]
    set sectorsToDoList ""
    for {set sector 1} {$sector<41} {incr sector} {
        set var Do[format %02ld $sector]
        global $var
        if [subst \$$var] {
            lappend sectorsToDoList [format %02ld $sector]
        }
    }
    if [llength $sectorsToDoList]==0 {
        SetStatusText "No sectors chosen."
        return ""
    }

    global typeList typeVarList
    eval global $typeVarList
    set typesToDoList ""
    set index 0
    foreach elem $typeVarList {
        if [subst \$$elem] {
            lappend typesToDoList [lindex $typeList $index]
        }
        incr index
    }
    if [llength $typesToDoList]==0 {
        SetStatusText "No absorber types chosen"
        return ""
    }

    if [catch {exec sddsquery -column $fileName} columnList] {
        return -code error "$columnList"
    }
    set compList ""
    foreach sector $sectorsToDoList {
        scan $sector "%ld" sector1
        set SHSector [format %02ld [expr 2*int(($sector1+1)/2)]]
        foreach type $typesToDoList {
            if [lsearch $columnList H2O:$sector:$type:T]==-1 continue
            lappend compList "-define=column,H2O:$sector:$type:TActual,H2O:$sector:$type:T H2O:$SHSector:PW:SH:T +,units=F"
            lappend compList "-define=column,H2O:$sector:$type:TRiseNorm,S35DCCT 10 > ? H2O:$sector:$type:T S35DCCT / : 0 \$ "
        }
    }

    if [catch \
          {eval exec sddsprocess $fileName $dataOutput \
             -filter=column,TimeOfDay,$lowerTime,$upperTime $compList } result] {
        SetStatusText "Error: $result"
        return ""
    }
    return $dataOutput
}

proc MakePlotControls {widget args} {
    global sparsingInterval plotDevice sameScaleY layoutChoice 
    global printerName labelSizeOption env groupMode plotTitle
    set sparsingInterval 1
    set plotDevice motif
    set sameScaleY 0
    set layoutChoice -layout=1,1
    set labelSizeOption -labelsize=0.02
    set groupMode sector
    set plotTitle ""
    if [info exists env(PRINTER)] {
        set printerName $env(PRINTER)
    } else {
        set printerName mcr1
    }

    set parent "" 
    APSStrictParseArguments {parent}

    APSFrame $widget -parent $parent -label "Plot controls"
    set parent $parent$widget.frame

    APSFrameGrid .grid -parent $parent \
      -yList {y1 y2} -width 10 \
      -xList {x1 x2 x3 x4}
        
    APSRadioButtonFrame .layout -parent ${parent}.grid.x1.y1 \
      -label Layout -orientation vertical \
      -variable layoutChoice \
      -buttonList {1x1 1x2 2x1 2x2 3x3 4x4 5x5} \
      -valueList {-layout=1,1 -layout=1,2 -layout=2,1 -layout=2,2 -layout=3,3 -layout=4,4 -layout=5,5} \
      -contextHelp {Choose the number of plot panels horizontally and vertical on each page.}
    APSRadioButtonFrame . -parent ${parent}.grid.x1.y2 \
      -label Grouping -orientation vertical \
      -variable groupMode -buttonList {"By sector" "By type"} \
      -valueList {sector type} \
      -contextHelp {Choose whether successive plots should be from the same sector or for the same type of readout.}

    APSCheckButtonFrame .misc  -parent ${parent}.grid.x2.y1 \
      -label Misc. -orientation vertical \
      -variableList {sameScaleY} -buttonList {"Same y scales."} 
    APSRadioButtonFrame .sparse  -parent ${parent}.grid.x3.y1 \
      -label Sparsing -orientation vertical \
      -variable sparsingInterval \
      -buttonList {None 2 4 8 16 32 64 128} \
      -valueList {1 2 4 8 16 32 64 128} \
      -contextHelp "For large amounts of data, a larger sparsing interval will result in\
faster display, but at the expense of only seeing a sample of the points."
    APSRadioButtonFrame .device  -parent ${parent}.grid.x4.y1 \
      -label Device -orientation vertical \
      -variable plotDevice \
      -buttonList {X-windows "B&W Postscript" "Color Postscript"} \
      -valueList {motif postscript cpostscript} \
      -contextHelp "Choose the plotting device.  Postscript is for delivery to a printer only."
    APSLabeledEntry .printer -parent ${parent}.grid.x4.y2 \
        -label "Printer: " -textVariable printerName -width 10
    APSRadioButtonFrame .labelsize -parent ${parent}.grid.x2.y2 \
        -label "Label size" -orientation vertical -variable labelSizeOption \
        -buttonList {normal +15% +30% +45% +60%} \
        -valueList {-labelsize=0.02 -labelsize=0.023 -labelsize=0.026 -labelsize=0.029 -labelsize=0.032} \
        -contextHelp "For layouts with many panels, the labels may be hard to read.  You can increase the size of the labels using these options."
            
    APSLabeledEntry .title -parent $parent \
      -label "Title: " -textVariable plotTitle -width 60
}

set doSmooth 0
set smoothPasses 1

MakeTypeWidget .type -parent .userFrame
MakeSectorsWidget .sectors -parent .userFrame
MakePlotControls .plotcontrol -parent .userFrame 
MakeSmoothWidget .smooth -parent .userFrame
MakeDateTimeFrame .date -parent .userFrame
MakeButtonRow .ops -parent .userFrame
