#!/bin/sh
# \
exec oagwish "$0" "$@"

set debugReviewAlarmLog 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 apsttk 1
APSStandardSetup

set CVSRevisionAuthor "\$Revision: 1.70 $ \$Author: soliday $"

AlarmReviewSetup 
set doMajor   1
set doMinor   0
set doInvalid 0
set doNoAlarm 0
set interestLevel 2
set pvMatch *
set pvExclude ""
set timeBin 60
set timeFilterMin 0
set timeFilterMax 0
set lastTimeFilterMin 0
set lastTimeFilterMax 0
set lastFileList ""
set lastDataFile ""

if {[lsearch -exact [font names] smallFixedFont] == -1} {
    eval font create smallFixedFont [font actual TkFixedFont]
    font configure smallFixedFont -size -10
}
proc SetStatusText {text} {
    global statusText
    set statusText "$text [exec date +%H:%M:%S]"
    update
}


proc MakePlotButtons {widget args} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In MakePlotButtons"}
    set parent ""
    APSParseArguments {parent}
    set w $parent$widget
    ttk::frame $w
    pack $w -side top -fill x

    APSButton .thplot0 -parent $w -text "HOUR HISTOGRAM" -width "" -command \
       {DoTimeHistPlots -versus TimeOfDay${timeHistType} -individualPV 0} \
      -contextHelp "Plots time histograms of alarm times for each selected alarm level and for \
process variables passing the filter." 

    APSButton .thplot1 -parent $w -text "TIME HISTOGRAM" -width "" -command \
       {DoTimeHistPlots -versus Time${timeHistType} -individualPV 0} \
      -contextHelp "Plots time histograms of alarm times for each selected alarm level and for \
process variables passing the filter." 

    APSButton .thplot2 -parent $w -text "PV's HISTOGRAM" -width "" -command \
       {DoTimeHistPlots -versus Time${timeHistType} -individualPV 1} \
      -contextHelp "Plots time histograms of alarm times for each selected alarm level and for \
each process variables passing the filter separately." 

    APSButton .tcplot -parent $w -text "TOTAL COUNTS" -width "" -command DoTotalCountsPlots \
      -contextHelp "Plots total alarm counts for each selected alarm level and for process \
variables passing the filter." 

    APSButton .print -parent $w -text "PRINTOUT" -width "" -command DoAlarmLogPrintout \
      -contextHelp "Prints alarm history sorted by process variable name and time." 

    APSButton .overlap -parent $w -text "OVERLAP ANALYSIS" -width "" -command DoAlarmEventOverlap \
      -contextHelp "Prints analysis of the overlap of selected events with a single event."

    APSButton .enable -parent $w -text "ENABLE" -width "" -command EnablePlotButtons \
      -contextHelp "Use to re-enable plot buttons after an abnormal termination of plotting or processing."
    APSButton .cleanup -parent $w -text "CLEAN UP" -width "" -command {APSDeleteTempFiles; SetStatusText "Temporary files deleted."} \
      -contextHelp "Use to clean up temporary files created during processing.  Should be done before exiting.  If done sooner, some processing may be repeated."
    
}

proc AddSpecialButtons {} {
    global systemChoice
    set w .userFrame
    catch {destroy $w.special}
    switch $systemChoice {
        SR {
            #No longer needed. The bit faults are translated inside sddsalarmlogger now.
            if {0} {
                APSFrame .special -parent $w -label "" -relief flat 
                APSButton .printPS -parent $w.special.frame -width "" \
                  -text "POWER SUPPLY TRIP" -command DoAlarmLogPowerSupplyTrip \
                  -contextHelp "Prints error messages sorted by process variable name and time." 
            }
        } 
        "CA Beacon Monitor" {
            APSFrame .special -parent $w -label "" -relief flat 
            APSButton .caswAnalysis1 -parent $w.special.frame -width "" \
              -text "INTERVAL ANALYSIS" -command "DoCASWAnalysis -mode interval" \
              -contextHelp "Prints analysis of intervals between beacons for each IOC"
            APSButton .caswAnalysis2 -parent $w.special.frame -width "" \
              -text "EVENT ANALYSIS" -command "DoCASWAnalysis -mode event" \
              -contextHelp "Prints analysis of intervals between beacons for each IOC"
            APSButton .caswAnalysis3 -parent $w.special.frame -width "" \
              -text "EVENT ANALYSIS (verbose)" -command "DoCASWAnalysis -mode event-verbose" \
              -contextHelp "Prints analysis of intervals between beacons for each IOC"
        }
        default {
        }
    }
}

proc DoCASWAnalysis {args} {
    set mode interval
    APSStrictParseArguments {mode}

    global debugReviewAlarmLog
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice sortPrintoutBy  
    global env dataDir countsID countThreshold countSortChoice fixedCountScales
    global filterFileList filterDescriptionList filterChoices defFile
    
    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
                               -descriptions $filterDescriptionList -choices $filterChoices]

    DisablePlotButtons 
    set names [DoAlarmLogProcessing -doSplit 0 -doIndex 0]
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        EnablePlotButtons
        return
    }
    
    set title \
      [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
         -dataDir $dataDir -dataFile $dataFile -filterChoices $filterChoices]

    set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
    SetStatusText "Preparing interval analysis printout... "

    set intervalAnalysis 0
    set eventAnalysis 0
    switch $mode {
        interval {
            set intervalAnalysis 1
        }
        event {
            set eventAnalysis 1
        }
        event-verbose {
            set eventAnalysis 2
        }
    }
    if [catch {PrintAlarmLog -dataFile $dataFile -outputFile $rootName.ps.txt \
                 -pvExclude "$pvExclude" -intervalAnalysis $intervalAnalysis \
                 -eventAnalysis $eventAnalysis \
                 -filterFiles $filterFilesSelected -title $title \
                 -topline $topline -major 0 -minor 0 -invalid 0 -noAlarm 0 -isAlarmData 0} result] {
        SetStatusText "$result"
        return 
    }
    SetStatusText "returned ok"

    APSFileDisplayWindow [APSUniqueName .] -fileName $rootName.ps.txt \
      -deleteOnClose 1 -width 160 -height 40 -contextHelp \
      "Alarm log printout: $title" \
      -comment "$title\n$topline" -font TkFixedFont \
      -printCommand "enscript -r"

    EnablePlotButtons 
    return
}


