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

APSApplication . -name  RFfrequencyHistory -overview "This plot the RF frequency of the storage ring overlaid with a curve of the outside temperature. The outside temperature is not affected by the sparse number."

set status ""

APSScrolledStatus .status -parent .userFrame -textVariable status \
  -width 80 -height 4 \
  -withButtons 1 -packOption "-fill x -expand true" 


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

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

    APSDateTimeAdjEntry .startDate -parent $w \
      -yearVariable ${rootname}StartYear \
      -monthVariable ${rootname}StartMonth \
      -dayVariable ${rootname}StartDay \
      -hourVariable ${rootname}StartHour \
      -label "Start (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 "End (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
}

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


proc MakePlotControls {widget args} {
    global plotDevice printerName labelSizeOption env 
    global userPlotOptions1 userPlotOptions2
    global sameScalesOption layoutOption sparse
    set layoutOption 1,1
    set sameScalesOption ""
    set plotDevice motif
    set labelSizeOption -labelsize=0.03
    set userPlotOptions1 ""
    set userPlotOptions2 ""
    if [info exists env(PRINTER)] {
        set printerName $env(PRINTER)
    } else {
        set printerName mcr1
    }

    set gridPack ""
    set parent "" 
    APSStrictParseArguments {parent gridPack}

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

    APSRadioButtonFrame .device  -parent ${parent} -gridPack "-column 0 -row 0 -sticky nw" \
      -label Device -orientation horizontal -limitPerRow 2 \
      -variable plotDevice \
      -buttonList {X-windows "B&W PS" "Color PS" "Color PS on Black"} \
      -valueList {motif postscript cpostscript cpostscript,onblack} \
      -contextHelp "Choose the plotting device.  Postscript is for delivery to a printer only."
    APSLabeledEntry .printer -parent ${parent} -gridPack "-column 1 -row 0 -sticky nw" \
        -label "Printer: " -textVariable printerName -width 10
    APSRadioButtonFrame .labelsize -parent ${parent} -gridPack "-column 0 -row 1 -sticky nw" \
      -label "Label size" -orientation horizontal -variable labelSizeOption \
      -buttonList {normal +15% +30% +45% +60%} \
      -valueList {-labelsize=0.03 -labelsize=0.0345 -labelsize=0.039 -labelsize=0.0435 -labelsize=0.048} \
      -contextHelp "For layouts with many panels, the labels may be hard to read.  You can increase the size of the labels using these options."
    
    APSRadioButtonFrame .sparse -parent ${parent} -gridPack "-column 0 -row 1 -sticky nw" \
      -label "Sparsing number" -orientation horizontal -variable sparse \
      -buttonList {1 2 4 8 16 32 64} \
      -valueList {1 2 4 8 16 32 64} \
      -contextHelp "For reducing the number of points in very large plots."
            
    APSLabeledEntry .extra1 -parent $parent \
      -gridPack "-column 0 -row 6 -columnspan 2 -sticky w" \
      -label "Extra options for RF frequency data: " \
      -textVariable userPlotOptions1 -width 60 \
      -contextHelp "Enter sddsplot options to be used for plotting the temperature data e.g. -sparse=2."

    APSLabeledEntry .extra2 -parent $parent \
      -gridPack "-column 0 -row 7 -columnspan 2 -sticky w" \
      -label "Extra options for weather temperature data: " \
      -textVariable userPlotOptions2 -width 60 \
      -contextHelp "Enter sddsplot options to be used for plotting the stored current data, e.g. -sparse=16."
}

