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

#
# $Log: not supported by cvs2svn $
# Revision 1.4  2008/09/22 20:20:09  soliday
# Updated to use the new data logger format.
#
# Revision 1.3  1998/07/14 15:17:11  borland
# New version per D. Blachowicz.  Now correctly uses the hour specifications
# from the user in computing the beam time.
#
# Revision 1.2  1998/05/12 16:58:08  emery
# Corrected the lib_patch directory from lib_PATCH to lib_patch.
#
# Revision 1.1  1998/02/20 21:49:10  borland
# First version per D. Blachowicz.
#
# 

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.5 $ \$Author: soliday $"

set nameList " "
lappend nameList {LINAC (electron)} {LINAC (positron)} {LTP} {PAR}\
                 {Booster (BTS line)} {Booster (BTS dump)} {Booster (end BTS line)}

set nameVarList " "
lappend nameVarList "L3:CM1" "L5:CM1" "LTP:PH1:Current" "P1P1:sum"\
                    "BTS:APH1:sum" "BTX:PH1:sum" "BTS:CPH2:sum"
 
set linacParDir /home/helios/oagData/monitoring/Current
set boosterDir /home/helios/oagData/monitoring/Charge


APSApplication . -name InjectorBeamTimeReview -version $CVSRevisionAuthor \
   -overview "Provides a number of hours during which beam was present for a selected \
   part of injector."


set statusText "Ready"

APSScrolledStatus .status -parent .userFrame -textVariable statusText -width 69 \
   -contextHelp "Displays number of days of interest and number of hours during \
   which beam was present for a selected part of injector." 

update


set userChoice [lindex $nameVarList 0]

APSRadioButtonFrame .machineRB -parent .userFrame -label "Part Of Injector: " \
   -variable userChoice -buttonList $nameList -valueList $nameVarList \
   -contextHelp "Button for selection of readback and control variables for \
   machine of interest."

update

# makes frame for date/time selection widgets (for range
# of dates to process)

proc MakeDateTimeFrame {widget args} {
     set parent .

     APSStrictParseArguments {parent}

     set label "Date/Time Range of Interest"

     APSFrame $widget -parent $parent -label $label

     set w $parent$widget.frame

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

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

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

     ResetMonDataFileList
     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
}

# finds the files between the chosen dates

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 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 MonDataFindFiles {} {
     global DataFileList Rootname DataDir statusText
     global StartMonth StartYear StartDay StartHour
     global EndMonth EndYear EndDay EndHour userChoice
     
    if {$DataDir == "/home/helios/oagData/monitoring/Current"} {
        set interval 64
    } elseif {$DataDir == "/home/helios/oagData/monitoring/Charge"} {
        set interval 8
    }
    append pvFiles "[FindPVDataFiles -ReadbackName $userChoice -SampleIntervals $interval \
                     -startDateList [APSFormatDate -year $StartYear -month $StartMonth \
                                     -day $StartDay -dateFormat list] \
                     -endDateList [APSFormatDate -year $EndYear -month $EndMonth \
                                   -day $EndDay -dateFormat list]] "
    append pvFiles "[FindPVDataFiles -ReadbackName GunRate -SampleIntervals $interval \
                     -startDateList [APSFormatDate -year $StartYear -month $StartMonth \
                                     -day $StartDay -dateFormat list] \
                     -endDateList [APSFormatDate -year $EndYear -month $EndMonth \
                                   -day $EndDay -dateFormat list]] "

    if ![llength $pvFiles] {
        set DataFileList ""
        set statusText "0 files found for time range."
        return
    }
    set DataFileList /tmp/[APSTmpString]
    APSAddToTempFileList $DataFileList
    if {[catch {eval exec sddscombinelogfiles $pvFiles $DataFileList} result]} {
        APSSetVarAndUpdate status $result
    }
    set statusText "[llength $DataFileList] files found. Working..."
    update
}

proc ResetMonDataFileList {} {
     global DataFileList 

     set DataFileList " "
     update
}

proc Process {} {
     global userChoice Rootname DataDir linacParDir boosterDir
     
     switch -glob -- $userChoice "
            L* -
            P1P1:sum {
                 set Rootname Current
                 set DataDir $linacParDir
            }
            B* {
                set Rootname ChargeFast
                set DataDir $boosterDir
            }
     "
     DayCorrection
}

#DayCorrection is finding discrepancy in the input dates 