APSApplication . -name ReviewAlarmLog -version $CVSRevisionAuthor \
  -overview {This tool provides for review of alarm logger data for various systems.}

set statusText Ready.
APSScrolledStatus .status -parent .userFrame -width 80 -textVariable statusText \
    -withButtons 1 -packOption "-fill both -expand true"

APSFrame .data -parent .userFrame -label "Data selection"
set w .userFrame.data.frame

set NewSystemCommands ""
foreach command $SystemCommands {
    lappend NewSystemCommands "$command; AddSpecialButtons"
}
set SystemCommands $NewSystemCommands

APSRadioButtonFrame .systemRB -parent $w -label "System: " \
  -buttonList $Systems -valueList $Systems -variable systemChoice \
  -commandList $SystemCommands -limitPerRow 9 \
  -contextHelp "Choose the system for which you wish to see data." \
  -orientation horizontal

APSDateTimeAdjEntry .date0 -parent $w \
    -dayVariable dayToPlot0 -monthVariable monthToPlot0 \
    -yearVariable yearToPlot0 -hourVariable hourToPlot0 \
    -label "Start Year/Month/Day/Hour:Minutes : "
APSDateTimeAdjEntry .date1 -parent $w \
    -dayVariable dayToPlot1 -monthVariable monthToPlot1 \
    -yearVariable yearToPlot1 -hourVariable hourToPlot1 \
    -label "End   Year/Month/Day/Hour:Minutes : "
set hourToPlot0 0
set hourToPlot1 24

APSLabeledEntry .dirname -parent $w -label "Directory: " \
  -textVariable dataDir -width 80 \
  -contextHelp "Shows the directory from which data is taken for Custom data."
APSLabeledEntry .filename -parent $w -label "Filename: " \
  -textVariable userFilename -width 80 \
  -contextHelp "Enter a filename from which to take alarm log data for Custom data."
APSLabeledEntry .filter -parent $w -label "Filter: " \
  -textVariable userFilter -width 80 \
  -contextHelp "Enter a filter to use with the file selection dialog for Custom data."
APSButton .filesel -parent $w -text "PICK FILE..." -width "" \
  -contextHelp "Use to select a file from which to take alarm log data for Custom data." \
  -command PickFilename
set pickFileWidget $w.filesel.button
set directoryWidget $w.dirname.entry
set filenameWidget $w.filename.entry
set filterWidget $w.filter.entry

APSFrame .filter -parent .userFrame -label "Data filtering" 
set w .userFrame.filter.frame
set pvFilterFrame $w

APSLabeledEntry .pvMatch -parent $w \
  -label "PV name match: " -width 60 -textVariable pvMatch \
  -contextHelp "Enter a wildcard string with which to select PV names. \
* matches 0 or more characters, while ? matches one character. \
 \[<text>\] matches one occurence of any character in <text>. \
 For example, all available storage ring A:Q1 and B:Q1 could be selected with S*\[AB\]:Q1*. \
 You may enter multiple strings separated by commas; in this case, any PV matching one or more \
 of the strings is included."
APSLabeledEntry .pvExclude -parent $w \
  -label "PV name exclude: " -width 60 -textVariable pvExclude \
  -contextHelp "Enter a wildcard string with which to exclude PV names. \
Use a blank entry to exclude none. \
* matches 0 or more characters, while ? matches one character. \
 \[<text>\] matches one occurence of any character in <text>. \
 For example, all available storage ring A:Q1 and B:Q1 could be selected with S*\[AB\]:Q1*. \
 You may enter multiple strings separated by commas; in this case, any PV matching one or more \
 of the strings is excluded."
set filterFileWidget ""
set filterDescriptionList ""
set filterFileList ""
set filterChoices ""
set timeUnit seconds
set multiplier 1.0
set commandList {SetTimeBinByUnits SetTimeBinByUnits SetTimeBinByUnits SetTimeBinByUnits}
APSCheckButtonFrame .severityCB -parent $w -label "Severity: " \
  -buttonList {MAJOR MINOR INVALID NO_ALARM} -variableList {doMajor doMinor doInvalid doNoAlarm} \
  -contextHelp "Choose the severity levels for which you wish to see data." \
  -orientation horizontal  -allNone 1

APSFrameGrid .fg -parent .userFrame -xList {f1 f2 f3}

APSFrame .hist -parent .userFrame.fg.f1 -label "Histogram control" 
set w .userFrame.fg.f1.hist.frame
APSLabeledEntry .binsize -parent $w -label "Bin size: " \
  -textVariable timeBin -width 30 \
  -contextHelp "Enter the size (or width) of the histogram bins in seconds."
APSRadioButtonFrame .units -parent $w -label "unit: " -buttonList {seconds hours days weeks} \
  -valueList {seconds hours days weeks} -variable timeUnit -orientation horizontal \
  -contextHelp "choose the units for bin size." -commandList $commandList
set timeHistType WS
APSRadioButtonFrame .type -parent $w -label "type: " -buttonList {IOC WS} \
    -valueList {"" WS} -variable timeHistType -orientation horizontal \
    -contextHelp "Choose which time value to histogram, the IOC time-stamp value or the time at which the data arrived at the workstation."

set countThreshold 0
set countSortChoice Name
set fixedCountScales 1
APSFrame .count -parent .userFrame.fg.f2 -label "Count control" 
set w .userFrame.fg.f2.count.frame
APSLabeledEntry .mintoshow -parent $w -label "Threshold (counts): " \
  -textVariable countThreshold -width 10 \
  -contextHelp "Enter the minimum number of counts to show on plots."
APSRadioButtonFrame .sort -parent $w -label "Sort by: " \
  -buttonList {Name Counts} -valueList {Name Counts} -variable countSortChoice \
  -contextHelp "Choose the type of sorting to determine the order in which counts are shown on plots." \
  -orientation horizontal