proc FindPVDataFiles {args} {
    set ReadbackName ""
    set StartTime [clock scan "Jan 01 00:00:00 1990"]
    set EndTime [clock seconds]
    set startDateList ""
    set endDateList ""
    set SampleIntervals "1 2 4 8 16 32 64 128 256"
    APSStrictParseArguments {ReadbackName StartTime EndTime SampleIntervals startDateList endDateList}

    if {[llength $startDateList]} {
        set StartTime [clock scan "[lindex $startDateList 2]/[lindex $startDateList 3]/[lindex $startDateList 0]"]
    }
    if {[llength $endDateList]} {
        set EndTime [clock scan "23:59:59 [lindex $endDateList 2]/[lindex $endDateList 3]/[lindex $endDateList 0]"]
    }
    
    set fileList ""
    set ReadbackName [join [split $ReadbackName / ] + ]
    set year [clock format $StartTime -format %Y]
    set month [clock format $StartTime -format %m]
    set endyear [clock format $EndTime -format %Y]
    set endmonth [clock format $EndTime -format %m]
    while {($year < $endyear) || (($year == $endyear) && ($month <= $endmonth))} {
        append fileList "[lsort [glob -nocomplain /home/helios/oagData/logging/Variable/[string toupper [string index ${ReadbackName} 0]]/${ReadbackName}/log-${year}-${month}.{gz,xz}]] "
        append fileList "[lsort [glob -nocomplain /home/helios/oagData/logging/\{[join $SampleIntervals ,]\}/${ReadbackName}/log-${year}-${month}.{gz,xz,????}]] "
        if {$month == 12} {
            set month 01
            incr year
        } else {
            scan $month %d month
            incr month
            set month [format %02d $month]
        }
    }
    return $fileList
}

