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

# $Log: not supported by cvs2svn $
# Revision 1.4  2000/01/25 15:51:54  borland
# New version per D. Blachowicz with changes requested by H. Friedsam.
#
# Revision 1.3  1999/09/20 13:33:25  borland
# New version per D. Blachowicz:
# I did some changes and I added one more sddsoutlier operation to detect
# "infinity" value in the data. It was a problem when some sensors had this
# value and the user tried to do a plot with an offset. Now, "infinity" value
# is substituted by the closest valuable number in the chosen time frame.
# The best area of above situation is day 08/01/99 when sensors S13 and S17
# were off.
# The new code is also detecting scenario when all sensors are off and the user
# is receiving proper information from the application.
#
# Revision 1.2  1999/07/29 16:02:45  borland
# New version per D. Blachowicz with processing of temperature readings.
#
# Revision 1.1  1999/01/29 16:18:27  borland
# First version, by 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: borland $"

APSApplication . -name HLSapplication -version $CVSRevisionAuthor \
  -overview "This application will help to analyze SR Hydrostatic Level System data."

set HLSstatus Ready.
APSScrolledStatus .status -parent .userFrame -width 75 \
        -textVariable HLSstatus -withButtons 1

set activeSensor ""
set selectionDisplayList ""

proc SetHLSStatus {text} {
     global HLSstatus
     set HLSstatus "[exec date +%H:%M:%S] $text"
     update
}