APSRadioButtonFrame .scaling -parent $w -label "Fixed scale: " \
  -buttonList {Yes No} -valueList {1 0} -variable fixedCountScales \
  -contextHelp "Choose whether scales for counts in plots are fixed for all plots or not." \
  -orientation horizontal

set sortPrintoutBy TimeOfDay
APSFrame .printout -parent .userFrame.fg.f3 -label "Printout control" 
set w .userFrame.fg.f3.printout.frame
APSRadioButtonFrame .sort -parent $w -label "Sort by: " \
  -buttonList {Name Time} -valueList {ControlName TimeOfDay} -variable sortPrintoutBy \
  -contextHelp "Choose the type of sorting to determine the order in which data is shown in printout." \
  -orientation horizontal

MakePlotButtons .plot -parent .userFrame

set isAlarmData 1
proc MakeDataFileList {} {
    global debugReviewAlarmLog defaultDataDir SystemRootnames Systems IsAlarmLogger
    if $debugReviewAlarmLog { puts stderr "In MakeDataFileList"}
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global dataDir userFilename systemChoice isAlarmData

    if $debugReviewAlarmLog { puts stderr "userFileName: >$userFilename<" }
    if [string length $userFilename] {
        # user has supplied a file
        return [list $userFilename]
    } elseif [string compare $systemChoice Custom]==0 {
        return ""
    }

    set systemRootname [lindex $SystemRootnames [lsearch $Systems $systemChoice]]
    set isAlarmData [lindex $IsAlarmLogger [lsearch $Systems $systemChoice]]
    if $isAlarmData {
        SetStatusText "Looking for alarm log files $defaultDataDir/$systemRootname/${systemRootname}-*"
    } else {
        SetStatusText "Looking for log files $defaultDataDir/$systemRootname/${systemRootname}-*"
    }
    set dataFileList \
        [APSFindFilesBetweenDates -tailsOnly 1 \
           -rootname ${systemRootname}- -directory $defaultDataDir/$systemRootname \
           -startDateList [APSFormatDate -year $yearToPlot0 \
                             -month $monthToPlot0 -day $dayToPlot0 -dateFormat list] \
           -endDateList [APSFormatDate -year $yearToPlot1 \
                             -month $monthToPlot1 -day $dayToPlot1 -dateFormat list] \
           ]
    set dataDir $defaultDataDir/$systemRootname
    return $dataFileList
}


proc DoAlarmLogProcessing {args} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoAlarmLogProcessing"}
    global doMajor doNoAlarm doMinor doInvalid interestLevel pvMatch pvExclude timeBin Multiplier
    global timeFilterMin timeFilterMax
    global systemChoice lastFileList lastDataFile
    global env dataDir userFilename lastTimeFilterMin lastTimeFilterMax
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global apsScriptUser isAlarmData

    set doIndex 1
    set doSplit 1
    APSStrictParseArguments {doIndex doSplit}

    set dataFileList [MakeDataFileList]
    if [llength $dataFileList]==0 {
        SetStatusText "No file chosen or found."
        return
    } 
    if $debugReviewAlarmLog {
        puts stderr "[llength $dataFileList] files found:"
        puts stderr [join $dataFileList \n]
    }

    set newData 0
    foreach dataFile $dataFileList {
        if ![file exists $dataDir/$dataFile] {
            if [string length $userFilename]==0 {
                SetStatusText "File $dataDir/$dataFile not found for that system and date."
            } else {
                SetStatusText "File $dataDir/$dataFile not found."
            }
            return ""
        }
        if {[string length $lastDataFile] && [file exists $lastDataFile] && \
              [file mtime $dataDir/$dataFile]>[file mtime $lastDataFile]} {
            if $debugReviewAlarmLog {
                puts stderr "$dataDir/$dataFile is newer than $lastDataFile"
            }
            set newData 1
        }
    }


    set fileList ""
    foreach file $dataFileList {
        lappend fileList $dataDir/$file
    }
    if  $debugReviewAlarmLog {
        puts stderr "fileList : $fileList"
    }

    if !$newData {
        set allMatch 0
        if [llength $fileList]==[llength $lastFileList] {
            set allMatch 1
            foreach file $lastFileList {
                if [lsearch -exact $fileList $file]==-1 {
                    set allMatch 0
                    break
                }
            } 
        }
        
        set lastFileList ""
        eval lappend lastFileList $fileList
        
        if {$allMatch && [string length $lastDataFile]} {
            set newData 0
            foreach file $fileList {
                if [file mtime $file]>[file mtime $lastDataFile] {
                    set newData 1
                } 
            }
            if !$newData {
                set fileList $lastDataFile
            }
        }
    }
    
    if [llength $fileList]>1 {
        if  $debugReviewAlarmLog {
            puts stderr "Combining [llength $fileList] files..."
        }
        SetStatusText "Combining [llength $fileList] files..."
        set dataDir /tmp
        set dataFile [APSTmpString]
        APSAddToTempFileList $dataDir/$dataFile
        eval exec sddscombine -recover $fileList $dataDir/$dataFile 
    } else {
        set dataDir /tmp
        set dataFile [APSTmpString]
        APSAddToTempFileList $dataDir/$dataFile
        exec sddsconvert -recover $fileList $dataDir/$dataFile 
    }
    set lastDataFile $dataDir/$dataFile
    if $debugReviewAlarmLog { puts stderr "dataFile : $dataFile   dataDir : $dataDir" }

    set dataRootname [file rootname $dataFile]
    set dataExtension [file extension $dataFile]
    set derefExtension .deref${dataExtension}1

    if [catch {APSConvertTimeToHours $hourToPlot0} result] {
        SetStatusText "Bad hours value for starting hour: $hourToPlot0: $result"
        return
    }
    set timeFilterMin \
      [exec timeconvert \
         -breakdown=year=$yearToPlot0,day=$dayToPlot0,month=$monthToPlot0,hour=$result]
    if [catch {APSConvertTimeToHours $hourToPlot1} result] {
        SetStatusText "Bad hours value for ending hour: $hourToPlot1: $result"
        return
    }
    set timeFilterMax \
      [exec timeconvert \
         -breakdown=year=$yearToPlot1,day=$dayToPlot1,month=$monthToPlot1,hour=$result]

    if [file exists [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}] {
        set tderef [file mtime [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}]
        set tdata  [file mtime $dataDir/$dataFile]
        if $debugReviewAlarmLog { 
            puts stderr "Old deref file exists from $tderef"
            puts stderr "Source file last changed at $tdata"
            puts stderr "Old time filter: $lastTimeFilterMin, $lastTimeFilterMax"
            puts stderr "New time filter: $timeFilterMin, $timeFilterMax"
        }
        if {$tdata>=$tderef || $timeFilterMin!=$lastTimeFilterMin || $timeFilterMax!=$lastTimeFilterMax} {
            if $debugReviewAlarmLog { 
                puts stderr "removing file [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}" 
                puts stderr "  $tdata>=$tderef or"
                puts stderr "  $timeFilterMin != $lastTimeFilterMin or"
                puts stderr "  $timeFilterMax != $lastTimeFilterMax"
            }
            exec rm -f [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}
        }
    }
    if $debugReviewAlarmLog { puts stderr "About to dereference."}

    if ![file exists [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}] {
        SetStatusText "Dereferencing..."
        set lastTimeFilterMin $timeFilterMin
        set lastTimeFilterMax $timeFilterMax
        if [catch {DereferenceAlarmLoggerData -isAlarmData $isAlarmData \
                     -fileName $dataDir/$dataFile \
                     -timeMin $timeFilterMin -timeMax $timeFilterMax \
                     -newFile [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}} result] {
            SetStatusText "Error: $result"
            return
        }
        if ![file exists [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}] {
            exec ln -s $dataDir/$dataFile [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}
        } else {
            APSAddToTempFileList [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension}
        }
    }
    # rootName is used for rootname in creating split and index files
    # dataFile is either a link to original data file (if it was already dereferenced) or
    # the dereferenced temperorary file
    set rootName [APSTmpDir]/${dataRootname}.$env(USER)$dataExtension
    set dataFile [APSTmpDir]/${apsScriptUser}${dataRootname}${derefExtension} 

    if $doSplit {
        SetStatusText "Splitting..."
        if [catch {SplitAlarmLoggerData -fileName $dataFile -rootName $rootName -isAlarmData $isAlarmData \
                     -minor $doMinor -major $doMajor -invalid $doInvalid -noAlarm $doNoAlarm -updateIffOld 1}] {
            global errorInfo
            APSAlertBox .[APSUniqueName  error] -errorMessage "Error splitting data: $errorInfo" 
            SetStatusText "Aborted due to error."
            return
        }
        APSAddToTempFileList $rootName.major $rootName.minor $rootName.invalid $rootName.no_alarm
    }

    if $doIndex {
        SetStatusText "Indexing..."
        if [catch {MakeIndexedControlNameList -fileName $dataFile -listFile $rootName.index \
                     -updateIffOld 1}] {
            global errorInfo
            APSAlertBox .[APSUniqueName  error] -errorMessage "Error making index: $errorInfo" 
            SetStatusText "Aborted due to error."
            return
        }
        APSAddToTempFileList $rootName.index
    }

    SetStatusText "Processing done."
    return [list $dataFile $rootName]
}