proc MakePlot {args} {
    global StartYear StartMonth StartDay StartHour
    global EndYear EndMonth EndDay EndHour
    global plotDevice printerName labelSizeOption env
    global userPlotOptions1 userPlotOptions2
    global sameScalesOption layoutOption sparse

    set plotType ""
    APSStrictParseArguments {} 

    set timeLabel "Time span: $StartYear/$StartMonth/$StartDay@$StartHour to $EndYear/$EndMonth/$EndDay@$EndHour"
    foreach item {Start End} {
        if [catch {APSConvertTimeToHours [set ${item}Hour]} hour] {
            APSSetVarAndUpdate status "Invalid [string tolower $item]ing hour: [set ${item}Hour]"
            return
        }
        set [string tolower $item]Time \
          [exec timeconvert \
             -breakDown=year=[set ${item}Year],month=[set ${item}Month],day=[set ${item}Day],hour=$hour]
        set ${item}DateList [APSFormatDate -year [set ${item}Year] \
                               -month [set ${item}Month] -day [set ${item}Day] -dateFormat list] 
    }
    
    if $startTime>=$endTime {
        APSSetVarAndUpdate status "Start time must be prior to end time."
        return
    }
    
    APSSetVarAndUpdate status "Working [clock format [clock seconds]]..."

    set weatherDataFileList \
      [APSFindFilesBetweenDates -tailsOnly 0 \
         -rootname met- \
         -directory /home/helios/oagData/ANLWeather \
         -startDateList $StartDateList -endDateList $EndDateList \
        ]
    set tmpfile /tmp/[APSTmpString]
    set i 0
    set rfDataSmallFileList ""
    APSSetVarAndUpdate status "Combining rf frequency files..."


    set pvFiles [FindPVDataFiles -ReadbackName rfFrequencyOffset \
                   -SampleIntervals "64" \
                   -startDateList $StartDateList \
                   -endDateList $EndDateList]
    append pvFiles " [FindPVDataFiles -ReadbackName S35DCCT \
                     -SampleIntervals 64 \
                      -startDateList $StartDateList \
                      -endDateList $EndDateList]"
    if ![llength $pvFiles] {
        return -code error "No rf data files found in date range."
    }
    set rfDataFileList /tmp/[APSTmpString]
    APSAddToTempFileList $rfDataFileList
    if {[catch {eval exec sddscombinelogfiles $pvFiles $rfDataFileList} result]} {
        APSSetVarAndUpdate status $result
        return -code error "Unable to combine log files"
    }
    foreach file $rfDataFileList {
        if [expr $i / 10 * 10 == $i] {
            APSSetVarAndUpdate status "Working on file $file (number $i)..."
        }
        if [catch {exec sddsprocess $file -pipe=out -noWarning \
                     -filter=col,S35DCCT,80,300 \
                     | sddssmooth -pipe -noWarning \
                     -col=rfFrequencyOffset \
                     -despike=neighbors=5,passes=3,average=5,threshold=20 \
                     | sddsconvert -pipe \
                     -delete=col,S35DCCT \
                     | sddsprocess -pipe=in $tmpfile.$i -noWarning \
                     -sparse=$sparse \
                 } result] {
            return -code error "RF frequency data processing error: $result"
        }
        lappend rfDataSmallFileList $tmpfile.$i
        incr i
    }
    if [catch {eval exec sddscombine $rfDataSmallFileList $tmpfile.rf \
                 -merge \
             } result] {
        return -code error "RF frequency data processing error: $result"
    }

    APSSetVarAndUpdate status "Combining weather files..."
    if ![llength $weatherDataFileList] {
       return -code error "No weather data files found in date range."
    }
    set i 0
    set weatherDataSmallFileList ""
    foreach file $weatherDataFileList {
        if [expr $i / 10 * 10 == $i] {
            APSSetVarAndUpdate status "Working on file $file (number $i)..."
        }
        if [catch {exec sddsconvert $file -pipe=out \
                     -retain=col,Time,Temperature10m \
                     | sddssort -pipe=in $tmpfile.$i \
                     -col=Time -unique \
                 } result] {
            return -code error "Weather data processing error: $result"
        }
        lappend weatherDataSmallFileList $tmpfile.$i
        incr i
    }
    if [catch {eval exec sddscombine $weatherDataSmallFileList $tmpfile.temp \
                 -merge \
             } result] {
        return -code error "Weather data processing error: $result"
    }
    

    set endArg ""
    if [string compare $plotDevice motif]!=0 {
        set endArg "| lpr -P$printerName"
    }

    if [catch {exec sddsprocess $tmpfile.rf -noWarning \
                 -proc=rfFrequencyOffset,drange,rfFrequencyDecile \
                 -proc=rfFrequencyOffset,median,rfFrequencyMedian} result] {
        return -code error "sddsprocess command error: $result"
    }
    if [catch {exec sdds2stream $tmpfile.rf \
                 -para=rfFrequencyDecile,rfFrequencyMedian} result] {
        return -code error "sdds2stream command error: $result"
    }
    set decile [lindex $result 0]
    set median [lindex $result 1]
    set lowerLimit [expr $median - $decile * 1.2]
    set upperLimit [expr $median + $decile * 1.2]
    if [catch {eval exec sddsplot \
                 \"-topline=RF Frequency Offset\" \
                 -device=$plotDevice -ticks=xtime -leg \
                 $labelSizeOption \
                 -filter=col,Time,$startTime,$endTime \
                 \
                 -col=Time,rfFrequencyOffset $tmpfile.rf \
                 -filter=col,rfFrequencyOffset,$lowerLimit,$upperLimit \
                 -graph=dot,type=0 $userPlotOptions1 \
                 \
                 -col=Time,Temperature10m $tmpfile.temp \
                 -filter=col,Temperature10m,-40,40 \
                 -omnipresent -graph=dot,type=1 $userPlotOptions2 \
                 -yscale=id=Temp $endArg & \
              } result] {
        return -code error "Plot command error: $result"
    }
    APSSetVarAndUpdate status "Plotting done."
}

APSFrame .gridFrame -parent .userFrame -label "" -relief flat
set w .userFrame.gridFrame.frame

set sparse 1

MakeDateTimeFrame .datetime -parent $w \
  -gridPack "-column 0 -row 0 -columnspan 2"

MakePlotControls .plotcon -parent $w \
  -gridPack "-column 0 -row 1 -columnspan 2"

APSButton .run2 -parent $w -text "Plot" \
  -command "MakePlot" \
  -gridPack "-column 0 -row 2 -sticky nw "



