Index: palm/trunk/SCRIPTS/batch_nc2vdf
===================================================================
--- palm/trunk/SCRIPTS/batch_nc2vdf	(revision 1610)
+++ 	(revision )
@@ -1,57 +1,0 @@
-#!/bin/bash
-#--------------------------------------------------------------------------------#
-# This file is part of PALM.
-#
-# PALM is free software: you can redistribute it and/or modify it under the terms
-# of the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# PALM. If not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright 1997-2014  Leibniz Universitaet Hannover
-#--------------------------------------------------------------------------------#
-#
-# Current revisions:
-# -----------------
-#
-# Former revisions:
-# -----------------
-# $Id$
-#
-# 1067 2012-11-26 10:13:14Z maronga
-# Initial revision
-#
-# Description:
-# ------------
-# Start script for nc2vdf in batch mode on UV in hannover/berlin. A config file
-# (nc2vdf.config) must be present in the executing directory.
-#--------------------------------------------------------------------------------#
-
-#PBS -N convert
-#PBS -j oe
-#PBS -l walltime=12:00:00
-#PBS -l nodes=1:ppn=1
-#PBS -l feature=uv
-#PBS -l partition=hannover
-#PBS -q smpq
-
-
-eval `/sw/swdist/bin/modulesinit`
-
-
-
-
-
-echo "Start $(date)"
-
-cd $PBS_O_WORKDIR
-
-nc2vdf nc2vdf.config
-
-
-echo "Ende $(date)"
Index: palm/trunk/SCRIPTS/hlrn_watchdog
===================================================================
--- palm/trunk/SCRIPTS/hlrn_watchdog	(revision 1610)
+++ 	(revision )
@@ -1,220 +1,0 @@
-#!/bin/ksh
-#--------------------------------------------------------------------------------#
-# This file is part of PALM.
-#
-# PALM is free software: you can redistribute it and/or modify it under the terms
-# of the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# PALM. If not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright 1997-2014  Leibniz Universitaet Hannover
-#--------------------------------------------------------------------------------#
-#
-# Current revisions:
-# -----------------
-# 
-# 
-# Former revisions:
-# -----------------
-# $Id$
-#
-# 1448 2014-08-07 10:47:05Z maronga
-# Bugfix: removed debug mode
-# 
-# 1446 2014-08-07 10:08:56Z maronga
-# Adapted for HLRN III. Added windows if no runs are queued.
-# 
-# 1046 2012-11-09 14:38:45Z maronga
-# code put under GPL (PALM 3.9)
-#
-# 1029 2012-10-17 15:33:56Z maronga
-# Initial revision
-#
-# Description:
-# ------------
-# The hlrn_watchdog works for jobs on HLRN in Hannover/Berlin and with KDE.
-# It can be used for monitoring currently submitted jobs and will display
-# Running, Idle and Blocked jobs in a separate window, which is updated every
-# 10 minutes. 
-# Starting: "hlrn_watchdog start <your hlrn username>"
-# Stopping: "hlrn_watchdog stop"
-#------------------------------------------------------------------------------!
-
-    check_hannover=true
-    check_berlin=true
-    debug=false
-
-    cd $PALM_BIN
-
-    gate_h="hlogin.hlrn.de"
-    gate_b="blogin.hlrn.de"
-    update_frequency=600
-
-#   trap strg+c
-    trap 'kill -9 $infoPID > /dev/null; kill -9 $dialogPID > /dev/null; exit' 2
-
-
-#   start/stop routine
-    if [[ $1 == "stop" ]]
-    then
-       result=`ps aux|grep -c "./hlrn_watchdog"`
-       if (( $result > 2 ))
-       then
-          result=`ps aux|grep -m1 "./hlrn_watchdog"`
-          killid=`echo $result | tr -s " " | cut -d" " -s -f2`
-          kill -9 $killid > /dev/null
-          killall kdialog
-
-          if [[ -f .watchdog_report.x ]] then
-             rm .watchdog_report.x
-          fi
-          if [[ -f .watchdog_status.x ]] then
-             rm .watchdog_status.x
-          fi
-          echo "*** hlrn_watchdog stopped."
-       else
-          echo "+++ hlrn_watchdog is not running."
-       fi
-       exit
-    elif [[ $1 == "start" ]]
-    then
-        result=`ps aux|grep -c "hlrn_watchdog"`
-        if (( $result > 2 ))
-        then
-           echo "+++ hlrn_watchdog is already running."
-        else
-           if [[ $debug = true ]] then
-              ./hlrn_watchdog $2 &
-           else
-              nohup ./hlrn_watchdog $2 1> /dev/null 2> /dev/null &
-           fi
-           echo "\n*** hlrn_watchdog starting..."
-        fi
-        exit
-    else
-#      login via ssh and collect information in .watchdog_report.x
-       while true
-       do
-          touch .watchdog_report.x
-          if [[ $check_hannover == true ]] then
-             ssh  $gate_h -l $1 "showq | egrep \"($1)\"" > .watchdog_report.x
-          fi
-          if [[ $check_berlin == true ]] then
-          ssh  $gate_b -l $1 "showq | egrep \"($1)\"" >> .watchdog_report.x
-          fi
-
-          i=0
-          j=0
-          cat .watchdog_report.x|while read variable
-          do
-#            analyze output
-             comid[$i]=`echo $variable | tr -s " " | cut -d" " -s -f1`
-             jobid[$i]=`echo ${comid[$i]} | tr -s " " | cut -d"." -s -f2`
-             complex[$i]=`echo ${comid[$i]} | tr -s " " | cut -d"." -s -f1`
-             username[$i]=`echo $variable | tr -s " " | cut -d" " -s -f2`
-             status[$i]=`echo $variable | tr -s " " | cut -d" " -s -f3`
-             nodes[$i]=`echo $variable | tr -s " " | cut -d" " -s -f4`
-             walltime[$i]=`echo $variable | tr -s " " | cut -d" " -s -f5`  
-             day[$i]=`echo $variable | tr -s " " | cut -d" " -s -f6`   
-             month[$i]=`echo $variable | tr -s " " | cut -d" " -s -f7`   
-             date[$i]=`echo $variable | tr -s " " | cut -d" " -s -f8`
-             subtime[$i]=`echo $variable | tr -s " " | cut -d" " -s -f9`   
-             ((i = i + 1))
-          done
-          rm .watchdog_report.x
-          touch .watchdog_status.x
-
-#         check for terminated jobs and status changes
-          k=0
-          cat .watchdog_status.x|while read variable
-          do
-#            analyze output
-             old_comid[$k]=`echo $variable | tr -s " " | cut -d" " -s -f1`
-             old_status[$k]=`echo $variable | tr -s " " | cut -d" " -s -f2` 
-             ((k = k + 1))
-          done
-          rm .watchdog_status.x
-
-          info=""
-          for ((m=0;m<$k;m++))
-          do
-             found=0
-             for ((n=0;n<$i;n++))
-             do        
-                if [[ ${old_comid[$m]} == ${comid[$n]} ]]
-                then
-                   if [[ ${old_status[$m]} != ${status[$n]} ]]
-                   then
-                       info="$info ${old_comid[$m]} has changed status from ${old_status[$m]} to ${status[$n]}.\n"
-                   fi
-                   found=1
-                   break
-                fi
-             done
-             if (( $found == 0 ))
-             then
-                info="$info ${old_comid[$m]} has been terminated (Status was ${old_status[$m]}).\n"
-             fi
-          done
-
-#         check whether any jobs are queued
-          touch .watchdog_report.x
-          file_size=`ls -l .watchdog_report.x | tr -s " " | cut -d " " -f 5`
-          if [[ $file_size == 0 ]] then
-            printf "No jobs queued.\n" >> .watchdog_report.x
-          fi
-
-#         get estimated starting time for all idle jobs and write watchdog output in .watchdog_report.x
-          while (( $j < $i ))
-          do
-             if [[ ${status[$j]} == "Idle" ]]
-             then
-                if [[ ${complex[$j]} == "hannover" ]]
-                then
-                   eststart[$j]=`ssh $gate_h -l $1 "showstart ${comid[$j]}|grep \"based start in\""`
-                else
-                   eststart[$j]=`ssh $gate_b -l $1 "showstart ${comid[$j]}|grep \"based start in\""`
-                fi
-                eststart[$j]="Start in: "`echo ${eststart[$j]} | tr -s " " | cut -d" " -s -f6`   
-             else
-                eststart[$j]=""
-             fi
-
-#            write final output line
-             ((k = j + 1))
-             printf "%-9s%8s%3s%04i%13s%11s%2s%-s%3s%-20s\n" "Job: $k:" "${status[$j]}" " @ " "${nodes[$j]}" " nodes, time:" "${walltime[$j]}" " (" "${comid[$j]}" "). " "${eststart[$j]}" >> .watchdog_report.x
-             printf "${comid[$j]} ${status[$j]}\n" >> .watchdog_status.x
-             ((j = j + 1))
-          done
-
-#         kill all windows
-          if  [[ "$infoPID" -ne "" ]] then
-             kill -9 $infoPID > /dev/null
-             unset $infoPID
-          fi
-          if  [[ "$dialogPID" -ne "" ]] then
-             kill -9 $dialogPID > /dev/null
-             unset $dialogPID
-          fi
-
-          timestamp=`date`
-
-#         create window and show information
-          kdialog --textbox .watchdog_report.x 550 150 --title "HLRN watchdog  (last update: $timestamp)" & dialogPID=$!
-
-#         in case of status changes and terminated jobs, inform the user
-          if [[ $info != "" ]]
-          then
-             kdialog --msgbox "$info" --title "HLRN Job Information" & infoPID=$!
-          fi
-
-          sleep $update_frequency
-       done
-
-    fi
Index: palm/trunk/SCRIPTS/hlrn_watchdog.kwinrule
===================================================================
--- palm/trunk/SCRIPTS/hlrn_watchdog.kwinrule	(revision 1610)
+++ 	(revision )
@@ -1,18 +1,0 @@
-[HLRN watchdog rule]
-Description=HLRN watchdog rule
-desktop=-1
-desktoprule=4
-position=
-positionrule=4
-skippager=true
-skippagerrule=3
-skipswitcher=true
-skipswitcherrule=3
-skiptaskbar=true
-skiptaskbarrule=3
-title=HLRN watchdog
-titlematch=2
-types=32
-wmclass=kdialog
-wmclasscomplete=false
-wmclassmatch=1
Index: palm/trunk/SCRIPTS/nc2vdf
===================================================================
--- palm/trunk/SCRIPTS/nc2vdf	(revision 1610)
+++ 	(revision )
@@ -1,133 +1,0 @@
-#!/bin/ksh
-#--------------------------------------------------------------------------------#
-# This file is part of PALM.
-#
-# PALM is free software: you can redistribute it and/or modify it under the terms
-# of the GNU General Public License as published by the Free Software Foundation,
-# either version 3 of the License, or (at your option) any later version.
-#
-# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# PALM. If not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright 1997-2014  Leibniz Universitaet Hannover
-#--------------------------------------------------------------------------------#
-#
-# Current revisions:
-# -----------------
-# 
-# 
-# Former revisions:
-# -----------------
-# $Id$
-#
-# 1310 2014-03-14 08:01:56Z raasch
-# adapted for use on desktop machines
-
-# 1067 2012-11-26 10:13:14Z maronga
-# Code put under GNU GPL
-#
-# Description:
-# ------------
-# Starting script for nc2vdf. The script does only work on hicegate2, bicegate2,
-# uv, on the imuk server. It can be adapted for use on any desktop machine.
-#------------------------------------------------------------------------------#
-
-    check_muk=false
-    check_hlrn=false
-    check_workstation=false
-    sys="unknown"
-
-    line=""
-    more $1 | grep "check_workstation" > tmp_mrun
-    while read line
-    do
-      check_workstation=`echo $line | cut -d"=" -s -f2`
-    done < tmp_mrun
-
-    line=""
-    more $1 | grep "WS_init" > tmp_mrun
-    while read line
-    do
-      WS_init=`echo $line | cut -d"=" -s -f2`
-    done < tmp_mrun
-
-    line=""
-    more $1 | grep "init_script" > tmp_mrun
-    while read line
-    do
-      vapor_init_path=`echo $line | cut -d"=" -s -f2`
-    done < tmp_mrun
-
-    rm tmp_mrun
-
-    echo "*** checking hostname..."
-    if [ $(expr "$HOSTNAME" : ".*muk.uni-hannover.de") -gt 0 ]
-    then
-       check_muk=true
-    fi
-
-    if [ $(expr "$HOSTNAME" : ".*hicegate2") -gt 0 ]
-    then
-       check_hlrn=true
-    fi
-    if [ $(expr "$HOSTNAME" : ".*bicegate2") -gt 0 ]
-    then
-       check_hlrn=true
-    fi
-    if [ $(expr "$HOSTNAME" : ".*huv") -gt 0 ]
-    then
-       check_hlrn=true
-    fi
-    if [ $(expr "$HOSTNAME" : ".*buv") -gt 0 ]
-    then
-       check_hlrn=true
-    fi
-
-
-
-
-
-    if [ $check_muk == "true" ]
-    then
-       sys="IMUK"
-       . /muksoft/packages/vapor/2.2.0/bin/vapor-setup.sh
-    fi
-
-    if [ $check_hlrn == "true" ]
-    then
-       sys="HLRN"
-       . /usr/share/modules/init/ksh
-       module load vapor
-       module load ncl
-    fi
-
-    if [ $check_workstation == "True" ]
-    then
-       sys="workstation"
-       if [ $WS_init == "True" ]
-       then
-          . $vapor_init_path
-       fi
-       if [ $WS_load == "True" ]
-       then
-          $WS_load_command
-       fi
-    fi
-
-    if [ $sys == "unknown" ]
-    then
-       echo "+++ unknown system."
-       #exit 0
-    else
-       echo "*** nc2vdf will execute at $sys"
-    fi
-
-    if which nc2vdf.ncl >/dev/null; then
-       ncl $PALM_BIN/nc2vdf.ncl "inputfile= \"$1\""
-    else
-       echo "  +++ nc2vdf.ncl not found."
-    fi
Index: palm/trunk/SCRIPTS/nc2vdf.config
===================================================================
--- palm/trunk/SCRIPTS/nc2vdf.config	(revision 1610)
+++ 	(revision )
@@ -1,104 +1,0 @@
-;--------------------------------------------------------------------------------!
-; This file is part of PALM.
-;
-; PALM is free software: you can redistribute it and/or modify it under the terms
-; of the GNU General Public License as published by the Free Software Foundation,
-; either version 3 of the License, or (at your option) any later version.
-;
-; PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-; A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License along with
-; PALM. If not, see <http://www.gnu.org/licenses/>.
-;
-; Copyright 1997-2014  Leibniz Universitaet Hannover
-;------------------------------------------------------------------------------!
-;
-; Current revisions:
-; -----------------
-; 
-; 
-; Former revisions:
-; -----------------
-; $Id$
-;
-; 1310 2014-03-14 08:01:56Z raasch
-; adapted for use on desktop machines
-;
-; 1067 2012-11-26 10:13:14Z marong
-; Initial revision
-;
-; Description:
-; ------------
-; Configuration file for nc2vdf.
-;------------------------------------------------------------------------------!
-; This configuration file uses NCL syntax.
-;------------------------------------------------------------------------------!
-; Define name of output file:
-    outputfile      = "vaporoutput" +".vdf"
-
-; Insert number and names of input files
-    numberoffiles   = 2
-    files           = new( (/numberoffiles/), string)
-    files(0)        = "palm/current_version/JOBS/building/OUTPUT/building_3d.nc"
-    files(1)        = "palm/current_version/JOBS/building/OUTPUT/building_3d.nc"
-    ;files(2)        = ï¿œ ; path from where nc2vdf is called
-
-; Insert names of variables to be taken from files specified above
-    alt_varnames = False
-    ; for using the alternative method (alt_varnames = True)
-    ; e.g. for varnames containing double quotes, get numbers from ncdump:
-
-    ;vars = new( (/numberoffiles,1/), integer)
-    ;vars(0,0) = 10
-    ;vars(1,0) = 9
-
-    nvars = 2 ; number of variables (per file)
-
-    ; normal method:
-    varString = new( (/numberoffiles,1/), string)
-    varString(0,0) = "u"
-    varString(1,0) = "w"
-
-; Specify index of start and end time step, 'False' will include all time steps
-    spec_ts = True
-    t_start = 0
-    t_end   = 3
-
-; Specify a maximum refinement level? 'False' will set the default value.
-    spec_reflevel = False
-    reflevel      = 1
-
-; LES used periodic lateral boundaries?
-    periodic = True
-
-; LES used grid stretching?
-    grid_stretch = False
-    stretch_level = 999
-
-;------------------------------------------------------------------------------!
-; Configuration for workstations (none IMUK/HLRN systems)
-    check_workstation = False
-                       ; Set check True to run script on none IMUK/HLRN systems.
-
-    ;WS_init          = False
-    ;init_script      = /muksoft/packages/vapor/2.2.0/bin/vapor-setup.sh
-                       ; Note: These lines alway stay comments for NCL
-                       ; as they are read by the shell script only.
-
-                       ; Set init True if VAPORs initialization script
-                       ; needs to run on the workstation (most linux systems).
-                       ; Provide path to script (without quotes; . /path/init.sh).
-
-    ;WS_load          = False
-    ;WS_load_command  = module load vapor ncl
-                       ; pass any command to the shell
-
-    install_path      = "/Applications/VAPOR.app/Contents/MacOS/" 
-                       ; customize VAPOR installation path 
-                       ; when running this script on a (Mac OS) workstation
-                       ; * will be ignored on HLRN or IMUK systems *
-
-;------------------------------------------------------------------------------!
-
Index: palm/trunk/SCRIPTS/nc2vdf.ncl
===================================================================
--- palm/trunk/SCRIPTS/nc2vdf.ncl	(revision 1610)
+++ 	(revision )
@@ -1,571 +1,0 @@
-;--------------------------------------------------------------------------------!
-; This file is part of PALM.
-;
-; PALM is free software: you can redistribute it and/or modify it under the terms
-; of the GNU General Public License as published by the Free Software Foundation,
-; either version 3 of the License, or (at your option) any later version.
-;
-; PALM is distributed in the hope that it will be useful, but WITHOUT ANY
-; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-; A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-;
-; You should have received a copy of the GNU General Public License along with
-; PALM. If not, see <http://www.gnu.org/licenses/>.
-;
-; Copyright 1997-2014  Leibniz Universitaet Hannover
-;------------------------------------------------------------------------------!
-;
-; Current revisions:
-; -----------------
-; 
-; 
-; Former revisions:
-; -----------------
-; $Id$
-;
-; 1310 2014-03-14 08:01:56Z raasch
-; adapted for use on desktop machines
-;
-; 1067 2012-11-26 10:13:14Z maronga
-; Code put under GNU GPL
-;
-; 1062 2012-11-21 15:57:18Z maronga
-; full batch mode support, loading configuration from an external file
-; fallback to interactive mode if no configuration present
-; batch mode does not support loading more than one variable per file if there
-; is more than one file specified (but there is a workaround)
-; you cannot add time steps to a variable from an additional file in batch mode
-;
-; 1046 2012-11-09 14:38:45Z maronga
-; Initial revision
-;
-; Description:
-; ------------
-; This NCL script coverts PALM NetCDF data to vdf, VAPOR's own data format. In
-; order to run this script, NCL version 5.2.0 or higher is required.
-; Default setting will be loaded from .nc2vdf.config.
-; The script does only work on hicegate2, bicegate2,
-; uv, on the imuk server. It can be adapted for use on any desktop machine.
-;------------------------------------------------------------------------------!
-
-load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"
-load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"
-load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
-load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/shea_util.ncl"
-
-alt_varnames = False
-man = True
-path = ""
-
-if(isfilepresent(inputfile)) then
-   print("*** Loading " + inputfile)
-   loadscript(inputfile)
-   man = False
-else
-    print("+++ Input file does not exist.")
-    man_resp = systemfunc("read -p 'Enter manual mode? (y/n) ' RESP; echo $RESP")
-    if (man_resp .eq. "y") then
-       man = True
-    else
-       print("+++ Exiting...")
-       exit
-    end if
-end if
-
-
-begin
-
-if (.not. man) then
-;   print loaded data from input file
-    print("*** loading " + dimsizes(files) + ":")
-    do i=0,dimsizes(files)-1
-       print("    " + i + ") " + files(i))
-    end do
-
-    print("*** will create dataset " + outputfile)
-end if
-
-;******************************************************
-;give path to the directory where NetCDF files are stored:
-    print("*** Checking hostname...")
-    sys        = "unknown"
-    query      = systemfunc("echo $HOSTNAME")
-    check_muk  = isStrSubset(query,"muk.uni-hannover.de")
-    check_hice = isStrSubset(query,"hicegate2")
-    check_bice = isStrSubset(query,"bicegate2")
-    check_huv  = isStrSubset(query,"huv")
-    check_buv  = isStrSubset(query,"buv")
-
-
-
-
-    if ( check_muk .eq. True ) then
-       print("*** nc2vdf will execute at IMUK")
-       sys  = "IMUK"
-    else
-       if ( check_hice .eq. True .or. check_bice .eq. True ) then
-          print("*** nc2vdf will execute on hicegate2/bicegate2")
-          sys = "HLRN"
-       else
-          if ( check_huv .eq. True .or. check_buv .eq. True ) then
-             print("*** nc2vdf will execute on UV")
-             sys = "HLRN"
-             else
-                if ( check_workstation .eq. True) then
-                print("*** nc2vdf will execute on a workstation PC/Mac")
-                sys = "workstation"
-                path = install_path
-          end if
-          end if
-       end if
-    end if
-    if ( sys .eq. "unknown" ) then
-       print("+++ unknown system. Exiting...")
-       exit
-    end if
-
-
-workpath = systemfunc("echo $PWD") + "/"
-
-
-;******************************************************
-;******************************************************
-if man then
-;specify name of output file:
-outputfile	= "output.vdf" ;<<<<------------- !!!
-end if
-;******************************************************
-;******************************************************
-
-x_min = new(1,double)
-x_max = new(1,double)
-x_min = 99.0
-x_max = -99.0
-y_min = new(1,double)
-y_max = new(1,double)
-y_min = 99.0
-y_max = -99.0
-z_min = new(1,double)
-z_max = new(1,double)
-z_min = 99.0
-z_max = -99.0
-
-vars3d      = ""
-
-
-
-if man then
-    ;**** Get names of variables appearing in the VDF file, then get their dimensions with min/max x,y,z
-    print(" ")
-    print("Choose the *.nc files containing 3D data by typing their indices (seperated by ','). Start with the first files of the timeseries.")
-    print(" ")
-    files_avail   = systemfunc("cd "+workpath+"; ls *.nc")
-    print(" "+files_avail)
-
-
-    files_in_ary  = toint(str_split(systemfunc("read file; echo $file"), ","))
-    nofiles       = dimsizes(files_in_ary)
-    file_in       = new(nofiles,string)
-
-    do i=0,nofiles-1
-        file_in(i)    = files_avail(files_in_ary(i))
-    end do
-else
-    file_in = files
-    nofiles = dimsizes(file_in)
-end if
-
-
-
-
-
-if (nofiles .ge. 2) then
-nvars   = 1
-if man then
-varString  = new((/nofiles,nvars/),string)
-end if; man
-dimNames   = new((/nofiles,nvars,4/),string)
-end if
-
-
-do i=0,nofiles-1
-    print("Loading file...")
-    f             = addfile(workpath+file_in(i),"r")
-
-    varNames      = getfilevarnames(f)
-
-
-    if man then
-    print(" ")
-    print("The following variables were found in "+file_in(i)+":")
-    print(" ")
-    print(" "+varNames)
-    print(" ")
-    print("Type the index of the VARIABLES (not dimensions) you want to visualize in Vapor (seperated by ',')")
-
-    vars       = toint(str_split(systemfunc("read vars; echo $vars"), ","))
-
-
-    nvars = dimsizes(vars)
-    end if; man
-
-    if (nofiles .eq. 1) then
-    if man then
-    varString  = new((/nofiles,nvars/),string)
-    end if; man
-    dimNames   = new((/nofiles,nvars,4/),string)
-    end if
-
-
-
-    do n=0,nvars-1
-       if man then
-       varString(i,n) = varNames(vars(n))
-       end if; man
-
-       if alt_varnames then
-            varString(i,n) = varNames(vars(i,n))
-       end if
-
-       if (vars3d .ne. "") then
-       vars3d       = vars3d + ":" + varString(i,n)
-       else
-       vars3d       = varString(i,n)
-       end if
-
-
-       dims          = getfilevardimsizes(f, varString(i,n))
-       dimNames(i,n,:) = getfilevardims(f, varString(i,n))
-
-
-
-       time     = f->$dimNames(i,n,0)$
-       t_max	= max(time)
-       z     	= f->$dimNames(i,n,1)$
-       y     	= f->$dimNames(i,n,2)$
-       x	    = f->$dimNames(i,n,3)$
-
-       if (z_min .ge. min(z)) then
-          z_min = min(z)
-       end if
-
-       if (z_max .le. max(z)) then
-          z_max = max(z)
-       end if
-
-       if (y_min .ge. min(y)) then
-          y_min = min(y)
-       end if
-
-       if (y_max .le. max(y)) then
-          y_max = max(y)
-       end if
-
-       if (x_min .ge. min(x)) then
-          x_min = min(x)
-       end if
-
-       if (x_max .le. max(x)) then
-          x_max = max(x)
-       end if
-
-       delete(z)
-       delete(y)
-       delete(x)
-    end do
-
-end do
-
-;print(varString)
-
-if man then
-delete(files_avail)
-end if
-
-if man then
-    print(" ")
-    periodic_resp              = systemfunc("read -p 'Periodic lateral boundaries? (y/n) ' RESP; echo $RESP")
-    if (periodic_resp .eq. "y") then
-        periodic = True
-    else
-        periodic = False
-    end if
-end if
-
-if (periodic) then
-   px		= 1
-   py		= 1
-else
-   px		= 0
-   py		= 0
-end if
-print(" ")
-print(" ")
-
-if man then
-    grid_resp              = systemfunc("read -p 'Is grid stretching used? (y/n) YES will cut of heights above dz_stretch_level? ' RESP; echo $RESP")
-    if (grid_resp .eq. "y") then
-        grid_stretch = True
-    else
-        grid_stretch = False
-    end if
-end if
-
-if (grid_stretch) then
-    if man then
-       stretch_level    = stringtointeger(systemfunc("read -p 'Please type height of dz_stretch_level (in meters) ' RESP; echo $RESP"))
-    end if; man
-    z_max = stretch_level ;**** limit z_max
-end if
-
-print(" ")
-
-;*******************************************************************************
-
-
-
-
-if (any(varNames .EQ. "zwwi")) then
-   var2d     = " -vars2dxy HGT:topo"
-   topo      = True
-   print(" ")
-   print("Found topography - will add 'zwwi' (w-grid) topography to *.vdf file.")
-   print(" ")
-else
-   var2d     = " "
-   topo      = False
-end if
-
-if man then
-print(" ")
-
-print(dims(0)+" time steps found in "+file_in)
-ts       = systemfunc("read -p 'Include all time steps in *.vdf file? (y/n) ' RESP; echo $RESP")
-
-if (ts .eq. "y") then
-   t_start 	= 0
-   t_end	= dimsizes(time)-1
-else
-   t_start	= stringtointeger(systemfunc("read -p 'Type index of first time step: ' ts; echo $ts"))
-   t_end	= stringtointeger(systemfunc("read -p 'Type index of last time step: ' ts; echo $ts"))
-end if
-end if
-
-if (.not. man) then
-    if (.not. spec_ts) then
-           t_start 	= 0
-           t_end	= dimsizes(time)-1
-    end if
-end if
-
-if man then
-    print(" ")
-    askreflevel              = systemfunc("read -p 'Specify a maximum refinement level? (y/n) No will set the default value.  ' RESP; echo $RESP")
-    if (askreflevel .eq. "y") then
-       reflevel    = systemfunc("read -p 'Please type maximum refinement level ' RESP; echo $RESP")
-       reflevel_str = "-level "+ reflevel
-    else
-       reflevel_str = ""
-    end if
-    print(" ")
-else
-    if spec_reflevel then
-        reflevel_str = "-level "+ reflevel
-    else
-       reflevel_str = ""
-    end if
-end if
-
-
-
-;*******************************************************************************
-;*******************************************************************************
-;*******************************************************************************
-print(" ")
-print("Creating *.vdf file")
-print(" ")
-;vars3d    = str_join(varString,":")
-
-a = systemfunc(path+"vdfcreate -dimension "+dims(3)+"x"+dims(2)+"x"+dims(1)+" -numts " + (t_end - t_start + 1) + var2d + " "+reflevel_str+" -vars3d "+vars3d+" -extents "+x_min+":"+y_min+":"+z_min+":"+x_max+":"+y_max+":"+z_max+" -periodic "+px+":"+py+":0 "+workpath+outputfile)
-delete(a)
-print("Done.")
-
-
-;*******************************************************************************
-print("Populating *.vdf file")
-
-do i=0,nofiles-1
-    do n=0,nvars-1
-       dimnamesstring = str_join(dimNames(i,n,::-1),":")
-       print(" ")
-       print("Variable: "+varString(i,n)+", number "+(n+1+i)+" of "+(nvars+nofiles-1) )
-       print(" ")
-       do t=t_start,t_end
-          print("Time step "+(t-t_start+1)+" of "+(t_end-t_start+1) )
-          a = systemfunc(path+"ncdf2vdf -dimnames "+dimnamesstring+" "+reflevel_str+" -varname "+varString(i,n)+" -ncdfvar "+varString(i,n)+" -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(i))
-          delete(a)
-       end do
-    end do
-end do
-
-if topo then
-   print(" ")
-   print("Adding topography (1)...")
-   print(" ")
-   do t=t_start,t_end
-      print("Time step "+(t-t_start+1)+" of "+(t_end-t_start+1) )
-      a = systemfunc(path+"ncdf2vdf -dimnames x:y "+reflevel_str+" -varname HGT -ncdfvar zwwi -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(0))
-      delete(a)
-   end do
-   print(" ")
-   print("Adding topography (2)...")
-   print(" ")
-   do t=t_start,t_end
-      print("Time step "+(t-t_start+1)+" of "+(t_end-t_start+1) )
-      a = systemfunc(path+"ncdf2vdf -dimnames x:y "+reflevel_str+" -varname topo -ncdfvar zwwi -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(0))
-      delete(a)
-   end do
-end if
-
-
-;*******************************************************************************
-if man then
-;**** Read more files and add them to VDF/VDC
-addmore = "y"
-do while (addmore .eq. "y")
-
-   addmore       = systemfunc("read -p 'Add time steps or 2D cross sections from additional *.nc files? (2d/time/n) ' RESP; echo $RESP")
-
-;**** Add time steps from additional 3D files
-    if (addmore .eq. "time") then
-
-    delete(f)
-
-    do i=0,nofiles-1
-
-        print(" ")
-        print("Choose the *.nc file that contains 3D data for "+varString(i,0)+" by typing itÂŽs index.")
-        print(" ")
-        files_avail   = systemfunc("cd "+workpath+"; ls *.nc")
-        print(" "+files_avail)
-        print(" ")
-        file_in(i)    = files_avail(toint(systemfunc("read file; echo $file")))
-
-    end do
-
-    f        = addfile(workpath+file_in(0),"r")
-
-    time     = f->time
-
-    a = systemfunc(path+"vdfedit -addts "+dimsizes(time)+" "+workpath+outputfile)
-    delete(a)
-
-    do i=0,nofiles-1
-        do n=0,nvars-1
-           dimnamesstring = str_join(dimNames(i,n,::-1),":")
-           print(" ")
-           print("Variable: "+varString(i,n)+", number "+(n+1+i)+" of "+(nvars+nofiles-1) )
-           print(" ")
-           do t=t_end,dimsizes(time)-1
-              print("Time step "+(t-t_end+1)+" of "+(dimsizes(time)-t_end) )
-              a = systemfunc(path+"ncdf2vdf -dimnames "+dimnamesstring+" "+reflevel_str+" -varname "+varString(i,n)+" -ncdfvar "+varString(i,n)+" -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(i))
-              delete(a)
-           end do
-        end do
-    end do
-
-    if topo then
-       print(" ")
-       print("Adding topography (1)...")
-       print(" ")
-       do t=t_end,dimsizes(time)-1
-          print("Time step "+(t-t_end+1)+" of "+(dimsizes(time)-t_end) )
-          a = systemfunc(path+"ncdf2vdf -dimnames x:y "+reflevel_str+" -varname HGT -ncdfvar zwwi -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(0))
-          delete(a)
-       end do
-       print(" ")
-       print("Adding topography (2)...")
-       print(" ")
-       do t=t_end,dimsizes(time)-1
-          print("Time step "+(t-t_end+1)+" of "+(dimsizes(time)-t_end) )
-          a = systemfunc(path+"ncdf2vdf -dimnames x:y "+reflevel_str+" -varname HGT -ncdfvar zwwi -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in(0))
-          delete(a)
-       end do
-    end if
-
-
-
-    t_end	= dimsizes(time)-1
-
-
-
-    end if
-
-
-;**** Add 2D cross sections
-   if (addmore .eq. "2d") then
-      delete(f)
-      delete(file_in)
-
-      print(" ")
-      print("Choose additional file to add 2D cross sections. Type index.")
-      print(" ")
-      files_avail   = systemfunc("cd "+workpath+"; ls *.nc")
-      print(" "+files_avail)
-
-      file_in       = files_avail(toint(systemfunc("read file; echo $file")))
-      delete(files_avail)
-
-      f             = addfile(workpath+file_in,"r")
-
-      varNames2d      = getfilevarnames(f)
-
-      crosstype       = systemfunc("read -p 'Please specify type of cross section (xy/xz/yz) ' RESP; echo $RESP")
-      print(" ")
-      print("The following variables were found in the file:")
-      print(" ")
-      print(" "+varNames2d)
-      print(" ")
-      print("Type the index of the variables you want to add to the *.vdf file (seperated by ',')")
-
-      vars2d       = toint(str_split(systemfunc("read vars; echo $vars"), ","))
-
-
-
-      nvars2d = dimsizes(vars2d)
-
-      varString2d  = new(dimsizes(vars2d),string)
-      dimNames2d   = new((/dimsizes(vars2d),4/),string)
-
-      do n=0,nvars2d-1
-	 varString2d(n) = varNames2d(vars2d(n))
-
-	 dims2d     = getfilevardimsizes(f,varString2d(n))
-	 dimNames2d(n,:) = getfilevardims(f,varString2d(n))
-
-
-      end do
-
-      vars2dstr    = str_join(varString2d,":")
-
-      a = systemfunc(path+"vdfedit -addvars2d"+crosstype+" "+vars2dstr+" "+workpath+outputfile)
-      delete(a)
-
-      do n=0,nvars2d-1
-	 dimnamesstring = str_join(dimNames2d(n,::-1),":")
-
-	 do t=0,dims2d(0)-1
-	    a = systemfunc(path+"ncdf2vdf -dimnames "+dimnamesstring+" "+reflevel_str+" -varname "+varNames2d(vars2d(n))+" -ncdfvar "+varNames2d(vars2d(n))+" -cnstnames time -cnstvals "+t+" -ts "+t+" "+workpath+outputfile+" "+workpath+file_in)
-	    delete(a)
-	 end do
-      end do
-      delete(varNames2d)
-   end if
-
-   addmore       = systemfunc("read -p 'Add additional *.nc files? (y/n) ' RESP; echo $RESP")
-end do
-end if; man
-;*******************************************************************************
-print("Done.")
-;*************
-end
Index: palm/trunk/SCRIPTS/palm_wd
===================================================================
--- palm/trunk/SCRIPTS/palm_wd	(revision 1611)
+++ palm/trunk/SCRIPTS/palm_wd	(revision 1611)
@@ -0,0 +1,675 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#--------------------------------------------------------------------------------#
+# This file is part of PALM.
+#
+# PALM is free software: you can redistribute it and/or modify it under the terms
+# of the GNU General Public License as published by the Free Software Foundation,
+# either version 3 of the License, or (at your option) any later version.
+#
+# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# PALM. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 1997-2015  Leibniz Universitaet Hannover
+#--------------------------------------------------------------------------------#
+#
+# Current revisions:
+# -----------------
+# Initial revision
+# 
+# Former revisions:
+# -----------------
+# $Id$
+#
+#
+# Description:
+# ------------
+# PALM watchdog client for monitoring batch jobs on a variety of hosts specified
+# by the user
+# 
+# Instructions:
+# -------------
+# 1) Modify the header section of palm_wd
+# 2) Move .wd.olddata and .wd.newdata to your palm directory 
+#    (e.g. /home/user/current_version/.wd.newdata etc.)
+# 3) Modify a copy of palm_wdd for each host to be monitored and move it to the
+#    respective hosts
+# 4) Start the client either from mrungui or from shell by "nohup palm_wd&"
+
+# To do:
+# ------
+# 1) Add "Options", "Help" and "Manual"
+# 2) Move user settings to a configuration file
+#------------------------------------------------------------------------------!
+
+import sys
+import subprocess as sub
+from PyQt4 import QtGui, QtCore, uic
+from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
+import time
+import datetime
+import shutil
+import os
+
+# START OF HEADER
+# Each list must contain the login host, the username and a description
+hostname     = ["hlogin.hlrn.de", "blogin.hlrn.de"]
+username     = ["nikmaron"      , "nikmaron"      ]
+description  = ["Hannover"      , "Berlin"        ]
+
+update_frequency = 600*1000
+
+# END OF HEADER
+
+# Determine PALM directories
+try: 
+   devnull = open(os.devnull, 'w')
+   out = sub.check_output("echo $PALM_BIN", shell=True, stderr=sub.STDOUT)
+   palm_bin = out.rstrip()
+   palm_dir = out.split("palm")[0] + "palm/" + out.split("palm")[1].split("/")[1]
+   out = None
+except:   
+   print "Error. $PALM_BIN is not set."
+   raise SystemExit
+
+
+# Dummy variables for the jobname and the progressbars
+jobname = ""
+timestamp = ""
+pbars = []
+job_data_list = []
+
+# MainWindow class
+class Watchdog(QtGui.QMainWindow):
+    
+    def __init__(self):
+        super(Watchdog, self).__init__()
+        
+        self.InitUi()   
+        
+   
+    # Initialized MainWindow UI
+    def InitUi(self):
+
+        # Load predefined mainwindow
+        uic.loadUi(palm_bin + '/palm_wd_files/wd.ui', self)
+
+        # Resize columns and set number of rows to zero. Column 6 is hidden and
+        # contains the remote jobname (e.g. hannover.174610)
+        self.table.setColumnWidth(0,230)
+        self.table.setColumnWidth(1,80)
+        self.table.setColumnWidth(2,50)
+        self.table.setColumnWidth(3,80)     
+        self.table.setColumnWidth(4,180)
+        self.table.setColumnWidth(5,115)   
+        self.table.setColumnHidden(6, True)
+        self.table.setRowCount(0) 
+        
+        # Display MainWindow
+        self.show()
+        QtGui.QApplication.processEvents()
+
+        # Start refresh timer. On timeout perform update
+        self.timer = QtCore.QTimer(self)
+        self.timer.timeout.connect(self.Refresh)
+        self.timer.setSingleShot(False)
+        self.timer.start(update_frequency)
+
+        # The timetimer counts the time since last update
+        self.timetimer= QtCore.QElapsedTimer()
+        self.timetimer.start()
+
+        # The labeltimer induces the update of the remaining time in the UI
+        self.labeltimer = QtCore.QTimer(self)
+        self.labeltimer.timeout.connect(self.UpdateLabel)
+        self.labeltimer.setSingleShot(False)
+
+        # Update in the UI will be performed at each 1/10 of the update interval
+        self.labeltimer.start(update_frequency/10)   
+        self.label.setText("Next update in " + str(update_frequency/1000/60) + "min")
+
+        # Update the list now
+        self.Refresh()
+        
+
+    # Add a custom context menu
+    def OpenContextMenu(self, position):
+        menu = QtGui.QMenu()
+       
+        # "Show details" -> fetch details for the selected job
+        detailsjobAction = menu.addAction('Show details')     
+        detailsjobAction.setStatusTip('Display detailed info for job')
+        detailsjobAction.triggered.connect(self.ShowDetails)
+
+        # "Cancel job" -> remove job from queuing system
+        canceljobAction = menu.addAction('Cancel job')
+        canceljobAction.setStatusTip('Remove job from queueing system')
+        canceljobAction.triggered.connect(self.CancelJob)
+        
+        # "Force stop" -> remove job from queuing system
+        stopjobAction = menu.addAction('Force stop')
+        stopjobAction.setStatusTip('Terminate job properly')
+        stopjobAction.triggered.connect(self.DoStop)
+   
+        # "Force restart" -> remove job from queuing system
+        restartjobAction = menu.addAction('Force restart')
+        restartjobAction.setStatusTip('Terminate job properly and initiate restart')
+        restartjobAction.triggered.connect(self.DoRestart)
+  
+        # "Remove from list" -> remove a completed job from the list
+        removefromlistAction = menu.addAction('Remove from list')     
+        removefromlistAction.setStatusTip('Remove finished job')
+        removefromlistAction.triggered.connect(lambda: self.RemoveFromList(-1))     
+
+        
+        # Activate/deactive contect menu items based on the status of the runs
+        state = self.table.item(self.table.currentRow(),3).text()
+        if (state == "Canceled" or state == "Completed" or state == "Terminated"):
+            detailsjobAction.setEnabled(False)
+            canceljobAction.setEnabled(False)  
+            removefromlistAction.setEnabled(True)  
+        else:
+            detailsjobAction.setEnabled(True)
+            canceljobAction.setEnabled(True)  
+            removefromlistAction.setEnabled(False)   
+ 
+        if ( state == "Running" ):
+	    stopjobAction.setEnabled(True) 
+            restartjobAction.setEnabled(True)   
+        else:
+	    stopjobAction.setEnabled(False) 
+            restartjobAction.setEnabled(False)   
+   
+        # Show the context menu
+        action = menu.exec_(self.table.mapToGlobal(position))
+
+
+    # Collecting watchdog data and display in the UI
+    def Refresh(self):
+      
+        # Use global variables
+        global jobs_save
+        global pbars
+
+        # Deactivate timer processes until update is finished
+        # QtGui.QApplication.processEvents() updates the UI whenever needed
+        self.labeltimer.stop() 
+        self.label.setText("Updating...") 
+        QtGui.QApplication.processEvents()
+        self.setEnabled(False)
+        QtGui.QApplication.processEvents()
+
+        # Get current timestamp
+        timestamp = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")
+        
+        # Open an empty file for the watchdog data        
+        file = open(palm_dir + '/.wd.newdata', 'w')
+        
+ 
+        # Set all required variables to their initial values. Sorting must be
+        # disabled.
+        self.table.setRowCount(0) 
+        self.table.setSortingEnabled(False)
+        i = -1
+        job_data_list = []
+        pbars = []
+        
+        # Scan all hosts in the variable hostname. For each host perform the
+        # update loop
+        for h in range(0,len(hostname)):
+	  
+	    # Perform ssh command
+            host    = username[h] + "@" + hostname[h]
+            ssh = sub.Popen(["ssh", "%s" % host, "/sw/tools/python/2.7.6/generic/bin/python palm_wdd queue " + username[h]],
+                           shell=False,
+                           stdout=sub.PIPE,
+                           stderr=sub.PIPE)
+            result = ssh.stdout.readlines()
+            result = filter(None, result)
+ 
+ 
+     	    # Delete all job data
+	    job_data_tmp = []
+            job_data = []
+            job_data_n = []    
+	    job_data_old = []
+	    job_data_old_n = []
+	    job_progress = 0
+
+            # In case of errors display error message
+            if ( len(result) < 1 ):
+                error = ssh.stderr.readlines()
+                if ( error != [] ):
+                    notify = QtGui.QMessageBox.warning(self,'Collect data',"Error. An error occured during read of job data for user " + username[h] +" for host " + description[h] + ".\n\nError message:\n" + ''.join(error))
+
+            # No error -> save job data
+            else:        
+
+                # Successively write to job_data
+                for j in range(0,len(result)):
+   
+  		    job_data_tmp.append(j)
+                    job_data_tmp[j] = result[j].split(" ")
+                    job_data_tmp[j] = filter(None, job_data_tmp[j])
+  
+                    job_data.append(j)   
+                    job_data[j] = [job_data_tmp[j][0], description[h], job_data_tmp[j][2],                  
+				   job_data_tmp[j][3], int(float(job_data_tmp[j][4])*100), job_data_tmp[j][5], 
+				   job_data_tmp[j][1], job_data_tmp[j][6].rstrip()]
+                    job_data_n.append(j)
+                    job_data_n[j] = job_data_tmp[j][1]
+
+            del(result)
+
+
+
+            # Now read the data from the last update from file. These data are
+            # already in the prefered format
+            file2 = open(palm_dir + '/.wd.olddata', 'r')
+	    result = file2.readlines()
+	    file2.close()
+	    
+            for j in range(0,len(result)):
+	        if ( result[j].split()[1] == description[h] ):
+		    job_data_old.append(j)
+                    job_data_old[j] = result[j].split(" ")
+                    job_data_old[j] = filter(None, job_data_old[j])
+                    job_data_old[j] = [line.rstrip('\n') for line in job_data_old[j]]
+                
+                    job_data_old_n.append(j)
+                    job_data_old_n[j] = job_data_old[j][6]
+
+            # Merge the job_data and job_data_old to find completed, new and
+            # still queued jobs     
+            if ( len(job_data_n) > 0 and len(job_data_old_n) > 0 ):
+               jobs_full  = list(set(job_data_old_n) | set(job_data_n))
+               jobs_known    = list(set(job_data_old_n) & set(job_data_n))
+               jobs_complete = set(job_data_old_n) - set(job_data_n)
+               jobs_new      = set(job_data_n) - set(job_data_old_n)
+            elif ( len(job_data_n) > 0 ):
+	       jobs_full  = job_data_n
+	       jobs_known    = []
+	       jobs_new = job_data_n
+	       jobs_complete = []
+	    elif ( len(job_data_old_n) > 0 ):
+	       jobs_full  = job_data_old_n
+	       jobs_known    = []
+	       jobs_new = []
+	       jobs_complete = job_data_old_n   
+	    else:
+	       jobs_full  = []
+	       jobs_known    = []         
+	       jobs_new = []
+	       jobs_complete = []
+
+            # Display all known jobs
+            to_display = [list(job_data_n).index(item) for item in list(jobs_known) if list(jobs_known) and list(job_data_n)]
+            for j in range(0,len(to_display)):
+	        i = i + 1
+                self.table.insertRow(i)
+                item = QtGui.QTableWidgetItem(job_data[to_display[j]][0])
+                item.setToolTip("Queuing name: " + job_data[to_display[j]][6])
+                self.table.setItem(i, 0, item)            
+                self.table.setItem(i, 1, QtGui.QTableWidgetItem(job_data[to_display[j]][1])) 
+                self.table.setItem(i, 2, QtGui.QTableWidgetItem(job_data[to_display[j]][2]))   
+                self.table.setItem(i, 3, QtGui.QTableWidgetItem(job_data[to_display[j]][3]))
+                item = QtGui.QTableWidgetItem(job_data[to_display[j]][5])
+                item.setToolTip("Estimated job start: " + job_data[to_display[j]][7])               
+                self.table.setItem(i, 5, item)  
+                self.table.setItem(i, 6, QtGui.QTableWidgetItem(job_data[to_display[j]][6]))  
+                self.table.item(i,2).setTextAlignment(QtCore.Qt.AlignRight)
+                self.table.item(i,5).setTextAlignment(QtCore.Qt.AlignRight)
+                pbars.append(i)
+                pbars[i] = QtGui.QProgressBar(self)
+                pbars[i].setValue(int(job_data[to_display[j]][4])) 
+ 
+                # Apply a color depending on the status of the job
+                if ( job_data[to_display[j]][3] == "Running" ):
+                    self.table.setCellWidget(i,4,pbars[j]) 
+		    self.table.item(i,0).setBackground(QtGui.QColor(255, 251, 168))
+		    self.table.item(i,1).setBackground(QtGui.QColor(255, 251, 168))
+		    self.table.item(i,2).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,3).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,5).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,6).setBackground(QtGui.QColor(255, 251, 168))
+                else:
+		    pbars[j].setEnabled(False)
+		    self.table.setCellWidget(i,4,pbars[j])
+                    self.table.item(i,0).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,1).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,2).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,3).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,5).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,6).setBackground(QtGui.QColor(255, 112, 118))
+                
+                # Save the job data to file
+                job_data_list.append(i)
+                job_data_list[i] = job_data[to_display[j]][0]
+                
+                printstring = str(job_data[to_display[j]][0]) + " " + \
+                              str(job_data[to_display[j]][1]) + " " + \
+                              str(job_data[to_display[j]][2]) + " " + \
+                              str(job_data[to_display[j]][3]) + " " + \
+                              str(job_data[to_display[j]][4]) + " " + \
+                              str(job_data[to_display[j]][5]) + " " + \
+                              str(job_data[to_display[j]][6]) + " " + \
+                              str(job_data[to_display[j]][7]) + "\n"
+                file.write(printstring)
+
+
+            # Display all new jobs
+            to_display = [list(job_data_n).index(item) for item in list(jobs_new) if list(jobs_new) and list(job_data_n)]
+            for j in range(0,len(to_display)):
+	        i = i + 1
+                self.table.insertRow(i)
+                item = QtGui.QTableWidgetItem(job_data[to_display[j]][0])
+                item.setToolTip("Queuing name: " + job_data[to_display[j]][6])
+                self.table.setItem(i, 0, item)   
+                self.table.setItem(i, 0, QtGui.QTableWidgetItem(job_data[to_display[j]][0]))            
+                self.table.setItem(i, 1, QtGui.QTableWidgetItem(job_data[to_display[j]][1])) 
+                self.table.setItem(i, 2, QtGui.QTableWidgetItem(job_data[to_display[j]][2]))   
+                self.table.setItem(i, 3, QtGui.QTableWidgetItem(job_data[to_display[j]][3])) 
+                item = QtGui.QTableWidgetItem(job_data[to_display[j]][5])
+                item.setToolTip("Estimated job start: " + job_data[to_display[j]][7])               
+                self.table.setItem(i, 5, item)  
+                self.table.setItem(i, 6, QtGui.QTableWidgetItem(job_data[to_display[j]][6]))  
+                self.table.item(i,2).setTextAlignment(QtCore.Qt.AlignRight)
+                self.table.item(i,5).setTextAlignment(QtCore.Qt.AlignRight)
+                
+                pbars.append(i)
+                pbars[i] = QtGui.QProgressBar(self)
+                pbars[i].setValue(int(job_data[to_display[j]][4]))   
+
+                # Apply a color depending on the status of the job
+                if ( job_data[to_display[j]][3] == "Running" ):
+		    self.table.setCellWidget(i,4,pbars[i])           
+		    self.table.item(i,0).setBackground(QtGui.QColor(255, 251, 168))
+		    self.table.item(i,1).setBackground(QtGui.QColor(255, 251, 168))
+		    self.table.item(i,2).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,3).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,5).setBackground(QtGui.QColor(255, 251, 168))
+                    self.table.item(i,6).setBackground(QtGui.QColor(255, 251, 168))
+                else:
+		    pbars[j].setEnabled(False)
+		    self.table.setCellWidget(i,4,pbars[i])
+                    self.table.item(i,0).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,1).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,2).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,3).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,5).setBackground(QtGui.QColor(255, 112, 118))
+                    self.table.item(i,6).setBackground(QtGui.QColor(255, 112, 118))
+          
+                # Save job data to file
+                job_data_list.append(i)
+                job_data_list[i] = job_data[to_display[j]][0]
+                
+                printstring = str(job_data[to_display[j]][0]) + " " + \
+                              str(job_data[to_display[j]][1]) + " " + \
+                              str(job_data[to_display[j]][2]) + " " + \
+                              str(job_data[to_display[j]][3]) + " " + \
+                              str(job_data[to_display[j]][4]) + " " + \
+                              str(job_data[to_display[j]][5]) + " " + \
+                              str(job_data[to_display[j]][6]) + " " + \
+                              str(job_data[to_display[j]][7]) + "\n"
+                file.write(printstring)
+
+
+            # Display all completed/canceled/aborted jobs. The watchdog cannot
+            # distinguish why the job has been finished
+            to_display = [list(job_data_old_n).index(item) for item in list(jobs_complete) if list(jobs_complete) and list(job_data_old_n)]
+            for j in range(0,len(to_display)):
+	        i = i + 1
+                self.table.insertRow(i)
+                item = QtGui.QTableWidgetItem(job_data_old[to_display[j]][0])
+                item.setToolTip("Queuing name: " + job_data_old[to_display[j]][6])
+                self.table.setItem(i, 0, item)          
+                self.table.setItem(i, 1, QtGui.QTableWidgetItem(job_data_old[to_display[j]][1])) 
+                self.table.setItem(i, 2, QtGui.QTableWidgetItem(job_data_old[to_display[j]][2]))   
+                self.table.setItem(i, 3, QtGui.QTableWidgetItem(job_data_old[to_display[j]][3]))  
+                pbars.append(i)
+                pbars[j] = QtGui.QProgressBar(self)
+                pbars[j].setValue(int(job_data_old[to_display[j]][4]))  
+                pbars[j].setEnabled(False)
+                self.table.setCellWidget(i,4,pbars[j]) 
+                item = QtGui.QTableWidgetItem(job_data_old[to_display[j]][5])
+                item.setToolTip("Estimated job start: " + job_data_old[to_display[j]][7])               
+                self.table.setItem(i, 5, item)  
+                self.table.setItem(i, 6, QtGui.QTableWidgetItem(job_data_old[to_display[j]][6]))  
+                self.table.item(i,2).setTextAlignment(QtCore.Qt.AlignRight)
+                self.table.item(i,5).setTextAlignment(QtCore.Qt.AlignRight)
+                self.table.setItem(i, 3, QtGui.QTableWidgetItem("Completed"))
+                
+                # Apply a color depending on the status of the job
+                self.table.item(i,0).setBackground(QtGui.QColor(172, 252, 175))
+                self.table.item(i,1).setBackground(QtGui.QColor(172, 252, 175))
+                self.table.item(i,2).setBackground(QtGui.QColor(172, 252, 175))
+                self.table.item(i,3).setBackground(QtGui.QColor(172, 252, 175))
+                self.table.item(i,5).setBackground(QtGui.QColor(172, 252, 175))
+                self.table.item(i,6).setBackground(QtGui.QColor(172, 252, 175))
+
+          
+                # Save job data to file
+                job_data_list.append(i)
+                job_data_list[i] = job_data_old[to_display[j]][0]
+
+                printstring = str(job_data_old[to_display[j]][0]) + " " + \
+                              str(job_data_old[to_display[j]][1]) + " " + \
+                              str(job_data_old[to_display[j]][2]) + " " + \
+                              str(job_data_old[to_display[j]][3]) + " " + \
+                              str(job_data_old[to_display[j]][4]) + " " + \
+                              str(job_data_old[to_display[j]][5]) + " " + \
+	                      str(job_data_old[to_display[j]][6]) + " " + \
+                              str(job_data_old[to_display[j]][7]) + "\n"
+                file.write(printstring)
+
+            del(jobs_complete)
+            del(jobs_new)
+            del(result)
+
+        file.close()
+
+        
+        # Update is complete, sorting can thus be re-enabled                
+        self.table.setSortingEnabled(True) 
+
+        # Update the logfile
+        if ( os.path.isfile(palm_dir + '/.wd.newdata') ):
+            shutil.copy(palm_dir + '/.wd.newdata',palm_dir + '/.wd.olddata')
+
+        # Re-enable timer processes             
+        self.setEnabled(True)
+        self.label2.setText("Last update: " + timestamp)
+        self.label.setText("Update complete.")
+        self.timetimer.restart()
+        self.timer.start()
+        self.labeltimer.start()
+        QtGui.QApplication.processEvents()
+       
+    # Canceling selected job from table
+    def CancelJob(self):
+
+        # Return internal jobname
+        jobname = self.table.item(self.table.currentRow(),6).text()
+ 
+        # Check description of job in order to login on the correct host
+        descr = self.table.item(self.table.currentRow(),1).text()
+        for h in range(0,len(description)):
+	    if ( descr == description[h] ):
+                host = username[h] + "@" + hostname[h]
+
+        ssh = sub.Popen(["ssh", "%s" % host, "/sw/tools/python/2.7.6/generic/bin/python palm_wdd cancel " + jobname],
+                           shell=False,
+                           stdout=sub.PIPE,
+                           stderr=sub.PIPE)
+        result = ssh.stdout.readlines()
+        result = filter(None, result)
+        
+        # In case of error display a warning message
+        if ( len(result) == 0 ):
+            error = ssh.stderr.readlines()
+            notify = QtGui.QMessageBox.warning(self,'Cancel job',"Error. Could not cancel job " + jobname + ".\n\nError message:\n" + ''.join(error))
+
+        # Otherwise inform the user and mark the job in the table
+        else:
+	    self.table.setItem(self.table.currentRow(),3,QtGui.QTableWidgetItem("Canceled"))
+            notify = QtGui.QMessageBox.information(self,'Cancel job',"Job" + jobname + " canceled!\n\nServer message:\n" + ''.join(result))
+
+
+    # Show detailed information on job. For documentation see above
+    def ShowDetails(self):
+
+        jobname = self.table.item(self.table.currentRow(),6).text()
+        descr   = self.table.item(self.table.currentRow(),1).text()
+        for h in range(0,len(description)):
+	    if ( descr == description[h] ):
+                host = username[h] + "@" + hostname[h]
+
+        ssh = sub.Popen(["ssh", "%s" % host, "/sw/tools/python/2.7.6/generic/bin/python palm_wdd check " + jobname],
+                           shell=False,
+                           stdout=sub.PIPE,
+                           stderr=sub.PIPE)
+        result = ssh.stdout.readlines()
+        result = filter(None, result)
+
+        if ( len(result) == 0 ):
+            error = ssh.stderr.readlines()
+            notify = QtGui.QMessageBox.warning(self,'Show job details',"Error. Could not fetch job details for " + jobname + ".\n\nError message:\n" + ''.join(error))
+        else:
+            notify = QtGui.QMessageBox.information(self,'Job details',"Details for job " + jobname + ":\n\n" + ''.join(result))
+
+
+    # Perform a forced stop on the job
+    def DoStop(self):
+
+        # Return internal jobname
+        jobname = self.table.item(self.table.currentRow(),6).text()
+ 
+        # Check description of job in order to login on the correct host
+        descr = self.table.item(self.table.currentRow(),1).text()
+        for h in range(0,len(description)):
+	    if ( descr == description[h] ):
+                host = username[h] + "@" + hostname[h]
+                user = username[h]
+
+        ssh = sub.Popen(["ssh", "%s" % host, "/sw/tools/python/2.7.6/generic/bin/python palm_wdd stop " + user + " " + jobname],
+                           shell=False,
+                           stdout=sub.PIPE,
+                           stderr=sub.PIPE)
+        result = ssh.stdout.readlines()
+        result = filter(None, result) 
+        
+        # In case of error display a warning message
+        if ( len(result) == 0 ):
+            error = ssh.stderr.readlines()
+            notify = QtGui.QMessageBox.warning(self,'Proper termination of job',"Error. Could not stop job " + jobname + ".\n\nError message:\n" + ''.join(error))
+
+        # Otherwise inform the user and mark the job in the table
+        else:
+	    self.table.setItem(self.table.currentRow(),3,QtGui.QTableWidgetItem("Terminated"))
+            notify = QtGui.QMessageBox.information(self,'Terminatie job',"Termination of job " + jobname + " was initiated!\n\nServer message:\n" + ''.join(result))
+
+
+    # Perform a forced stop on the job
+    def DoRestart(self):
+
+        # Return internal jobname
+        jobname = self.table.item(self.table.currentRow(),6).text()
+ 
+        # Check description of job in order to login on the correct host
+        descr = self.table.item(self.table.currentRow(),1).text()
+        for h in range(0,len(description)):
+	    if ( descr == description[h] ):
+                host = username[h] + "@" + hostname[h]
+                user = username[h]
+
+        ssh = sub.Popen(["ssh", "%s" % host, "/sw/tools/python/2.7.6/generic/bin/python palm_wdd restart " + user + " " + jobname],
+                           shell=False,
+                           stdout=sub.PIPE,
+                           stderr=sub.PIPE)
+        result = ssh.stdout.readlines()
+        result = filter(None, result)
+        
+        # In case of error display a warning message
+        if ( len(result) == 0 ):
+            error = ssh.stderr.readlines()
+            notify = QtGui.QMessageBox.warning(self,'Proper termination of job',"Error. Could not stop job " + jobname + ".\n\nError message:\n" + ''.join(error))
+
+        # Otherwise inform the user and mark the job in the table
+        else:
+	    self.table.setItem(self.table.currentRow(),3,QtGui.QTableWidgetItem("Terminated"))
+            notify = QtGui.QMessageBox.information(self,'Terminate job for restart',"Restart for job" + jobname + " was initiated!\n\nServer message:\n" + ''.join(result))
+            
+
+    # Remove a job from list - removes the current row from the table and from
+    # save file
+    def RemoveFromList(self, row):
+        if ( row == -1 ):
+	    row = self.table.currentRow()
+
+        # Read data from save file
+        job_to_delete = self.table.item(row,6).text()
+        self.table.removeRow(row)
+        file = open(palm_dir + '/.wd.olddata', 'r')
+        result = file.readlines()
+        result = filter(None, result)
+	file.close()
+        file = open(palm_dir + '/.wd.olddata', 'w')
+	
+	job_data_old = []
+	
+        if ( len(result) == 0 ):
+            notify = QtGui.QMessageBox.warning(self,'Read from .wd.olddata',"Error message:\n\nCould not read from file. I/O error.")
+	else: 
+	    # Save data in array job_data_old
+	    for j in range(0,len(result)):
+                job_data_old.append(j)
+                job_data_old[j] = result[j].split(" ")
+                job_data_old[j] = filter(None, job_data_old[j])
+                job_data_old[j] = [line.rstrip('\n') for line in job_data_old[j]]
+                
+                # Check if line j is the selected job, if not -> save to file
+                if ( job_data_old[j][6] != job_to_delete ):
+                    printstring = str(job_data_old[j][0]) + " " + \
+                                  str(job_data_old[j][1]) + " " + \
+                                  str(job_data_old[j][2]) + " " + \
+                                  str(job_data_old[j][3]) + " " + \
+                                  str(job_data_old[j][4]) + " " + \
+                                  str(job_data_old[j][5]) + " " + \
+                                  str(job_data_old[j][6]) + " " + \
+                                  str(job_data_old[j][7]) + "\n"
+                    file.write(printstring)
+           
+        file.close() 
+
+    # Remove all completed jobs from list
+    def ClearList(self):
+      
+       num_of_lines = self.table.rowCount()
+       
+       # Delete all lines with completed/canceled jobs from list. The counter
+       # must decrease as the line numbers would be messed up otherwise
+       for j in range(num_of_lines-1,-1,-1): 
+           state = self.table.item(j,3).text()
+           if ( state == "Completed" or state == "Canceled" or state == "Terminated"):
+              self.RemoveFromList(j)
+         
+    # Update the label
+    def UpdateLabel(self):
+        remaining_time = (update_frequency - self.timetimer.elapsed()) / 1000 / 60
+        self.label.setText("Next update in " + str(remaining_time) + " min")
+        
+
+# Main loop       
+def main():
+    
+    app = QtGui.QApplication(sys.argv)
+    res = Watchdog() 
+    sys.exit(app.exec_())
+
+
+if __name__ == '__main__':
+    main()   
Index: palm/trunk/SCRIPTS/palm_wd_files/wd.ui
===================================================================
--- palm/trunk/SCRIPTS/palm_wd_files/wd.ui	(revision 1611)
+++ palm/trunk/SCRIPTS/palm_wd_files/wd.ui	(revision 1611)
@@ -0,0 +1,665 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="enabled">
+   <bool>true</bool>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>758</width>
+    <height>183</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>758</width>
+    <height>117</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>758</width>
+    <height>1000</height>
+   </size>
+  </property>
+  <property name="contextMenuPolicy">
+   <enum>Qt::CustomContextMenu</enum>
+  </property>
+  <property name="windowTitle">
+   <string>PALM Watchdog</string>
+  </property>
+  <property name="windowIcon">
+   <iconset>
+    <normaloff>wd.ico</normaloff>wd.ico</iconset>
+  </property>
+  <property name="animated">
+   <bool>true</bool>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <property name="sizePolicy">
+    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+     <horstretch>0</horstretch>
+     <verstretch>0</verstretch>
+    </sizepolicy>
+   </property>
+   <property name="minimumSize">
+    <size>
+     <width>0</width>
+     <height>0</height>
+    </size>
+   </property>
+   <property name="maximumSize">
+    <size>
+     <width>16777215</width>
+     <height>16777215</height>
+    </size>
+   </property>
+   <layout class="QGridLayout" name="gridLayout">
+    <item row="1" column="0">
+     <widget class="QLabel" name="label2">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>210</width>
+        <height>20</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>190</width>
+        <height>20</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::Box</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Plain</enum>
+      </property>
+      <property name="text">
+       <string>Last update: 27-08-2014 12:50</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="1">
+     <widget class="QLabel" name="label">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>150</width>
+        <height>20</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>135</width>
+        <height>20</height>
+       </size>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::Box</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Plain</enum>
+      </property>
+      <property name="text">
+       <string>Next update in 120min</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="2">
+     <widget class="QPushButton" name="button_update">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>120</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>100</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="text">
+       <string>Update list</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="3">
+     <widget class="QPushButton" name="button_clear">
+      <property name="minimumSize">
+       <size>
+        <width>120</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>100</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="text">
+       <string>Clear list</string>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="4">
+     <widget class="QPushButton" name="button_quit">
+      <property name="minimumSize">
+       <size>
+        <width>120</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>100</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="text">
+       <string>Quit</string>
+      </property>
+      <property name="shortcut">
+       <string>Ctrl+Q</string>
+      </property>
+      <property name="checkable">
+       <bool>false</bool>
+      </property>
+      <property name="autoRepeat">
+       <bool>false</bool>
+      </property>
+      <property name="default">
+       <bool>false</bool>
+      </property>
+      <property name="flat">
+       <bool>false</bool>
+      </property>
+     </widget>
+    </item>
+    <item row="0" column="0" colspan="5">
+     <widget class="QTableWidget" name="table">
+      <property name="enabled">
+       <bool>true</bool>
+      </property>
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>20</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>0</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="sizeIncrement">
+       <size>
+        <width>0</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="contextMenuPolicy">
+       <enum>Qt::CustomContextMenu</enum>
+      </property>
+      <property name="frameShape">
+       <enum>QFrame::StyledPanel</enum>
+      </property>
+      <property name="frameShadow">
+       <enum>QFrame::Plain</enum>
+      </property>
+      <property name="lineWidth">
+       <number>1</number>
+      </property>
+      <property name="verticalScrollBarPolicy">
+       <enum>Qt::ScrollBarAsNeeded</enum>
+      </property>
+      <property name="horizontalScrollBarPolicy">
+       <enum>Qt::ScrollBarAlwaysOff</enum>
+      </property>
+      <property name="autoScroll">
+       <bool>false</bool>
+      </property>
+      <property name="editTriggers">
+       <set>QAbstractItemView::NoEditTriggers</set>
+      </property>
+      <property name="tabKeyNavigation">
+       <bool>false</bool>
+      </property>
+      <property name="showDropIndicator" stdset="0">
+       <bool>false</bool>
+      </property>
+      <property name="dragDropOverwriteMode">
+       <bool>false</bool>
+      </property>
+      <property name="alternatingRowColors">
+       <bool>false</bool>
+      </property>
+      <property name="selectionMode">
+       <enum>QAbstractItemView::SingleSelection</enum>
+      </property>
+      <property name="selectionBehavior">
+       <enum>QAbstractItemView::SelectRows</enum>
+      </property>
+      <property name="textElideMode">
+       <enum>Qt::ElideLeft</enum>
+      </property>
+      <property name="showGrid">
+       <bool>true</bool>
+      </property>
+      <property name="gridStyle">
+       <enum>Qt::SolidLine</enum>
+      </property>
+      <property name="sortingEnabled">
+       <bool>true</bool>
+      </property>
+      <property name="wordWrap">
+       <bool>false</bool>
+      </property>
+      <property name="cornerButtonEnabled">
+       <bool>false</bool>
+      </property>
+      <property name="rowCount">
+       <number>3</number>
+      </property>
+      <attribute name="horizontalHeaderVisible">
+       <bool>true</bool>
+      </attribute>
+      <attribute name="horizontalHeaderCascadingSectionResizes">
+       <bool>false</bool>
+      </attribute>
+      <attribute name="horizontalHeaderDefaultSectionSize">
+       <number>128</number>
+      </attribute>
+      <attribute name="horizontalHeaderHighlightSections">
+       <bool>false</bool>
+      </attribute>
+      <attribute name="verticalHeaderVisible">
+       <bool>false</bool>
+      </attribute>
+      <attribute name="verticalHeaderDefaultSectionSize">
+       <number>20</number>
+      </attribute>
+      <attribute name="verticalHeaderMinimumSectionSize">
+       <number>18</number>
+      </attribute>
+      <row/>
+      <row/>
+      <row/>
+      <column>
+       <property name="text">
+        <string>Job</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignJustify|AlignVCenter</set>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Host</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignJustify|AlignVCenter</set>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Nodes</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Status</string>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Progress</string>
+       </property>
+       <property name="font">
+        <font>
+         <weight>50</weight>
+         <bold>false</bold>
+        </font>
+       </property>
+       <property name="textAlignment">
+        <set>AlignJustify|AlignVCenter</set>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Remaining time</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Jobname</string>
+       </property>
+      </column>
+      <item row="0" column="0">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="0" column="1">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="0" column="2">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+      <item row="0" column="3">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="0" column="4">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="0" column="5">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+      <item row="1" column="0">
+       <property name="text">
+        <string>11</string>
+       </property>
+      </item>
+      <item row="1" column="1">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="1" column="2">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+      <item row="1" column="3">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="1" column="4">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="1" column="5">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+      <item row="2" column="0">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="2" column="1">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="2" column="2">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+      <item row="2" column="3">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="2" column="4">
+       <property name="text">
+        <string>1</string>
+       </property>
+      </item>
+      <item row="2" column="5">
+       <property name="text">
+        <string>1</string>
+       </property>
+       <property name="textAlignment">
+        <set>AlignRight|AlignVCenter</set>
+       </property>
+      </item>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>758</width>
+     <height>21</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="actionRefresh"/>
+    <addaction name="actionOptions"/>
+    <addaction name="actionQuit"/>
+   </widget>
+   <widget class="QMenu" name="menuHelp">
+    <property name="title">
+     <string>Help</string>
+    </property>
+    <addaction name="actionManual"/>
+    <addaction name="actionAbout"/>
+   </widget>
+   <addaction name="menuFile"/>
+   <addaction name="menuHelp"/>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+  <action name="actionRefresh">
+   <property name="text">
+    <string>Refresh</string>
+   </property>
+   <property name="statusTip">
+    <string>Update job list</string>
+   </property>
+   <property name="shortcut">
+    <string>F5</string>
+   </property>
+  </action>
+  <action name="actionQuit">
+   <property name="icon">
+    <iconset>
+     <normaloff>exit.png</normaloff>exit.png</iconset>
+   </property>
+   <property name="text">
+    <string>Quit</string>
+   </property>
+   <property name="iconText">
+    <string>Quit</string>
+   </property>
+   <property name="toolTip">
+    <string>Quit PALM Watchdog</string>
+   </property>
+   <property name="statusTip">
+    <string>Quit PALM Watchdog</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+Q</string>
+   </property>
+  </action>
+  <action name="actionOptions">
+   <property name="text">
+    <string>Options</string>
+   </property>
+  </action>
+  <action name="actionManual">
+   <property name="text">
+    <string>Manual</string>
+   </property>
+  </action>
+  <action name="actionAbout">
+   <property name="text">
+    <string>About</string>
+   </property>
+  </action>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>actionQuit</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>338</x>
+     <y>135</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>table</sender>
+   <signal>customContextMenuRequested(QPoint)</signal>
+   <receiver>MainWindow</receiver>
+   <slot>OpenContextMenu()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>360</x>
+     <y>45</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>383</x>
+     <y>114</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>actionRefresh</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>Refresh()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>374</x>
+     <y>72</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>button_update</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>Refresh()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>405</x>
+     <y>135</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>562</x>
+     <y>134</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>button_clear</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>ClearList()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>554</x>
+     <y>142</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>634</x>
+     <y>136</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>button_quit</sender>
+   <signal>clicked()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>710</x>
+     <y>140</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>656</x>
+     <y>150</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <slots>
+  <slot>OpenContextMenu()</slot>
+  <slot>Refresh()</slot>
+  <slot>ClearList()</slot>
+ </slots>
+</ui>
Index: palm/trunk/SCRIPTS/palm_wdd
===================================================================
--- palm/trunk/SCRIPTS/palm_wdd	(revision 1611)
+++ palm/trunk/SCRIPTS/palm_wdd	(revision 1611)
@@ -0,0 +1,215 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#--------------------------------------------------------------------------------#
+# This file is part of PALM.
+#
+# PALM is free software: you can redistribute it and/or modify it under the terms
+# of the GNU General Public License as published by the Free Software Foundation,
+# either version 3 of the License, or (at your option) any later version.
+#
+# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# PALM. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 1997-2015  Leibniz Universitaet Hannover
+#--------------------------------------------------------------------------------#
+#
+# Current revisions:
+# -----------------
+# Initial revision
+# 
+# Former revisions:
+# -----------------
+# $Id$
+#
+#
+# Description:
+# ------------
+# PALM watchdog client for monitoring batch jobs on a variety of hosts specified
+# by the user. The watchdog server requires python 2.7 or higher installed on
+# host to be monitored.
+# 
+# Instructions:
+# -------------
+# 1) Modify the header section of palm_wd
+# 2) Move .wd.olddata and .wd.newdata to your palm directory 
+#    (e.g. /home/user/current_version/.wd.newdata etc.)
+# 3) Modify a copy of palm_wdd for each host to be monitored and move it to the
+#    respective hosts
+# 4) Start the client either from mrungui or from shell by "nohup palm_wd&"
+#
+# To do:
+# ------
+# 1) Add "Options", "Help" and "Manual"
+# 2) Move user settings to a configuration file
+#------------------------------------------------------------------------------!
+
+import os
+import sys
+from subprocess import check_output
+
+# START OF HEADER
+
+# configuration for host
+cmd_readqueue      = "showq | egrep "
+cmd_tmpdir         = "/gfs1/tmp/"
+cmd_canceljob      = "canceljob"
+cmd_checkjob       = "checkjob"
+cmd_realname_grep  = "AName"
+cmd_starttime      = "showstart"
+cmd_starttime_grep = "start in"
+
+# END OF HEADER
+
+
+action   = str(sys.argv[1])
+data     = str(sys.argv[2])
+if ( len(sys.argv) > 3 ):
+   data2 =  str(sys.argv[3])
+
+
+cmd_readqueue = cmd_readqueue + data
+cmd_tmpdir    = cmd_tmpdir + data
+
+
+
+# reading queuing system
+def ReadQueue(username):
+  
+#  collect queuing information
+   try:
+      out = check_output(cmd_readqueue, shell=True)
+      job_list = out.splitlines()
+      out = None
+#  do nothing for empty results list
+   except:
+      job_list = []
+  
+ 
+   job_data_tmp = []
+   for j in range(0,len(job_list)):
+
+      # Write temporary data array containing the job information.
+      job_data_tmp.append(j)
+      job_data_tmp[j] = job_list[j].split(" ")
+      job_data_tmp[j] = filter(None, job_data_tmp[j])
+
+      cmd_realname = cmd_checkjob + " " + job_data_tmp[j][0] + "|grep " + cmd_realname_grep 
+
+      # retrieve real job name for all jobs
+      try:  
+         out = check_output(cmd_realname, shell=True)
+         job_realname = out.split(" ")[1].rstrip()
+      except:
+         job_realname = "error"
+
+
+      # for running jobs, determine progress                  
+      if ( job_data_tmp[j][2] == "Running" ):
+  
+         # collect progress information
+         cmd_progress = "cat " + cmd_tmpdir + "/" + username + "." + job_data_tmp[j][0].partition(".")[2] + "/PROGRESS"
+         try: 
+
+            devnull = open(os.devnull, 'w')
+            out = check_output(cmd_progress, shell=True, stderr=devnull)
+            progress_lines = out.splitlines()
+            job_progress = progress_lines[1].split(" ")[1]
+            out = None
+         except:
+            job_progress = "0" 
+
+      else:
+         job_progress = "0" 
+
+      # return the job data
+      job_starttime = GetStartTime(job_data_tmp[j][0])
+      print job_realname + " " + job_data_tmp[j][0] + " " + job_data_tmp[j][3] + " " + job_data_tmp[j][2] + " " + job_progress + " "  + job_data_tmp[j][4] + " " + job_starttime
+
+
+# check details of specific job
+def CheckJob(jobid):
+
+   cmd_checkjob_tmp = cmd_checkjob + " " + jobid
+
+   try:  
+      out = check_output(cmd_checkjob_tmp, shell=True)
+      job_details = out
+   except:
+      job_details = "No details available." 
+
+   return job_details
+
+
+# cancel a specific job
+def CancelJob(jobid):
+
+   cmd_canceljob_tmp = cmd_canceljob + " " + jobid
+
+   try:  
+      out = check_output(cmd_canceljob_tmp, shell=True)
+      job_canceled = out
+   except:
+      job_canceled = "Action failed." 
+
+   return job_canceled
+
+
+# retrieve estimated start time of job
+def GetStartTime(jobid):
+
+   cmd_starttime_tmp = cmd_starttime + " " + jobid + "|grep \"" + cmd_starttime_grep + "\"" 
+
+   try:  
+      out = check_output(cmd_starttime_tmp, shell=True)
+      job_starttime = out.split()[5]
+   except:
+      job_starttime = "Action failed." 
+
+   return job_starttime
+
+
+def DoStopNow(username,jobid):
+
+   # collect progress information
+   cmd_dostop = "touch " + cmd_tmpdir + "/" + username + "." + jobid.partition(".")[2] + "/DO_STOP_NOW"
+   try: 
+      devnull = open(os.devnull, 'w')
+      out = check_output(cmd_dostop, shell=True, stderr=devnull)
+      out = None
+   except:
+      return_message = "Action failed."  
+      return return_message
+
+def DoRestartNow(username,jobid):
+
+   # collect progress information
+   cmd_dorestart = "touch " + cmd_tmpdir + "/" + username + "." + jobid.partition(".")[2] + "/DO_RESTART_NOW"
+   try: 
+      devnull = open(os.devnull, 'w')
+      out = check_output(cmd_dorestart, shell=True, stderr=devnull)
+      out = None
+   except:
+      return_message = "Action failed."  
+      return return_message
+
+
+# START OF MAIN
+if ( action == "queue" ):
+   ReadQueue(data)
+elif ( action == "check"):
+   print CheckJob(data)
+elif ( action == "cancel"):
+   print CancelJob(data)
+elif ( action == "start"):
+   print GetStartTime(data)
+elif ( action == "stop"):
+   print DoStopNow(data,data2)
+elif ( action == "restart"):
+   print DoRestartNow(data,data2)
+else:
+   print "Error. Action " + action + " unknown."
+
Index: palm/trunk/UTIL/mrungui/mainwindow.cpp
===================================================================
--- palm/trunk/UTIL/mrungui/mainwindow.cpp	(revision 1610)
+++ palm/trunk/UTIL/mrungui/mainwindow.cpp	(revision 1611)
@@ -18,4 +18,5 @@
 // Current revisions:
 // -----------------