proc MakePlotTitle {args} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In MakePlotTitle"}
    set pvMatch ""
    set pvExclude ""
    set system ""
    set dataDir ""
    set dataFile ""
    set filterChoices ""
    APSParseArguments {pvMatch pvExclude system dataDir dataFile filterChoices}
    if [string compare $system Custom] {
        set title "$system alarms"
    } else {
        set title "$dataDir/[file tail $dataFile] alarms"
    }
    if [string compare "$pvMatch" "*"] {
        set title "$title match:[APSMakeSafeQualifierString $pvMatch]"
    }
    if [string length "$pvExclude"] {
        set title "$title exclude:[APSMakeSafeQualifierString $pvExclude]"
    }
    if [llength $filterChoices] {
        set title "$title: filters:[join $filterChoices ,]"
    }
    return $title
}

set histID 0

proc DoTimeHistPlots {args} {
    set versus TimeOfDayWS
    set individualPV 0
    APSStrictParseArguments {versus individualPV}
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoTimeHistPlots"}
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier timeUnit
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice
    global env dataDir histID
    global errorInfo isAlarmData
    
    global filterFileList filterDescriptionList filterChoices

    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
        -descriptions $filterDescriptionList -choices $filterChoices]

    DisablePlotButtons 
    set names [DoAlarmLogProcessing]
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        return
    }
    incr histID

    SetStatusText "Making histograms..."
    set divisor 1.0
    if {[string match TimeOfDay* $versus]} {
       set divisor 3600.0
    } 
  
    if !$individualPV {
        if [catch {MakeAlarmHistograms -rootName $rootName \
                 -minor $doMinor -major $doMajor -invalid $doInvalid -noAlarm $doNoAlarm \
                 -timeBin [expr $timeBin*$multiplier/$divisor] -versus $versus \
                 -pvMatch "$pvMatch" -pvExclude "$pvExclude" -isAlarmData $isAlarmData \
                 -extension his$histID -filterFiles $filterFilesSelected} exceptions] {
            APSAlertBox .[APSUniqueName error] -errorMessage "$errorInfo"
            SetStatusText "Aborted histogramming due to error."
            return
        }
        if $exceptions {
            SetStatusText "Warning: $exceptions unusual messages from histogram subroutine"
        }

        SetStatusText "Plotting..."
        set title \
        [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
             -dataDir $dataDir -dataFile $dataFile -filterChoices $filterChoices]

        set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
        if [catch {PlotAlarmHistograms \
                 -versus $versus -rootName $rootName -minor $doMinor -major $doMajor \
                 -noAlarm $doNoAlarm -invalid $doInvalid -separate 1 -title "$title" \
                 -extension his$histID -topline "$topline" -isAlarmData $isAlarmData }] {
		 puts stderr "$errorInfo"
            APSAlertBox .[APSUniqueName error] -errorMessage "$errorInfo"
	    
            SetStatusText "Aborted histogram plotting due to error."
            return
        }
        APSAddToTempFileList $rootName.minor.his$histID $rootName.major.his$histID $rootName.invalid.his$histID \
           $rootName.no_alarm.his$histID
    } else {
        if [catch {MakeIndividualPVAlarmHistograms -rootName $rootName -isAlarmData $isAlarmData \
                 -minor $doMinor -major $doMajor -invalid $doInvalid -noAlarm $doNoAlarm \
                 -timeBin [expr $timeBin*$multiplier/$divisor] -versus $versus \
                 -pvMatch "$pvMatch" -pvExclude "$pvExclude" \
                 -extension indPVhis -filterFiles $filterFilesSelected} exceptions] {
		 puts stderr "$errorInfo"
            APSAlertBox .[APSUniqueName error] -errorMessage "$errorInfo"
            SetStatusText "Aborted histogramming due to error."
            return
        }
        if $exceptions {
            SetStatusText "Warning: $exceptions unusual messages from histogram subroutine"
        }

        SetStatusText "Plotting..."
        set title \
        [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
             -dataDir $dataDir -dataFile $dataFile -filterChoices $filterChoices]

        set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
        if {[catch {PlotIndividualPVAlarmHistograms \
                        -versus $versus -rootName $rootName -minor $doMinor -major $doMajor -isAlarmData $isAlarmData \
                        -noAlarm $doNoAlarm -invalid $doInvalid -separate 1 -title "$title" \
                        -extension indPVhis -topline "$topline" } result ]} {
            puts stderr "$result"
            APSAlertBox .[APSUniqueName error] -errorMessage "$result"
            SetStatusText "Aborted histogram plotting due to error."
            return
        }
    }

    EnablePlotButtons
}

