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

set LocationList [list A:GV1 A:P0 A:P1 A:P2 A:P3 A:P4 A:P5 A:P6 A:VC14 A:VC16 B:P6 B:P5 B:P4 B:P3 B:CA1 B:P2 B:P1 B:P0 B:GV1]

set dataDir /home/helios/oagData/logging/SRBpmTemperature
set knownColumnList [exec sdds2stream -column=ReadbackName /home/helios/oagData/logging/SRBpmTemperature/SRBpmTemperature.mon]
set fileListUpdateTime 0
   
APSApplication . -name SRChamberTempTrending -overview \
    {This application allows for plotting of any selected group of chamber temperatures to show trends with time and current.}

set w .userFrame

set configStatus ""
APSScrolledStatus .status -parent .userFrame -textVariable configStatus \
                          -width 100 -height 10
proc SetStatusText {text} {
   global configStatus
   set configStatus "$text"
   update
}


APSSRSectorButtons .lbuttons -parent .userFrame \
  -rootname location -orientation horizontal -label "Thermocouple Selections" -description "Thermocouple selection" \
  -itemList $LocationList -packOption "-side top" -itemLabelList $LocationList \
  -colorDesc 0 -sectorControl 1 

proc CollateSelections {args} {
    global LocationList selectedList LocationCount dataPlotting knownColumnList

    # Set per-location lists to empty
    foreach location $LocationList {
        set selectedList($location) [list ]
        set LocationCount($location) 0
    }
    # Set full-ring list to empty
    set selectedList(ring) [list ]
    set LocationCount(ring) 0
    
    for {set sector 1} {$sector<=40} {incr sector} {
        set ssector [format S%02d $sector]
        set LocationCount($ssector) 0
        set selectedList($ssector) [list ]
        foreach location $LocationList {
            set varName location$ssector$location
            global $varName
            if ![info exists $varName] {
                puts stderr "Not found: $varName"
                continue
            }
            if [set $varName] {
                lappend selectedList($ssector) $ssector$location:TemperatureM
                lappend selectedList($location) $ssector$location:TemperatureM
                lappend selectedList(ring) $ssector$location:TemperatureM
                incr LocationCount($ssector) 1
                incr LocationCount(ring) 1
                incr LocationCount($location) 1
            }
        }
    }

    SetStatusText "Working..."
    if ![string length [set file [FindFiles]]] {
        SetStatusText "No data found."
        set dataPlotting 0
    } else {
        set dataPlotting 1
    }
}   


proc MakeMainWindow {widget args} {
    global statisticScope normalizationType xAxis statisticType fixedScale groupingType includeOnPlot layoutSelection
    set parent ""
    APSStrictParseArguments {parent}

    APSFrame .tablo -parent $parent -label Plotting: -packOption "-side left -anchor nw"

    set w $parent.tablo.frame

    set statisticType None
    APSRadioButtonFrame .rb1 -parent $w -label "Statistic: " -variable statisticType -orientation horizontal \
      -buttonList "None Average Maximum" -valueList "None Average Maximum" \
      -commandList [list "APSDisableWidget $w.rb15" "APSEnableWidget $w.rb15" "APSEnableWidget $w.rb15"]

    set statisticScope Ring
    APSRadioButtonFrame .rb15 -parent $w -label "Stat. scope: " -variable statisticScope -orientation horizontal \
        -buttonList "Sector Location Ring" -valueList "Sector Location Ring"
    APSDisableWidget $w.rb15

    set groupingType None
    APSRadioButtonFrame .rb16 -parent $w -label "Grouping: " -variable groupingType -orientation horizontal \
        -buttonList "None All Sector Location" -valueList "None All Sector Location"

    set normalizationType None
    APSRadioButtonFrame .rb2 -parent $w -label "Normalization: " -variable normalizationType -orientation horizontal \
        -buttonList "None I I^2 I^2/B" -valueList "None I I2 I2OverB"

    set xAxis Time
    APSRadioButtonFrame .rb3 -parent $w -label "x Axis: " -variable xAxis -orientation horizontal \
        -buttonList "Time Current" -valueList "Time S-DCCT:CurrentM"

    set fixedScale 0
    APSRadioButtonFrame .rb4 -parent $w -label "Fixed scale: " -variable fixedScale -orientation horizontal \
        -buttonList "Yes No" -valueList "1 0"

    set includeOnPlot Nothing
    APSRadioButtonFrame .rb6 -parent $w -label "Also plot: " -variable includeOnPlot -orientation horizontal \
        -buttonList "Nothing Current Bunches" -valueList "Nothing Current Bunches"

    set layoutList [list ]
    for {set ix 1} {$ix < 9} {incr ix} {
        for {set iy 1} {$iy < 9} {incr iy} {
            lappend layoutList ${ix}x${iy}
        }
    }
    set layoutSelection 1x1
    APSComboboxFrame .cb1 -parent $w -label "Layout" -textVariable layoutSelection -itemList $layoutList

    APSButton .go -parent $w -text "Plot" -command  "PlotTemperatureVs" 
    APSButton .go2 -parent $w -text "Export" -command  "PlotTemperatureVs -export 1" 

} 