+// Added routine start_watchdog.
 //
 // Former revisions:
@@ -1263,4 +1264,13 @@
     out << tmptime + " " + mrunline;
     file.close();
+
+    return 0;
+}
+
+//****************************************************************************//
+//  Start watchdog (palm_wd)
+int MainWindow::start_watchdog()
+{
+    system("nohup palm_wd >> /dev/null 2>&1 &");
 
     return 0;
Index: palm/trunk/UTIL/mrungui/mainwindow.h
===================================================================
--- palm/trunk/UTIL/mrungui/mainwindow.h	(revision 1610)
+++ palm/trunk/UTIL/mrungui/mainwindow.h	(revision 1611)
@@ -2,4 +2,5 @@
 // Current revisions:
 // -----------------
+// Added slot start_watchdog 
 //
 // Former revisions:
@@ -58,4 +59,5 @@
     int save_to_file();
     int save_default();
+    int start_watchdog();
     int open_from_file();
     int open_last();
Index: palm/trunk/UTIL/mrungui/mainwindow.ui
===================================================================
--- palm/trunk/UTIL/mrungui/mainwindow.ui	(revision 1610)
+++ palm/trunk/UTIL/mrungui/mainwindow.ui	(revision 1611)
@@ -1359,8 +1359,8 @@
     <property name="geometry">
      <rect>
-      <x>2190</x>
-      <y>99</y>
+      <x>2175</x>
+      <y>98</y>
       <width>133</width>
-      <height>182</height>
+      <height>206</height>
      </rect>
     </property>
@@ -1376,4 +1376,5 @@
     <addaction name="action_save"/>
     <addaction name="action_default"/>
+    <addaction name="action_start_wd"/>
     <addaction name="action_quit"/>
    </widget>
@@ -1437,4 +1438,9 @@
    </property>
   </action>
+  <action name="action_start_wd">
+   <property name="text">
+    <string>Start watchdog</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="1" margin="11"/>
@@ -1502,5 +1508,5 @@
     <hint type="sourcelabel">
      <x>160</x>
-     <y>657</y>
+     <y>655</y>
     </hint>
     <hint type="destinationlabel">
@@ -1518,5 +1524,5 @@
     <hint type="sourcelabel">
      <x>73</x>
-     <y>657</y>
+     <y>655</y>
     </hint>
     <hint type="destinationlabel">
@@ -1710,5 +1716,5 @@
     <hint type="sourcelabel">
      <x>429</x>
-     <y>281</y>
+     <y>279</y>
     </hint>
     <hint type="destinationlabel">
@@ -1726,5 +1732,5 @@
     <hint type="sourcelabel">
      <x>431</x>
-     <y>256</y>
+     <y>254</y>
     </hint>
     <hint type="destinationlabel">
@@ -1742,5 +1748,5 @@
     <hint type="sourcelabel">
      <x>415</x>
-     <y>314</y>
+     <y>312</y>
     </hint>
     <hint type="destinationlabel">
@@ -1774,5 +1780,5 @@
     <hint type="sourcelabel">
      <x>72</x>
-     <y>541</y>
+     <y>539</y>
     </hint>
     <hint type="destinationlabel">
@@ -1790,5 +1796,5 @@
     <hint type="sourcelabel">
      <x>76</x>
-     <y>566</y>
+     <y>564</y>
     </hint>
     <hint type="destinationlabel">
@@ -1806,5 +1812,5 @@
     <hint type="sourcelabel">
      <x>53</x>
-     <y>591</y>
+     <y>589</y>
     </hint>
     <hint type="destinationlabel">
@@ -1950,5 +1956,5 @@
     <hint type="sourcelabel">
      <x>119</x>
-     <y>403</y>
+     <y>401</y>
     </hint>
     <hint type="destinationlabel">
@@ -1966,5 +1972,5 @@
     <hint type="sourcelabel">
      <x>149</x>
-     <y>428</y>
+     <y>426</y>
     </hint>
     <hint type="destinationlabel">
@@ -1998,5 +2004,5 @@
     <hint type="sourcelabel">
      <x>179</x>
-     <y>478</y>
+     <y>476</y>
     </hint>
     <hint type="destinationlabel">
@@ -2030,5 +2036,5 @@
     <hint type="sourcelabel">
      <x>361</x>
-     <y>428</y>
+     <y>426</y>
     </hint>
     <hint type="destinationlabel">
@@ -2046,5 +2052,5 @@
     <hint type="sourcelabel">
      <x>328</x>
-     <y>453</y>
+     <y>451</y>
     </hint>
     <hint type="destinationlabel">
@@ -2062,5 +2068,5 @@
     <hint type="sourcelabel">
      <x>262</x>
-     <y>503</y>
+     <y>501</y>
     </hint>
     <hint type="destinationlabel">
@@ -2078,5 +2084,5 @@
     <hint type="sourcelabel">
      <x>324</x>
-     <y>503</y>
+     <y>501</y>
     </hint>
     <hint type="destinationlabel">
@@ -2110,5 +2116,5 @@
     <hint type="sourcelabel">
      <x>796</x>
-     <y>387</y>
+     <y>386</y>
     </hint>
     <hint type="destinationlabel">
@@ -2142,5 +2148,5 @@
     <hint type="sourcelabel">
      <x>850</x>
-     <y>438</y>
+     <y>436</y>
     </hint>
     <hint type="destinationlabel">
@@ -2174,5 +2180,5 @@
     <hint type="sourcelabel">
      <x>885</x>
-     <y>488</y>
+     <y>486</y>
     </hint>
     <hint type="destinationlabel">
@@ -2190,5 +2196,5 @@
     <hint type="sourcelabel">
      <x>900</x>
-     <y>513</y>
+     <y>511</y>
     </hint>
     <hint type="destinationlabel">
@@ -2206,5 +2212,5 @@
     <hint type="sourcelabel">
      <x>900</x>
-     <y>538</y>
+     <y>536</y>
     </hint>
     <hint type="destinationlabel">
@@ -2222,5 +2228,5 @@
     <hint type="sourcelabel">
      <x>900</x>
-     <y>563</y>
+     <y>561</y>
     </hint>
     <hint type="destinationlabel">
@@ -2270,5 +2276,5 @@
     <hint type="sourcelabel">
      <x>307</x>
-     <y>657</y>
+     <y>655</y>
     </hint>
     <hint type="destinationlabel">
@@ -2447,4 +2453,20 @@
      <x>730</x>
      <y>295</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>458</x>
+     <y>344</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>action_start_wd</sender>
+   <signal>triggered()</signal>
+   <receiver>MainWindow</receiver>
+   <slot>start_watchdog()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
     </hint>
     <hint type="destinationlabel">
@@ -2472,4 +2494,5 @@
   <slot>save_default()</slot>
   <slot>help()</slot>
+  <slot>start_watchdog()</slot>
  </slots>
 </ui>