proc MakeIndividualPVAlarmHistograms {args} {
    global debugReviewAlarmLog 
    if $debugReviewAlarmLog { puts stderr "In MakeAlarmHistograms"}
    set rootName ""
    set major 0
    set minor 0
    set invalid 0
    set noAlarm 0
    set timeBin 0
    set pvMatch *
    set pvExclude ""
    set extension indPVhis
    set versus TimeOfDayWS
    set filterFiles ""
    set isAlarmData 1
    APSParseArguments {rootName major minor invalid timeBin pvMatch pvExclude extension \
                         noAlarm versus filterFiles isAlarmData}
    if {$timeBin<=0 || [string length $rootName]==0} {
        return -code error -errorinfo "Invalid arguments" 0
    }
   
    if {!$minor && !$major && !$invalid && !$noAlarm} {
        return -code error -errorinfo "No severities selected" 0
    }

    if [llength $filterFiles] {
        set filterFile [APSTmpDir]/[APSTmpString]
        APSAddToTempFileList $filterFile
        if [catch {eval exec sddscombine -recover -merge $filterFiles -pipe=out \
                     | sddssort -pipe=in -column=ControlName -unique $filterFile} result] {
            return -code error "MakeAlarmHistograms: $result"
        }
        set selectCommand "| sddsselect -pipe $filterFile -match=ControlName -reuse=page,row"
    } else {
        set selectCommand ""
    }

    # make time histograms of various severity alarms
    set exceptions 0
    set no_alarm $noAlarm
    if !$isAlarmData {
        set severityList all
        set all 1
    } else {
        set severityList [list minor major invalid no_alarm]
    }
    foreach severity $severityList {
        if [subst \$$severity] {
            if ![file exists $rootName.$severity] {
                return -code error -errorinfo "File not found: $rootName.$severity" 0
            }
            if {[string length "$pvMatch"] || [string length "$pvExclude"] || [string length $selectCommand]} {
	        global fileList$severity ControlNameList$severity
	        set fileList$severity ""
		set ControlNameList$severity ""
	        set severityFile [APSTmpDir]/[APSTmpString]
		APSAddToTempFileList $severityFile
                set timeArg ""
                set filterList {}
                if [string compare "$pvMatch" "*"] {
                    lappend filterList [MakeMatchOption -pvMatch $pvMatch]
                }
                if [string length "$pvExclude"] {
                    lappend filterList  [MakeMatchOption -pvExclude $pvExclude]
                }
                if ![catch { eval exec sddsprocess $rootName.$severity -pipe=out \
                              $filterList -nowarning \
                              $selectCommand \
			    | sddsprocess -pipe=in $severityFile -nowarning} result] {
		    if {[file exists $severityFile]} {       
	                 set ControlNameList ""
                         set arows 0

                         catch {exec sdds2stream $severityFile -rows} rows     
                         set arows [string trimright [APSStringTrimRight ${rows} rows]]
		         if $arows {
		            catch {APSGetSDDSColumn -fileName $severityFile \
                                   -column ControlName} ControlNameList
                            if [llength $ControlNameList] {
		                set uniqueControlNameList ""
		                foreach name $ControlNameList {
                                   if {[lsearch $uniqueControlNameList $name] < 0} {
			                lappend uniqueControlNameList $name
			           }
		                }
		                set count 0
		                foreach conNam $uniqueControlNameList {
                                  if [catch {eval exec sddsprocess $severityFile -pipe=out -nowarning \
				              -match=column,ControlName=$conNam \
                                            | sddshist -pipe=in $rootName.$severity.$extension.$count \
                                              -data=$versus -sides -size=$timeBin} message] {
                                      incr exceptions
				  }
				  APSAddToTempFileList $rootName.$severity.$extension.$count
				  lappend fileList$severity $rootName.$severity.$extension.$count
				  lappend ControlNameList$severity $conNam
				  incr count
				}
			    }
			  }
		    }
                }
            } else {
                return -code error "No PV selected for processing."
	    }
        }
    }
    return -code ok $exceptions
}