proc MakeDateTimeFrame {widget args} {
    set parent .
    set rootname ""
    APSStrictParseArguments {parent rootname glitchMode}

    set label "Date/Time Range of Interest"

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

    APSDateTimeAdjEntry .startDate -parent $w \
       -yearVariable ${rootname}StartYear \
       -monthVariable ${rootname}StartMonth \
       -dayVariable ${rootname}StartDay \
       -hourVariable ${rootname}StartHour \
       -label "Starting date/time (year, month, day, hour): " -defaultHour 0 \
       -command "" 
    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 "" 

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

proc MakeOutputFrame {} {
     global analysisOption w3 w4 finalSensorsList refSensorOn fourierVar
     global selectionDisplayList separate offset analysis
     set analysisOption Initial
     set refSensorOn 0

     if ![string compare $fourierVar yes] {
          set radioButList [list {Raw data} {Filtered data} {Offset by average} {Fourier Transforms}]
	  set radioValList [list Initial Filtered Averaged Fourier]
	  set commandList [list {MakeDisplayListForSelection Initial} \
	                        {MakeDisplayListForSelection Filtered} \
				{MakeDisplayListForSelection Averaged} \
				{MakeDisplayListForSelection Fourier}]
     } else {
          set radioButList [list {Raw data} {Filtered data} {Offset by average}]
	  set radioValList [list Initial Filtered Averaged]
	  set commandList [list {MakeDisplayListForSelection Initial} \
	                        {MakeDisplayListForSelection Filtered} \
				{MakeDisplayListForSelection Averaged}]
     }
     APSFrame .frame1 -parent .userFrame -label "Review Section" -relief raised -labelFont {courier 12 bold}
     set w4 .userFrame.frame1.frame
     APSRadioButtonFrame .dataOPT -parent $w4 -label " Data Review Options:  " \
	-limitPerRow 4 -variable analysisOption -buttonList $radioButList \
	-valueList $radioValList -orientation vertical -packOption "-side left" \
	-commandList $commandList -relief flat \
	-contextHelp "Selection of data file through all stages of processing. \
         Fast Fourier Transforms radio button is going to appear after the transforms \
	 are invoked."

     APSFrame .frame2 -parent $w4 -label "Reference Sensors" \
        -packOption "-side left"
     APSScrolledList .refList -parent $w4.frame2.frame -height 3 \
        -name "Reference Sensors" -itemList $finalSensorsList \
        -selectMode single -callback SetReferenceSensor \
	-contextHelp "List of sensors in the processed data which may be used for a reference. \
	 Double click over the position of the sensors will invoke reference processing. \
	 All files in the Data Analysis Options box will reference to the chosen sensor. \
	 To clear references just push \"Clear\" button or choose another sensor."
     APSButton .clear -parent $w4.frame2.frame -text "Clear Selection" \
        -command ClearSelection -contextHelp "To clear all references and reset Data Analysis \
	 Options files to mode zero. Invokes deleting of all previous reference files."
     $w4.frame2.frame.clear.button configure -width 22
     APSDisableButton $w4.frame2.frame.clear.button

     APSFrame .frame3 -parent $w4 -label "Plot Selection" -packOption "-side right"
     APSScrolledList .plotList -parent $w4.frame3.frame -height 3 \
        -name "Plot Selection" -itemList $selectionDisplayList \
        -selectMode extended -callback "" \
	-contextHelp "Select sensor(s) to be plotted by custom set procedure."
     APSButton .plot -parent $w4.frame3.frame -text "Plot" -packOption "-side right" \
        -command PlotSelection -contextHelp "Invokes custom built plots for a currently \
         active review option."
     APSCheckButtonFrame .checkBut -parent $w4.frame3.frame \
        -buttonList [list "separate " "offset"] -variableList [list separate offset] \
	-orientation horizontal -label "" -relief flat -packOption "-anchor w" \
	-contextHelp "Choose \"separate\" if you want to view plots on separate displays. \
	Choose \"offset\" when you want to view data in offset of first value for each \
        sensor. Both possibilities are optional."

     MakeDisplayListForSelection Initial

     APSFrame .output -parent .userFrame -relief flat
     set w3 .userFrame.output.frame
     APSButton .sddsplot -parent $w3 -text "quickSDDSplot..." \
	-command LaunchQuickSDDSPlot \
	-contextHelp "Launches quickSDDSplot with the selected data as input."
     $w3.sddsplot.button configure -width 20
     APSButton .sddsexport -parent $w3 -text "EXPORT..." \
	-command LaunchsddsExportData1 \
	-contextHelp "Launches sddsExportData with the selected data as input, allowing you to make spreadsheet or text data."
     $w3.sddsexport.button configure -width 20
     APSButton .timeexport -parent $w3 -text "Tide Data Export..." \
	-command LaunchsddsExportData2 \
	-contextHelp "Launches sddsExportData with the selected data as input, allowing you to make spreadsheet or text data. Date & DayTime columns for a time display. Modified sensor columns. It is available for the Level analysis only. "
     $w3.timeexport.button configure -width 20
     if [string compare $analysis Temp]==0 {
	 APSDisableButton .userFrame.output.frame.timeexport.button
     } 
}

proc MakeDisplayListForSelection {argument} {
     global mainInitialFile mainFilteredFile mainAveragedFile mainFFTFile
     global selectionDisplayList w4
     set displayFile ""

     if [llength $selectionDisplayList] {
         $w4.frame3.frame.plotList.listbox delete 0 end
     }
         
     switch $argument {
             Initial {set displayFile $mainInitialFile}
	     Filtered {set displayFile $mainFilteredFile}
	     Averaged {set displayFile $mainAveragedFile}
	     Fourier {set displayFile $mainFFTFile}
	     default {
	        SetHLSStatus "MakeDisplayListForSelection: Invalid review option $argument."
		return
	     }
     }
     if [catch {APSGetSDDSNames -fileName $displayFile} columnList] {
		SetHLSStatus "MakeDisplayListForSelection: $columnList"
		return
     }
     set columnList [lsort $columnList]
     set timeIndex [lsearch -exact $columnList Time]
     set fIndex [lsearch -exact $columnList f]
     if $timeIndex>=0 {
	 set selectionDisplayList [lreplace $columnList $timeIndex $timeIndex]
     } elseif {$fIndex >=0} {
	 set selectionDisplayList [lreplace $columnList $fIndex $fIndex]
     } else {
         foreach column $columnList {
	    lappend selectionDisplayList $column
         }
     }
     if [llength $selectionDisplayList] {
         foreach elem $selectionDisplayList {
            $w4.frame3.frame.plotList.listbox insert end $elem
	 }
     }
}

proc ClearSelection {} {
     global w2 w4 refSensorOn
     $w4.frame2.frame.refList.listbox selection clear 0 end

     DeleteTMP *.sensRef

     set refSensorOn 0
     APSDisableButton $w4.frame2.frame.clear.button
     APSEnableButton $w2.fourierT.button
     SetHLSStatus "Reference sensor is erased."
     bell
}

proc SetReferenceSensor {item doubleclick} {
     global activeSensor refSensorOn w2 w4
     global mainAveragedFile mainFilteredFile mainInitialFile
     global sensRefInitialFile sensRefFilteredFile sensRefAveragedFile

     if $doubleclick {
        if {[string compare $activeSensor $item] != 0} {
	  set activeSensor $item
	  set sensRefInitialFile [APSTmpDir]/[APSTmpString].sensRef.HLS
	  set sensRefFilteredFile [APSTmpDir]/[APSTmpString].sensRef.HLS
	  set sensRefAveragedFile [APSTmpDir]/[APSTmpString].sensRef.HLS

	  APSDisableButton $w2.fourierT.button
	  SetHLSStatus "Setting reference sensor..."
	  DeleteTMP *.sensRef
	  if [catch \
	        {eval exec sddsprocess $mainInitialFile -pipe=out -noWarnings \
	             {"-define=column,tempColumn,$activeSensor,units=um"} \
	             {"-redefine=col,%s,%s tempColumn -,select=S??G*"} \
		     | sddsconvert -pipe=in $sensRefInitialFile \
		       -delete=columns,tempColumn} result] {
	       SetHLSStatus "sensRefInitialFile: $result"
	       return
	   }
	   if [catch \
	         {eval exec sddsprocess $mainFilteredFile -pipe=out -noWarnings \
	             {"-define=column,tempColumn,$activeSensor,units=um"} \
	             {"-redefine=col,%s,%s tempColumn -,select=S??G*"} \
		     | sddsconvert -pipe=in $sensRefFilteredFile \
		       -delete=columns,tempColumn} result] {
		  SetHLSStatus "sensRefFilteredFile: $result"
		  return
	   }
	   if [catch \
		 {eval exec sddsprocess $mainAveragedFile -pipe=out -noWarnings \
	             {"-define=column,tempColumn,$activeSensor,units=um"} \
	             {"-redefine=col,%s,%s tempColumn -,select=S??G*"} \
		     | sddsconvert -pipe=in $sensRefAveragedFile \
		       -delete=columns,tempColumn} result] {
		  SetHLSStatus "sensRefAveragedFile: $result"
		  return
	   }
	   APSEnableButton $w4.frame2.frame.clear.button
	   set refSensorOn 1
	   SetHLSStatus  "$item is set for reference."
	   bell
        } else {
	   SetHLSStatus  "$item is alredy set for reference."
	   bell
        }
    }
}

proc RemoveOutputFrame {} {
     set p1 .userFrame.frame1
     set p2 .userFrame.output
     set w4 .userFrame.frame1.frame
     set w3 .userFrame.output.frame
     
     foreach widget [list $p1 $w4.dataOPT $w4.frame2 $w4.frame2.frame.refList \
           $w4.frame2.frame.clear $p2 $w3.sddsplot $w3.sddsexport .sensors] {
        if [winfo exists $widget] {
	    destroy $widget
	}
     }
     .userFrame.procFR.frame.fourierT.button configure -state disabled
} 

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

    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 FindDataFiles {args} {
    set StartYear 0
    set StartMonth 0
    set StartDay 0
    set EndYear 0
    set EndMonth 0
    set EndDay 0
    if [APSStrictParseArguments {StartYear StartMonth StartDay EndYear EndMonth EndDay}] {
        return -code error "FindDataFiles: bad arguments."
    }
    global HLSFileList DataDir 
    set DataDir /home/helios/oagData/monitoring/HSLevel
    if [catch {APSFindFilesBetweenDates -tailsOnly 1\
               -rootname HSLevel- -directory $DataDir\
               -startDateList [APSFormatDate -year $StartYear\
	             -month $StartMonth -day $StartDay -dateFormat list]\
               -endDateList [APSFormatDate -year $EndYear -month $EndMonth\
                     -day $EndDay -dateFormat list]} HLSFileList] {
        return -code error "FindDataFiles: $HLSFileList."
    } else {
        SetHLSStatus "[llength $HLSFileList] files found. Please, wait..."
    }
}

proc PlotSelection {} {
     global selectionDisplayList plotFile fourier w4 separate offset topline
     global HLSStartYear HLSStartMonth HLSStartDay HLSStartHour StartTime 
     global HLSEndYear HLSEndMonth HLSEndDay HLSEndHour EndTime
     global analysisOption analysis
     set plotOptionList ""
     set plotColumnList ""

     set indexList [$w4.frame3.frame.plotList.listbox curselection]

     if [llength $indexList] {
         foreach i $indexList {
            lappend plotColumnList [lindex $selectionDisplayList $i]
         }
     } else {
         SetHLSStatus "No selection was done for plotting."
	 bell
	 return
     }

     SetPlotExportFile plot

     if [llength $plotColumnList] {
         if !$fourier {
              lappend plotOptionList "-column=Time,([join $plotColumnList ,])"
	      lappend plotOptionList "-mode=y=linear,x=linear"
	      lappend plotOptionList "-ticks=xtime"
	      lappend plotOptionList "-filter=column,Time,$StartTime,$EndTime"
	      if $offset {
                  lappend plotOptionList "-mode=y=offset"
	      }
	 } else {
              lappend plotOptionList "-column=f,([join $plotColumnList ,])"
	      lappend plotOptionList "-mode=y=log,y=special,x=log,x=special"
	 }
     }
     if $separate {
         lappend plotOptionList "-separate=namestring"
         lappend plotOptionList "-groupby=namestring"     	 
         lappend plotOptionList "-graph=line,vary"
     } else {
         lappend plotOptionList "-graph=line,vary,eachfile"
	 if {[llength $plotColumnList] > 1} {
	      if {[string compare $analysis Level] == 0} {
                   set units um
	      } else {
		   set units degC
              }
	      lappend plotOptionList "-yLabel=${analysis}($units)"
	 }
     }

     lappend plotOptionList "-layout=1,1"
     lappend plotOptionList "-legend"
     lappend plotOptionList "-topline=$topline"
     lappend plotOptionList "&"     
	      
     if {[string compare $analysisOption Initial]==0} {
          set plotName Raw
     } else {
          set plotName $analysisOption
     }
     SetHLSStatus "Plotting $plotName data..."
     eval exec sddsplot -device=motif $plotFile $plotOptionList
}

proc SetPlotExportFile {activity} {
     global mainFFTFile mainAveragedFile mainFilteredFile mainInitialFile
     global sensRefInitialFile sensRefFilteredFile sensRefAveragedFile
     global plotFile exportFile
     global refSensorOn analysisOption fourier topline activeSensor
     set fourier 0

     if !$refSensorOn {
         switch $analysisOption {
              Initial {
                    set activeFile $mainInitialFile
                    set topline "Plot for \"Raw data\""
	      }
	      Filtered {
		    set activeFile $mainFilteredFile
                    set topline "Plot for \"Filtered data\""
	      }
	      Averaged {
		    set activeFile $mainAveragedFile
                    set topline "Plot for \"Offset by average\""
	      }
	      Fourier {
		    set activeFile $mainFFTFile
		    set fourier 1
                    set topline "Plot for \"Fourier Transforms\""
	      }
	      default {
		 SetHLSStatus "Invalid review option $analysisOption."
		 return
	      }
	  }
     } else {
         switch $analysisOption {
              Initial {
		    set activeFile $sensRefInitialFile
                    set topline "Plot for \"Raw data\" in reference to $activeSensor"
	      }
	      Filtered {
		    set activeFile $sensRefFilteredFile
                    set topline "Plot for \"Filtered data\" in reference to $activeSensor"
	      }
	      Averaged {
		    set activeFile $sensRefAveragedFile
                    set topline "Plot for \"Offset by average\" in reference to $activeSensor"
	      }
	      Fourier {
		    set activeFile $mainFFTFile
		    set fourier 1
                    set topline "Plot for \"Fourier Transforms\""
	      }
	      default {
		 SetHLSStatus "Invalid analysis option $analysisOption."
		 return
	      }
	  }
     }

     switch $activity {
             plot {set plotFile $activeFile}
	     export {set exportFile $activeFile}
	     default {
		 SetHLSStatus "SetPlotExportFile: Invalid activity option $activity."
		 return
	     }
     }
}

proc LaunchQuickSDDSPlot {} {
    global HLSStartYear HLSStartMonth HLSStartDay HLSStartHour
    global HLSEndYear HLSEndMonth HLSEndDay HLSEndHour
    global plotFile fourier analysisOption

    SetPlotExportFile plot

    if ![file exists $plotFile] {
        SetHLSStatus "No data selected or found."
        return
    }
    set Dir [file dirname $plotFile]
    set file [file tail $plotFile]

    SetHLSStatus "quickSDDSplot is lunched with $analysisOption file." 

    if $fourier {
        exec quickSDDSplot -dataDirectory $Dir -dataFileList $file \
           -message "Data from SR Hydrostatic Level logger." \
           -groupMessage HSLevel &
    } else {
        exec quickSDDSplot -dataDirectory $Dir -timeFilterMode "day" \
           -timeFilterStart "$HLSStartYear $HLSStartMonth $HLSStartDay $HLSStartHour" \
           -timeFilterEnd "$HLSEndYear $HLSEndMonth $HLSEndDay $HLSEndHour" \
           -dataFileList $file -message "Data from SR Hydrostatic Level logger." \
           -groupMessage HSLevel &
    }
}

proc LaunchsddsExportData1 {} {
    global HLSStartYear HLSStartMonth HLSStartDay HLSStartHour
    global HLSEndYear HLSEndMonth HLSEndDay HLSEndHour
    global exportFile analysisOption

    SetPlotExportFile export

    if ![file exists $exportFile] {
        SetHLSStatus "No data selected or found."
        return
    }
    set Dir [file dirname $exportFile]
    set file [file tail $exportFile]

    SetHLSStatus "sddsExportData is lunched with $analysisOption file." 

    exec sddsExportData -dataDirectory $Dir -timeFilterMode "day" \
      -timeFilterStart "$HLSStartYear $HLSStartMonth $HLSStartDay $HLSStartHour" \
      -timeFilterEnd "$HLSEndYear $HLSEndMonth $HLSEndDay $HLSEndHour" \
      -dataFileList $file -message "Data from SR Hydrostatic Level logger." &
}

proc LaunchsddsExportData2 {} {
    global HLSStartYear HLSStartMonth HLSStartDay HLSStartHour
    global HLSEndYear HLSEndMonth HLSEndDay HLSEndHour
    global exportFile analysisOption

    SetPlotExportFile export

    if ![file exists $exportFile] {
        SetHLSStatus "No data selected or found."
        return
    }
    set convExportFile [APSTmpDir]/[APSTmpString]

    if [catch {eval exec sddstimeconvert $exportFile -pipe=out \
        -breakdown=column,Time,year=TheYear,month=TheMonth,day=DayOfMonth,hour=HourOfDay \
        | sddsprocess -pipe -noWarnings \
          {"-convertUnits=column,S??G*,m,um,1e-6"} \
          {"-print=col,Date,%d/%02d/%02d,TheYear,TheMonth,DayOfMonth,units=(yyyy/mm/dd)"} \
	  {"-define=column,MinuteFl,HourOfDay Hour - 60 *"} \
          {"-cast=column,Hour,HourOfDay,short"} \
          {"-cast=column,Minute,MinuteFl,short"} \
          {"-print=col,DayTime,%02d:%02d,Hour,Minute,units=(hh:mm)"} \
        | sddsconvert -pipe=in $convExportFile \
	  {"-delete=col,TheYear,TheMonth,DayOfMonth,HourOfDay,MinuteFl,Hour,Minute"}} result] {
        SetHLSStatus "LaunchsddsExportData2: $result"
    }
    set Dir [file dirname $convExportFile]
    set file [file tail $convExportFile]

    SetHLSStatus "sddsExportData is lunched with $analysisOption file." 

    exec sddsExportData -dataDirectory $Dir \
      -dataFileList $file -message "Data from SR Hydrostatic Level logger." &
}

proc TimeConvertion {} {
     global HLSStartMonth HLSStartYear HLSStartDay HLSStartHour 
     global HLSEndMonth HLSEndYear HLSEndDay HLSEndHour 
     global sTime eTime StartTime EndTime

     set intervalString "$HLSStartMonth/$HLSStartDay/$HLSStartYear $HLSStartHour hour and $HLSEndMonth/$HLSEndDay/$HLSEndYear $HLSEndHour hour"

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

     if [catch {eval exec timeconvert -breakDown=year=$HLSStartYear,month=$HLSStartMonth,day=$HLSStartDay,hour=$hour0} StartTime] {
         return -code error "Error: $StartTime"
     }
     if [catch {eval exec timeconvert -breakDown=year=$HLSEndYear,month=$HLSEndMonth,day=$HLSEndDay,hour=$hour1} EndTime] {
         return -code error "Error: $EndTime"
     }

     if {$HLSStartYear > $HLSEndYear} {
         return -code error {Starting year must be <= ending year.}
     } elseif {$HLSStartYear == $HLSEndYear} {
        if {$HLSStartMonth > $HLSEndMonth} {
           return -code error {Starting month must be <= ending month.}
        } elseif {$HLSStartMonth == $HLSEndMonth} {
           if {$HLSStartDay > $HLSEndDay} {
              return -code error {Starting day must be <= ending day.}
           } 
        } 
     }

# If StartTime is lower than a date of sensor renaming (07/17/1998)  
     if {$StartTime < 9.00651318788658261e+08} {
	 bell
         return -code error "Starting date is lower than a date of sensors'\
	    renaming (07/17/1998).      Processing is abandon."
     }
         
     set sTime "$HLSStartMonth/$HLSStartDay/$HLSStartYear $HLSStartHour hour"
     set eTime "$HLSEndMonth/$HLSEndDay/$HLSEndYear $HLSEndHour hour"
     update
}

proc Process {} {
     global HLSStartMonth HLSStartYear HLSStartDay HLSStartHour 
     global HLSEndMonth HLSEndYear HLSEndDay HLSEndHour
     global HLSFileList DataDir StartTime EndTime selectedSensors
     global sensorsList dataRefFile userName fourierVar analysis
     global activeSensor
     set activeSensor ""
     set sensorsList ""
     set selectedSensors ""
     set dataRefFile [APSTmpDir]/[APSTmpString].HLS

     DeleteTMP "*${userName}*.HLS"
     set fourierVar no

     RemoveOutputFrame
     SetHLSStatus "Processing data..."
     if [catch {TimeConvertion} result] {
		SetHLSStatus "$result"
		return
     }

     if [catch {FindDataFiles -StartYear $HLSStartYear -StartMonth $HLSStartMonth\
                -StartDay $HLSStartDay -EndYear $HLSEndYear -EndMonth $HLSEndMonth\
                -EndDay $HLSEndDay} result] {
           SetHLSStatus "Process: $result"
	   return
     }
     if ![llength $HLSFileList] {
	  SetHLSStatus "No data selected or found."
	  return
     }

     if [catch {CombineFilesAndProvideSensorsList $StartTime $EndTime $analysis} result] {
               SetHLSStatus "$result"
	       return
     }

     if [llength $sensorsList] {
        SetHLSStatus "Displaying a list of sensors read from the files..."
	set sensorsList [lsort -increasing $sensorsList]
	APSScrolledListWindow .sensors \
	    -name "HLS sensors selection" \
	    -label "Pick sensors for processing." \
	    -itemList $sensorsList \
	    -selectionVar $selectedSensors \
	    -callback ContinueProcWithChosenSensors \
	    -contextHelp "This window displays all names of the sensors read from chosen log files. \
	     Select all valid sensors, and press \"Accept\" to continue processing with selected sensors \
	     and keep the list displayed, or press \"Close\" to continue processing with selected sensors \
             and close the list window."
        APSDialogBoxAddButton .all -parent .sensors -text "Select All" -command "SelectAll sensorsList"
	bind .sensors.userFrame.sl.listbox <Button-2> {
          .sensors.userFrame.sl.listbox selection clear [.sensors.userFrame.sl.listbox nearest %y]}
	bell
     }
}

proc CombineFilesAndProvideSensorsList {startT endT attr} {
     global HLSFileList DataDir dataRefFile sensorsList dInterval
     set processedFile1 [APSTmpDir]/[APSTmpString].HLS
     set finalList ""
     set i [llength $HLSFileList]
     for {set index 0} {$index < $i} {incr index} {
          lappend finalList $DataDir/[lindex $HLSFileList $index]
     }

     if {![string length $dInterval] || $dInterval<1} {
          set dInterval 1
     }

     if ![string compare $attr Level] {
       if $dInterval!=1 {
         if [catch \
	      {eval exec sddscombine $finalList -pipe=out -merge \
              {"-retain=col,Time,TimeOfDay,*${attr}*"} \
	      | sddsrunstats -pipe \
              {"-mean=Time,TimeOfDay,*${attr}*"} \
	        -noOverlap -points=$dInterval -partialOk \
	      | sddsconvert -pipe -edit=col,*Mean,%/Mean// \
              | sddsprocess -pipe -noWarnings \
                -filter=column,TimeOfDay,0,24 \
                -filter=column,Time,${startT},${endT} \
	      {"-redefine=col,%s,%s -1 *,select=S??G*"} \
              | tee $dataRefFile \
              | sddsconvert -pipe=in $processedFile1 \
	        -delete=col,TimeOfDay,Time} result] {
	    return -code error "Combine1 $result"
         }
       } else {
         if [catch \
	      {eval exec sddscombine $finalList -pipe=out -merge \
              {"-retain=col,Time,TimeOfDay,*${attr}*"} \
              | sddsprocess -pipe -noWarnings \
                -filter=column,TimeOfDay,0,24 \
                -filter=column,Time,${startT},${endT} \
	      {"-redefine=col,%s,%s -1 *,select=S??G*"} \
              | tee $dataRefFile \
              | sddsconvert -pipe=in $processedFile1 \
	        -delete=col,TimeOfDay,Time} result] {
	    return -code error "Combine1 $result"
         }
       }
     } else {
       if $dInterval!=1 {
         if [catch \
	      {eval exec sddscombine $finalList -pipe=out -merge \
              {"-retain=col,Time,TimeOfDay,*${attr}*"} \
	      | sddsrunstats -pipe \
              {"-mean=Time,TimeOfDay,*${attr}*"} \
	        -noOverlap -points=$dInterval -partialOk \
	      | sddsconvert -pipe -edit=col,*Mean,%/Mean// \
              | sddsprocess -pipe -noWarnings \
                -filter=column,TimeOfDay,0,24 \
                -filter=column,Time,${startT},${endT} \
              | tee $dataRefFile \
              | sddsconvert -pipe=in $processedFile1 \
	        -delete=col,TimeOfDay,Time} result] {
	    return -code error "Combine1 $result"
         }
       } else {
         if [catch \
	      {eval exec sddscombine $finalList -pipe=out -merge \
              {"-retain=col,Time,TimeOfDay,*${attr}*"} \
              | sddsprocess -pipe -noWarnings \
                -filter=column,TimeOfDay,0,24 \
                -filter=column,Time,${startT},${endT} \
              | tee $dataRefFile \
              | sddsconvert -pipe=in $processedFile1 \
	        -delete=col,TimeOfDay,Time} result] {
	    return -code error "Combine1 $result"
         }
       }
     }

     if [catch {APSGetSDDSNames -fileName $processedFile1} sensorsList] {
         return -code error "$sensorsList"
     }
     catch {file delete -force $processedFile1}
}

proc SelectAll {yList} {
     global $yList

     .sensors.userFrame.sl.listbox selection set 0 end
}

proc DisableSensorsList {} {
     .sensors.buttonRow.accept.button configure -state disabled
     .sensors.buttonRow.all.button configure -state disabled
     .sensors.buttonRow.close.button configure -command "destroy .sensors"
}

proc ContinueProcWithChosenSensors {list} {
     global mainInitialFile dataRefFile mainFilteredFile mainAveragedFile
     global StartTime EndTime analysis
     global offLimit finalSensorsList fourierVar selectedSensorsString

     DisableSensorsList

     if ![llength $list] {
          SetHLSStatus "No sensor selection was done."
	  bell
          return
     }     
     set selectedSensorsString [join $list ,]
     set filteringList ""
     set finalSensorsList ""
     set eraseSensList ""
     set mainFilteredFile ""
     set mainInitialFile [APSTmpDir]/[APSTmpString].mainInit.HLS
     set mainAveragedFile [APSTmpDir]/[APSTmpString].mainAvg.HLS
     set processedFile4 [APSTmpDir]/[APSTmpString].mainFilt.HLS
     set processedFile5 [APSTmpDir]/[APSTmpString].mainFilt.HLS
     set testFile4 [APSTmpDir]/[APSTmpString].mainFilt.HLS.test

     foreach file [list mainFilteredFile mainAveragedFile mainInitialFile] {
        if [file exists [set $file]] {
	    catch {eval exec rm [set $file]}
	}
     }
     SetHLSStatus "Filtering..."

     if [catch \
         {eval exec sddsconvert $dataRefFile $mainInitialFile \
	     {"-retain=col,Time,$selectedSensorsString"}} result1] {
            SetHLSStatus "result1 = $result1"
            return
     }
     if ![string compare $analysis Level] {
         set units um
         set highLimit [expr $offLimit - 50]
         if [catch \
             {eval exec sddsoutlier $mainInitialFile -pipe=out -noWarnings \
                 -absLimit=10000 -replaceOnly=value=0 \
                 -columns=$selectedSensorsString \
		| sddsoutlier -pipe \
                 -maximumLimit=$highLimit -replaceOnly=interp \
                 -columns=$selectedSensorsString \
                | tee $processedFile4 \
	        | sddsprocess -pipe -process=S??G*,max,%s \
                | sdds2stream -pipe -parameter=$selectedSensorsString} maxParamList] {
             SetHLSStatus "sddsoutlier:  $maxParamList."
             return
         }

         set length [llength $maxParamList]
	 for {set i 0} {$i < $length} {incr i} {
              if {[lindex $maxParamList $i] < $highLimit} {
	           lappend finalSensorsList [lindex $list $i]
 	      } else {
	           lappend eraseSensList [lindex $list $i]
	           SetHLSStatus "There is no valid data for sensor [lindex $list $i]."
	      }
          }
     } else {
         set units degC
         set lowLimit [expr $offLimit + 2]
         if [catch \
             {eval exec sddsoutlier $mainInitialFile -pipe=out -noWarnings \
                 -absLimit=100 -replaceOnly=value=0 \
                 -columns=$selectedSensorsString \
		| sddsoutlier -pipe \
                 -minimumLimit=$lowLimit -replaceOnly=interp \
                 -columns=$selectedSensorsString \
                | tee $processedFile4 \
	        | sddsprocess -pipe -process=S??G*,min,%s \
                | sdds2stream -pipe -parameter=$selectedSensorsString} minParamList] {
             SetHLSStatus "sddsoutlier:  $minParamList."
             return
         }
	set length [llength $minParamList]
	for {set i 0} {$i < $length} {incr i} {
	    if {[lindex $minParamList $i] > $lowLimit} {
		lappend finalSensorsList [lindex $list $i]
	    } else {
		lappend eraseSensList [lindex $list $i]
		SetHLSStatus "There is no valid data for sensor [lindex $list $i]."
	    }
	}
     }
     set eraseLength [llength $eraseSensList]
     if $eraseLength {
         if {$eraseLength == $length} {
             SetHLSStatus "No valid $analysis data for any sensor in the chosen time frame."
             bell
	     return
         }
         set eraseSensString [join $eraseSensList ,]
	 if [catch \
                 {eval exec sddsconvert $processedFile4 $processedFile5 \
	               {"-delete=col,$eraseSensString"}} result] {
                  SetHLSStatus "$result"
		  return
	 }
	 set mainFilteredFile $processedFile5
	 catch {file delete -force $processedFile4}
     } else {
         set mainFilteredFile $processedFile4
     }

     SetHLSStatus "Applying an average value..."

     if [catch \
         {eval exec sddsrowstats $mainFilteredFile -pipe=out \
	        -mean=Avg${analysis},S??G* \
	      | sddsprocess -pipe=in $mainAveragedFile -noWarnings \
	      {"-process=Avg${analysis},first,Avg${analysis}_T0"} \
	      {"-define=column,AvgDiff,Avg${analysis} Avg${analysis}_T0 -,units=$units"} \
	      {"-redefine=col,%s,%s AvgDiff -,select=S??G*"}} result] {
            SetHLSStatus "$result"
	    return
     }

     SetHLSStatus "Processing is done."
     bell
     APSEnableButton .userFrame.procFR.frame.fourierT.button
     MakeOutputFrame
}

proc DoFourierTransforms {} {
     global mainAveragedFile mainFFTFile fourierVar
     global selectedSensorsString
     set mainFFTFile [APSTmpDir]/[APSTmpString].mainFFT.HLS

     SetPushButtons 0

     SetHLSStatus "Applying Fast Fourier Transforms..."

     if [file exists $mainAveragedFile] {
        RemoveOutputFrame
	set sizeOfFile 0
	set sizeOfFile [file size $mainAveragedFile]

	if $sizeOfFile {
	    set N [expr $sizeOfFile / 3500000]
	    if {$N < 1} {set N 1}
	}
	if {$N > 1} {
	    if [catch {eval exec sddsprocess $mainAveragedFile -pipe=out \
	                    -noWarnings -sparse=$N \
	                  | sddsfft -pipe=in $mainFFTFile \
	                  {"-columns=Time,$selectedSensorsString"} \
	                    -noWarnings -window -suppressAverage} result] {
		SetHLSStatus "$result"
		return
	    }
	} else {
	    if [catch {eval exec sddsfft $mainAveragedFile $mainFFTFile \
	                  {"-columns=Time,$selectedSensorsString"} \
	                    -noWarnings -window -suppressAverage} result] {
		SetHLSStatus "$result"
		return
	    }
	}
	set fourierVar yes
	MakeOutputFrame

        SetPushButtons 1
	APSDisableButton .userFrame.procFR.frame.fourierT.button

        SetHLSStatus "Fast Fourier Transforms done."
	bell
     }
}

proc SetPushButtons {state} {
     global w4
     if $state {
	APSEnableButton .userFrame.procFR.frame.fourierT.button
	APSEnableButton .userFrame.output.frame.sddsplot.button
	APSEnableButton .userFrame.output.frame.sddsexport.button
	APSEnableButton .userFrame.procFR.frame.process.button
	APSEnableButton $w4.frame3.frame.plot.button
     } else {
	APSDisableButton .userFrame.procFR.frame.fourierT.button
	APSDisableButton .userFrame.output.frame.sddsplot.button
	APSDisableButton .userFrame.output.frame.sddsexport.button
	APSDisableButton .userFrame.procFR.frame.process.button
	APSDisableButton $w4.frame3.frame.plot.button
     }
}

proc DeleteTMP {root} {
     set oldDir [pwd]
     cd [APSTmpDir]/
     if ![catch {glob $root} tmpFileList] {
          foreach f $tmpFileList {
	    if [catch {file delete $f} result] {
		SetHLSStatus "$result"
		return
	    }
	  }
	  unset tmpFileList
     }
     cd $oldDir
}

proc SetLevelAnalysis {} {
     global analysis offLimit
     if [string compare $analysis Level]!=0 {
         RemoveOutputFrame
         set analysis Level
         set offLimit -6000
         SetHLSStatus {Active analysis set to: Level}
         bell
	 if [winfo exists .userFrame.output.frame.timeexport.button] {
	     APSEnableButton .userFrame.output.frame.timeexport.button
	 }
     }
}

proc SetTempAnalysis {} {
     global analysis offLimit
     if [string compare $analysis Temp]!=0 {
         RemoveOutputFrame
         set analysis Temp
         set offLimit 0
         SetHLSStatus {Active analysis set to: Temperature}
         bell
	 if [winfo exists .userFrame.output.frame.timeexport.button] {
	    APSDisableButton .userFrame.output.frame.timeexport.button
	 }
     }
}


APSMenubarAddMenu .analysis -parent .menu -text Analysis
.menu.analysis.menu add command -label "Level" -underline 0 \
     -command SetLevelAnalysis
.menu.analysis.menu add separator
.menu.analysis.menu add command -label "Temperature" -underline 0 \
     -command SetTempAnalysis

set userDir [pwd]
set analysis Level
set offLimit -6000
SetHLSStatus {Active analysis set to: Level}
bell

catch {exec whoami} userName

MakeDateTimeFrame .timeFrame -parent .userFrame -rootname HLS

APSFrame .procTM -parent .userFrame -label "Process Time" 
set w1 .userFrame.procTM.frame
APSLabeledOutput .sTime -parent $w1 -label "Start: " \
   -textVariable sTime -packOption "-side left" -width 30 \
   -contextHelp "Start time for the time range of the processed log files."
APSLabeledOutput .eTime -parent $w1 -label "End: " \
   -textVariable eTime -packOption "-side right" -width 30 \
   -contextHelp "End time for the time range of the processed log files."

APSFrame .procFR -parent .userFrame -relief flat
set w2 .userFrame.procFR.frame 
APSButton .process -parent $w2 -text "Process" -command Process -packOption \
   "-side left -anchor c" -contextHelp "Invokes a processing of the chosen log files. \
    Filtering and applying of an average value will be proceeded. If processing \
    was done before, it will delete all previous temporary process files."
$w2.process.button configure -width 18 -height 3

APSButton .fourierT -parent $w2 -text "Fourier Analysis" -packOption "-side left -anchor c" \
   -command DoFourierTransforms -contextHelp "Invokes Fast Fourier Transforms to the data \
    with an average value applied in mode zero. Additionally Fourier radio button will appear \
    in the analysis option box."
$w2.fourierT.button configure -width 18 -height 3

set fourierVar no

APSFrameGrid .procInfo -parent $w2 -packOption "-side right" -relief raised \
   -xList {x1} -yList {y1 y2 y3 y4}
set w22 $w2.procInfo

pack [label $w22.x1.y1.infoLabel -text "Analysis Info" \
      -font {courier 12 bold}] -fill both -expand false

APSLabeledOutput .active -parent $w22.x1.y2 -packOption "-side top" -label "  Active:   "\
   -textVariable analysis -width 20 -contextHelp ""

APSLabeledEntry .offLimit -parent $w22.x1.y3 -label "  Off Limit:" \
   -textVariable offLimit -packOption "-side bottom" -width 20 \
   -contextHelp "Limit value for sensors during turn off mode."

set dInterval 1
APSLabeledEntry .interval -parent $w22.x1.y4 -packOption "-side top" -label "  Time Interval:"\
   -textVariable dInterval -width 16 -contextHelp "Interval value allows elimination of data to make smaller data sets."

APSDisableButton $w2.fourierT.button

dp_atexit set "DeleteTMP \"*${userName}*.HLS\""