#======================================================================= 
# Process of the plotting selected data
#======================================================================= 
proc PlotTemperatureVs {args} {
    global statisticScope normalizationType xAxis statisticType fixedScale groupingType knownColumnList layoutSelection
    global existingDataFile dataPlotting includeOnPlot
    global selectedList
    global LocationList 
    global LocationCount     
    global bucketsMin bucketsMax
    global currentMin currentMax
    global startTime endTime

    set export 0
    APSStrictParseArguments {export}

    set graphicType dot
    if [string compare $xAxis "Time"]==0 {
        set graphicType line
    }
    
    CollateSelections

    if {$dataPlotting < 1} return
    
    if {$LocationCount(ring) == 0} {
       SetStatusText "Choose something to display"
       return
    }

    set tmpFile /tmp/[APSTmpString]
    #APSAddToTempFileList $tmpFile
    
    set plotColumnsList [list ]

    set selectedColumns -retain=column,S-DCCT:*,Time,SRBucketsFilled
    set selectedTemperatureList [list ]
    foreach item $selectedList(ring) {
        if [lsearch -exact $knownColumnList $item]!=-1 {
            append selectedColumns ,$item
            lappend selectedTemperatureList $item
        }
    }
    
    set statResultList [list ]
    set rowstatsOptList [list ]
    set localGroupingType $groupingType
    set statLabelPart ""
    if [string compare None $statisticType] {
        set statisticOperation(Maximum) maximum
        set statisticOperation(Average) mean
        set statisticLabel(Maximum) Max
        set statisticLabel(Average) Mean
        set limitTemperature toplimit=150,bottomLimit=0
        set statLabelPart "$statisticType "
        switch $statisticScope {
            Ring {
                set statInputList ""
                foreach item $selectedList(ring) {
                    lappend statInputList $item
                }
                lappend rowstatsOptList -$statisticOperation($statisticType)=$statisticLabel($statisticType)RingTemperature,[join $statInputList ,],$limitTemperature
                lappend statResultList $statisticLabel(${statisticType})RingTemperature
                set localGroupingType None
            }
            Location {
                foreach ip $LocationList {
                    if $LocationCount($ip)!=0 {
                        lappend rowstatsOptList -$statisticOperation($statisticType)=$statisticLabel($statisticType)${ip}Temperature,[join $selectedList($ip) ,],$limitTemperature
                        lappend statResultList $statisticLabel(${statisticType})${ip}Temperature
                    }
                }
                if [lsearch -exact [list Sector Location] $localGroupingType]!=-1 {
                    set localGroupingType None
                }
            }
            Sector {
                for {set sector 1} {$sector<41} {incr sector} {
                    set ssector [format S%02d $sector]
                    if $LocationCount($ssector)!=0 {
                        lappend rowstatsOptList -$statisticOperation($statisticType)=$statisticLabel($statisticType)${ssector}Temperature,[join $selectedList($ssector) ,],$limitTemperature
                        lappend statResultList $statisticLabel(${statisticType})${ssector}Temperature
                    }
                }
                if [lsearch -exact [list Sector Location] $localGroupingType]!=-1 {
                    set localGroupingType None
                }
            }
        }
        set plotColumnsList $statResultList
    } else {
        set plotColumnsList $selectedTemperatureList
    }

    lappend defineList "-redefine=column,S-DCCT:CurrentM,S-DCCT:CurrentM abs 1e-6 +,units=mA"
    switch $normalizationType {
        None {
            set yLabel "${statLabelPart}Temperature (C)"
        }
        I {
            set yLabel "${statLabelPart}Normalized Temperature (C/mA)"
            if [llength $statResultList] {
                foreach statResult $statResultList {
                    lappend defineList "-redefine=column,${statResult},$statResult S-DCCT:CurrentM abs 1e-16 + /,units=degC/mA"
                }
            } else {
                foreach column $selectedTemperatureList {
                    lappend defineList "-redefine=column,${column},$column S-DCCT:CurrentM abs 1e-16 + /,units=degC/mA"
                }
            }
        }
        I2 {
            set yLabel "${statLabelPart}Normalized Temperature (C/mA^2)"
            if [llength $statResultList] {
                foreach statResult $statResultList {
                    lappend defineList "-redefine=column,${statResult},$statResult S-DCCT:CurrentM abs 1e-16 + sqr /,units=degC/mA^2"
                }
            } else {
                foreach column $selectedTemperatureList {
                    lappend defineList "-redefine=column,${column},$column S-DCCT:CurrentM abs 1e-16 + sqr /,units=degC/mA^2"
                }
            }
        }
        I2OverB {
            # The data isn't in the data logger yet
            SetStatusText "I^2/B normalization not ready yet"
            return
            set yLabel "${statLabelPart}Normalized Temperature (C/mA^2/\#Bunches)"
            if [llength $statResultList] {
                foreach statResult $statResultList {
                    lappend defineList "-redefine=column,${statResult},$statResult S-DCCT:CurrentM abs 1e-16 + sqr / SRBucketsFilled /,units=degC/mA^2/\#Bunches"
                }
            } else {
                foreach column $selectedTemperatureList {
                    lappend defineList "-redefine=column,${column},$column S-DCCT:CurrentM abs 1e-16 + sqr / SRBucketsFilled /,units=degC/mA^2/\#Bunches"
                }
            }
        }
    }

    set filterList [list ]
    if {$bucketsMin>1 || $bucketsMax<1296} {
        # The data isn't in the data logger yet
        SetStatusText "Filtering by number of filled buckets not ready yet"
        return
        #lappend filterList -filter=column,SRBucketsFilled,$bucketsMin,$bucketsMax
    }
    lappend filterList -filter=col,Time,$startTime,$endTime
    lappend filterList -filter=column,S-DCCT:CurrentM,$currentMin,$currentMax

    if [llength $rowstatsOptList] {
        if {![catch {eval exec sddsconvert $existingDataFile -pipe=out $selectedColumns \
                       | sddsrowstats -pipe $rowstatsOptList \
                       | sddsprocess -pipe=in $tmpFile $defineList} result]==0} {
            SetStatusText "Problem preparing data (1): $result"
            set dataPlotting 0                   
            return 
        } 
    } else {
        if {![catch {eval exec sddsconvert $existingDataFile -pipe=out $selectedColumns \
                       | sddsprocess -pipe=in $tmpFile $defineList} result]==0} {
            SetStatusText "Problem preparing data (2): $result"
            set dataPlotting 0                   
            return 
        }
    }

    if $export {
        set choose 1
        while {$choose} {
            set choose 0
            set filename [APSFileSelectDialog .fsd -width 40 -checkValidity 0 -selectDir 0 -reverseSort 0]
            if ![string length $filename] return
            if [file exists $filename] {
                switch [APSMultipleChoice .msd -question "$filename exists. What do you want to do?" \
                          -labelList {Overwrite "Specify another file" Abort} \
                          -returnList "Overwrite Repeat Abort"] {
                              Overwrite {
                                  set choose 0
                              }
                              Repeat {
                                  set choose 1
                              }
                              Abort {
                                  return
                              }
                          }
            }
        }
        file copy -force $tmpFile $filename
        SetStatusText "Exported data to $filename"
        return
    }

    if $fixedScale {
        lappend plotOptionList -same=y,global
    }

    if [string compare $xAxis Time]==0 {
        lappend plotOptionList -ticks=xtime
    }

    if [string compare $includeOnPlot Nothing]==0 {
        set forceLegend 0
    } else {
        set forceLegend 1
    }
    set columnOptionList [list ]
    switch $localGroupingType {
        None {
            lappend plotOptionList -graph=$graphicType,vary
            foreach item $plotColumnsList {
                lappend columnOptionList -column=$xAxis,$item $tmpFile
                if $forceLegend {
                    lappend columnOptionList -legend
                }
                lappend columnOptionList -end
            }
        }
        All {
            lappend plotOptionList "-ylabel=$yLabel"
            lappend plotOptionList -graph=$graphicType,vary -order=spect 
            lappend columnOptionList -column=$xAxis,([join $plotColumnsList ,]) $tmpFile -legend=edit=%/:TemperatureM//%/Temperature// -end
        }
        Sector {
            lappend plotOptionList -graph=$graphicType,vary 
            set ssectorList [list ]
            foreach item $plotColumnsList {
                eval set ssector [os editstring S/:/100D $item]
                if [lsearch $ssectorList $ssector]==-1 {
                    lappend ssectorList $ssector
                }
                lappend ssectorItemList($ssector) $item
            }
            foreach ssector $ssectorList {
                lappend columnOptionList -column=$xAxis,([join $ssectorItemList($ssector) ,])  $tmpFile
                lappend columnOptionList "-ylabel=$yLabel" -legend=edit=%/:TemperatureM//%/Temperature// -end
            }
        }
        Location {
            lappend plotOptionList -graph=$graphicType,vary -order=spect
            set locationList [list ]
            foreach item $plotColumnsList {
                eval set location [os editstring 3dx/:/%/:TemperatureM// $item]
                if [lsearch $locationList $location]==-1 {
                    lappend locationList $location
                }
                lappend locationItemList($location) $item
            }
            foreach location $locationList {
                lappend columnOptionList -column=$xAxis,([join $locationItemList($location) ,])  $tmpFile "-ylabel=$yLabel"
                lappend columnOptionList -legend=edit=%/:TemperatureM// -end
            }
        }
    }

    switch $includeOnPlot {
        Nothing {
        } 
        Current {
            lappend plotOptionList -yscale=request
            eval lappend plotOptionList  -column=$xAxis,S-DCCT:CurrentM $tmpFile -omnipresent -graph=line,type=10 -legend=spec=Current $filterList
        }
        Bunches {
            lappend plotOptionList -yscale=request
            eval lappend plotOptionList  -column=$xAxis,SRBucketsFilled $tmpFile -omnipresent -graph=line,type=10 -legend=spec=Bunches $filterList
        }
    }
    regexp {(.*)x(.*)} $layoutSelection all nx ny
    if {$ny!=1} {
        lappend plotOptionList -join=x
    }
    
    eval exec sddsplot -layout=$nx,$ny -limit=ymax=150 $filterList -sever=xgap=32 $plotOptionList $columnOptionList &
}
         
#======================================================================= 
# Process of the creating DateTime window
#======================================================================= 
proc MakeDateTimeFrame {widget args} {

   set parent .
   set rootname ""
   set label "Date/Time Range of Interest:"
   set bucketsMin 0
   set bucketsMax 1296
   set currentMin 0
   set currentMax 150
   set label2 "Filters:"

   APSStrictParseArguments {parent rootname}

   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

#--------------------------------------------------------- 
# Exec SetDateTimeToToday processes: 
#   
   SetDateTimeToToday -rootname ${rootname}Start -hour 0
   SetDateTimeToToday -rootname ${rootname}End  -hour 24
}
      
#======================================================================= 
# Process of the creating Filters window
#======================================================================= 
proc MakeFiltersFrame {widget args} {
 
   global bucketsMin bucketsMax            # number of the filled buckets 
   global currentMin         # minimal used current
   global currentMax         # maximal used current

   set parent .
   set rootname ""
   set bucketsMin 0
   set bucketsMax 1296
   set currentMin 0.0
   set currentMax 205.0

   APSStrictParseArguments {parent rootname}

   APSFrame $widget -parent $parent -label "Filters: " \

   set w $parent$widget.frame

   APSLabeledEntryFrame .buckets -parent $w -label "Buckets (min, max):" \
     -variableList {bucketsMin bucketsMax} -width 5 \
     -orientation horizontal \
     -contextHelp "Specify range of number of filled buckets to include."

   APSLabeledEntryFrame .maxCurrent -parent $w -label "  Current (min, max; mA):" \
     -variableList {currentMin currentMax} -width 5 \
     -orientation horizontal \
     -contextHelp "Specify range of beam current to include."

}

#======================================================================= 
# Process
#======================================================================= 
proc SetDateTimeToToday {args} {

#   global dayVariable

   set rootname ""
   set hour 0
#--------------------------------------------------------- 
# Exec ResetDataFileList process:
#  
   ResetDataFileList

   APSStrictParseArguments {rootname hour}

#--------------------------------------------------------
# Attention: these descriptions cann't be placed before defintions 
# variables rootname and hour !!!
#
   global ${rootname}Month 
   global ${rootname}Year 
   global ${rootname}Day 
   global ${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
   set fileListUpdateTime 0

#======================================================================= 
# Erasing list of the selected files before new selection of them and
# reset flag dataFileListIsOld 
#======================================================================= 
proc ResetDataFileList {} {
   global dataFileList       # list of the selected files
   global dataFileListIsOld  # flag: =1 when list dataFileList is empty;
                             #       =0 when this list is ready 
   set dataFileList ""
   set dataFileListIsOld 1
}

set existingDataFile ""
set lastFileList [list ]
set fileListUpdateTime 0
    
proc FindFiles {args} {
    global StartMonth StartYear StartDay StartHour
    global EndMonth EndYear EndDay EndHour
    global startTime endTime 
    global existingDataFile    # merged data stored in this file
    global fileListUpdateTime  # time of the last update of current list 
                               # lastFileList with selected files
    global dataDir             # directory with main data files
    global dataFileListIsOld   # flag: =1 when list dataFileList is empty;
                               #       =0 when this list is ready 
    global lastFileList        # current list with selercted files
    set Rootname SRBpmTemperature

    set findOnly 0
    APSStrictParseArguments {findOnly}

    set startDate [APSFormatDate -year $StartYear -month $StartMonth -day $StartDay -dateFormat list]
    if [catch {APSConvertTimeToHours $StartHour} hour] {
        SetStatusText "Bad time value: $StartHour"
        return
    }
    set startTime [exec timeconvert -breakDown=year=$StartYear,day=$StartDay,month=$StartMonth,hour=$hour ]
    
    set endDate [APSFormatDate -year $EndYear -month $EndMonth -day $EndDay -dateFormat list]
    if [catch {APSConvertTimeToHours $EndHour} hour] {
        SetStatusText "Bad time value: $EndHour"
        return
    }
    set endTime [exec timeconvert -breakDown=year=$EndYear,day=$EndDay,month=$EndMonth,hour=$hour ]

    set dataFileList [APSFindFilesBetweenDates -rootname $Rootname- -directory $dataDir -startDateList $startDate -endDateList $endDate ]

    if [string length $existingDataFile] {
        set dataFileListIsOld 0
        if [llength $lastFileList] {
            foreach dataFile $dataFileList {
                if [lsearch -exact $lastFileList $dataFile]==-1 {
                    set dataFileListIsOld 1
                }
            }
        }
        if !$dataFileListIsOld {
            SetStatusText "Using the same source files"
            # Same data files being used
            foreach item $lastFileList {
                set mtime [file mtime $item]
                if {$mtime > $fileListUpdateTime} {
                    SetStatusText "Files have changed since last accessed"
                    set dataFileListIsOld 1
                    break
                }
            }
            if !$dataFileListIsOld {
                return $existingDataFile
            }
        }
    }

    SetStatusText "[llength $dataFileList] files found."
    if $findOnly {
        return $dataFileList
    }

    set lastFileList $dataFileList
    set fileListUpdateTime [clock seconds]

    # Merge all the data files
    set tmpFile /tmp/[APSTmpString]
    set existingDataFile $tmpFile

    if [llength $dataFileList]==0 return

    APSAddToTempFileList $tmpFile
    SetStatusText "Merging data files..."
    if [catch {eval exec sddscombine -merge $dataFileList $tmpFile} result] {
        SetStatusText "Merging problem with file $tmpFile: $result"
        return ""
    }
    SetStatusText "Files merged"

    set dataFileListIsOld 0

    return $tmpFile
}

#======================================================================= 
# Creating all menu in working window
#======================================================================= 

MakeMainWindow .plotting -parent .userFrame
MakeDateTimeFrame .datetime -parent .userFrame
MakeFiltersFrame .filters -parent .userFrame

SetStatusText "Ready."
update