proc PlotIndividualPVAlarmHistograms {args} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In PlotAlarmHistograms"}
    set rootName ""
    set minor 0
    set major 0
    set invalid 0
    set noAlarm 0
    set separate 0
    set clipHead 0
    set title ""
    set topline ""
    set extension indPVhis
    set versus TimeOfDayWS
    set isAlarmData 1
    APSParseArguments {rootName minor major invalid separate clipHead title extension noAlarm \
                     versus topline isAlarmData}

    if {[string length $rootName]==0} {
        return -code error "Empty file rootname"
    }
    set sddsplotArgs {}
    set dataPresent 0
    if $separate { lappend sddsplotArgs -separate }
    if $clipHead { lappend sddsplotArgs "-clip=1,0" }
    set no_alarm $noAlarm
    if !$isAlarmData {
        set severityList all
        set all 1
    } else {
        set severityList [list minor major invalid no_alarm]
    }
    foreach severity $severityList {
        if [subst \$$severity] {
            global fileList$severity ControlNameList$severity
            if {[llength [set fileList$severity]] && [llength [set ControlNameList$severity]]} {
                 if [lsearch -exact [list Time TimeWS TimeIOC] $versus]!=-1 {
                    lappend sddsplotArgs -ticks=xtime
                 }
		 foreach conNam [set ControlNameList$severity] {
                    set topline1 "[string toupper $severity] alarms for $conNam: [APSMakeSafeQualifierString $topline]"
		    set file [lindex [set fileList$severity] [lsearch [set ControlNameList$severity] $conNam]]
                    lappend sddsplotArgs "-column=$versus,frequency" "$file" "-topline=$topline1"
                    set dataPresent 1
		 }
	     } else {
                 SetStatusText "No data found for $severity alarms"
	     }
        }
    } 
    if $dataPresent {
        eval exec sddsplot -same=x,global {"-title=[APSMakeSafeQualifierString $title]"} \
          -graph=line,vary -ylabel=NumberOfAlarms $sddsplotArgs &
    }
    return -code ok
}

set countsID 0

proc DoTotalCountsPlots {} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoTotalCountsPlots"}
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice
    global env dataDir countsID countThreshold countSortChoice fixedCountScales
    global filterFileList filterDescriptionList filterChoices isAlarmData

    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
        -descriptions $filterDescriptionList -choices $filterChoices]

    incr countsID 
    DisablePlotButtons 
    set names [DoAlarmLogProcessing]
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        return
    }
    
    set t ""
    if {[catch {exec sdds2stream $dataFile -array=ControlNameString} allPVs]} {
    } else {
        foreach match [split $pvMatch ','] {
            if {[lsearch -glob $allPVs $pvMatch] == -1} {
                lappend t "This alarm logger is not logging any PVs that match $match"
            }
        }
    }

    SetStatusText "Counting alarms..."
    CountAlarmOccurences -rootName $rootName \
      -minor $doMinor -major $doMajor -invalid $doInvalid -noAlarm $doNoAlarm \
      -indexFile $rootName.index -pvMatch "$pvMatch" -pvExclude "$pvExclude" \
      -countMin $countThreshold -sortBy $countSortChoice \
      -extension counts$countsID -filterFiles $filterFilesSelected \
      -isAlarmData $isAlarmData
    APSAddToTempFileList $rootName.minor.counts$countsID $rootName.major.counts$countsID $rootName.invalid.counts$countsID $rootName.no_alarm.counts$countsID

    SetStatusText "Plotting..."
    set title \
      [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
         -dataDir $dataDir -dataFile $dataFile -filterFileList $filterChoices]
    if {$t != ""} {
        set title "[join $t \n]\n$title"
    }

    set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
    PlotAlarmOccurences -rootName $rootName -minor $doMinor -major $doMajor -invalid $doInvalid \
      -noAlarm $doNoAlarm \
      -title "$title" -extension counts$countsID -fixedScale $fixedCountScales \
      -topline "$topline" -isAlarmData $isAlarmData

    PrintAlarmOccurences -rootName $rootName -minor $doMinor -major $doMajor -invalid $doInvalid \
      -noAlarm $doNoAlarm \
      -title "$title" -extension counts$countsID \
      -topline "$topline" -isAlarmData $isAlarmData

    EnablePlotButtons 
}

proc DoAlarmLogPrintout {} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoAlarmLogPrintout"}
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice sortPrintoutBy 
    global env dataDir countsID countThreshold countSortChoice fixedCountScales
    global filterFileList filterDescriptionList filterChoices isAlarmData

    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
        -descriptions $filterDescriptionList -choices $filterChoices]
   
    DisablePlotButtons 
    set names [DoAlarmLogProcessing -doSplit 0 -doIndex 0]
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        EnablePlotButtons
        return
    }

    set title \
      [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
         -dataDir $dataDir -dataFile $dataFile -filterChoices $filterChoices]

    set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
    SetStatusText "Preparing printout... "
    set defFile $rootName.ps
    if [catch {PrintAlarmLog -dataFile $dataFile -outputFile $rootName.txt \
                 -pvMatch "$pvMatch" -pvExclude "$pvExclude" -sortBy $sortPrintoutBy \
                 -filterFiles $filterFilesSelected -title $title \
                 -topline $topline -isAlarmData $isAlarmData \
                 -major $doMajor -minor $doMinor -invalid $doInvalid -noAlarm $doNoAlarm} result] {
        SetStatusText "$result"
        return 
    }
    
    APSFileDisplayWindow [APSUniqueName .] -fileName $rootName.txt \
      -deleteOnClose 1 -width 165 -height 40 -contextHelp \
      "Alarm log printout: $title" -font smallFixedFont \
      -comment "$title\n$topline" \
      -printCommand "enscript -r"

    EnablePlotButtons 
}



proc DisablePlotButtons {} {
    APSDisableButton .userFrame.plot.thplot0.button
    APSDisableButton .userFrame.plot.thplot1.button
    APSDisableButton .userFrame.plot.thplot2.button
    APSDisableButton .userFrame.plot.tcplot.button
    APSDisableButton .userFrame.plot.print.button
    APSDisableButton .userFrame.plot.overlap.button
    catch {APSDisableButton .userFrame.special.frame.printPS.button}
    catch {APSDisableButton .userFrame.special.frame.caswAnalysis1.button}
    catch {APSDisableButton .userFrame.special.frame.caswAnalysis2.button}
    catch {APSDisableButton .userFrame.special.frame.caswAnalysis3.button}
}