proc DayCorrection {} {
     global StartMonth StartYear StartDay StartHour StartTime
     global EndMonth EndYear EndDay EndHour EndTime
     global statusText

     if {[catch {APSConvertTimeToHours $StartHour} hour0] || \
            [catch {APSConvertTimeToHours $EndHour} hour1]} {
             APSAlertBox [APSUniqueName .] -errorMessage "Bad hour syntax in time filter"
	     return
     }

     if [catch {eval exec timeconvert -breakDown=year=$StartYear,month=$StartMonth,day=$StartDay,hour=$hour0} StartTime] {
         set statusText "Error: $StartTime"
     }
     if [catch {eval exec timeconvert -breakDown=year=$EndYear,month=$EndMonth,day=$EndDay,hour=$hour1} EndTime] {
         set statusText "Error: $EndTime"
     }

     if {$StartYear > $EndYear} {
         set statusText {Starting year must be <= ending year.}
     } elseif {$StartYear == $EndYear} {
        if {$StartMonth > $EndMonth} {
           set statusText {Starting month must be <= ending month.}
        } elseif {$StartMonth == $EndMonth} {
           if {$StartDay > $EndDay} {
              set statusText {Starting day must be <= ending day.}
           } else {
             MonDataFindFiles
             CallTime
           }   
        } else { 
           MonDataFindFiles
           CallTime
        }
     } else {
        MonDataFindFiles
        CallTime
     }
}


proc CallTime {} {
     global Rootname DataDir userChoice lowerLim partOfMachine
     global finalList DataFileList nameList nameVarList
     set finalList " "

     set partOfMachine [lindex $nameList [lsearch $nameVarList $userChoice]]
     
    if {![llength $DataFileList]} {
        return
    }
    set finalList $DataFileList
    

     switch $userChoice {
            L3:CM1 { 
                 set lowerLim 0.1
                 WithGunRateCorrectionFinalProcess
            }
            L5:CM1 {
                 set lowerLim 0.001
                 WithGunRateCorrectionFinalProcess
            }
            LTP:PH1:Current {
                 set lowerLim 0.1
                 WithGunRateCorrectionFinalProcess
            }
            P1P1:sum {
                 set lowerLim 50
                 NoGunRateCorrectionFinalProcess
            }
            BTS:APH1:sum {
                 set lowerLim 50
                 WithGunRateCorrectionFinalProcess
            }
            BTX:PH1:sum {
                 set lowerLim 50
                 NoGunRateCorrectionFinalProcess
            }
            BTS:CPH2:sum {
                 set lowerLim 50
                 WithGunRateCorrectionFinalProcess 
            }
     }
}

proc NoGunRateCorrectionFinalProcess {} {
     global userChoice finalList lowerLim partOfMachine
     global StartTime EndTime
     set highLim 1e300
     set tmpFile /tmp/[APSTmpString]

     if [catch {eval exec sddsprocess $finalList {"-pipe=out"} {"-noWarnings"} \
        {"-filter=column,Time,${StartTime},${EndTime}"} \
        {"-process=Time,count,TotalSamples"} \
        {"-process=Time,spread,TimeSpread"}\
	{"-filter=col,${userChoice},${lowerLim},${highLim}"}\
	{"-process=Time,count,SamplesWithBeam"}\
        {"-define=parameter,factor,2.78e-4"}\
        {"-define=parameter,TimeWithBeam,TimeSpread SamplesWithBeam * TotalSamples / factor *,units=h"}\
        | sdds2stream -pipe=in\
	{"-parameter=TimeWithBeam"}} result] {
           APSSetVarAndUpdate statusText "Error: [format "%6.6f" $result]"
	} else {
           APSSetVarAndUpdate statusText \
              "Beam time was [format "%6.6f" $result] hours in $partOfMachine."
	}
}


proc WithGunRateCorrectionFinalProcess {} {
     global userChoice finalList lowerLim partOfMachine
     global StartTime EndTime
     set highLim 1e300
     set tmpFile /tmp/[APSTmpString]

     if [catch {eval exec sddsprocess $finalList {"-pipe=out"} {"-noWarnings"}\
         {"-filter=column,Time,${StartTime},${EndTime}"} \
        {"-process=Time,count,TotalSamples"}\
        {"-process=Time,spread,TimeSpread"}\
        {"-redefine=column,$userChoice,GunRate 0 > ? $userChoice : 0 $ "}\
	{"-filter=col,${userChoice},${lowerLim},${highLim}"}\
	{"-process=Time,count,SamplesWithBeam"}\
        {"-define=parameter,factor,2.78e-4"}\
        {"-define=parameter,TimeWithBeam,TimeSpread SamplesWithBeam * TotalSamples / factor *,units=h"}\
        | sdds2stream -pipe=in\
	{"-parameter=TimeWithBeam"}} result] {
           APSSetVarAndUpdate statusText "Error: [format "%6.6f" $result]"
	} else {
           APSSetVarAndUpdate statusText \
              "Beam time was [format "%6.6f" $result] hours in $partOfMachine."
	}
}

MakeDateTimeFrame .timeFrame -parent .userFrame  


APSButton .bt1 -parent .userFrame -text Process -command {Process} \
   -contextHelp "Invokes a setup of files of interest for selected dates\
   and calculates an amount of beam time for selected machine" 

update