proc EnablePlotButtons {} {
    APSEnableButton .userFrame.plot.thplot0.button
    APSEnableButton .userFrame.plot.thplot1.button
    APSEnableButton .userFrame.plot.thplot2.button
    APSEnableButton .userFrame.plot.tcplot.button
    APSEnableButton .userFrame.plot.print.button
    APSEnableButton .userFrame.plot.overlap.button
    catch {APSEnableButton .userFrame.special.frame.printPS.button}
    catch {APSEnableButton .userFrame.special.frame.caswAnalysis1.button}
    catch {APSEnableButton .userFrame.special.frame.caswAnalysis2.button}
    catch {APSEnableButton .userFrame.special.frame.caswAnalysis3.button}
}


set LastPickFileDir ""
set pickFileDir ""
proc PickFilename { } { 
    global userFilename pickFileDir lastPickFileDir dataDir defaultDataDir userFilter
    global systemChoice SystemRootnames  Systems
    set index [lsearch $Systems $systemChoice]

    if [string length [lindex $SystemRootnames $index]] {
        set listFilter [lindex $SystemRootnames $index]-????-???-????*
    } elseif [string length $userFilter] {
        set listFilter ${userFilter}*
    } else {
        set listFilter *-????-???-????*
    }

    if [string compare $systemChoice Custom] {
        set pickFileDir $defaultDataDir 
    } else {
        set pickFileDir $dataDir
    }
    set userFilename [APSFileSelectDialog .[APSTmpString] -listDir $pickFileDir \
                        -contextHelp "File select box for ReviewAlarmLog data file." \
                       -listFilter $listFilter ]
    if [string length $userFilename]==0 return
    set pickFileDir [file dirname $userFilename]
    set dataDir $pickFileDir
    set userFilename [file tail $userFilename]
}

proc SetNoncustomMode {} {
    global userFilename pickFileWidget filterWidget filterFileWidget filterFileList filterDescriptionList filterChoices
    global directoryWidget filenameWidget  defaultDataDir pvFilterFrame systemChoice dataDir
    set userFilename ""
    APSDisableButton $pickFileWidget
    global Systems SystemRootnames IsAlarmLogger SystemIndex
    set index [lsearch $Systems $systemChoice]
    set SystemIndex $index
    set dataDir $defaultDataDir/[lindex $SystemRootnames $index]
    $filterWidget configure -state disabled
    $directoryWidget configure -state disabled
    $filenameWidget configure -state disabled

    set filterIndexFile $defaultDataDir/FilterFiles/$systemChoice.index
    set filterDescriptionList {}
    set filterFileList {}
    set filterChoices {}
    if [file exists $filterIndexFile] {
        if {[catch {APSGetSDDSColumn -fileName $filterIndexFile -column FilterDescription} filterDescriptionList] || \
              [catch {APSGetSDDSColumn -fileName $filterIndexFile -column FilterFile} filterFileList]} {
            APSSetVarAndUpdate statusText "Problem reading filter index file for $systemChoice."
            return
        }
    }

    if ![llength $filterDescriptionList] {
        if {[string length $filterFileWidget] && [winfo exists $filterFileWidget]} {
            destroy $filterFileWidget
        }
        return
    }

    if {[string length $filterFileWidget] && [winfo exists $filterFileWidget]} {
        $filterFileWidget.userFrame.sl.listbox delete 0 end
        eval $filterFileWidget.userFrame.sl.listbox insert 0 $filterDescriptionList
    } else {
        APSScrolledListWindow .fflist -parent $pvFilterFrame -height 3 \
            -selectionVar filterChoices -label "Filter choices"  -autoAccept 1 \
            -closeButton 0 -acceptButton 0 -clearButton 1
        set filterFileWidget $pvFilterFrame.fflist
        eval $filterFileWidget.userFrame.sl.listbox insert 0 $filterDescriptionList
    }
}

proc SetCustomMode {} {
    global userFilename pickFileWidget filterWidget
    global directoryWidget filenameWidget filterFileWidget
    set userFilename ""
    APSEnableButton $pickFileWidget
    $filterWidget configure -state normal
    $directoryWidget configure -state normal
    $filenameWidget configure -state normal
    if {[string length $filterFileWidget] && [winfo exists $filterFileWidget]} {
        destroy $filterFileWidget
    }
}

proc MakeFilterFileSelectionList {args} {
    global defaultDataDir
    set files {}
    set descriptions {}
    set choices {} 
    APSStrictParseArguments {files descriptions choices}
    set selectionList {}
    foreach elem $choices {
        set index [lsearch -exact $descriptions $elem]
        if $index!=-1 {
            lappend selectionList $defaultDataDir/FilterFiles/[lindex $files $index]
        } else {
            APSSetVarAndUpdate status "Not found: $elem"
        }
    }
    return $selectionList
}

proc DoAlarmEventOverlap {} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoAlarmEventOverlap"}
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice sortPrintoutBy 
    global env dataDir countsID countThreshold countSortChoice fixedCountScales
    global filterFileList filterDescriptionList filterChoices
    global isAlarmData

    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
        -descriptions $filterDescriptionList -choices $filterChoices]
    
    set filterList {}
    if [string compare "$pvMatch" "*"] {
        lappend filterList [MakeMatchOption -pvMatch $pvMatch]
    }
    if [string length "$pvExclude"] {
        lappend filterList [MakeMatchOption -pvExclude $pvExclude]
    }
    DisablePlotButtons 
    if $debugReviewAlarmLog { puts stderr "Doing alarm log processing"}
    set names [DoAlarmLogProcessing -doSplit 0 -doIndex 0 ]
    if $debugReviewAlarmLog { puts stderr "Finished with alarm log processing"}
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        EnablePlotButtons
        return
    }

    set tmpRoot [APSTmpDir]/[APSTmpString]
    set sevFilter ""
    if !$isAlarmData {
        set severityList all
        set severityVarList doAll
        set doAll 1
    } else {
        set severityList [list minor major invalid no_alarm]
        set severityVarList [list doMinor doMajor doInvalid doNoAlarm]
        foreach severity $severityList sevVar $severityVarList {
            if {[set $sevVar]} {
                if [string length $sevFilter]==0 {
                    set sevFilter -match=column,AlarmSeverity=[string toupper $severity]
                } else {
                    set sevFilter $sevFilter,AlarmSeverity=[string toupper $severity],|
                }
            }
        }
    }
    if [string length $sevFilter] {
        lappend filterList $sevFilter
    }

    APSAddToTempFileList $tmpRoot.data 
    if [llength $filterList] {
        SetStatusText "Filtering..."
        if $debugReviewAlarmLog { puts stderr "Filter is $filterList"}
        if [catch {eval exec sddsprocess $filterList $dataFile $tmpRoot.data} result] {
            SetStatusText "$result"
            return
        }
        set dataFile $tmpRoot.data
    }
          
    SetStatusText "Finding list of unique channels..."
    # Figure out what channels are present in the data
    if [catch {exec sddssort $dataFile -pipe=out -column=ControlNameIndex -unique \
             | sdds2stream -pipe=in -column=ControlName -ignoreFormats} ControlNameList] {
        EnablePlotButtons
        SetStatusText "$ControlNameList"
        return
    }
    set ControlNameList [lsort $ControlNameList]
    set itemList ""
    foreach item $ControlNameList {
        lappend itemList [string trim $item "\n"]
    }
    set size [expr $timeBin*$multiplier]
    while 1 {
        if {[catch {APSChooseItemFromList -name "Choose event to overlap with" \
                      -itemList $itemList -returnIndices 0} overlapEvent] || \
              ![string length $overlapEvent]} {
            EnablePlotButtons
            if [string length $overlapEvent] {
                SetStatusText "$overlapEvent"
            }
            return
        }

        SetStatusText "Doing overlap analysis with $overlapEvent..."
        if [catch {exec sddseventhist $dataFile -pipe=out -dataColumn=TimeWS -eventIdentifier=ControlName \
                     -overlapEvent=$overlapEvent -sizeOfBins=$size \
                     | sddsprocess -pipe -process=*Overlap,sum,%sSum \
                     | sddscollapse -pipe \
                     | sddstranspose -pipe -oldColumnName=ControlName -rootname=Overlap \
                     | sddsprocess -pipe -match=column,ControlName=*OverlapSum \
                     -reedit=column,ControlName,%/.${overlapEvent}OverlapSum// \
                     -nowarning -filter=column,Overlap,0,0,! \
                     | sddssort -pipe -column=Overlap,decreasing \
                     | tee $rootName.overlap \
                     | sddsprintout -pipe=in $rootName.txt \
                     "-title=Alarm overlap printout of all events with $overlapEvent" \
                     -column=ControlName,format=%40s \
                     -column=Overlap} result] {
            SetStatusText "$result"
            return
        }
        APSFileDisplayWindow [APSUniqueName .] -fileName $rootName.txt \
          -sddsExportableFile $rootName.overlap \
          -deleteOnClose 1 -width 160 -height 40 -contextHelp \
          "Alarm overlap printout of all events with $overlapEvent" \
          -comment "Alarm overlap printout of all events with $overlapEvent" \
          -font TkFixedFont \
          -printCommand "enscript -r"
        SetStatusText "Done."
    }
    EnablePlotButtons 
}

proc DoAlarmLogPowerSupplyTrip {} {
    global debugReviewAlarmLog
    if $debugReviewAlarmLog { puts stderr "In DoAlarmLogPrintout"}
    global doMajor doMinor doInvalid doNoAlarm interestLevel pvMatch pvExclude timeBin multiplier
    global dayToPlot0 monthToPlot0 yearToPlot0 hourToPlot0
    global dayToPlot1 monthToPlot1 yearToPlot1 hourToPlot1
    global systemChoice sortPrintoutBy  
    global env dataDir countsID countThreshold countSortChoice fixedCountScales
    global filterFileList filterDescriptionList filterChoices defFile
    
    if [string compare $systemChoice SR]!=0 {
        SetStatusText "Power Supply Trip is only valid for SR."
        bell
        return
    }
    
    set filterFilesSelected [MakeFilterFileSelectionList -files $filterFileList \
                               -descriptions $filterDescriptionList -choices $filterChoices]

    DisablePlotButtons 
    set names [DoAlarmLogProcessing -doSplit 0 -doIndex 0]
    set dataFile [lindex $names 0]
    set rootName [lindex $names 1]
    if [string length $dataFile]==0 {
        EnablePlotButtons
        return
    }
    
    set title \
      [MakePlotTitle -pvMatch "$pvMatch" -pvExclude "$pvExclude" -system $systemChoice \
         -dataDir $dataDir -dataFile $dataFile -filterChoices $filterChoices]

    set topline "$yearToPlot0/$monthToPlot0/$dayToPlot0@$hourToPlot0 - $yearToPlot1/$monthToPlot1/$dayToPlot1@$hourToPlot1"
    SetStatusText "Preparing power supply printout... "
    if [catch {PrintAlarmLog -dataFile $dataFile -outputFile $rootName.ps.txt -decode 1\
                 -pvMatch "*StatusCALC,*OnOffStatusM" -pvExclude "$pvExclude" -sortBy $sortPrintoutBy \
                 -filterFiles $filterFilesSelected -title $title \
                 -topline $topline \
                 -major $doMajor -minor $doMinor -invalid $doInvalid -noAlarm $doNoAlarm} result] {
        SetStatusText "$result"
        return 
    }
    
    APSFileDisplayWindow [APSUniqueName .] -fileName $rootName.ps.txt \
      -deleteOnClose 1 -width 160 -height 40 -contextHelp \
      "Alarm log printout: $title" \
      -comment "$title\n$topline" -font TkFixedFont \
      -printCommand "enscript -r"

    EnablePlotButtons 
    return
}

proc SetTimeBinByUnits {} {
    global timeUnit multiplier
    switch $timeUnit {
        hours {
            set multiplier 3600.0
        }
        days {
            set multiplier [expr 24.0*3600.0]
        }
        weeks {
            set multiplier [expr 7*24.0*3600.0]
        }
        seconds {
            set multiplier 1.0
        }
    }
  #  puts $multiplier
}

dp_atexit append {SetStatusText "Cleaning up prior to exit..."}
SetCustomMode
