diff --git a/LCU/checkhardware/checkHardware.py b/LCU/checkhardware/checkHardware.py
index 0de384348857e23fb8b7d2a7eac6136525df9214..429848f942676192e935a090710000a07eee7b32 100755
--- a/LCU/checkhardware/checkHardware.py
+++ b/LCU/checkhardware/checkHardware.py
@@ -1,9 +1,50 @@
 #!/usr/bin/python
 
+info = '''    ----------------------------------------------------------------------------
+    Usage of arguments
+    -cf=fullfilename  : full path and filename for the configurationfile to use.
+    -l=2              : set level to 2 (default level is 0)
+                      level 0    : manual checks, use keys listed below 
+                      level 1..n : see checkhardware.conf file for checks done
+    
+    To start a long check set number of runs or start and stop time, if start time
+    is not given the first run is started immediately
+    -r=1              : repeats, number of runs to do
+    -start=[date_time]: start time of first run, format [YYYYMMDD_HH:MM:SS]
+    -stop=[date_time] : stop time of last run, format [YYYYMMDD_HH:MM:SS]
+    
+    Set logging level, can be: debug|info|warning|error
+    -ls=debug         : print all information on screen, default=info
+    -lf=info          : print debug|warning|error information to log file, default=debug
+    
+    Select checks to do, can be combined with all levels
+    -s(rcumode)       : signal check for rcumode
+    -sh(rcumode)      : short test for rcumode 1..4
+    -f(rcumode)       : flat test for rcumode 1..4
+    -d(rcumode)       : down test for rcumode 1..4
+    -o(rcumode)       : oscillation check for rcumode
+    -sp(rcumode)      : spurious check for rcumode
+    -n(rcumode)[=120] : noise check for rcumode, optional data time in seconds default = 120 sec.
+    -e(rcumode)[=120] : do all HBA element tests, optional data time in seconds default = 10 sec.
+    -sn(rcumode)      : HBA summator noise check.
+    -m(rcumode)       : HBA modem check.
+    
+    -rcu(mode)        : do all rcu(mode) tests
+    
+    -rv               : RSP version check, always done
+    -tv               : TBB version check, always done
+    -spu              : RSP spu voltage check
+    -tm               : TBB memmory check
+    
+    example   : ./checkHardware.py -s5 -n5=180
+    ----------------------------------------------------------------------------'''
+
+
 import os
 import sys
+import traceback
 
-check_version = '0214'
+check_version = '0615'
 
 mainPath = r'/opt/stationtest'
 libPath  = os.path.join(mainPath, 'lib')
@@ -26,123 +67,105 @@ os.umask(001)
 
 logger = None
 
-def printHelp():
-    print "----------------------------------------------------------------------------"
-    print "Usage of arguments"
-    print "-l=2              : set level to 2 (default level is 0)"
-    print "                  level 0    : manual checks, use keys listed below"
-    print "                  level 1..n : see checkhardware.conf file for checks done"
-    print
-    print "To start a long check set number of runs or start and stop time, if start time"
-    print "is not given the first run is started immediately"
-    print "-r=1              : repeats, number of runs to do"
-    print "-start=[date_time]: start time of first run, format [YYYYMMDD_HH:MM:SS]"
-    print "-stop=[date_time] : stop time of last run, format [YYYYMMDD_HH:MM:SS]"
-    print
-    print "Set logging level, can be: debug|info|warning|error"
-    print "-ls=debug         : print all information on screen, default=info"
-    print "-lf=info          : print debug|warning|error information to log file, default=debug"
-    print
-    print "Select checks to do, can be combined with all levels"
-    print "-s(rcumode)       : signal check for rcumode (1|3|5)"
-    print "-o(rcumode)       : oscillation check for rcumode (1|3|5)"
-    print "-sp(rcumode)      : spurious check for rcumode (1|3|5)"
-    print "-n(rcumode)[=120] : noise check for rcumode (1|3|5), optional data time in seconds"
-    print "                    default data time = 300 sec for hba and 180 sec for lba"
-    print "-ehba[=120]       : do all HBA element tests, optional data time in seconds"
-    print "                    default data time = 10 sec"
-    print "-es7              : do element signal check in rcumode 7, and skip rcumode 5 test"
-    print "-m                : HBA modem check, automatic selected if other hba check are selected"
-    print "-sn               : HBA summator noise check"
-    print
-    print "-lbl              : do all LBL tests"
-    print "-lbh              : do all LBH tests"
-    print "-hba              : do all HBA tests"
-    print "-s7               : do S7 test instead of S5, must be places before -hba"
-    print
-    print "-rv               : RSP version check"
-    print "-tv               : TBB version check"
-    print "-tm               : TBB memmory check"
-    print
-    print "example   : ./checkHardware.py -s5 -n5=180"
-
-
-    print "----------------------------------------------------------------------------"
-
-rcu_m1_keys  = ('LBL','O1','SP1','N1','S1')
-rcu_m3_keys  = ('LBH','O3','SP3','N3','S3')
-rcu_m5_keys  = ('HBA','M','O5','SN','SP5','N5','S5','S7','EHBA','ES7')
-rsp_keys     = ('RV',) + rcu_m1_keys + rcu_m3_keys + rcu_m5_keys
+rcu_keys    = ('RCU1','RCU2','RCU3','RCU4','RCU5','RCU6','RCU7')
+rcu_m1_keys = ('O1','SP1','N1','S1','SH1','D1','F1')
+rcu_m2_keys = ('O2','SP2','N2','S2','SH2','D2','F2')
+rcu_m3_keys = ('O3','SP3','N3','S3','SH3','D3','F3')
+rcu_m4_keys = ('O4','SP4','N4','S4','SH4','D4','F4')
+rcu_m5_keys = ('M5','O5','SN5','SP5','N5','S5','E5')
+rcu_m6_keys = ('M6','O6','SN6','SP6','N6','S6','E6')
+rcu_m7_keys = ('M7','O7','SN7','SP7','N7','S7','E7')
+
+rcu_m12_keys  = rcu_m1_keys + rcu_m2_keys
+rcu_m34_keys  = rcu_m3_keys + rcu_m4_keys
+rcu_m567_keys = rcu_m5_keys + rcu_m6_keys + rcu_m7_keys
+
+rsp_keys     = ('RV','SPU') + rcu_keys + rcu_m12_keys + rcu_m34_keys + rcu_m567_keys
 tbb_keys     = ('TV','TM')
 control_keys = ('R','START','STOP')
 all_keys     = control_keys + rsp_keys + tbb_keys
 rsp_check    = False
-rcu_m5_check = False
 tbb_check    = False
 
 args = dict()
-# get command line arguments
-testInfo = dict()
-testInfo['START']  = "Start checks"
-testInfo['STOP']   = "Stop  checks"
-testInfo['R']      = "Number of test repeats set to"
-testInfo['O1']     = "LBA mode-1 Oscillation test"
-testInfo['SP1']    = "LBA mode-1 Spurious test"
-testInfo['N1']     = "LBA mode-1 Noise test"
-testInfo['S1']     = "LBA mode-1 RF test"
-testInfo['O3']     = "LBA mode-3 Oscillation test"
-testInfo['SP3']    = "LBA mode-3 Spurious test"
-testInfo['N3']     = "LBA mode-3 Noise test"
-testInfo['S3']     = "LBA mode-3 RF test"
-testInfo['O5']     = "HBA mode-5 Oscillation test"
-testInfo['SP5']    = "HBA mode-5 Spurious test"
-testInfo['N5']     = "HBA mode-5 Noise test"
-testInfo['S5']     = "HBA mode-5 RF test"
-testInfo['S7']     = "HBA mode-7 RF test"
-testInfo['EHBA']   = "HBA mode-5 Element tests"
-testInfo['ES7']    = "HBA mode-7 Element signal tests"
-testInfo['M']      = "HBA mode-5 Modem test"
-testInfo['SN']     = "HBA mode-5 Summator noise test"
-testInfo['RV']     = "RSP Version test"
-testInfo['TM']     = "TBB Memory test"
-testInfo['TV']     = "TBB Version test"
+# next checks are always done
+args['RV'] = '-'
+args['TV'] = '-'
+#args['SPU'] = '-'
 
+
+def printHelp():
+    print info
+
+# return readable info for test
+def getTestInfo(key=''):
+    if key[-1] in '1234567':
+        test_name = ''
+        test = key[:-1]
+        mode = key[-1]
+        
+        if mode in '1234':
+            ant_type = 'LBA'
+        else:
+            ant_type = 'HBA'
+            
+        if test in ('O',):
+            test_name += 'Oscillation'
+        if test in ('SP',):
+            test_name += 'Spurious'
+        if test in ('N',):
+            test_name += 'Noise'
+        if test in ('S',):
+            test_name += 'RF'
+        if test in ('SH',):
+            test_name += 'Short'
+        if test in ('D',):
+            test_name += 'Down'
+        if test in ('F',):
+            test_name += 'Flat'                
+        if test in ('S',):
+            test_name += 'RF'
+        if test in ('SN',):
+            test_name += 'Summator noise'
+        if test in ('E',):
+            test_name += 'Element'
+        if test in ('M',):
+            test_name += 'Modem'    
+        
+        return '%s mode-%c %s check' % (ant_type, mode, test_name)
+    
+    if key in 'RV':
+        return 'RSP Version check'
+    if key in 'SPU':
+        return 'RSP SPU check'    
+    if key in 'TV':
+        return 'TBB Version check'
+    if key in 'TM':
+        return 'TBB Memory check'
+    if key in 'START':
+        return 'START checks'
+    if key in 'STOP':
+        return 'STOP checks'    
+    if key in 'R':
+        return 'Number of test repeats set to'
+    return('')    
+        
 def addToArgs(key, value):
     if key == '':
         return
-    global args, rsp_check, rcu_m5_check, tbb_check
+    global args, rsp_check, tbb_check
     if key in rsp_keys or key in tbb_keys or key in ('H','L','LS','LF','R','START','STOP'):
         if value != '-':
             args[key] = value
-        else:   
-            if key == 'LBL':
-                args['O1'] = '-'
-                args['SP1'] = '-'
-                args['N1'] = '-'
-                args['S1'] = '-'
-            elif key == 'LBH':
-                args['O3'] = '-'
-                args['SP3'] = '-'
-                args['N3'] = '-'
-                args['S3'] = '-'
-            elif key == 'HBA':
-                args['O5'] = '-'
-                args['SN'] = '-'
-                args['SP5'] = '-'
-                args['N5'] = '-'
-                if not args.has_key('S7'):
-                    args['S5'] = '-'
-            else:    
-                args[key] = '-'
+        else:    
+            args[key] = '-'
         
-        if key in rcu_m5_keys:
-            rcu_m5_check = True
         if key in rsp_keys:
             rsp_check = True
         if key in tbb_keys:
             tbb_check = True
     else:
-        sys.exit("Unknown key %s" %(key))
+        sys.exit('Unknown key %s' %(key))
     return
     
            
@@ -183,7 +206,12 @@ def setLevelTests(conf):
 class cConfiguration:
     def __init__(self):
         self.conf = dict()
-        f = open("/opt/stationtest/checkHardware.conf", 'r')
+        if args.has_key('CF'):
+            filename = args.get('CF')
+        else:
+            filename = '/localhome/stationtest/config/checkHardware.conf'
+        
+        f = open('/localhome/stationtest/config/checkHardware.conf', 'r')
         data = f.readlines()
         f.close()
         for line in data:
@@ -196,7 +224,7 @@ class cConfiguration:
                 key = key.replace('_','-')
                 self.conf[key] = value
             except:
-                print "Not a valid configuration setting: %s" %(line)
+                print 'Not a valid configuration setting: %s' %(line)
 
     def getInt(self,key, default=0):
         return (int(self.conf.get(key, str(default))))
@@ -223,7 +251,7 @@ def init_logging():
         screen_log_level = args.get('LS', 'WARNING')
         file_log_level   = args.get('LF', 'DEBUG')
     except:
-        print "Not a legal log level, try again"
+        print 'Not a legal log level, try again'
         sys.exit(-1)
 
     station = getHostName()
@@ -270,7 +298,7 @@ def backupLogFiles():
 def waitForStart(start_datetime):
     start_time = time.mktime(start_datetime.timetuple())
     if start_time > time.time():
-        logger.info("delayed start, sleep till %s" %(time.asctime(start_datetime.timetuple())))
+        logger.info('delayed start, sleep till %s' %(time.asctime(start_datetime.timetuple())))
     
     while start_time > time.time():
         wait_time = start_time - time.time()
@@ -280,13 +308,8 @@ def waitForStart(start_datetime):
 
 
 def main():
-    #global args
-    #global all_keys
-    #global rsp_check, rcu_m5_check, tbb_check
-    #global logger
-
     getArguments()
-    print args
+    #print args
     if len(args) == 0 or args.has_key('H'):
         printHelp()
         sys.exit()
@@ -306,15 +329,15 @@ def main():
     StID = getHostName()
 
     logger.info('== START HARDWARE CHECK ==')
-    logger.info("== requested checks and settings ==")
-    logger.info("-"*40)
+    logger.info('== requested checks and settings ==')
+    logger.info('-'*40)
     for i in all_keys:
         if args.has_key(i):
             if args.get(i) == '-':
-                logger.info(" %s" %(testInfo.get(i)))
+                logger.info(' %s' %(getTestInfo(i)))
             else:
-                logger.info(" %s, time = %s" %(testInfo.get(i), args.get(i)))
-    logger.info("-"*40)
+                logger.info(' %s, time = %s' %(getTestInfo(i), args.get(i)))
+    logger.info('-'*40)
     
     removeAllDataFiles()
 
@@ -323,7 +346,7 @@ def main():
     if args.has_key('STOP'):
         stop = args.get('STOP')
         if len(stop) != 17:
-                sys.exit("wrong stoptime format must be YYYYMMDD_HH:MM:SS")
+                sys.exit('wrong stoptime format must be YYYYMMDD_HH:MM:SS')
         stop_datetime = datetime.datetime(int(stop[:4]),int(stop[4:6]),int(stop[6:8]), \
                                           int(stop[9:11]),int(stop[12:14]),int(stop[15:]))
         stop_time = time.mktime(stop_datetime.timetuple())
@@ -331,19 +354,19 @@ def main():
         if args.has_key('START'):
             start = args.get('START')
             if len(start) != 17:
-                sys.exit("wrong starttime format must be YYYYMMDD_HH:MM:SS")
+                sys.exit('wrong starttime format must be YYYYMMDD_HH:MM:SS')
             start_datetime = datetime.datetime(int(start[:4]),int(start[4:6]),int(start[6:8]), \
                                                int(start[9:11]),int(start[12:14]),int(start[15:]))
             if (time.mktime(start_datetime.timetuple()) < time.time()):
                 #print time.mktime(start_datetime.timetuple()), time.time()
-                logger.error("Stop program, StartTime in past")
+                logger.error('Stop program, StartTime in past')
                 sys.exit(2)
             if(time.mktime(start_datetime.timetuple()) > stop_time):
-                logger.error("Stop program, stop before start")
+                logger.error('Stop program, stop before start')
                 sys.exit(2)    
             waitForStart(start_datetime)
         
-        logger.info("run checks till %s" %(time.asctime(stop_datetime.timetuple())))
+        logger.info('run checks till %s' %(time.asctime(stop_datetime.timetuple())))
     
     start_time = time.gmtime()
     # Read in RemoteStation.conf
@@ -358,11 +381,12 @@ def main():
         
                     
     # set manualy marked bad antennas
-    log_dir = conf.getStr('log-dir-global')
+    log_dir = os.path.join(conf.getStr('log-dir-global'), 'stationtest')
     host = getHostName()
     if os.path.exists(log_dir):
-        logger.info("add bad_antenna_list data to db")
-        f = open(os.path.join(log_dir, "bad_antenna_list.txt"), 'r')
+        full_filename = os.path.join(log_dir, 'bad_antenna_list.txt')
+        logger.info('add bad_antenna_list data from file "%s" to db' %(full_filename))
+        f = open(full_filename, 'r')
         data = f.readlines()
         for line in data:
             if line[0] == '#':
@@ -374,14 +398,14 @@ def main():
                         ant_type = ant[:3].strip().upper()
                         if ant_type == 'LBA':
                             ant_nr = int(ant[3:].strip())
-                            #print "ant type=%s nr=%d" %(ant_type, ant_nr)
+                            #print 'ant type=%s nr=%d' %(ant_type, ant_nr)
                             if ant_nr < nLBH:
                                 db.lbh.ant[ant_nr].on_bad_list = 1
                             else:
                                 db.lbl.ant[ant_nr-nLBH].on_bad_list = 1
                         elif ant_type == 'HBA':
                             ant_nr = int(ant[3:].strip())
-                            #print "ant type=%s nr=%d" %(ant_type, ant_nr)
+                            #print 'ant type=%s nr=%d' %(ant_type, ant_nr)
                             db.hba.tile[ant_nr].on_bad_list = 1
                 break
     
@@ -394,24 +418,25 @@ def main():
     start_level, board_errors = swlevel()
     sw_level, board_errors = swlevel(2)
     if start_level == 1:
-        logger.info("Wait 30 seconds while startup RSPDriver")
+        logger.info('Wait 30 seconds while startup RSPDriver')
         time.sleep(30.0)
     if sw_level == 2:
         tbb = cTBB(db)
         rsp = cRSP(db)
+        spu = cSPU(db)
 
         # do RSP tests if requested
         if rsp_check == True:
             # check if RSPDriver is running
             if checkActiveRSPDriver() == False:
-                logger.warn("RSPDriver not running")
+                logger.warn('RSPDriver not running')
             else:
                 # wait for RSP boards ready, and reset 48V if needed, max 2x if no board errors after 48V reset
                 rsp_ready = False
                 restarts = 2
                 while (not rsp_ready) and (restarts > 0):
                     if waitRSPready() == False:
-                        logger.warn("Not all RSP boards ready, reset 48V to recover")
+                        logger.warn('Not all RSP boards ready, reset 48V to recover')
                         swlevel(1)
                         reset48V()
                         restarts -= 1
@@ -430,7 +455,9 @@ def main():
                 if rsp_ready:
                     if args.has_key('RV'):
                         rsp.checkVersions(conf.getStr('bp-version'), conf.getStr('ap-version'))
-    
+                    
+                    
+                        
                     resetRSPsettings()
     
                     lbl = cLBA(db, db.lbl)
@@ -447,129 +474,143 @@ def main():
                         try:
                             runstart = time.time()
                             if stop_time > -1:
-                                logger.info("\n=== Start testrun %d ===\n" %(repeat_cnt))
+                                logger.info('\n=== Start testrun %d ===\n' %(repeat_cnt))
                             else:
-                                logger.info("\n=== Start testrun %d of %d ===\n" %(repeat_cnt, repeats))
+                                logger.info('\n=== Start testrun %d of %d ===\n' %(repeat_cnt, repeats))
                             
-                            # do all rcumode 1 tests if available
+                            if args.has_key('SPU'):
+                                spu.checkStatus()
+
+                            # check if mode 1,2 is available on this station
                             if StID in CoreStations or StID in RemoteStations:
-                                if args.has_key('O1'):
-                                    lbl.checkOscillation(mode=1)
+                                for mode in (1, 2):
+                                    lbl.reset()
+                                    # do all rcumode 1,2 tests        
+                                    if 'RCU%d' % mode in args or 'SH%d' % mode in args:
+                                       lbl.checkShort(mode=mode)
+                                    
+                                    if 'RCU%d' % mode in args or 'F%d' % mode in args:
+                                       lbl.checkFlat(mode=mode)
+                                    
+                                    if 'RCU%d' % mode in args or 'D%d' % mode in args:
+                                       lbl.checkDown(mode=mode, subband=conf.getInt('lbl-test-sb',301))
+                                                          
+                                    
+                                    
+                                    if 'RCU%d' % mode in args or 'O%d' % mode in args:
+                                        lbl.checkOscillation(mode=mode)
+                
+                                    if 'RCU%d' % mode in args or 'SP%d' % mode in args:
+                                        lbl.checkSpurious(mode=mode)
+                
+                                    if 'RCU%d' % mode in args or 'N%d' % mode in args:
+                                        if 'RCU%d' % mode in args or args.get('N%d' %(mode)) == '-':
+                                            recordtime = 120
+                                        else:
+                                            recordtime = int(args.get('N%d' %(mode)))
+                                        lbl.checkNoise(mode=mode,
+                                                       record_time=recordtime,
+                                                       low_deviation=conf.getFloat('lba-noise-min-deviation', -3.0),
+                                                       high_deviation=conf.getFloat('lba-noise-max-deviation', 2.5),
+                                                       max_diff=conf.getFloat('lba-noise-max-difference', 2.0))
+                                    
+                                    if 'RCU%d' % mode in args or 'S%d' % mode in args:
+                                       lbl.checkSignal(mode=mode,
+                                                       subband=conf.getInt('lbl-test-sb',301),
+                                                       min_signal=conf.getFloat('lba-rf-min-signal', 75.0),
+                                                       low_deviation=conf.getFloat('lba-rf-min-deviation', -2.0),
+                                                       high_deviation=conf.getFloat('lba-rf-max-deviation', 2.0))
+                            
+                            for mode in (3, 4):
+                                lbh.reset()
+                                # do all rcumode 3,4 tests
+                                if 'RCU%d' % mode in args or 'SH%d' % mode in args:
+                                   lbh.checkShort(mode=mode)
+                                
+                                if 'RCU%d' % mode in args or 'F%d' % mode in args:
+                                   lbh.checkFlat(mode=mode)
+                                
+                                if 'RCU%d' % mode in args or 'D%d' % mode in args:
+                                   lbh.checkDown(mode=mode, subband=conf.getInt('lbh-test-sb',301))
+
+                                if 'RCU%d' % mode in args or 'O%d' % mode in args:
+                                    lbh.checkOscillation(mode=mode)
             
-                                if args.has_key('SP1'):
-                                    lbl.checkSpurious(mode=1)
+                                if 'RCU%d' % mode in args or 'SP%d' % mode in args:
+                                    lbh.checkSpurious(mode=mode)
             
-                                if args.has_key('N1'):
-                                    if args.get('N1') == '-':
-                                        recordtime = 180
+                                if 'RCU%d' % mode in args or 'N%d' % mode in args:
+                                    if 'RCU%d' % mode in args or args.get('N%d' %(mode)) == '-':
+                                        recordtime = 120
                                     else:
-                                        recordtime = int(args.get('N1'))
-                                    lbl.checkNoise(mode=1,
+                                        recordtime = int(args.get('N%d' %(mode)))
+                                    lbh.checkNoise(mode=mode,
                                                    record_time=recordtime,
                                                    low_deviation=conf.getFloat('lba-noise-min-deviation', -3.0),
                                                    high_deviation=conf.getFloat('lba-noise-max-deviation', 2.5),
-                                                   max_diff=conf.getFloat('lba-noise-max-difference', 2.0))
-            
-                                if repeat_cnt == 1 and args.has_key('S1'):
-                                   lbl.checkSignal(mode=1,
-                                                   subband=conf.getInt('lbl-test-sb',301),
-                                                   min_signal=conf.getFloat('lba-rf-min-signal', 75.0),
-                                                   low_deviation=conf.getFloat('lba-rf-min-deviation', -2.0),
-                                                   high_deviation=conf.getFloat('lba-rf-max-deviation', 2.0))                        
-                            
-                            # do all rcumode 3 tests        
-                            if args.has_key('O3'):
-                                lbh.checkOscillation(mode=3)
-        
-                            if args.has_key('SP3'):
-                                lbh.checkSpurious(mode=3)
-        
-                            if args.has_key('N3'):
-                                if args.get('N3') == '-':
-                                    recordtime = 180
-                                else:
-                                    recordtime = int(args.get('N3'))
-                                lbh.checkNoise(mode=3,
-                                               record_time=recordtime,
-                                               low_deviation=conf.getFloat('lba-noise-min-deviation', -3.0),
-                                               high_deviation=conf.getFloat('lba-noise-max-deviation', 2.5),
-                                               max_diff=conf.getFloat('lba-noise-max-difference', 1.5))
-                          
-                            if repeat_cnt == 1 and args.has_key('S3'):
-                                lbh.checkSignal(mode=3, 
-                                                subband=conf.getInt('lbh-test-sb',301),
-                                                min_signal=conf.getFloat('lba-rf-min-signal', 75.0),
-                                                low_deviation=conf.getFloat('lba-rf-min-deviation', -2.0),
-                                                high_deviation=conf.getFloat('lba-rf-max-deviation', 2.0))
-        
-                            # do all rcumode 5 tests    
-                            # do always a modem check if an other hba check is requested
-                            if rcu_m5_check:
-                                hba.checkModem(mode=5)
-                                hba.turnOffBadTiles()
-        
-                            if args.has_key('O5'):
-                                hba.checkOscillation(mode=5)
-        
-                            if args.has_key('SN'):
-                                hba.checkSummatorNoise(mode=5)
-        
-                            if args.has_key('SP5'):
-                                hba.checkSpurious(mode=5)
-        
-                            if args.has_key('N5'):
-                                if args.get('N5') == '-':
-                                    recordtime = 300
-                                else:
-                                    recordtime = int(args.get('N5'))
-                                hba.checkNoise(mode=5,
-                                               record_time=recordtime,
-                                               low_deviation=conf.getFloat('hba-noise-min-deviation', -3.0),
-                                               high_deviation=conf.getFloat('hba-noise-max-deviation', 2.5),
-                                               max_diff=conf.getFloat('hba-noise-max-difference', 2.0))
-        
-        
-                            if repeat_cnt == 1 and args.has_key('S5'):
-                                hba.checkSignal(mode=5, subband=conf.getInt('hba-test-sb',155),
-                                                        min_signal=conf.getFloat('hba-rf-min-signal', 80.0),
-                                                        low_deviation=conf.getFloat('hba-rf-min-deviation', -24.0),
-                                                        high_deviation=conf.getFloat('hba-rf-max-deviation', 12.0))
-                            
-                            # RF test in mode 7 for UK station
-                            if repeat_cnt == 1 and args.has_key('S7'):
-                                hba.checkSignal(mode=7, subband=conf.getInt('hba-test-sb',155),
-                                                        min_signal=conf.getFloat('hba-rf-min-signal', 80.0),
-                                                        low_deviation=conf.getFloat('hba-rf-min-deviation', -24.0),
-                                                        high_deviation=conf.getFloat('hba-rf-max-deviation', 12.0))
+                                                   max_diff=conf.getFloat('lba-noise-max-difference', 1.5))
+                                
+                                if 'RCU%d' % mode in args or 'S%d' % mode in args:
+                                    lbh.checkSignal(mode=mode, 
+                                                    subband=conf.getInt('lbh-test-sb',301),
+                                                    min_signal=conf.getFloat('lba-rf-min-signal', 75.0),
+                                                    low_deviation=conf.getFloat('lba-rf-min-deviation', -2.0),
+                                                    high_deviation=conf.getFloat('lba-rf-max-deviation', 2.0))
         
-                            runtime = (time.time() - runstart)
-                            
-                            # All element test
-                            if args.has_key('EHBA'):
-                                if args.get('EHBA') == '-':
-                                    recordtime = 10
-                                else:
-                                    recordtime = int(args.get('EHBA'))
+                            for mode in (5, 6, 7):
+                                # do all rcumode 5, 6, 7 tests    
+                                hba.reset()
+                                
+                                if 'RCU%d' % mode in args or 'M%d' % mode in args:
+                                    hba.checkModem(mode=mode)
+                                    hba.turnOffBadTiles()
+            
+                                if 'RCU%d' % mode in args or 'O%d' % mode in args:
+                                    hba.checkOscillation(mode=mode)
+            
+                                if 'RCU%d' % mode in args or 'SN%d' % mode in args:
+                                    hba.checkSummatorNoise(mode=mode)
+            
+                                if 'RCU%d' % mode in args or 'SP%d' % mode in args:
+                                    hba.checkSpurious(mode=mode)
+            
+                                if 'RCU%d' % mode in args or 'N%d' % mode in args:
+                                    if 'RCU%d' % mode in args or args.get('N%d' %(mode)) == '-':
+                                        recordtime = 120
+                                    else:
+                                        recordtime = int(args.get('N%d' %(mode)))
+                                    hba.checkNoise(mode=mode,
+                                                   record_time=recordtime,
+                                                   low_deviation=conf.getFloat('hba-noise-min-deviation', -3.0),
+                                                   high_deviation=conf.getFloat('hba-noise-max-deviation', 2.5),
+                                                   max_diff=conf.getFloat('hba-noise-max-difference', 2.0))
+            
+            
+                                if 'RCU%d' % mode in args or 'S%d' % mode in args:
+                                    hba.checkSignal(mode=mode, subband=conf.getInt('hba-test-sb',155),
+                                                            min_signal=conf.getFloat('hba-rf-min-signal', 80.0),
+                                                            low_deviation=conf.getFloat('hba-rf-min-deviation', -24.0),
+                                                            high_deviation=conf.getFloat('hba-rf-max-deviation', 12.0))
+                                
+                                runtime = (time.time() - runstart)
+                                
+                                # All element test
+                                if 'E%d' % mode in args:
+                                    if args.get('E%d' %(mode)) == '-':
+                                        recordtime = 10
+                                    else:
+                                        recordtime = int(args.get('E%d' %(mode)))
+                                    
+                                    hba.checkElements(  mode=mode, 
+                                                        record_time=recordtime,
+                                                        subband=conf.getInt('hba-test-sb',155),
+                                                        noise_low_deviation=conf.getFloat('ehba-noise-min-deviation', -3.0),
+                                                        noise_high_deviation=conf.getFloat('ehba-noise-max-deviation', 2.5),
+                                                        noise_max_diff=conf.getFloat('ehba-noise-max-difference', 1.5),
+                                                        rf_min_signal=conf.getFloat('ehba-rf-min-signal', 70.0),
+                                                        rf_low_deviation=conf.getFloat('ehba-rf-min-deviation', -24.0),
+                                                        rf_high_deviation=conf.getFloat('ehba-rf-max-deviation', 12.0))
                                 
-                                hba.checkElements(  mode=5, 
-                                                    record_time=recordtime,
-                                                    subband=conf.getInt('hba-test-sb',155),
-                                                    noise_low_deviation=conf.getFloat('ehba-noise-min-deviation', -3.0),
-                                                    noise_high_deviation=conf.getFloat('ehba-noise-max-deviation', 2.5),
-                                                    noise_max_diff=conf.getFloat('ehba-noise-max-difference', 1.5),
-                                                    rf_min_signal=conf.getFloat('ehba-rf-min-signal', 70.0),
-                                                    rf_low_deviation=conf.getFloat('ehba-rf-min-deviation', -24.0),
-                                                    rf_high_deviation=conf.getFloat('ehba-rf-max-deviation', 12.0),
-                                                    skip_signal_test=args.has_key('ES7'))
-                            
-                            # Element test in mode 7 for UK station
-                            if args.has_key('ES7'):
-                                hba.checkElementsSignal(  mode=7, 
-                                                          subband=conf.getInt('hba-test-sb',155),
-                                                          rf_min_signal=conf.getFloat('ehba-rf-min-signal', 70.0),
-                                                          rf_low_deviation=conf.getFloat('ehba-rf-min-deviation', -24.0),
-                                                          rf_high_deviation=conf.getFloat('ehba-rf-max-deviation', 12.0))
-                            
                             # stop test if driver stopped
                             db.rsp_driver_down = not checkActiveRSPDriver()
                             if db.rsp_driver_down and (restarts > 0):
@@ -588,7 +629,11 @@ def main():
                             
 
                         except:
-                            logger.error("Program fault, RSP test (%s)" %(sys.exc_value))
+                            logging.error('Caught %s', str(sys.exc_info()[0]))
+                            logging.error(str(sys.exc_info()[1]))
+                            logging.error('TRACEBACK:\n%s', traceback.format_exc())
+                            logging.error('Aborting NOW')
+                            #logger.error('Program fault, RSP test (%s)' %(sys.exc_value))
                             #raise
                             break
                             
@@ -610,25 +655,27 @@ def main():
                         db.addTestDone('TM')
                         tbb.checkMemory()
                 except:
-                    logger.error("Program fault, TBB test (%s)" %(sys.exc_value))
+                    logger.error('Program fault, TBB test (%s)' %(sys.exc_value))
     db.check_stop_time = time.gmtime()
 
     # do db test and write result files to log directory
     log_dir = conf.getStr('log-dir-local')
     if os.path.exists(log_dir):
-        logger.info("write result data")
+        logger.info('write result data')
         db.test(log_dir)
     else:
-        logger.warn("not a valid log directory")
+        logger.warn('not a valid log directory')
     if not db.rsp_driver_down:
-        logger.info("Going back to swlevel %d" %(start_level))
+        logger.info('Going back to swlevel %d' %(start_level))
         swlevel(start_level)
-    logger.info("Test ready.")
+        
+    logger.info('Test ready.')
     writeMessage('!!!     The test is ready and the station can be used again!               !!!')
 
     # delete files from data directory
     removeAllDataFiles()
     sys.exit(0)
 
+
 if __name__ == '__main__':
     main()
diff --git a/LCU/checkhardware/doStationTest.sh b/LCU/checkhardware/doStationTest.sh
index 2b7ef23a4100d7353adef84c1d28623a3abe73eb..5e58022ea93d67496125a448c0b3091fea7d850a 100755
--- a/LCU/checkhardware/doStationTest.sh
+++ b/LCU/checkhardware/doStationTest.sh
@@ -116,4 +116,4 @@ if [ $SERVICE == "yes" ]
 then
     # Show last results on screen
     showTestResult.py -f=$locallogdir$filenameNow
-fi
\ No newline at end of file
+fi
diff --git a/LCU/checkhardware/lib/data_lib.py b/LCU/checkhardware/lib/data_lib.py
index c920cb0a30203d391a56c16e745856a195b60984..7ee4dc4f931eb4fddf2839a10de7a64cd2f0bb54 100644
--- a/LCU/checkhardware/lib/data_lib.py
+++ b/LCU/checkhardware/lib/data_lib.py
@@ -22,12 +22,12 @@ class cRCUdata:
     global logger
     def __init__(self, n_rcus, minvalue=1):
         self.n_rcus   = n_rcus
-        self.frames   = 0
-        self.clock    = 200.0
         self.minvalue = minvalue
         self.active_rcus = range(self.n_rcus)
-        self.mask = [] # mask selects subbands to block
+        self.subband_mask = []  # subband_mask selects subbands to block
+        self.active_rcus_changed = False
         self.reset()
+        self.reset_masks()
 
     def reset(self):
         self.ssData = np.ones((self.n_rcus, 1, 512), np.float64)
@@ -35,15 +35,27 @@ class cRCUdata:
         self.testSubband_X  = 0
         self.testSignal_Y   = -1.0
         self.testSubband_Y  = 0
+        self.frames   = 0
+        self.clock    = 200.0
+        self.rec_time = 0
+    
+    def reset_masks(self):
+        logger.debug('reset rcu mask')
+        self.rcu_mask = []  # rcu_mask selects rcus to block
 
+    def getRecTime(self):
+        return self.rec_time
+        
     def setActiveRcus(self, rcus):
         self.active_rcus = rcus
 
-    def setInActiveRcus(self, rcus):
-        self.active_rcus = range(self.n_rcus)
-        for i in rcus:
-            self.active_rcus.remove(i)
-
+    def setInActiveRcu(self, rcu):
+        logger.debug('delete rcu %d from active-rcu list' % rcu) 
+        if rcu in self.active_rcus:
+            self.active_rcus.remove(rcu)
+            self.add_to_rcu_mask(rcu)
+            self.active_rcus_changed = True
+    
     def getActiveRcus(self, pol='XY'):
         rcus = []
         for i in self.active_rcus:
@@ -55,15 +67,27 @@ class cRCUdata:
                 rcus.append(i)        
         return (rcus)
 
+    def isActiveRcusChanged(self):
+        return self.active_rcus_changed
+    
+    def resetActiveRcusChanged(self):
+        self.active_rcus_changed = False
+        
+    def add_to_rcu_mask(self, rcu):
+        if rcu not in self.rcu_mask:
+            self.rcu_mask.append(rcu)
+            logger.debug('bad-rcu-mask=%s' % str(sorted(self.rcu_mask)))
+            
     def setMask(self, blocked_subbands):
-        self.mask = blocked_subbands
+        self.subband_mask = blocked_subbands
 
     def getMask(self):
-        return (self.mask)
+        return (self.subband_mask)
     
     def record(self, rec_time=2, read=True, slow=False):
         removeAllDataFiles()
         self.reset()
+        self.rec_time = rec_time
         
         if slow == True:
             x_list = []
@@ -116,8 +140,11 @@ class cRCUdata:
     # subbands is list to mask
     def getMaskedData(self):
         data = self.ssData.copy()
-        for sb in self.mask:
+        for sb in self.subband_mask:
             data[:,:,sb] = np.ma.masked
+        for rcu in range(self.n_rcus):
+            if rcu in self.rcu_mask:
+                data[rcu,:,:] = np.ma.masked
         return (data)
 
     def getMeanSpectra(self, pol='XY'):
@@ -140,13 +167,13 @@ class cRCUdata:
         return(np.mean(self.ssData[rcu,:,:], axis=0))
         
     def getSubbands(self, rcu):
-        return (self.ssData[int(rcu),:,:].mean(axis=0))
+        return (self.getMaskedData()[int(rcu),:,:].mean(axis=0))
     
     def getSubbandX(self):
-        return (self.ssData[0::2,:,self.testSubband_Y].mean(axis=1))
+        return (self.getMaskedData()[0::2,:,self.testSubband_Y].mean(axis=1))
     
     def getSubbandY(self):
-        return (self.ssData[1::2,:,self.testSubband_Y].mean(axis=1))
+        return (self.getMaskedData()[1::2,:,self.testSubband_Y].mean(axis=1))
                        
     def getAll(self, pol='XY'):
         if pol in ('XY', 'xy'):
@@ -163,13 +190,13 @@ class cRCUdata:
         return (self.getMaskedData()[1::2,:,:])
            
     def getMedianRcu(self, rcu):
-        return(np.ma.median(self.ssData[int(rcu),:,:].mean(axis=0)))
+        return(np.ma.median(self.getMaskedData()[int(rcu),:,:].mean(axis=0)))
 
     def searchTestSignal(self, subband=-1, minsignal=75.0, maxsignal=100.0):
         # ss = median for all band over all rcu's
         # forget subband 0    
-        ssX = np.ma.median(self.ssData[::2,:,:].mean(axis=1),axis=0)
-        ssY = np.ma.median(self.ssData[1::2,:,:].mean(axis=1),axis=0)
+        ssX = np.ma.median(self.getMaskedData()[::2,:,:].mean(axis=1),axis=0)
+        ssY = np.ma.median(self.getMaskedData()[1::2,:,:].mean(axis=1),axis=0)
         
         if subband != -1:
             if ssX[subband] > minsignal and ssY[subband] > minsignal:
diff --git a/LCU/checkhardware/lib/lofar_lib.py b/LCU/checkhardware/lib/lofar_lib.py
index 7903294844d32e8d3373802c95e333667a8d9367..23c2061d11e2e2c565c1c9096333a90dd3f98e67 100644
--- a/LCU/checkhardware/lib/lofar_lib.py
+++ b/LCU/checkhardware/lib/lofar_lib.py
@@ -382,7 +382,7 @@ def getClock():
     return (clock)
     
 # function used for antenna testing        
-def swapXY(state):
+def swap_xy(state):
     if state in (0,1):
         if state == 1:
             logger.info("XY-output swapped")
@@ -414,10 +414,16 @@ def turnonRCUs(mode, rcus):
     rspctl('--rcuenable=1 --select=%s' %(select), wait=0.0)
     logger.info("setweights")
     rspctl('--aweights=8000,0', wait=0.0)
+    
     if mode == 5:
         rspctl('--specinv=1', wait=0.0)
     else:
         rspctl('--specinv=0', wait=0.0)
+    
+    if mode < 3:
+        swap_xy(state=1)
+    else:
+        swap_xy(state=0)
     logger.info("set rcu mode")
     rsp_rcu_mode(mode, rcus)
     #rcumode = mode
@@ -458,7 +464,7 @@ def rsp_hba_delay(delay, rcus, discharge=True):
     
     if delay == active_delay_str:
         logger.debug("requested delay already active, skip hbadelay command")
-        return (0)
+        return (1)
     
     if discharge == True:
         # count number of elements off in last command
diff --git a/LCU/checkhardware/lib/search_lib.py b/LCU/checkhardware/lib/search_lib.py
index f5f8de7e5adaaeca5d65b21cda1c7549190b3649..4c6fb1bdf6f0227116f0f564d4959f563b27aa95 100644
--- a/LCU/checkhardware/lib/search_lib.py
+++ b/LCU/checkhardware/lib/search_lib.py
@@ -10,7 +10,7 @@ from sys import exit
 import logging
 from time import sleep
 
-search_version = '0314'
+search_version = '0415'
 
 logger = logging.getLogger()
 
@@ -27,24 +27,24 @@ class cSearchPeak:
             self.max_peaks = []
             self.min_peaks = []
         return
-    
+
     def search(self, delta, max_width=100, skip_list=[]):
         self.max_peaks = []
         self.min_peaks = []
-        
+
         x = arange(0,len(self.data),1)
-        
+
         if not isscalar(delta):
             exit('argument delta must be a scalar')
-        
+
         if delta <= 0:
             exit('argument delta must be positive')
-        
+
         maxval, minval = self.data[1], self.data[1]
         maxpos, minpos  = 1, 1
-        
+
         lookformax = True
-        
+
         # add subband to skiplist
         skiplist = []
         if len(skip_list) > 0:
@@ -62,16 +62,16 @@ class cSearchPeak:
             if now > maxval:
                 maxval = now
                 maxpos = x[i]
-                
+
             if now < minval:
                 minval = now
                 minpos = x[i]
-                            
+
             if lookformax:
                 if now < (maxval - delta):
                     if maxpos not in skiplist:
                         peakwidth, min_sb, max_sb = self.getPeakWidth(maxpos, delta)
-                        #logger.debug("maxpos=%d, width=%d" %(maxpos, peakwidth))                        
+                        #logger.debug("maxpos=%d, width=%d" %(maxpos, peakwidth))
                         if (peakwidth < max_width):
                             self.max_peaks.append([maxpos, min_sb, max_sb])
                     minval = now
@@ -89,14 +89,14 @@ class cSearchPeak:
         if len(self.max_peaks) == 0:
             self.max_peaks.append([maxpos, maxpos, maxpos])
         return
-        
+
     # return data[nr]
     def getPeakValue(self, nr):
         try:
             return (self.data[nr])
         except:
             return (NaN)
-    
+
     def getPeakWidth(self, nr, delta):
         peakval = self.data[nr]
         minnr   = nr
@@ -111,27 +111,31 @@ class cSearchPeak:
                 maxnr = sb
             if self.data[sb] <= (peakval - delta):
                 break
-            
+
         return (maxnr-minnr, minnr, maxnr)
-        
-    # return value and subband nr    
+
+    # return value and subband nr
     def getMaxPeak(self):
         maxval = 0.0
-        nr_bin = -1
+        minsb  = 0.0
+        maxsb  = 0.0
+        binnr = -1
 
         for peak, min_sb, max_sb in self.max_peaks:
             if self.data[peak] > maxval:
                 maxval = self.data[peak]
-                nr_bin = peak
-        return (maxval, nr_bin)
-    
+                binnr  = peak
+                minsb  = min_sb
+                maxsb  = max_sb
+        return (maxval, binnr, minsb, maxsb)
+
     def getSumPeaks(self):
         peaksum = 0.0
         for peak, min_sb, max_sb in self.max_peaks:
             peaksum += self.data[peak]
         return (peaksum)
-            
-    # return value and sbband nr    
+
+    # return value and sbband nr
     def getMinPeak(self):
         minval = Inf
         nr_bin = -1
@@ -141,7 +145,7 @@ class cSearchPeak:
                 minval = self.data[peak]
                 nr_bin = peak
         return (minval, nr_bin)
-    
+
     def nMaxPeaks(self):
         return (len(self.max_peaks))
 
@@ -150,12 +154,31 @@ def PSD(data, sampletime):
     if data.ndim != 1:
         return ([],[])
     fft_data = fft.fft(data)
-    n  = fft_data.size    
+    n  = fft_data.size
     psd_freq = fft.fftfreq(n, sampletime)
     psd = power(abs(fft_data),2)/n
     return (psd[:n/2], psd_freq[:n/2])
 
+def searchFlat(data):
+    _data = data.getAll().mean(axis=1)
+    flat_info = list()
+    for rcu in data.active_rcus:
+        mean_signal = ma.mean(_data[rcu,:])
+        if mean_signal > 61.0 and mean_signal < 64.5:
+            logger.info("rcu=%d: cable probable off" %(rcu))
+            flat_info.append((rcu, mean_signal))
+    return(flat_info)
 
+def searchShort(data):
+    _data = data.getAll().mean(axis=1)
+    short_info = list()
+    for rcu in data.active_rcus:
+        mean_signal = ma.mean(_data[rcu,:])
+        if mean_signal > 55.0 and mean_signal < 61.0:
+            logger.info("rcu=%d: cable shorted" %(rcu))
+            short_info.append((rcu, mean_signal))
+    return(short_info)
+    
 def searchDown(data, subband):
     _data = data.getAll().mean(axis=1)
     down_info = list()
@@ -163,84 +186,90 @@ def searchDown(data, subband):
     start_sb = subband - 70
     stop_sb  = subband + 70
     delta    = 3
-    
+
     peaks = cSearchPeak(ma.median(_data[:,start_sb:stop_sb], axis=0))
     if not peaks.valid_data:
         return (down_info, shifted_info)
 
     peaks.search(delta=delta)
-    (median_max_val, median_max_sb) = peaks.getMaxPeak()
-    peakwidth, min_sb, max_sb = peaks.getPeakWidth(median_max_sb, delta)
+    (median_max_val, median_max_sb, min_sb, max_sb) = peaks.getMaxPeak()
+    median_bandwidth = max_sb - min_sb
+    #peakwidth, min_sb, max_sb = peaks.getPeakWidth(median_max_sb, delta)
     median_max_sb += start_sb
-    
-    median_value = ma.median(_data[:,start_sb:stop_sb]) 
+
+    median_value = ma.median(_data[:,start_sb:stop_sb])
     logger.debug("reference peak in band %d .. %d : subband=%d, bw(3dB)=%d, median-value-band=%3.1fdB" %\
-                (start_sb, stop_sb, (median_max_sb), peakwidth, median_value))
+                (start_sb, stop_sb, (median_max_sb), median_bandwidth, median_value))
 
     peaks_array    = zeros((_data.shape[0]),'i')
     peaks_bw_array = zeros((_data.shape[0]),'i')
-    
+
     for rcu in data.active_rcus:
         peaks = cSearchPeak(_data[rcu,start_sb:stop_sb])
         if peaks.valid_data:
             peaks.search(delta=delta)
-            (maxpeak_val, maxpeak_sb) = peaks.getMaxPeak()
-            
+            (maxpeak_val, maxpeak_sb, min_sb, max_sb) = peaks.getMaxPeak()
+
             if maxpeak_sb > 0:
-                peakwidth, min_sb, max_sb = peaks.getPeakWidth(max_sb, delta)
-                peaks_bw_array[rcu] = peakwidth
+                #peakwidth, min_sb, max_sb = peaks.getPeakWidth(maxpeak_sb, delta)
+                peaks_bw_array[rcu] = max_sb - min_sb
                 peaks_array[rcu] = start_sb + maxpeak_sb
             else:
                 peaks_bw_array[rcu] = stop_sb - start_sb
                 peaks_array[rcu] = subband
-                
+
     for ant in range(_data.shape[0]/2):
         x_rcu = ant * 2
         y_rcu = x_rcu + 1
-        
+
         mean_val_trigger = False
         down_trigger     = False
-        
+
         ant_x_mean_value = ma.mean(_data[x_rcu,start_sb:stop_sb])
         ant_y_mean_value = ma.mean(_data[y_rcu,start_sb:stop_sb])
-            
+
         logger.debug("rcu=%d/%d: X-top, sb%d, bw=%d, mean-value-band=%3.1f  Y-top, sb%d, bw=%d, mean-value-band=%3.1f" %\
                     (x_rcu, y_rcu, peaks_array[x_rcu], peaks_bw_array[x_rcu], ant_x_mean_value, peaks_array[y_rcu], peaks_bw_array[y_rcu], ant_y_mean_value))
-        
-        if (((ant_x_mean_value < (median_value - 3.0)) and (ant_x_mean_value > 66)) and
+
+        if (((ant_x_mean_value < (median_value - 3.0)) and (ant_x_mean_value > 66)) or
             ((ant_y_mean_value < (median_value - 3.0)) and (ant_y_mean_value > 66))):
             logger.debug("rcu_bin=%d/%d: mean signal in test band for X and Y lower than normal" %(x_rcu, y_rcu))
             mean_val_trigger = True
-            
-        if ((((abs(peaks_array[x_rcu] - median_max_sb) > 5) or (abs(peaks_bw_array[x_rcu] - peakwidth) > 5)) and (peaks_bw_array[x_rcu] > 3)) or 
-            (((abs(peaks_array[y_rcu] - median_max_sb) > 5) or (abs(peaks_bw_array[y_rcu] - peakwidth) > 5)) and (peaks_bw_array[y_rcu] > 3))):
+
+        if ((((abs(peaks_array[x_rcu] - median_max_sb) > 10) or (abs(median_bandwidth - peaks_bw_array[x_rcu]) > 10)) and (peaks_bw_array[x_rcu] > 3)) or
+            (((abs(peaks_array[y_rcu] - median_max_sb) > 10) or (abs(median_bandwidth - peaks_bw_array[y_rcu]) > 10)) and (peaks_bw_array[y_rcu] > 3))):
             logger.debug("rcu=%d/%d: antenna probable down" %(x_rcu, y_rcu))
             down_trigger = True
-        
-        if mean_val_trigger and down_trigger:    
+
+        if mean_val_trigger and down_trigger:
             down_info.append((ant, peaks_array[x_rcu], peaks_array[y_rcu], median_max_sb))
-        
+
         if not down_trigger:
-            if ((peaks_bw_array[x_rcu] > 3) and (abs(peaks_array[x_rcu] - median_max_sb) > 5)):
+            if ((peaks_bw_array[x_rcu] > 20) and (abs(peaks_array[x_rcu] - median_max_sb) > 10)):
                 logger.debug("rcu=%d: X-top shifted normal=%d, now=%d" %(x_rcu, median_max_sb, peaks_array[x_rcu]))
                 shifted_info.append((x_rcu, peaks_array[x_rcu], median_max_sb))
-            
-            if ((peaks_bw_array[y_rcu] > 3) and (abs(peaks_array[y_rcu] - median_max_sb) > 5)):
+
+            if ((peaks_bw_array[y_rcu] > 20) and (abs(peaks_array[y_rcu] - median_max_sb) > 10)):
                 logger.debug("rcu=%d: Y-top shifted normal=%d, now=%d" %(y_rcu, median_max_sb, peaks_array[y_rcu]))
                 shifted_info.append((y_rcu, peaks_array[y_rcu], median_max_sb))
-                
-    return (down_info, shifted_info)
     
+    # if more than half de antennes down or shifted, skip test
+    if len(down_info) > (_data.shape[0] / 2):
+        down_info = list()
+    if len(shifted_info) > (_data.shape[0] / 2):
+        shifted_info = list()    
+    return (down_info, shifted_info)
+
 
 # find oscillation
 def search_oscillation(data, pol, delta):
     info = list()
-    _data = data.getAll(pol=pol)    
-    mean_spectras  = ma.mean(_data, axis=1)
-    median_spectra = ma.median(mean_spectras, axis=0)
-    median_low     = ma.median(_data.min(axis=1))
+    _data = data.getAll(pol=pol)
+    mean_spectras = ma.mean(_data, axis=1)
+    mean_spectra  = ma.mean(mean_spectras, axis=0)
+    mean_low      = ma.mean(_data.min(axis=1))
     info.append((-1, 0, 0, 0))
-        
+
     for rcu in data.getActiveRcus(pol):
         rcu_bin = rcu
         if pol not in ('XY', 'xy'):
@@ -249,31 +278,31 @@ def search_oscillation(data, pol, delta):
         #max_peak_val  = 0
         max_n_peaks   = 0
         max_sum_peaks = 0
-        peaks = cSearchPeak(mean_spectras[rcu_bin,:]-median_spectra)
+        peaks = cSearchPeak(mean_spectras[rcu_bin,:] - mean_spectra)
         if peaks.valid_data:
             peaks.search(delta=delta, max_width=8)
             max_val       = mean_spectras[rcu_bin,:].max()
             max_n_peaks   = peaks.nMaxPeaks()
             max_sum_peaks = peaks.getSumPeaks()
-        
-        bin_low = _data[rcu_bin,:,:].min(axis=0).mean()    
+
+        bin_low = _data[rcu_bin,:,:].min(axis=0).mean()
         if max_n_peaks > 5:
             logger.debug("rcu_bin=%d: number-of-peaks=%d  max_value=%3.1f  peaks_sum=%5.3f low_value=%3.1f" %\
-                        (rcu_bin, max_n_peaks, max_val, max_sum_peaks, bin_low))        
-            if bin_low > (median_low + 2.0): #peaks.getSumPeaks() > (median_sum_peaks * 2.0):
+                        (rcu_bin, max_n_peaks, max_val, max_sum_peaks, bin_low))
+            if bin_low > (mean_low + 2.0): #peaks.getSumPeaks() > (median_sum_peaks * 2.0):
                 info.append((rcu_bin, max_sum_peaks, max_n_peaks, bin_low))
-        
+
         if max_val > 150.0: # only one high peek
             info.append((rcu_bin, max_sum_peaks, max_n_peaks, bin_low))
-            
+
     return (info) #(sorted(info,reverse=True))
 
 # find summator noise
 def search_summator_noise(data, pol, min_peak):
     sn_info = list() # summator noise
     cr_info = list() # cable reflection
-    _data = data.getAll(pol=pol)    
-    
+    _data = data.getAll(pol=pol)
+
     secs = _data.shape[1]
     for rcu in sorted(data.getActiveRcus(pol)):
         rcu_bin = rcu
@@ -287,7 +316,7 @@ def search_summator_noise(data, pol, min_peak):
             peaks_ref = cSearchPeak(_data[:,sec,:].mean(axis=0))
             if peaks_ref.valid_data:
                 peaks_ref.search(delta=min_peak)
-            
+
             peaks = cSearchPeak(_data[rcu_bin,sec,:])
             if peaks.valid_data:
                 peaks.search(delta=min_peak, skip_list=peaks_ref.max_peaks)
@@ -300,11 +329,11 @@ def search_summator_noise(data, pol, min_peak):
                 last_sb_val = peaks.getPeakValue(last_sb)
                 for sb, min_sb, max_sb in peaks.max_peaks[1:]:
                     sb_val = peaks.getPeakValue(sb)
-                    
+
                     sb_diff     = sb - last_sb
                     sb_val_diff = sb_val - last_sb_val
                     if sb_diff in (3,4):
-                        if abs(sb_val_diff) < 2.0: 
+                        if abs(sb_val_diff) < 2.0:
                             sn_peaks += 1
                         elif abs(sb_val_diff) > 5.0:
                             sn_peaks = 0
@@ -312,23 +341,23 @@ def search_summator_noise(data, pol, min_peak):
                         if abs(sb_val_diff) < 2.0:
                             cr_peaks += 1
                         elif abs(sb_val_diff) > 5.0:
-                            cr_peaks = 0    
+                            cr_peaks = 0
                     last_sb     = sb
                     last_sb_val = sb_val
-                    
+
                 sum_sn_peaks += sn_peaks
                 sum_cr_peaks += cr_peaks
                 max_peaks = max(max_peaks, n_peaks)
 
         if (sum_sn_peaks > (secs * 3.0)):
-            sn_peaks = sum_sn_peaks / secs             
+            sn_peaks = sum_sn_peaks / secs
             sn_info.append((rcu_bin, sn_peaks, max_peaks))
         if sum_cr_peaks > (secs * 3.0):
-            cr_peaks = sum_cr_peaks / secs             
-            cr_info.append((rcu_bin, cr_peaks, max_peaks))  
+            cr_peaks = sum_cr_peaks / secs
+            cr_info.append((rcu_bin, cr_peaks, max_peaks))
     return (sn_info, cr_info)
 
-    
+
 # find noise
 # noise looks like the noise floor is going up and down
 #
@@ -338,7 +367,7 @@ def search_noise(data, pol, low_deviation, high_deviation, max_diff):
     high_info   = list()
     low_info    = list()
     jitter_info = list()
-    
+
     ref_value    = ma.median(_data)
     # loop over rcus
     for rcu in sorted(data.getActiveRcus(pol)):
@@ -349,7 +378,7 @@ def search_noise(data, pol, low_deviation, high_deviation, max_diff):
         rcu_bin_value = ma.median(_data[rcu_bin,:,:])
         if rcu_bin_value < (ref_value + low_deviation):
             logger.debug("rcu_bin=%d: masked, low signal, ref=%5.3f val=%5.3f" %(rcu_bin, ref_value, rcu_bin_value))
-            low_info.append((rcu_bin, _data[rcu_bin,:,:].min(), -1 , (ref_value+low_deviation), (_data[rcu_bin,:,:].max() - _data[rcu_bin,:,:].min())))             
+            low_info.append((rcu_bin, _data[rcu_bin,:,:].min(), -1 , (ref_value+low_deviation), (_data[rcu_bin,:,:].max() - _data[rcu_bin,:,:].min())))
             _data[rcu_bin,:,:] = ma.masked
     spec_median  = ma.median(_data, axis=2)
     spec_max     = spec_median.max(axis=1)
@@ -382,39 +411,48 @@ def search_noise(data, pol, low_deviation, high_deviation, max_diff):
                 n_bad_high_secs = 1
                 n_bad_low_secs  = 1
             n_bad_jitter_secs  = 0
-            
+
             rcu_bin_max_diff = spec_max[rcu_bin] - spec_min[rcu_bin]
             #logger.debug("rcu_bin_max_diff %f" %(rcu_bin_max_diff))
             # loop over secs
             for val in spec_median[rcu_bin,:]:
-                #logger.debug("rcu_bin=%d: high-noise value=%5.3fdB  max-ref-value=%5.3fdB" %(rcu_bin, val, ref_value)) 
+                #logger.debug("rcu_bin=%d: high-noise value=%5.3fdB  max-ref-value=%5.3fdB" %(rcu_bin, val, ref_value))
                 if (val > high_limit):
                     n_bad_high_secs += 1
-                
+
                 if (val < low_limit):
                     n_bad_low_secs += 1
-            
-            if n_bad_high_secs > 1:    
+
+            if n_bad_high_secs > 1:
                 high_info.append((rcu_bin, spec_max[rcu_bin], n_bad_high_secs, high_limit, rcu_bin_max_diff))
-                logger.debug("rcu_bin=%d: max-noise=%5.3f  %d of %d seconds bad" %(rcu_bin, spec_max[rcu_bin], n_bad_high_secs, n_secs)) 
+                logger.debug("rcu_bin=%d: max-noise=%5.3f  %d of %d seconds bad" %(rcu_bin, spec_max[rcu_bin], n_bad_high_secs, n_secs))
+
+            if n_bad_low_secs > 1:
+                low_info.append((rcu_bin, spec_min[rcu_bin], n_bad_low_secs , low_limit, rcu_bin_max_diff))
+                logger.debug("rcu_bin=%d: min-noise=%5.3f %d of %d seconds bad" %(rcu_bin, spec_min[rcu_bin], n_bad_low_secs, n_secs))
 
-            if n_bad_low_secs > 1:    
-                low_info.append((rcu_bin, spec_min[rcu_bin], n_bad_low_secs , low_limit, rcu_bin_max_diff)) 
-                logger.debug("rcu_bin=%d: min-noise=%5.3f %d of %d seconds bad" %(rcu_bin, spec_min[rcu_bin], n_bad_low_secs, n_secs)) 
-            
             if (n_bad_high_secs == 0) and (n_bad_low_secs == 0):
+                max_cnt = 0
+                min_cnt = 0
                 if rcu_bin_max_diff > (ref_diff + max_diff):
                     check_high_value = ref_value + (ref_diff / 2.0)
                     check_low_value  = ref_value - (ref_diff / 2.0)
                     for val in spec_median[rcu_bin,:]:
-                        if val > check_high_value or val < check_low_value:
-                            n_bad_jitter_secs += 1
-                    jitter_info.append((rcu_bin, rcu_bin_max_diff, ref_diff, n_bad_jitter_secs))
-                    logger.debug("rcu_bin=%d: max spectrum fluctuation %5.3f dB" %(rcu_bin, rcu_bin_max_diff)) 
+                        if val > check_high_value:
+                            max_cnt += 1
+                        if val < check_low_value:
+                            min_cnt += 1
+                            
+                    # minimal 20% of the values must be out of the check band
+                    secs = _data.shape[1]
+                    if max_cnt > (secs * 0.10) and min_cnt > (secs * 0.10):
+                        n_bad_jitter_secs = max_cnt + min_cnt
+                        jitter_info.append((rcu_bin, rcu_bin_max_diff, ref_diff, n_bad_jitter_secs))
+                    logger.debug("rcu_bin=%d: max spectrum fluctuation %5.3f dB" %(rcu_bin, rcu_bin_max_diff))
     return (low_info, high_info, jitter_info)
 
 # find spurious around normal signals
-# 
+#
 def search_spurious(data, pol, delta):
     info = list()
     _data = data.getAll(pol=pol)
@@ -424,9 +462,9 @@ def search_spurious(data, pol, delta):
     peaks = cSearchPeak(median_spec)
     if not peaks.valid_data:
         return (info)
-    
+
     # first mask peaks available in all data
-    peaks.search(delta=(delta/2.0)) #deta=20 for HBA 
+    peaks.search(delta=(delta/2.0)) #deta=20 for HBA
     for peak, min_sb, max_sb in peaks.max_peaks:
         peakwidth = max_sb - min_sb
         if peakwidth > 8:
@@ -434,10 +472,10 @@ def search_spurious(data, pol, delta):
         min_sb = max(min_sb-1, 0)
         max_sb = min(max_sb+1, peaks.n_data-1)
         logger.debug("mask sb %d..%d" %(min_sb, max_sb))
-        for i in range(min_sb, max_sb, 1):        
+        for i in range(min_sb, max_sb, 1):
             mean_data[:,i] = ma.masked
-    
-    # search in all data for spurious 
+
+    # search in all data for spurious
     for rcu in sorted(data.getActiveRcus(pol)):
         rcu_bin = rcu
         if pol not in ('XY', 'xy'):
@@ -454,7 +492,7 @@ def search_spurious(data, pol, delta):
                 if peakwidth < 100 and peak_val != NaN:
                     logger.debug("rcu_bin=%d: spurious, subband=%d..%d, peak=%3.1fdB" %(rcu_bin, min_sb, max_sb, peak_val))
             if peaks.nMaxPeaks() > 10:
-                #print rcu_bin, peaks.nMaxPeaks()                    
+                #print rcu_bin, peaks.nMaxPeaks()
                 info.append(rcu_bin)
     return(info)
-    
+
diff --git a/LCU/checkhardware/lib/test_db.py b/LCU/checkhardware/lib/test_db.py
index bb10fb6f37b165ed7d2d4b2ff1a5a7786b3e7a6c..50b50b87a182baaec1c461d00d87e63abb59cb10 100644
--- a/LCU/checkhardware/lib/test_db.py
+++ b/LCU/checkhardware/lib/test_db.py
@@ -5,8 +5,9 @@ from general_lib import *
 from lofar_lib import *
 import time
 import logging
+import string
 
-db_version = '0214'
+db_version = '0415'
 
 logger = None
 def init_test_db():
@@ -18,100 +19,109 @@ class cDB:
     def __init__(self, StID, nRSP, nTBB, nLBL, nLBH, nHBA, HBA_SPLIT):
         self.StID              = StID
         self.nr_rsp            = nRSP
+        self.nr_spu            = nRSP / 4
         self.nr_rcu            = nRSP * 8
         self.nr_lbl            = nLBL
         self.nr_lbh            = nLBH
         self.nr_hba            = nHBA
         self.hba_split         = HBA_SPLIT
         self.nr_tbb            = nTBB
-        
+
         self.script_versions   = ''
-        
+
         self.board_errors      = list()
         self.rcumode           = -1
-        self.tests             = ''
+        self.tests_done        = list()
         self.check_start_time  = 0
         self.check_stop_time   = 0
-        self.rsp_driver_down   = False 
-        self.tbb_driver_down   = False 
-        
+        self.rsp_driver_down   = False
+        self.tbb_driver_down   = False
+
         self.station_error     = 0
         self.rspdriver_version = "ok"
         self.rspctl_version    = "ok"
         self.tbbdriver_version = "ok"
         self.tbbctl_version    = "ok"
-        
+
         self.test_end_time     = -1
-        
+
+        self.spu = list()
+        for i in range(self.nr_spu):
+            self.spu.append(self.cSPU(i))
+
         self.rsp = list()
         for i in range(nRSP):
             self.rsp.append(self.cRSP(i))
-        
+
         self.tbb = list()
         for i in range(nTBB):
             self.tbb.append(self.cTBB(i))
-        
+
         self.rcu_state = list()
         for i in range(self.nr_rcu):
             self.rcu_state.append(0)
-        
+
         self.lbl = deepcopy(self.cLBA_DB(label='LBL', nr_antennas=nLBL, nr_offset=48))
         self.lbh = deepcopy(self.cLBA_DB(label='LBH', nr_antennas=nLBH, nr_offset=0))
         self.hba = deepcopy(self.cHBA_DB(nr_tiles=nHBA, split=self.hba_split))
-    
+
     def setTestEndTime(self, end_time):
         if end_time > time.time():
-    	    self.test_end_time = end_time
+            self.test_end_time = end_time
         else:
-            logger.warn("end time in past")	
+            logger.warn("end time in past")
         return
-   
-    # returns True if before end time 
+
+    # returns True if before end time
     def checkEndTime(self, duration=0.0):
         if self.test_end_time == -1:
-        	return (True)
+            return (True)
         if (time.time() + duration) < self.test_end_time:
             return (True)
         else:
-            return (False)		
-    	
+            return (False)
+
     # add only ones
     def addTestDone(self, name):
-        if self.tests.find(name) == -1:
-            self.tests += ','
-            self.tests += name
-    
+        if name not in self.tests_done:
+            self.tests_done.append(name)
+
     # check if already done
     def isTestDone(self, name):
-        if self.tests.find(name) == -1:
+        if name in self.tests_done:
             return (False)
         return (True)
-        
+
     # test
     def test(self, logdir):
         if self.rspdriver_version != "ok" or self.rspctl_version != "ok":
             self.station_error = 1
-            
+
         if self.tbbdriver_version != "ok" or self.tbbctl_version != "ok":
             self.station_error = 1
+
+        for _spu in self.spu:
+            ok = _spu.test()
+            if not ok:
+                self.station_error = 1
             
         for _rsp in self.rsp:
             ok = _rsp.test()
             if not ok:
                 self.station_error = 1
-        
+
         for _tbb in self.tbb:
             ok = _tbb.test()
             if not ok:
                 self.station_error = 1
-        
+
         # test rcu's first
         for _rcu in range(self.nr_rcu):
             error_count = 0
-            
+
             ant_nr = _rcu / 2
             pol_nr = _rcu % 2  # 0=X, 1=Y
-            
+
             if pol_nr == 0:
                 if self.nr_lbl > 0 and self.lbl.ant[ant_nr].x.error: error_count += 1
                 if self.lbh.ant[ant_nr].x.error: error_count += 1
@@ -120,28 +130,28 @@ class cDB:
                 if self.nr_lbl > 0 and self.lbl.ant[ant_nr].y.error: error_count += 1
                 if self.lbh.ant[ant_nr].y.error: error_count += 1
                 if self.hba.tile[ant_nr].y.rcu_error: error_count += 1
-                    
+
             if error_count >= 2:
                 self.rcu_state[_rcu] = 1
-           
+
         self.station_error = max(self.station_error, self.lbl.test(), self.lbh.test(), self.hba.test())
-        
+
         self.makeLogFile(logdir)
         return (self.station_error)
-    
-    
+
+
     # make standard log file
     def makeLogFile(self, logdir):
         #print logdir
         date = getShortDateStr(self.check_start_time)
         log = cTestLogger(logdir)
-        
+
         log.addLine("%s,NFO,---,VERSIONS,%s" %(date, self.script_versions))
-        
-        log.addLine("%s,NFO,---,STATION,NAME=%s" %(date, getHostName()))   
-        
+
+        log.addLine("%s,NFO,---,STATION,NAME=%s" %(date, getHostName()))
+
         log.addLine("%s,NFO,---,RUNTIME,START=%s,STOP=%s" %(date, getDateTimeStr(self.check_start_time), getDateTimeStr(self.check_stop_time)))
-        
+
         info = ""
         bad = ""
         for ant in self.lbl.ant:
@@ -149,55 +159,76 @@ class cDB:
                 bad += "%d " %(ant.nr_pvss)
         if len(bad) > 0:
             info += "LBL=%s," %(bad[:-1])
-        
+
         bad = ""
         for ant in self.lbh.ant:
             if ant.on_bad_list == 1:
-                bad += "%d " %(ant.nr_pvss)        
+                bad += "%d " %(ant.nr_pvss)
         if len(bad) > 0:
             info += "LBH=%s," %(bad[:-1])
-            
+
         bad = ""
         for tile in self.hba.tile:
             if tile.on_bad_list == 1:
-                bad += "%d " %(tile.nr)    
+                bad += "%d " %(tile.nr)
         if len(bad) > 0:
             info += "HBA=%s," %(bad[:-1])
         if len(info) > 0:
             log.addLine("%s,NFO,---,BADLIST,%s" %(date, info[:-1]))
-        
+
         if self.rsp_driver_down:
             log.addLine("%s,NFO,---,DRIVER,RSPDRIVER=DOWN" %(date))
-        
+
         if self.tbb_driver_down:
             log.addLine("%s,NFO,---,DRIVER,TBBDRIVER=DOWN" %(date))
-        
+
         if len(self.board_errors):
             boardstr = ''
             for board in self.board_errors:
                 boardstr += "RSP-%d=DOWN," %(board)
             log.addLine("%s,NFO,---,BOARD,%s" %(date, boardstr[:-1]))
-        
-        log.addLine("%s,NFO,---,CHECKS%s" %(date, self.tests))
-        
+
+        log.addLine("%s,NFO,---,CHECKS,%s" %(date, string.join(self.tests_done, ',')))
+
         log.addLine("%s,NFO,---,STATISTICS,BAD_LBL=%d,BAD_LBH=%d,BAD_HBA=%d,BAD_HBA0=%d,BAD_HBA1=%d" %\
                    (date, self.lbl.nr_bad_antennas, self.lbh.nr_bad_antennas, self.hba.nr_bad_tiles, self.hba.nr_bad_tiles_0, self.hba.nr_bad_tiles_1))
-        
-        
+
+
         if self.rspdriver_version != "ok" or self.rspctl_version != "ok":
             log.addLine("%s,RSP,---,VERSION,RSPDRIVER=%s,RSPCTL=%s" %\
                        (date, self.rspdriver_version, self.rspctl_version))
-        
+
+        for spu in self.spu:
+            spu.test()
+            if not spu.voltage_ok:
+                valstr = ''
+                if not spu.rcu_ok: valstr += ",RCU-5.0V=%3.1f" %(spu.rcu_5_0V)
+                if not spu.lba_ok: valstr += ",LBA-8.0V=%3.1f" %(spu.lba_8_0V)
+                if not spu.hba_ok: valstr += ",HBA-48V=%3.1f" %(spu.hba_48V)
+                if not spu.spu_ok: valstr += ",SPU-3.3V=%3.1f" %(spu.spu_3_3V)
+                if len(valstr):
+                    log.addLine("%s,SPU,%03d,VOLTAGE%s" %(date, spu.nr, valstr))
+                
+            if not spu.temp_ok:
+                log.addLine("%s,SPU,%03d,TEMPERATURE,PCB=%3.1f" %\
+                           (date, spu.nr, spu.temp))
+
         for rsp in self.rsp:
             rsp.test()
             if not rsp.version_ok:
                 log.addLine("%s,RSP,%03d,VERSION,BP=%s,AP=%s" %\
                            (date, rsp.nr, rsp.bp_version, rsp.ap_version))
-        
+            if not rsp.voltage_ok:
+                log.addLine("%s,RSP,%03d,VOLTAGE,1.2V=%3.1f,2.5V=%3.1f,3.3V=%3.1f" %\
+                           (date,rsp.nr, rsp.voltage1_2, rsp.voltage2_5, rsp.voltage3_3))
+            if not rsp.temp_ok:
+                log.addLine("%s,RSP,%03d,TEMPERATURE,PCB=%3.1f,BP=%3.1f,AP0=%3.1f,AP1=%3.1f,AP2=%3.1f,AP3=%3.1f" %\
+                           (date,rsp.nr, rsp.pcb_temp, rsp.bp_temp, rsp.ap0_temp, rsp.ap1_temp, rsp.ap2_temp, rsp.ap3_temp))
+
         if self.tbbdriver_version != "ok" or self.tbbctl_version != "ok":
             log.addLine("%s,TBB,---,VERSION,TBBDRIVER=%s,TBBCTL=%s" %\
                        (date, self.tbbdriver_version, self.tbbctl_version))
-        
+
         for tbb in self.tbb:
             tbb.test()
             if not tbb.version_ok:
@@ -205,67 +236,82 @@ class cDB:
                            (date, tbb.nr, tbb.tp_version, tbb.mp_version))
             if not tbb.memory_ok:
                 log.addLine("%s,TBB,%03d,MEMORY" %(date, tbb.nr))
-                           
+
         for rcu in range(self.nr_rcu):
             if self.rcu_state[rcu]:
                 log.addLine("%s,RCU,%03d,BROKEN" % (date, rcu))
-        
-        # lbl/lbh        
+
+        # lbl/lbh
         for lba in (self.lbl, self.lbh):
-            
+
             if lba.signal_check_done:
                 if lba.test_signal_x == 0 or lba.test_signal_y == 0:
                     log.addLine("%s,%s,---,NOSIGNAL" %(date, lba.label))
-    
+
                 elif lba.avg_2_low:
-                    log.addLine("%s,%s,---,TOOLOW ,AVGX=%3.1f,AVGY=%3.1f" %(date, lba.label, lba.avg_x, lba.avg_y))
-    
+                    log.addLine("%s,%s,---,TOOLOW,AVGX=%3.1f,AVGY=%3.1f" %(date, lba.label, lba.avg_x, lba.avg_y))
+
                 else:
                     if lba.error:
                         log.addLine("%s,%s,---,TESTSIGNAL,SUBBANDX=%d,SIGNALX=%3.1f,SUBBANDY=%d,SIGNALY=%3.1f" %\
                                    (date, lba.label, lba.test_subband_x, lba.test_signal_x, lba.test_subband_y, lba.test_signal_y))
-                   
-             
-            if lba.noise_check_done or lba.oscillation_check_done or lba.spurious_check_done or lba.signal_check_done:                               
+
+
+            if lba.noise_check_done or lba.oscillation_check_done or lba.spurious_check_done or lba.signal_check_done or\
+                    lba.short_check_done or lba.flat_check_done or lba.down_check_done:
                 for ant in lba.ant:
                     if ant.down:
-                            log.addLine("%s,%s,%03d,DOWN  ,X=%3.1f,Y=%3.1f,Xoff=%d,Yoff=%d" %\
+                            log.addLine("%s,%s,%03d,DOWN,X=%3.1f,Y=%3.1f,Xoff=%d,Yoff=%d" %\
                                        (date, lba.label, ant.nr_pvss, ant.x.test_signal, ant.y.test_signal, ant.x.offset, ant.y.offset))
                     else:
                         if lba.signal_check_done:
                             valstr = ''
                             if ant.x.too_low or ant.x.too_high: valstr += ",X=%3.1f" %(ant.x.test_signal)
-                            if ant.y.too_low or ant.y.too_high: valstr += ",Y=%3.1f" %(ant.y.test_signal)    
+                            if ant.y.too_low or ant.y.too_high: valstr += ",Y=%3.1f" %(ant.y.test_signal)
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,RF_FAIL%s" %(date, lba.label, ant.nr_pvss, valstr))
                         
+                        if lba.flat_check_done:    
+                            valstr = ''
+                            if ant.x.flat: valstr += ",Xmean=%3.1f" %(ant.x.flat_val)
+                            if ant.y.flat: valstr += ",Ymean=%3.1f" %(ant.y.flat_val)
+                            if len(valstr):
+                                log.addLine("%s,%s,%03d,FLAT%s" %(date, lba.label, ant.nr_pvss, valstr))
+                        
+                        if lba.short_check_done:    
+                            valstr = ''
+                            if ant.x.short: valstr += ",Xmean=%3.1f" %(ant.x.short_val)
+                            if ant.y.short: valstr += ",Ymean=%3.1f" %(ant.y.short_val)
+                            if len(valstr):
+                                log.addLine("%s,%s,%03d,SHORT%s" %(date, lba.label, ant.nr_pvss, valstr))    
+
                         if lba.oscillation_check_done:
                             valstr = ''
                             if ant.x.osc: valstr += ',X=1'
                             if ant.y.osc: valstr += ',Y=1'
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,OSCILLATION%s" %(date, lba.label, ant.nr_pvss, valstr))
-                        
+
                         if lba.spurious_check_done:
                             valstr = ''
                             if ant.x.spurious: valstr += ',X=1'
                             if ant.y.spurious: valstr += ',Y=1'
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,SPURIOUS%s" %(date, lba.label, ant.nr_pvss, valstr))
-                            
+
                         if lba.noise_check_done:
                             noise = False
                             valstr = ''
-                            if ant.x.low_noise: 
+                            if not ant.x.flat and ant.x.low_noise:
                                 proc = (100.0 / ant.x.low_seconds) * ant.x.low_bad_seconds
                                 valstr += ',Xproc=%5.3f,Xval=%3.1f,Xdiff=%5.3f,Xref=%3.1f' %(proc, ant.x.low_val, ant.x.low_diff, ant.x.low_ref)
-                            if ant.y.low_noise: 
+                            if not ant.y.flat and ant.y.low_noise:
                                 proc = (100.0 / ant.y.low_seconds) * ant.y.low_bad_seconds
                                 valstr += ',Yproc=%5.3f,Yval=%3.1f,Ydiff=%5.3f,Yref=%3.1f' %(proc, ant.y.low_val, ant.y.low_diff, ant.y.low_ref)
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,LOW_NOISE%s" %(date, lba.label, ant.nr_pvss, valstr))
                                 noise = True
-                        
+
                             valstr = ''
                             if ant.x.high_noise:
                                 proc = (100.0 / ant.x.high_seconds) * ant.x.high_bad_seconds
@@ -276,7 +322,7 @@ class cDB:
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,HIGH_NOISE%s" %(date, lba.label, ant.nr_pvss, valstr))
                                 noise = True
-                            
+
                             valstr = ''
                             if not noise and ant.x.jitter:
                                 proc = (100.0 / ant.x.jitter_seconds) * ant.x.jitter_bad_seconds
@@ -287,19 +333,19 @@ class cDB:
                             if len(valstr):
                                 log.addLine("%s,%s,%03d,JITTER%s" %(date, lba.label, ant.nr_pvss, valstr))
             lba = None
-        # end lbl/lbh                
-        
-        
+        # end lbl/lbh
+
+
         # hba
         if self.hba.signal_check_done:
             valstr = ''
             if self.hba.ref_signal_x[0] == 0 and self.hba.ref_signal_x[1] == 0:
                 valstr += ",X"
             if self.hba.ref_signal_y[0] == 0 and self.hba.ref_signal_y[1] == 0:
-                valstr += ",Y"    
+                valstr += ",Y"
             if len(valstr):
                 log.addLine("%s,HBA,---,NOSIGNAL%s" %(date, valstr))
-                        
+
         for tile in self.hba.tile:
             if tile.x.error or tile.y.error:
                 # check for broken summators
@@ -311,16 +357,16 @@ class cDB:
                         for elem in tile.element:
                             if elem.no_modem:
                                 valstr += ",E%02d=??" %(elem.nr)
-                            
+
                             elif elem.modem_error:
                                 valstr += ",E%02d=error" %(elem.nr)
                         if len(valstr):
                             log.addLine("%s,HBA,%03d,MODEM%s" %(date, tile.nr, valstr))
-                    
+
                 if self.hba.noise_check_done:
                     valstr = ''
                     noise = False
-                    
+
                     if tile.x.low_noise:
                         proc = (100.0 / tile.x.low_seconds) * tile.x.low_bad_seconds
                         valstr += ',Xproc=%5.3f,Xval=%3.1f,Xdiff=%5.3f,Xref=%3.1f' %(proc, tile.x.low_val, tile.x.low_diff, tile.x.low_ref)
@@ -330,12 +376,12 @@ class cDB:
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,LOW_NOISE%s" %(date, tile.nr, valstr))
                         noise = True
-                
+
                     valstr = ''
                     if tile.x.high_noise:
                         proc = (100.0 / tile.x.high_seconds) * tile.x.high_bad_seconds
                         valstr += ',Xproc=%5.3f,Xval=%3.1f,Xdiff=%5.3f,Xref=%3.1f' %(proc, tile.x.high_val, tile.x.high_diff, tile.x.high_ref)
-                    if tile.y.high_noise: 
+                    if tile.y.high_noise:
                         proc = (100.0 / tile.y.high_seconds) * tile.y.high_bad_seconds
                         valstr += ',Yproc=%5.3f,Yval=%3.1f,Ydiff=%5.3f,Yref=%3.1f' %(proc, tile.y.high_val, tile.y.high_diff, tile.y.high_ref)
                     if len(valstr):
@@ -351,35 +397,35 @@ class cDB:
                         valstr += ',Yproc=%5.3f,Ydiff=%5.3f,Yref=%3.1f' %(proc, tile.y.jitter_val, tile.y.jitter_ref)
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,JITTER%s" %(date, tile.nr, valstr))
-                            
+
                 if self.hba.oscillation_check_done:
                     valstr = ''
                     if tile.x.osc: valstr += ',X=1'
                     if tile.y.osc: valstr += ',Y=1'
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,OSCILLATION%s" %(date, tile.nr, valstr))
-                
+
                 if tile.p_summator_error:
-                    log.addLine("%s,HBA,%03d,P_SUMMATOR" %(date, tile.nr))     
-                
-                
-                
+                    log.addLine("%s,HBA,%03d,P_SUMMATOR" %(date, tile.nr))
+
+
+
                 if self.hba.summatornoise_check_done:
-                    valstr = ''    
+                    valstr = ''
                     if tile.x.summator_noise: valstr += ',X=1'
                     if tile.y.summator_noise: valstr += ',Y=1'
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,SUMMATOR_NOISE%s" %(date, tile.nr, valstr))
-                    
+
                 if self.hba.spurious_check_done:
-                    valstr = ''    
+                    valstr = ''
                     if tile.x.spurious: valstr += ',X=1'
                     if tile.y.spurious: valstr += ',Y=1'
-                    if len(valstr):    
+                    if len(valstr):
                         log.addLine("%s,HBA,%03d,SPURIOUS%s" %(date, tile.nr, valstr))
-                
+
                 if self.hba.signal_check_done:
-                    valstr = ''    
+                    valstr = ''
                     if tile.x.too_low or tile.x.too_high:
                         valstr += ",X=%3.1f %d %3.1f %3.1f %d %3.1f" %\
                                   (tile.x.test_signal[0], self.hba.test_subband_x[0], self.hba.ref_signal_x[0],\
@@ -390,7 +436,7 @@ class cDB:
                                    tile.y.test_signal[1], self.hba.test_subband_y[1], self.hba.ref_signal_y[1])
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,RF_FAIL%s" %(date, tile.nr, valstr))
-                                       
+
                 valstr = ''
                 if self.hba.element_check_done:
                     for elem in tile.element:
@@ -400,7 +446,7 @@ class cDB:
                             if not tile.c_summator_error:
                                 if elem.no_modem:
                                     valstr += ",M%d=??" %(elem.nr)
-                                
+
                                 elif elem.modem_error:
                                     valstr += ",M%d=error" %(elem.nr)
                         else:
@@ -409,29 +455,29 @@ class cDB:
                                     valstr += ",OX%d=1" %(elem.nr)
                                 if elem.y.osc:
                                     valstr += ",OY%d=1" %(elem.nr)
-                            
+
                             elif elem.x.spurious or elem.y.spurious:
                                 if elem.x.spurious:
                                     valstr += ",SPX%d=1" %(elem.nr)
                                 if elem.y.spurious:
                                     valstr += ",SPY%d=1" %(elem.nr)
-                            
+
                             elif elem.x.low_noise or elem.x.high_noise or elem.y.low_noise or elem.y.high_noise or elem.x.jitter or elem.y.jitter:
                                 if elem.x.low_noise:
                                     valstr += ",LNX%d=%3.1f %5.3f" %(elem.nr, elem.x.low_val, elem.x.low_diff)
-                                
+
                                 if elem.x.high_noise:
                                     valstr += ",HNX%d=%3.1f %5.3f" %(elem.nr, elem.x.high_val, elem.x.high_diff)
-                                
+
                                 if (not elem.x.low_noise) and (not elem.x.high_noise) and (elem.x.jitter > 0.0):
                                     valstr += ",JX%d=%5.3f" %(elem.nr, elem.x.jitter)
-                                    
+
                                 if elem.y.low_noise:
-                                    valstr += ",LNY%d=%3.1f %5.3f" %(elem.nr, elem.y.low_val, elem.y.low_diff)               
-                                
+                                    valstr += ",LNY%d=%3.1f %5.3f" %(elem.nr, elem.y.low_val, elem.y.low_diff)
+
                                 if elem.y.high_noise:
                                     valstr += ",HNY%d=%3.1f %5.3f" %(elem.nr, elem.y.high_val, elem.y.high_diff)
-                                
+
                                 if (not elem.y.low_noise) and (not elem.y.high_noise) and (elem.y.jitter > 0.0):
                                     valstr += ",JY%d=%5.3f" %(elem.nr, elem.y.jitter)
                             else:
@@ -443,7 +489,7 @@ class cDB:
                                                   (elem.nr,\
                                                    elem.x.test_signal[0], elem.x.test_subband[0], elem.x.ref_signal[0],\
                                                    elem.x.test_signal[1], elem.x.test_subband[1], elem.x.ref_signal[1])
-                                
+
                                 if elem.y.ref_signal[0] == 0 and elem.y.ref_signal[1] == 0:
                                     log.addLine("%s,HBA,%03d,NOSIGNAL,E%02dY" %(date, tile.nr, elem.nr))
                                 else:
@@ -452,37 +498,71 @@ class cDB:
                                                   (elem.nr,\
                                                    elem.y.test_signal[0], elem.y.test_subband[0], elem.y.ref_signal[0],\
                                                    elem.y.test_signal[1], elem.y.test_subband[1], elem.y.ref_signal[1])
-                
+
                     if len(valstr):
                         log.addLine("%s,HBA,%03d,E_FAIL%s" %(date, tile.nr, valstr))
-        # end HBA 
+        # end HBA
         return
-        
+
 #=======================================================================================================================
-# database from here                
+# database from here
+    class cSPU:
+        def __init__(self, nr):
+            self.nr = nr
+            self.rcu_5_0V   = 0.0
+            self.lba_8_0V   = 0.0
+            self.hba_48V    = 0.0
+            self.spu_3_3V   = 0.0
+            self.rcu_ok     = 1
+            self.lba_ok     = 1
+            self.hba_ok     = 1
+            self.spu_ok     = 1
+            self.voltage_ok = 1
+            self.temp       = 0.0
+            self.temp_ok    = 1
+
+        def test(self):
+            self.voltage_ok = 0
+            if self.rcu_ok and self.lba_ok and self.hba_ok and self.spu_ok:
+                self.voltage_ok = 1
+            return(self.voltage_ok)
+
+
     class cRSP:
         def __init__(self, nr):
             self.nr = nr
-            
+
             self.test_done  = 0
             self.board_ok   = 1
             self.ap_version = 'ok'
             self.bp_version = 'ok'
             self.version_ok = 1
-        
+            self.voltage1_2 = 0.0
+            self.voltage2_5 = 0.0
+            self.voltage3_3 = 0.0
+            self.voltage_ok = 1
+            self.pcb_temp   = 0.0
+            self.bp_temp    = 0.0
+            self.ap0_temp   = 0.0
+            self.ap1_temp   = 0.0
+            self.ap2_temp   = 0.0
+            self.ap3_temp   = 0.0
+            self.temp_ok    = 1
+
         def test(self):
             if self.ap_version != 'ok' or self.bp_version != 'ok':
                 self.version_ok = 0
-            return
-    # used by LBA and HBA antenna class        
+            return (self.version_ok and self.voltage_ok and self.temp_ok)
+
+    # used by LBA and HBA antenna class
     class cPolarity:
         def __init__(self, rcu=None):
-            
+
             self.rcu            = rcu
             self.rcu_off        = 0 # 0 = RCU on, 1 = RCU off
             self.rcu_error      = 0
-            
-            # status variables 0|1       
+
+            # status variables 0|1
             self.error          = 0    #
             self.too_low        = 0    #
             self.too_high       = 0    #
@@ -493,50 +573,58 @@ class cDB:
             self.no_signal      = 0    # signal below 2dB
             self.summator_noise = 0    #
             self.spurious       = 0    #
+            self.flat           = 0    #
+            self.short          = 0    #
 
-            # test result of signal test, 
+            # test result of signal test,
             # only for HBA element test, firt value ctrl=129 second value ctrl=253
             self.test_subband   = [0, 0]
             self.ref_signal     = [-1, -1]
             self.test_signal    = [0.0, 0.0]
             self.offset         = 0
-            
+
             # measured values filled on error
-            # proc : bad time in meausured time 0..100%        
+            # proc : bad time in meausured time 0..100%
             # val  : max or min meausured value
             self.low_seconds     = 0
             self.low_bad_seconds = 0
             self.low_val         = 100.0  #
             self.low_diff        = 0.0
             self.low_ref         = 0.0  #
-    
+
             self.high_seconds     = 0
             self.high_bad_seconds = 0
             self.high_val         = 0.0  #
             self.high_diff        = 0.0
             self.high_ref         = 0.0  #
-            
+
             self.jitter_seconds     = 0
             self.jitter_bad_seconds = 0
             self.jitter_val         = 0.0
             self.jitter_ref         = 0.0
-    
+            
+            self.flat_val           = 0.0
+            self.short_val          = 0.0
+
     class cLBA_DB:
         def __init__(self, label, nr_antennas, nr_offset=0):
             self.rsp_driver_down         = False
             self.noise_check_done        = 0
             self.signal_check_done       = 0
+            self.short_check_done        = 0
+            self.flat_check_done         = 0
+            self.down_check_done         = 0
             self.spurious_check_done     = 0
             self.oscillation_check_done  = 0
-            
+
             self.noise_low_deviation     = 0.0
             self.noise_high_deviation    = 0.0
             self.noise_max_fluctuation   = 0.0
-            
+
             self.rf_low_deviation        = 0.0
             self.rf_high_deviation       = 0.0
             self.rf_subband              = 0
-            
+
             self.check_time_noise        = 0
             self.nr_antennas             = nr_antennas
             self.nr_offset               = nr_offset
@@ -554,21 +642,22 @@ class cDB:
             for i in range(self.nr_antennas):
                 self.ant.append(self.cAntenna(i, self.nr_offset))
             return
-        
+
         def test(self):
             if self.rsp_driver_down:
                 return (self.error)
-            if self.noise_check_done or self.signal_check_done or self.spurious_check_done or self.oscillation_check_done:
+            if self.noise_check_done or self.signal_check_done or self.short_check_done or self.flat_check_done or\
+                    self.down_check_done or self.signal_check_done or self.spurious_check_done or self.oscillation_check_done:
                 self.nr_bad_antennas = 0
-            
+
             for ant in self.ant:
                 ant.test()
                 ant_error = max(ant.x.error, ant.y.error)
                 self.error = max(self.error, ant_error)
                 if ant_error:
                     self.nr_bad_antennas += 1
-            return (self.error) 
-        
+            return (self.error)
+
         # return select string for rspctl command
         def selectList(self):
             select = list()
@@ -577,12 +666,12 @@ class cDB:
                     select.append(ant.x.rcu)
                     select.append(ant.y.rcu)
             return (select)
-            
+
         def resetRcuState(self):
             for ant in self.ant:
                 ant.x.rcu_off = 0
                 ant.y.rcu_off = 0
-            
+
         class cAntenna:
             def __init__(self, nr, nr_offset):
                 self.nr          = nr
@@ -590,15 +679,17 @@ class cDB:
                 self.on_bad_list = 0
                 self.x           = cDB.cPolarity(rcu=(self.nr * 2))
                 self.y           = cDB.cPolarity(rcu=((self.nr * 2) + 1))
-                
+
                 self.down = 0
                 return
-                
+
             def test(self):
-                self.x.error = max(self.x.too_low, self.x.too_high, self.x.osc, self.x.high_noise, self.x.low_noise, self.x.jitter, self.x.spurious, self.down)
-                self.y.error = max(self.y.too_low, self.y.too_high, self.y.osc, self.y.high_noise, self.y.low_noise, self.y.jitter, self.y.spurious, self.down)
+                self.x.error = max(self.x.too_low, self.x.too_high, self.x.osc, self.x.high_noise, self.x.low_noise, 
+                                   self.x.jitter, self.x.spurious, self.down, self.x.flat, self.x.short)
+                self.y.error = max(self.y.too_low, self.y.too_high, self.y.osc, self.y.high_noise, self.y.low_noise, 
+                                   self.y.jitter, self.y.spurious, self.down, self.y.flat, self.y.short)
                 return
-            
+
     class cHBA_DB:
         def __init__(self, nr_tiles, split):
             self.rsp_driver_down           = False
@@ -609,7 +700,7 @@ class cDB:
             self.oscillation_check_done    = 0
             self.summatornoise_check_done  = 0
             self.element_check_done        = 0
-            
+
             self.hba_split                 = split
             self.check_time_noise          = 0
             self.check_time_noise_elements = 0
@@ -629,7 +720,7 @@ class cDB:
             for i in range(self.nr_tiles):
                 self.tile.append(self.cTile(i))
             return
-        
+
         def test(self):
             if self.rsp_driver_down:
                 return (self.error)
@@ -640,22 +731,22 @@ class cDB:
                     self.nr_bad_tiles_1 = 0
                 else:
                     self.nr_bad_tiles   = 0
-                    
+
             for tile in self.tile:
                 tile.test()
                 tile_error = max(tile.x.error, tile.y.error)
                 self.error = max(self.error, tile_error)
-                
+
                 if tile_error:
                     if self.hba_split == 1:
                         if tile.nr < 24:
                             self.nr_bad_tiles_0 += 1
                         else:
                             self.nr_bad_tiles_1 += 1
-                    else:        
+                    else:
                         self.nr_bad_tiles += 1
-            return (self.error)   
-        
+            return (self.error)
+
         # return select string for rspctl command
         def selectList(self):
             select = list()
@@ -664,28 +755,28 @@ class cDB:
                     select.append(tile.x.rcu)
                     select.append(tile.y.rcu)
             return (select)
-            
+
         def resetRcuState(self):
             for tile in self.tile:
                 tile.x.rcu_off = 0
                 tile.y.rcu_off = 0
-        
+
         class cTile:
             def __init__(self, nr):
                 self.nr          = nr
                 self.on_bad_list = 0
                 self.x           = cDB.cPolarity(rcu=(nr*2))
                 self.y           = cDB.cPolarity(rcu=(nr*2+1))
-            
+
                 self.noise_low_deviation     = 0.0
                 self.noise_high_deviation    = 0.0
                 self.noise_max_fluctuation   = 0.0
-                
+
                 self.rf_low_deviation        = 0.0
                 self.rf_high_deviation       = 0.0
                 self.rf_subband              = 0
-            
-                self.no_power         = 0    # signal around 60dB  
+
+                self.no_power         = 0    # signal around 60dB
                 self.p_summator_error = 0
                 self.c_summator_error = 0
                 self.nr_elements      = 16
@@ -693,7 +784,7 @@ class cDB:
                 for i in range(1,self.nr_elements+1,1):
                     self.element.append(self.cElement(i))
                 return
-            
+
             def test(self):
                 no_modem_cnt = 0
                 modem_err_cnt = 0
@@ -712,10 +803,10 @@ class cDB:
                         no_modem_cnt += 1
                     if elem.modem_error:
                         modem_err_cnt += 1
-    
+
                     self.x.error = max(self.x.error, elem.x.error)
                     self.y.error = max(self.y.error, elem.y.error)
-                    
+
                 if (no_modem_cnt >= 8) or (modem_err_cnt >= 8):
                     self.c_summator_error = 1
                 if no_power_cnt >= 15:
@@ -724,15 +815,15 @@ class cDB:
                     self.x.rcu_error = 1
                 if y_no_signal_cnt == 16:
                     self.y.rcu_error = 1
-                
+
                 self.x.error = max(self.x.error, self.x.too_low, self.x.too_high, self.x.low_noise, self.x.no_signal, self.x.high_noise, self.x.jitter, self.x.osc,
-                                   self.x.summator_noise, self.x.spurious, self.p_summator_error, self.c_summator_error) 
-                
+                                   self.x.summator_noise, self.x.spurious, self.p_summator_error, self.c_summator_error)
+
                 self.y.error = max(self.y.error, self.y.too_low, self.y.too_high, self.y.low_noise, self.y.no_signal, self.y.high_noise, self.y.jitter, self.y.osc,
-                                   self.y.summator_noise, self.y.spurious, self.p_summator_error, self.c_summator_error) 
+                                   self.y.summator_noise, self.y.spurious, self.p_summator_error, self.c_summator_error)
                 return
-            
-            
+
+
             class cElement:
                 def __init__(self, nr):
                     self.nr = nr
@@ -742,7 +833,7 @@ class cDB:
                     self.noise_low_deviation     = 0.0
                     self.noise_high_deviation    = 0.0
                     self.noise_max_fluctuation   = 0.0
-                    
+
                     self.rf_low_deviation        = 0.0
                     self.rf_high_deviation       = 0.0
                     self.rf_subband              = 0
@@ -750,27 +841,27 @@ class cDB:
                     self.no_power                = 0    # signal around 60dB
                     self.no_modem                = 0    # modem reponse = ??
                     self.modem_error             = 0    # wrong response from modem
-                    
+
                     return
-                
+
                 def test(self):
                     modem_err = 0
-                    if self.no_modem or self.modem_error:  
+                    if self.no_modem or self.modem_error:
                         modem_err = 1
-                        
+
                     self.x.error = max(self.x.too_low, self.x.too_high, self.x.low_noise, self.x.high_noise, self.x.no_signal,
                                        self.x.jitter, self.no_power, self.x.spurious, self.x.osc, modem_err)
-                    
-                    self.y.error = max(self.y.too_low, self.y.too_high, self.y.low_noise, self.y.high_noise, self.y.no_signal, 
+
+                    self.y.error = max(self.y.too_low, self.y.too_high, self.y.low_noise, self.y.high_noise, self.y.no_signal,
                                        self.y.jitter, self.no_power, self.y.spurious, self.y.osc, modem_err)
                     return
-         
-                
+
+
     class cTDS:
         def __init__(self):
             self.test_done = 0
             self.ok = 1
-    
+
     class cTBB:
         def __init__(self, nr):
             self.nr = nr
@@ -780,13 +871,13 @@ class cDB:
             self.memory_size = 0
             self.version_ok = 1
             self.memory_ok = 1
-        
+
         def test(self):
             if self.tp_version != 'ok' or self.mp_version != 'ok':
                 self.version_ok = 0
             if self.memory_size != 0:
                 self.memory_ok = 0
-                
-            return 
-            
-            
+
+            return
+
+
diff --git a/LCU/checkhardware/lib/test_lib.py b/LCU/checkhardware/lib/test_lib.py
index 3569eadd9401292750ba550c0dad6e84b65aeb03..4b0e814903ccfbbfc87773565d0e5475dea78b1d 100644
--- a/LCU/checkhardware/lib/test_lib.py
+++ b/LCU/checkhardware/lib/test_lib.py
@@ -9,7 +9,7 @@ import os
 import numpy as np
 import logging
 
-test_version = '0514'
+test_version = '0615'
 
 logger = None
 def init_test_lib():
@@ -22,6 +22,76 @@ def init_test_lib():
 #DefaultLBASubband = 301
 #DefaultHBASubband = 155
 
+class cSPU:
+    def __init__(self, db):
+        self.db = db
+        
+    def checkStatus(self):
+        """
+        check PSU if boards idle and fully loaded
+        """ 
+        logger.info("=== SPU status check ===")
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down, skip test")
+            return
+        # [0] = no-load,  [1] = full-load
+        
+        noload = []
+        fullload = []
+        logger.debug("check spu no load")
+        answer = rspctl('--spustatus')
+
+        # check if Driver is available
+        if answer.find('No Response') > 0:
+            logger.warn("No RSPDriver")
+            self.db.rspdriver_version = 0
+        else:
+            infolines = answer.splitlines()
+            for line in infolines:
+                li = line.split("|")
+                if li[0].strip().isdigit():
+                    sr = int(li[0].strip())
+                    noload.append([sr, float(li[1]), float(li[2]), float(li[3]), float(li[4])])
+                    self.db.spu[sr].temp = float(li[5])
+                    logger.debug("Subrack %d voltages: rcu=%3.1f  lba=%3.1f  hba=%3.1f  spu=%3.1f  temp: %3.1f" %\
+                                (sr, float(li[1]), float(li[2]), float(li[3]), float(li[4]), self.db.spu[sr].temp))
+
+            # turn on all hbas
+            logger.debug("check spu full load")
+            rsp_rcu_mode(5, self.db.hba.selectList())
+            answer = rspctl('--spustatus')
+            infolines = answer.splitlines()
+            for line in infolines:
+                li = line.split("|")
+                if li[0].strip().isdigit():
+                    sr = int(li[0].strip())
+                    fullload.append([sr, float(li[1]), float(li[2]), float(li[3]), float(li[4])])
+                    logger.debug("Subrack %d voltages: rcu=%3.1f  lba=%3.1f  hba=%3.1f  spu=%3.1f  temp: %3.1f" %\
+                                (sr, float(li[1]), float(li[2]), float(li[3]), float(li[4]), self.db.spu[sr].temp))
+
+            
+            for sr in range(self.db.nr_spu):
+                # calculate mean of nload, fullload
+                self.db.spu[sr].rcu_5_0V = (noload[sr][1] + fullload[sr][1]) / 2.0
+                self.db.spu[sr].lba_8_0V = (noload[sr][2] + fullload[sr][2]) / 2.0
+                self.db.spu[sr].hba_48V  = (noload[sr][3] + fullload[sr][3]) / 2.0
+                self.db.spu[sr].spu_3_3V = (noload[sr][4] + fullload[sr][4]) / 2.0
+                if (abs(4.7 - self.db.spu[sr].rcu_5_0V) > 0.2):
+                    self.db.spu[sr].rcu_ok = 0
+                
+                if (abs(7.6 - self.db.spu[sr].lba_8_0V) > 0.2):
+                    self.db.spu[sr].lba_ok = 0
+                # if voltage drop is too high
+                if (abs(45.75 - self.db.spu[sr].hba_48V) > 0.75) or ((noload[sr][3] - fullload[sr][3]) > 1.0):
+                    self.db.spu[sr].hba_ok = 0
+                
+                if (abs(3.3 - self.db.spu[sr].spu_3_3V) > 0.2):
+                    self.db.spu[sr].spu_ok = 0            
+                
+        logger.info("=== Done SPU check ===")
+        self.db.addTestDone('SPU')
+        return
+
 # class for checking TBB boards using tbbctl
 class cTBB:
     global logger
@@ -30,12 +100,12 @@ class cTBB:
         self.nr = self.db.nr_tbb
         self.driverstate = True
         #tbbctl('--free')
-            
-    # check software versions of driver, tbbctl and TP/MP firmware    
+
+    # check software versions of driver, tbbctl and TP/MP firmware
     def checkVersions(self, driverV, tbbctlV, tpV, mpV ):
         logger.info("=== TBB Version check ===")
         answer = tbbctl('--version')
-        
+
         # check if Driver is available
         if answer.find('TBBDriver is NOT responding') > 0:
             logger.warn("No TBBDriver")
@@ -48,21 +118,21 @@ class cTBB:
             if info[0].split()[-1] != driverV:
                 logger.warn("Not right Driver version")
                 self.db.tbbdriver_version = info[0].split()[-1]
-            
+
             if info[1].split()[-1] != tbbctlV:
                 logger.warn("Not right tbbctl version")
                 self.db.tbbctl_version = info[1].split()[-1]
-            
+
             # check if image_nr > 0 for all boards
             if str(info).count('V') != (self.nr * 4):
                 logger.warn("WARNING, Not all boards in working image")
-            
+
             for tbb in self.db.tbb:
                 board_info = info[2+tbb.nr].strip().split('  ')
                 #print board_info
                 if board_info[3].split()[1] != tpV:
                     logger.warn("Board %d Not right TP version" %(tbb.nr))
-                    tbb.tp_version = board_info[3].split()[1]    
+                    tbb.tp_version = board_info[3].split()[1]
 
                 if board_info[4].split()[1] != mpV:
                     logger.warn("Board %d Not right MP version" %(tbb.nr))
@@ -70,8 +140,8 @@ class cTBB:
         logger.info("=== Done TBB Version check ===")
         self.db.addTestDone('TV')
         return
-    
-    # Check memory address and data lines            
+
+    # Check memory address and data lines
     def checkMemory(self):
         logger.info("=== TBB Memory check ===")
         tbbctl('--free')
@@ -82,28 +152,32 @@ class cTBB:
             if info[0].strip() != 'All Addresslines OK':
                 logger.warn("Board %d Addresline error" %(tbb.nr))
                 ok = False
-            
+
             if info[1].strip() != 'All Datalines OK':
                 logger.warn("Board %d Datalines error" %(tbb.nr))
                 ok = False
-            
+
             if not ok:
                 tbb.memory_ok = 0
                 logger.info(answer)
+        # turn on recording again
+        tbbctl('--alloc')
+        tbbctl('--record')
+        rspctl('--tbbmode=transient')
         logger.info("=== Done TBB Memory check ===")
         self.db.addTestDone('TM')
         return
 #### end of cTBB class ####
 
-                
+
 # class for checking RSP boards using rspctl
 class cRSP:
     global logger
     def __init__(self, db):
         self.db = db
         self.nr = self.db.nr_rsp
-    
-    # check software versions of driver, tbbctl and TP/MP firmware    
+
+    # check software versions of driver, tbbctl and TP/MP firmware
     def checkVersions(self, bpV, apV ):
         logger.info("=== RSP Version check ===")
         if not checkActiveRSPDriver():
@@ -118,63 +192,142 @@ class cRSP:
         else:
             infolines = answer.splitlines()
             info = infolines
-            
+
             images_ok = True
             # check if image_nr > 0 for all boards
             if str(info).count('0.0') != 0:
                 logger.warn("WARNING, Not all boards in working image")
                 images_ok = False
-            
+
             for rsp in self.db.rsp:
                 board_info = info[rsp.nr].split(',')
-                
+
                 if board_info[1].split()[3] != bpV:
                     logger.warn("Board %d Not right BP version" %(rsp.nr))
                     rsp.bp_version = board_info[1].split()[3]
                     images_ok = False
-            
+
                 if board_info[2].split()[3] != apV:
                     logger.warn("Board %d Not right AP version" %(rsp.nr))
                     rsp.ap_version = board_info[2].split()[3]
                     images_ok = False
-        
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return (False)
-            
+
         logger.info("=== Done RSP Version check ===")
         self.db.addTestDone('RV')
-            
         return (images_ok)
+
+    def checkBoard(self):
+        ok = True
+        logger.info("=== RSP Board check ===")
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down, skip test")
+            return (False)
+        answer = rspctl('--status')
+        p2 = 0
+        for rsp in self.db.rsp:
+            p1 = answer.find("RSP[%2d]" %(rsp.nr), p2)
+            p2 = answer.find("\n", p1)
+            d = [float(i.split(":")[1].strip()) for i in answer[p1+7:p2].split(',')]
+            if len(d) == 3:
+                rsp.voltage1_2 = d[0]
+                if d[0] < 1.1 or d[0] > 1.3:
+                    rsp.voltage_ok = 0
+                    logger.info("RSP board %d [1.2V]=%3.1fV" %(rsp.nr, d[0]))
+                rsp.voltage2_5 = d[1]
+                if d[1] < 2.4 or d[1] > 2.6:
+                    rsp.voltage_ok = 0
+                    logger.info("RSP board %d [2.5V]=%3.1fV" %(rsp.nr, d[1]))
+                rsp.voltage3_3 = d[2]
+                if d[2] < 3.2 or d[2] > 3.4:
+                    rsp.voltage_ok = 0
+                    logger.info("RSP board %d [3.3V]=%3.1fV" %(rsp.nr, d[2]))
+
+        for rsp in self.db.rsp:
+            p1 = answer.find("RSP[%2d]" %(rsp.nr), p2)
+            p2 = answer.find("\n", p1)
+            d = [float(i.split(":")[1].strip()) for i in answer[p1+7:p2].split(',')]
+            if len(d) == 6:
+                rsp.pcb_temp   = d[0]
+                if d[0] > 45.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [pcb_temp]=%3.1f" %(rsp.nr, d[0]))
+                rsp.bp_temp    = d[1]
+                if d[1] > 75.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [bp_temp]=%3.1f" %(rsp.nr, d[1]))
+                rsp.ap0_temp   = d[2]
+                if d[2] > 75.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [ap0_temp]=%3.1f" %(rsp.nr, d[2]))
+                rsp.ap1_temp   = d[3]
+                if d[3] > 75.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [ap1_temp]=%3.1f" %(rsp.nr, d[3]))
+                rsp.ap2_temp   = d[4]
+                if d[4] > 75.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [ap2_temp]=%3.1f" %(rsp.nr, d[4]))
+                rsp.ap3_temp   = d[5]
+                if d[5] > 75.0:
+                    rsp.temp_ok = 0
+                    logger.info("RSP board %d [ap3_temp]=%3.1f" %(rsp.nr, d[5]))
+        return (ok)
+
 #### end of cRSP class ####
 
 
 # class for testing LBA antennas
 class cLBA:
-    global logger
+    #global logger
     # mode='lba_low' or 'lba_high'
     def __init__(self, db, lba):
         self.db  = db
         self.lba = lba
         self.rcudata = cRCUdata(self.lba.nr_antennas*2)
+        self.rcudata.setActiveRcus(self.lba.selectList())
         
         # Average normal value = 150.000.000 (81.76 dBm) -3dB +3dB
         # LOW/HIGH LIMIT is used for calculating mean value
         self.lowLimit = -3.0 #dB
         self.highLimit = 3.0 #dB
-        
+
         # MEAN LIMIT is used to check if mean of all antennas is ok
         self.meanLimit = 66.0 #dB
     
+    def reset(self):
+        self.rcudata.reset()
+        self.rcudata.reset_masks()
+        self.rcudata.setActiveRcus(self.lba.selectList())
+    
     def turnOffAnt(self, ant_nr):
         ant = self.lba.ant[ant_nr]
         ant.x.rcu_off = 1
         ant.y.rcu_off = 1
+        self.rcudata.setInActiveRcu(ant.x.rcu)
+        self.rcudata.setInActiveRcu(ant.y.rcu)
         logger.info("turned off antenna %d RCU(%d,%d)" %(ant.nr_pvss, ant.x.rcu, ant.y.rcu))
         rspctl("--rcumode=0 --select=%d,%d" %(ant.x.rcu, ant.y.rcu), wait=2.0)
         rspctl("--rcuenable=0 --select=%d,%d" %(ant.x.rcu, ant.y.rcu), wait=2.0)
         return
-    
+
+    def set_mode(self, mode):
+        if self.db.rcumode != mode:
+            self.db.rcumode = mode
+            turnoffRCUs()
+            turnonRCUs(mode=mode, rcus=self.lba.selectList())
+            self.lba.resetRcuState()
+            self.rcudata.reset()
+        
+    def record_data(self, rec_time, new_data=False):
+        if new_data or self.rcudata.isActiveRcusChanged() or self.rcudata.getRecTime() < rec_time:
+            logger.debug('record info changed')
+            self.rcudata.resetActiveRcusChanged()
+            self.rcudata.record(rec_time=rec_time)
+        
     # check for oscillating tiles and turn off RCU
     # stop one RCU each run
     def checkOscillation(self, mode):
@@ -182,48 +335,43 @@ class cLBA:
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-        
+
         if self.db.checkEndTime(duration=28.0) == False:
             logger.warn("check stopped, end time reached")
             return
-                
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.lba.selectList())
-            self.lba.resetRcuState()
-        
+
+        self.set_mode(mode)
+
         clean = False
         while not clean:
             if self.db.checkEndTime(duration=18.0) == False:
                 logger.warn("check stopped, end time reached")
                 return
-        
-            
+
             clean = True
-            self.rcudata.setActiveRcus(self.lba.selectList())
-            self.rcudata.record(rec_time=5)
-            
-            # result is a sorted list on maxvalue
-            result = search_oscillation(data=self.rcudata, pol='XY', delta=4.0)
-            if len(result) > 1:    
-                clean = False
-                rcu, peaks_sum, n_peaks, rcu_low  = sorted(result[1:], reverse=True)[0] #result[1]
-                ant = rcu / 2
-                ant_polarity = rcu % 2
-                logger.info("RCU %d LBA %d Oscillation sum=%3.1f peaks=%d low=%3.1fdB" %\
-                           (rcu, self.lba.ant[ant].nr_pvss, peaks_sum, n_peaks, rcu_low))
-                self.turnOffAnt(ant)
-                if ant_polarity == 0:
-                    self.lba.ant[ant].x.osc = 1
-                else:
-                    self.lba.ant[ant].y.osc = 1
-        
+            self.record_data(rec_time=3)
+            
+            for pol_nr, pol in enumerate(('X', 'Y')):
+                # result is a sorted list on maxvalue
+                result = search_oscillation(data=self.rcudata, pol=pol, delta=6.0)
+                if len(result) > 1:
+                    clean = False
+                    ant, peaks_sum, n_peaks, ant_low  = sorted(result[1:], reverse=True)[0] #result[1]
+                    #ant = rcu / 2
+                    #ant_polarity = rcu % 2
+                    rcu = (ant * 2) + pol_nr
+                    logger.info("RCU %d LBA %d Oscillation sum=%3.1f peaks=%d low=%3.1fdB" %\
+                               (rcu, self.lba.ant[ant].nr_pvss, peaks_sum, n_peaks, ant_low))
+                    self.turnOffAnt(ant)
+                    if pol_nr == 0:
+                        self.lba.ant[ant].x.osc = 1
+                    else:
+                        self.lba.ant[ant].y.osc = 1
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
+
         self.lba.oscillation_check_done = 1
         self.db.addTestDone('O%d' %(mode))
         logger.info("=== Done %s oscillation test ===" %(self.lba.label))
@@ -239,22 +387,17 @@ class cLBA:
             logger.warn("check stopped, end time reached")
             return
 
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.lba.selectList())
-            self.lba.resetRcuState()
-        
+        self.set_mode(mode)
+
         for ant in self.lba.ant:
             if ant.x.rcu_off or ant.y.rcu_off:
                 logger.info("skip low-noise test for antenna %d, RCUs turned off" %(ant.nr))
-        self.rcudata.setActiveRcus(self.lba.selectList())
-        self.rcudata.record(rec_time=record_time)
         
+        self.record_data(rec_time=record_time)
+
         # result is a sorted list on maxvalue
         low_noise, high_noise, jitter = search_noise(self.rcudata, 'XY', low_deviation, high_deviation, max_diff)
-        
+
         for n in low_noise:
             rcu, val, bad_secs, ref, diff = n
             ant = rcu / 2
@@ -264,11 +407,12 @@ class cLBA:
             logger.info("RCU %d Ant %d Low-Noise value=%3.1f bad=%d(%d) limit=%3.1f diff=%3.3f" %\
                        (rcu, self.lba.ant[ant].nr_pvss, val, bad_secs, self.rcudata.frames, ref, diff))
             
-            if rcu%2 == 0:                             
+            self.rcudata.add_to_rcu_mask(rcu)
+            if rcu%2 == 0:
                 antenna = self.lba.ant[ant].x
-            else:                          
+            else:
                 antenna = self.lba.ant[ant].y
-            
+
             antenna.low_seconds     += self.rcudata.frames
             antenna.low_bad_seconds += bad_secs
             if val < self.lba.ant[ant].x.low_val:
@@ -276,19 +420,20 @@ class cLBA:
                 antenna.low_val   = val
                 antenna.low_ref   = ref
                 antenna.low_diff  = diff
-            
-        for n in high_noise:    
+
+        for n in high_noise:
             rcu, val, bad_secs, ref, diff = n
             ant = rcu / 2
             #self.turnOffAnt(ant)
             logger.info("RCU %d Ant %d High-Noise value=%3.1f bad=%d(%d) ref=%3.1f diff=%3.1f" %\
                        (rcu, self.lba.ant[ant].nr_pvss, val, bad_secs, self.rcudata.frames, ref, diff))
-            
-            if rcu%2 == 0:                             
+
+            self.rcudata.add_to_rcu_mask(rcu)
+            if rcu%2 == 0:
                 antenna = self.lba.ant[ant].x
-            else:                          
+            else:
                 antenna = self.lba.ant[ant].y
-            
+
             antenna.high_seconds     += self.rcudata.frames
             antenna.high_bad_seconds += bad_secs
             if val > self.lba.ant[ant].x.high_val:
@@ -296,202 +441,308 @@ class cLBA:
                 antenna.high_val   = val
                 antenna.high_ref   = ref
                 antenna.high_diff  = diff
-        
+
         for n in jitter:
             rcu, val, ref, bad_secs = n
             ant = rcu / 2
             logger.info("RCU %d Ant %d Jitter, fluctuation=%3.1fdB  normal=%3.1fdB" %(rcu, self.lba.ant[ant].nr_pvss, val, ref))
-            
-            if rcu%2 == 0:                             
+
+            self.rcudata.add_to_rcu_mask(rcu)
+            if rcu%2 == 0:
                 antenna = self.lba.ant[ant].x
-            else:                          
-                antenna = self.lba.ant[ant].y           
-            
+            else:
+                antenna = self.lba.ant[ant].y
+
             antenna.jitter_seconds     += self.rcudata.frames
             antenna.jitter_bad_seconds += bad_secs
             if val > antenna.jitter_val:
                 antenna.jitter     = 1
                 antenna.jitter_val = val
                 antenna.jitter_ref = ref
-        
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
-        self.lba.noise_check_done = 1        
+
+        self.lba.noise_check_done = 1
         self.db.addTestDone('NS%d=%d' %(mode, record_time))
         logger.info("=== Done %s noise test ===" %(self.lba.label))
-        return    
-    
+        return
+
     def checkSpurious(self, mode):
         logger.info("=== Start %s spurious test ===" %(self.lba.label))
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=12.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.lba.selectList())
-            self.lba.resetRcuState()
 
-        self.rcudata.setActiveRcus(self.lba.selectList())
-        self.rcudata.record(rec_time=2)
-        
+        self.set_mode(mode)
+        self.record_data(rec_time=3)
+            
         # result is a sorted list on maxvalue
         result = search_spurious(self.rcudata, 'XY', delta=3.0)
         for rcu in result:
             ant = rcu / 2
             ant_polarity  = rcu % 2
-            #self.turnOffAnt(ant)
+            #self. turnOffAnt(ant)
             logger.info("RCU %d Ant %d pol %d Spurious" %(rcu, self.lba.ant[ant].nr_pvss, ant_polarity))
+            
+            self.rcudata.add_to_rcu_mask(rcu)
             if ant_polarity == 0:
                 self.lba.ant[ant].x.spurious = 1
             else:
                 self.lba.ant[ant].y.spurious = 1
-        
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
-        self.lba.spurious_check_done = 1        
+
+        self.lba.spurious_check_done = 1
         self.db.addTestDone('SP%d' %(mode))
         logger.info("=== Done %s spurious test ===" %(self.lba.label))
-        return        
+        return
+
+    def checkShort(self, mode):
+        logger.info("=== Start %s Short test ===" %(self.lba.label))
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down, skip test")
+            return
+
+        if self.db.checkEndTime(duration=15.0) == False:
+            logger.warn("check stopped, end time reached")
+            return
+
+        self.set_mode(mode)
+        self.record_data(rec_time=3)
+            
+        # search for shorted cable (input), mean signal all subbands between 55 and 61 dB
+        logger.debug("Check Short")
+        short = searchShort(self.rcudata)
+        for i in short:
+            rcu, mean_val = i
+            ant = rcu / 2
+            pol = rcu % 2
+            
+            logger.info("%s %2d RCU %3d Short, mean value band=%5.1fdB" %\
+                       (self.lba.label, self.lba.ant[ant].nr_pvss, rcu, mean_val)) 
+            
+            self.rcudata.add_to_rcu_mask(rcu)
+            if pol == 0:
+                self.lba.ant[ant].x.short = 1;
+                self.lba.ant[ant].x.short_val = mean_val;
+            else:    
+                self.lba.ant[ant].y.short = 1;
+                self.lba.ant[ant].y.short_val = mean_val;
+
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down while testing, skip result")
+            return
+
+        self.lba.short_check_done = 1
+        self.db.addTestDone('SH%d' %(mode))
+        logger.info("=== Done %s Short test ===" %(self.lba.label))
+        return
+
+    def checkFlat(self, mode):
+        logger.info("=== Start %s Flat test ===" %(self.lba.label))
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down, skip test")
+            return
+
+        if self.db.checkEndTime(duration=15.0) == False:
+            logger.warn("check stopped, end time reached")
+            return
+            
+        self.set_mode(mode)
+        self.record_data(rec_time=3)
+        
+        # search for flatliners, mean signal all subbands between 63 and 65 dB
+        logger.debug("Check Flat")
+        flat = searchFlat(self.rcudata)
+        for i in flat:
+            rcu, mean_val = i
+            ant = rcu / 2
+            pol = rcu % 2
+            
+            logger.info("%s %2d RCU %3d Flat, mean value band=%5.1fdB" %\
+                       (self.lba.label, self.lba.ant[ant].nr_pvss, rcu, mean_val)) 
+            
+            self.rcudata.add_to_rcu_mask(rcu)
+            if pol == 0:
+                self.lba.ant[ant].x.flat = 1;
+                self.lba.ant[ant].x.flat_val = mean_val;
+            else:    
+                self.lba.ant[ant].y.flat = 1;
+                self.lba.ant[ant].y.flat_val = mean_val;
+                
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down while testing, skip result")
+            return
+
+        self.lba.flat_check_done = 1
+        self.db.addTestDone('F%d' %(mode))
+        logger.info("=== Done %s Flat test ===" %(self.lba.label))
+        return
+        
+        
+    def checkDown(self, mode, subband):
+        logger.info("=== Start %s Down test ===" %(self.lba.label))
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down, skip test")
+            return
+
+        if self.db.checkEndTime(duration=15.0) == False:
+            logger.warn("check stopped, end time reached")
+            return
+
+        self.set_mode(mode)
+        self.record_data(rec_time=3)
         
+        # mark lba as down if top of band is lower than normal and top is shifted more than 10 subbands to left or right
+        logger.debug("Check Down")
+        down, shifted = searchDown(self.rcudata, subband)
+        for i in down:
+            ant, max_x_sb, max_y_sb, mean_max_sb = i
+            max_x_offset = max_x_sb - mean_max_sb
+            max_y_offset = max_y_sb - mean_max_sb
+            
+            if self.lba.ant[ant].x.flat or self.lba.ant[ant].x.short or self.lba.ant[ant].y.flat or self.lba.ant[ant].y.short:
+                continue
+            
+            self.lba.ant[ant].x.offset = max_x_offset
+            self.lba.ant[ant].y.offset = max_y_offset
+            self.lba.ant[ant].down = 1
+            logger.info("%s %2d RCU %3d/%3d Down, offset-x=%d offset-y=%d" %\
+                       (self.lba.label, self.lba.ant[ant].nr_pvss, self.lba.ant[ant].x.rcu, self.lba.ant[ant].y.rcu, max_x_offset, max_y_offset))
+            self.rcudata.add_to_rcu_mask(self.lba.ant[ant].x.rcu)
+            self.rcudata.add_to_rcu_mask(self.lba.ant[ant].y.rcu)
+        for i in shifted:
+            rcu, max_sb, mean_max_sb = i
+            ant = rcu / 2
+            logger.info("%s %2d RCU %3d shifted top on sb=%d, normal=sb%d" %(self.lba.label, self.lba.ant[ant].nr_pvss, rcu, max_sb, mean_max_sb))
+
+        if not checkActiveRSPDriver():
+            logger.warn("RSPDriver down while testing, skip result")
+            return
+
+        self.lba.down_check_done = 1
+        self.db.addTestDone('D%d' %(mode))
+        logger.info("=== Done %s Down test ===" %(self.lba.label))
+        return
+        
+    
     def checkSignal(self, mode, subband, min_signal, low_deviation, high_deviation):
         logger.info("=== Start %s RF test ===" %(self.lba.label))
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=15.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            if mode < 3:
-                swapXY(state=1)
-            else:
-                swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.lba.selectList())
-            self.lba.resetRcuState()
 
-        self.rcudata.setActiveRcus(self.lba.selectList())   
-        self.rcudata.record(rec_time=5)
+        self.set_mode(mode)
+        self.record_data(rec_time=3)
+
         self.rcudata.searchTestSignal(subband=subband, minsignal=min_signal, maxsignal=90.0)
-        
+
         logger.info("For X used test subband=%d (%3.1f dB) in mode %d" %\
                      (self.rcudata.testSubband_X, self.rcudata.testSignal_X, mode))
         logger.info("For Y used test subband=%d (%3.1f dB) in mode %d" %\
-                     (self.rcudata.testSubband_Y, self.rcudata.testSignal_Y, mode))             
-        
+                     (self.rcudata.testSubband_Y, self.rcudata.testSignal_Y, mode))
+
         if self.rcudata.testSubband_X == 0 or self.rcudata.testSubband_Y == 0:
             logger.warn("LBA mode %d, No test signal found" %(mode))
             return
-        
+
         ssdataX = self.rcudata.getSubbandX()
         ssdataY = self.rcudata.getSubbandY()
         #if np.ma.count(ssdataX) == 0 or np.ma.count(ssdataY) == 0:
             # all zeros (missing settings!!)
         #    return
-            
-        # use only values between lowLimit and highLimit for average calculations    
+
+        # use only values between lowLimit and highLimit for average calculations
         dataInBandX = np.ma.masked_outside(ssdataX, (self.rcudata.testSignal_X + self.lowLimit), (self.rcudata.testSignal_X + self.highLimit))
         medianValX = np.ma.median(dataInBandX)
-        
+
         dataInBandY = np.ma.masked_outside(ssdataY, (self.rcudata.testSignal_Y + self.lowLimit), (self.rcudata.testSignal_Y + self.highLimit))
         medianValY = np.ma.median(dataInBandY)
-                
+
         logger.info("used medianValX=%f" %(medianValX))
         logger.info("used medianValY=%f" %(medianValY))
         if medianValX < self.meanLimit or medianValY < self.meanLimit:
             self.lba.avg_2_low = 1
             self.lba.avg_x = medianValX
             self.lba.avg_y = medianValY
-        
+
         self.lba.test_signal_x = medianValX
         self.lba.test_signal_y = medianValY
         self.lba.test_subband_x = self.rcudata.testSubband_X
         self.lba.test_subband_y = self.rcudata.testSubband_Y
-
+        
+        logger.debug("Check RF signal")
         for ant in self.lba.ant:
             ant.x.test_signal = ssdataX[ant.nr]
             ant.y.test_signal = ssdataY[ant.nr]
             
             loginfo = False
             if ssdataX[ant.nr] < (medianValX + low_deviation):
-                ant.x.too_low = 1
+                if not max(ant.x.flat, ant.x.short, ant.down):
+                    ant.x.too_low = 1
                 if ssdataX[ant.nr] < 2.0:
                     ant.x.rcu_error = 1
                 loginfo = True
-            
+
             if ssdataX[ant.nr] > (medianValX + high_deviation):
                 ant.x.too_high = 1
                 loginfo = True
-            
+
             if ssdataY[ant.nr] < (medianValY + low_deviation):
-                ant.y.too_low = 1
+                if not max(ant.y.flat, ant.y.short, ant.down):
+                    ant.y.too_low = 1
                 if ssdataY[ant.nr] < 2.0:
                     ant.y.rcu_error = 1
                 loginfo = True
-            
+
             if ssdataY[ant.nr] > (medianValY + high_deviation):
                 ant.y.too_high = 1
                 loginfo = True
-            
+
             if loginfo:
                 logger.info("%s %2d  RCU %3d/%3d   X=%5.1fdB  Y=%5.1fdB" %(self.lba.label, ant.nr_pvss, ant.x.rcu, ant.y.rcu, ssdataX[ant.nr], ssdataY[ant.nr]))
-                     
-        # mark lba as down if top of band is lower than normal and top is shifted more than 10 subbands to left or right
-        
-        down, shifted = searchDown(self.rcudata, subband)
-        for i in down:
-            ant, max_x_sb, max_y_sb, mean_max_sb = i
-            max_x_offset = max_x_sb - mean_max_sb
-            max_y_offset = max_y_sb - mean_max_sb
-            
-            self.lba.ant[ant].x.offset = max_x_offset
-            self.lba.ant[ant].y.offset = max_y_offset
-            self.lba.ant[ant].down = 1
-            logger.info("%s %2d RCU %3d/%3d Down, offset-x=%d offset-y=%d" %\
-                       (self.lba.label, self.lba.ant[ant].nr_pvss, self.lba.ant[ant].x.rcu, self.lba.ant[ant].y.rcu, max_x_offset, max_y_offset))
-        
-        for i in shifted:
-            rcu, max_sb, mean_max_sb = i
-            ant = rcu / 2
-            logger.info("%s %2d RCU %3d shifted top on sb=%d, normal=sb%d" %(self.lba.label, self.lba.ant[ant].nr_pvss, rcu, max_sb, mean_max_sb)) 
-        
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-        
+
         self.lba.signal_check_done = 1
         self.db.addTestDone('S%d' %(mode))
         logger.info("=== Done %s RF test ===" %(self.lba.label))
         return
-#### end of cLBA class ####        
+#### end of cLBA class ####
 
 
 # class for testing HBA antennas
 class cHBA:
-    global logger
+    #global logger
     def __init__(self, db, hba):
         self.db  = db
         self.hba = hba
         self.rcudata = cRCUdata(hba.nr_tiles*2)
+        self.rcudata.setActiveRcus(self.hba.selectList())
         self.rcumode = 0
-    
+
+    def reset(self):
+        self.rcudata.reset()
+        self.rcudata.reset_masks()
+        self.rcudata.setActiveRcus(self.hba.selectList())
+        
     def turnOnTiles(self):
         pass
-    
+
     def turnOffTile(self, tile_nr):
         tile = self.hba.tile[tile_nr]
         tile.x.rcu_off = 1
@@ -499,7 +750,7 @@ class cHBA:
         logger.info("turned off tile %d RCU(%d,%d)" %(tile.nr, tile.x.rcu, tile.y.rcu))
         rspctl("--rcumode=0 --select=%d,%d" %(tile.x.rcu, tile.y.rcu), wait=2.0)
         return
-   
+
     def turnOffBadTiles(self):
         for tile in self.hba.tile:
             if tile.x.rcu_off and tile.y.rcu_off:
@@ -514,7 +765,21 @@ class cHBA:
             if tile.x.osc or tile.y.osc or (no_modem >= 8) or (modem_error >= 8):
                 self.turnOffTile(tile.nr)
         return
-    
+
+    def set_mode(self, mode):
+        if self.db.rcumode != mode:
+            self.db.rcumode = mode
+            turnoffRCUs()
+            turnonRCUs(mode=mode, rcus=self.hba.selectList())
+            self.hba.resetRcuState()
+            self.rcudata.reset()
+        
+    def record_data(self, rec_time, new_data=False):
+        if new_data or self.rcudata.isActiveRcusChanged() or self.rcudata.getRecTime() < rec_time:
+            logger.debug('record info changed')
+            self.rcudata.resetActiveRcusChanged()
+            self.rcudata.record(rec_time=rec_time)
+
     def checkModem(self, mode):
         # setup internal test db
         n_elements = 16
@@ -529,23 +794,18 @@ class cHBA:
                 tile.append(test)
             modem_tst.append(tile)
         # done
-        
+
         logger.info("=== Start HBA modem test ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
-            return
-        
-        if self.db.checkEndTime(duration=50.0) == False:
-            logger.warn("check stopped, end time reached")
-            return
-        
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
-        
+            return
+
+        if self.db.checkEndTime(duration=50.0) == False:
+            logger.warn("check stopped, end time reached")
+            return
+
+        self.set_mode(mode)
+
         time.sleep(4.0)
         ctrlstr = list()
         ctrlstr.append(('129,'* 16)[:-1]) # 0ns
@@ -558,33 +818,35 @@ class cHBA:
         #rsp_hba_delay(delay=ctrlstr[6], rcus=self.hba.selectList(), discharge=False)
         tst_nr = 0
         for ctrl in ctrlstr:
-            
+
             rsp_hba_delay(delay=ctrl, rcus=self.hba.selectList(), discharge=False)
             data = rspctl('--realdelays', wait=1.0).splitlines()
-            
+
             ctrllist = ctrl.split(',')
             for line in data:
                 if line[:3] == 'HBA':
                     rcu = int(line[line.find('[')+1:line.find(']')])
                     hba_nr = rcu / 2
+                    if self.hba.tile[hba_nr].on_bad_list:
+                        continue
                     ant_polarity = rcu % 2
                     realctrllist = line[line.find('=')+1:].strip().split()
                     for elem in self.hba.tile[hba_nr].element:
                         if ctrllist[elem.nr-1] != realctrllist[elem.nr-1]:
                             logger.info("Modemtest Tile=%d RCU=%d Element=%d ctrlword=%s response=%s" %\
                                          (hba_nr, rcu, elem.nr, ctrllist[elem.nr-1], realctrllist[elem.nr-1]))
-                            
+
                             if realctrllist[elem.nr-1].count('?') == 3:
                                 #elem.no_modem += 1
-                                modem_tst[hba_nr][elem.nr-1][tst_nr][0] = 1 
+                                modem_tst[hba_nr][elem.nr-1][tst_nr][0] = 1
                             else:
                                 #elem.modem_error += 1
-                                modem_tst[hba_nr][elem.nr-1][tst_nr][1] = 1 
+                                modem_tst[hba_nr][elem.nr-1][tst_nr][1] = 1
             tst_nr += 1
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-        
+
         # analyse test results and add to DB
         no_modem    = dict()
         modem_error = dict()
@@ -601,7 +863,7 @@ class cHBA:
                         n_modem_error[elem_nr] += 1
                 no_modem[tile_nr]  = n_no_modem
                 modem_error[tile_nr] = n_modem_error
-                
+
         n_tile_err = 0
         for tile in no_modem:
             n_elem_err = 0
@@ -631,57 +893,52 @@ class cHBA:
                 for elem_nr in range(n_elements):
                     if no_modem[tile_nr][elem_nr] > 3: # more than 3 ctrl values went wrong
                         self.db.hba.tile[tile_nr].element[elem_nr].modem_error = 1
-        
+
         self.hba.modem_check_done = 1
-        self.db.addTestDone('M')
+        self.db.addTestDone('M%d' % mode)
         logger.info("=== Done HBA modem test ===")
         #self.db.rcumode = 0
         return
-        
+
     # check for summator noise and turn off RCU
     def checkSummatorNoise(self, mode):
         logger.info("=== Start HBA tile based summator-noise test ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=25.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
-            
+
+        self.set_mode(mode)
+
         delay_str = ('253,'* 16)[:-1]
         rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-        self.rcudata.setActiveRcus(self.hba.selectList())   
-        self.rcudata.record(rec_time=15)
         
+        self.record_data(rec_time=12)
+
         for pol_nr, pol in enumerate(('X', 'Y')):
-            sum_noise, cable_reflection = search_summator_noise(data=self.rcudata, pol=pol, min_peak=0.7)
+            sum_noise, cable_reflection = search_summator_noise(data=self.rcudata, pol=pol, min_peak=0.8)
             for n in sum_noise:
                 bin_nr, cnt, n_peaks = n
                 tile = bin_nr
                 logger.info("RCU %d Tile %d Summator-Noise cnt=%3.1f peaks=%3.1f" %(self.hba.tile[tile].x.rcu, tile, cnt, n_peaks))
                 if pol == 'X':
                     self.hba.tile[tile].x.summator_noise = 1
-                else:    
+                else:
                     self.hba.tile[tile].y.summator_noise = 1
                 self.turnOffTile(tile)
 
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
-        self.hba.summatornoise_check_done = 1    
-        self.db.addTestDone('SN')
+
+        self.hba.summatornoise_check_done = 1
+        self.db.addTestDone('SN%d' %(mode))
         logger.info("=== Done HBA tile based summator-noise test ===")
         return
-    
+
     # check for oscillating tiles and turn off RCU
     # stop one RCU each run
     def checkOscillation(self, mode):
@@ -689,21 +946,16 @@ class cHBA:
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=35.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
-        
+
+        self.set_mode(mode)
+
         delay_str = ('253,'* 16)[:-1]
-        rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-        
+        get_new_data = rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
+
         clean = False
         while not clean:
             if self.db.checkEndTime(duration=25.0) == False:
@@ -711,74 +963,76 @@ class cHBA:
                 return
 
             clean = True
-            self.rcudata.setActiveRcus(self.hba.selectList())
-            self.rcudata.record(rec_time=8)
             
-            # result is a sorted list on maxvalue
-            result = search_oscillation(data=self.rcudata, pol='XY', delta=6.0) # start_sb=45, stop_sb=350
-            if len(result) > 1:
-                if len(result) == 2:
-                    rcu, max_sum, n_peaks, rcu_low = result[1]
-                else:
-                    ref_low = result[0][3]
-                    max_low_rcu = (-1, -1)
-                    max_sum_rcu = (-1, -1)
-                    for i in result[1:]:
-                        rcu, max_sum, n_peaks, rcu_low = i
-                        if max_sum > max_sum_rcu[0]: max_sum_rcu = (max_sum, rcu) 
-                        if (rcu_low - ref_low) > max_low_rcu[0]: max_low_rcu = (rcu_low, rcu)
+            self.record_data(rec_time=12, new_data=get_new_data)
+            
+            for pol_nr, pol in enumerate(('X', 'Y')):
+                # result is a sorted list on maxvalue
+                result = search_oscillation(data=self.rcudata, pol=pol, delta=6.0) # start_sb=45, stop_sb=350
+                if len(result) > 1:
+                    if len(result) == 2:
+                        tile, max_sum, n_peaks, rcu_low = result[1]
+                    else:
+                        ref_low = result[0][3]
+                        max_low_tile = (-1, -1)
+                        max_sum_tile = (-1, -1)
+                        for i in result[1:]:
+                            tile, max_sum, n_peaks, tile_low = i
+                            #rcu = (tile * 2) + pol_nr
+                            if max_sum > max_sum_tile[0]:
+                                max_sum_tile = (max_sum, tile)
+                            if (tile_low - ref_low) > max_low_tile[0]:
+                                max_low_tile = (tile_low, tile)
+
+                        rcu_low, tile = max_low_tile
                     
-                    rcu_low, rcu = max_low_rcu
-                clean = False        
-                tile = rcu / 2
-                tile_polarity  = rcu % 2        
-                logger.info("RCU %d Tile %d Oscillation sum=%3.1f peaks=%d low=%3.1f" %\
-                           (rcu, tile, max_sum, n_peaks, rcu_low))
-                self.turnOffTile(tile)
-                if tile_polarity == 0:
-                    self.hba.tile[tile].x.osc = 1
-                else:
-                    self.hba.tile[tile].y.osc = 1
-               
+                    clean = False
+                    get_new_data = True
+                    #tile = rcu / 2
+                    #tile_polarity  = rcu % 2
+                    rcu = (tile * 2) + pol_nr
+                    logger.info("RCU %d Tile %d Oscillation sum=%3.1f peaks=%d low=%3.1f" %\
+                               (rcu, tile, max_sum, n_peaks, tile_low))
+                    self.turnOffTile(tile)
+                    if pol_nr == 0:
+                        self.hba.tile[tile].x.osc = 1
+                    else:
+                        self.hba.tile[tile].y.osc = 1
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-        
+
         self.hba.oscillation_check_done = 1
         self.db.addTestDone('O%d' %(mode))
         logger.info("=== Done HBA tile based oscillation test ===")
         return
- 
+
     def checkNoise(self, mode, record_time, low_deviation, high_deviation, max_diff):
         logger.info("=== Start HBA tile based noise test ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=(record_time+60.0)) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
-        
+
+        self.set_mode(mode)
+
         for tile in self.hba.tile:
             if tile.x.rcu_off or tile.y.rcu_off:
                 logger.info("skip low-noise test for tile %d, RCUs turned off" %(tile.nr))
-                
+
         delay_str = ('253,'* 16)[:-1]
-        rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-        self.rcudata.setActiveRcus(self.hba.selectList())
-        self.rcudata.record(rec_time=record_time)
+        get_new_data = rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
         
+        self.record_data(rec_time=record_time, new_data=get_new_data)
+
         for pol_nr, pol in enumerate(('X', 'Y')):
             # result is a sorted list on maxvalue
             low_noise, high_noise, jitter = search_noise(self.rcudata, pol, low_deviation, high_deviation, max_diff)
-            
+
             for n in low_noise:
                 bin_nr, val, bad_secs, ref, diff = n
                 tile = bin_nr
@@ -787,7 +1041,7 @@ class cHBA:
                     continue
                 logger.info("RCU %d Tile %d Low-Noise value=%3.1f bad=%d(%d) limit=%3.1f diff=%3.3f" %\
                            (rcu, tile, val, bad_secs, self.rcudata.frames, ref, diff))
-                
+
                 if pol == 'X':
                     tile_polarity = self.hba.tile[tile].x
                 else:
@@ -800,76 +1054,71 @@ class cHBA:
                     tile_polarity.low_val   = val
                     tile_polarity.low_ref   = ref
                     tile_polarity.low_diff  = diff
-                    
-            for n in high_noise:    
+
+            for n in high_noise:
                 bin_nr, val, bad_secs, ref, diff = n
                 tile = bin_nr
                 rcu = (tile * 2) + pol_nr
                 logger.info("RCU %d Tile %d High-Noise value=%3.1f bad=%d(%d) limit=%3.1f diff=%3.1f" %\
                            (rcu, tile, val, bad_secs, self.rcudata.frames, ref, diff))
-                
+
                 if pol == 'X':
                     tile_polarity = self.hba.tile[tile].x
                 else:
                     tile_polarity = self.hba.tile[tile].y
-                    
+
                 tile_polarity.high_seconds     += self.rcudata.frames
-                tile_polarity.high_bad_seconds += bad_secs    
+                tile_polarity.high_bad_seconds += bad_secs
                 if val > tile_polarity.high_val:
                     tile_polarity.high_noise = 1
                     tile_polarity.high_val   = val
                     tile_polarity.high_ref   = ref
                     tile_polarity.high_diff  = diff
-            
+
             for n in jitter:
                 bin_nr, val, ref, bad_secs = n
                 tile = bin_nr
                 rcu = (tile * 2) + pol_nr
                 logger.info("RCU %d Tile %d Jitter, fluctuation=%3.1fdB  normal=%3.1fdB" %(rcu, tile, val, ref))
-                
+
                 if pol == 'X':
                     tile_polarity = self.hba.tile[tile].x
                 else:
                     tile_polarity = self.hba.tile[tile].y
-                
-                tile_polarity.jitter_seconds     += self.rcudata.frames 
-                tile_polarity.jitter_bad_seconds += bad_secs 
+
+                tile_polarity.jitter_seconds     += self.rcudata.frames
+                tile_polarity.jitter_bad_seconds += bad_secs
                 if val > tile_polarity.jitter_val:
                     tile_polarity.jitter     = 1
                     tile_polarity.jitter_val = val
                     tile_polarity.jitter_ref = ref
-            
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
+
         self.hba.noise_check_done = 1
         self.db.addTestDone('NS%d=%d' %(mode, record_time))
         logger.info("=== Done HBA tile based noise test ===")
-        return    
-  
+        return
+
     def checkSpurious(self, mode):
         logger.info("=== Start HBA tile based spurious test ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=12.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
+
+        self.set_mode(mode)
 
         delay_str = ('253,'* 16)[:-1]
-        rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-        self.rcudata.setActiveRcus(self.hba.selectList())    
-        self.rcudata.record(rec_time=2)
+        get_new_data = rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
         
+        self.record_data(rec_time=12, new_data=get_new_data)
+
         for pol_nr, pol in enumerate(('X', 'Y')):
             # result is a sorted list on maxvalue
             result = search_spurious(self.rcudata, pol, delta=3.0)
@@ -881,40 +1130,35 @@ class cHBA:
                     self.hba.tile[tile].x.spurious = 1
                 else:
                     self.hba.tile[tile].y.spurious = 1
-            
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-        
+
         self.hba.spurious_check_done = 1
         self.db.addTestDone('SP%d' %(mode))
         logger.info("=== Done HBA spurious test ===")
-        return    
-    
+        return
+
     def checkSignal(self, mode, subband, min_signal, low_deviation, high_deviation):
         logger.info("=== Start HBA tile based RF test ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-            
+
         if self.db.checkEndTime(duration=37.0) == False:
             logger.warn("check stopped, end time reached")
             return
-            
-        if self.db.rcumode != mode:
-            self.db.rcumode = mode
-            swapXY(state=0)
-            turnoffRCUs()
-            turnonRCUs(mode=mode, rcus=self.hba.selectList())
-            self.hba.resetRcuState()
-        
+
+        self.set_mode(mode)
+
         # check twice
         # 128 ...
         # 253 ...
         for tile in self.hba.tile:
             if tile.x.rcu_off or tile.y.rcu_off:
                 logger.info("skip signal test for tile %d, RCUs turned off" %(tile.nr))
-                    
+
         logger.info("start test")
         for ctrl in ('128,', '253,'):
             if self.db.checkEndTime(duration=20.0) == False:
@@ -923,48 +1167,48 @@ class cHBA:
 
             if ctrl == '128,': ctrl_nr = 0
             elif ctrl == '253,': ctrl_nr = 1
-                
+
             logger.info("HBA signal test, ctrl word %s" %(ctrl[:-1]))
 
             delay_str = (ctrl*16)[:-1]
             rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-            self.rcudata.setActiveRcus(self.hba.selectList())
-            self.rcudata.record(rec_time=2)
+            
+            self.record_data(rec_time=2, new_data=True)
             self.rcudata.searchTestSignal(subband=subband, minsignal=min_signal, maxsignal=150.0)
             logger.info("HBA, X used test subband=%d  avg_signal=%3.1f" %(self.rcudata.testSubband_X, self.rcudata.testSignal_X))
             logger.info("HBA, Y used test subband=%d  avg_signal=%3.1f" %(self.rcudata.testSubband_Y, self.rcudata.testSignal_Y))
-            
+
             if (self.rcudata.testSignal_X != -1) and (self.rcudata.testSignal_Y != -1):
-                
+
                 self.hba.ref_signal_x[ctrl_nr]   = self.rcudata.testSignal_X
                 self.hba.ref_signal_y[ctrl_nr]   = self.rcudata.testSignal_Y
                 self.hba.test_subband_x[ctrl_nr] = self.rcudata.testSubband_X
                 self.hba.test_subband_y[ctrl_nr] = self.rcudata.testSubband_Y
-                
+
                 ssdataX = self.rcudata.getSubbandX()
                 ssdataY = self.rcudata.getSubbandY()
                 avgX = self.rcudata.testSignal_X
                 avgY = self.rcudata.testSignal_Y
                 minX = ssdataX.min()
                 minY = ssdataY.min()
-                
+
                 # if all elements in range
                 #if minX < (avgX + self.min_dB) and minY < (avgY + self.min_dB):
                 #    continue
-                    
+
                 logger.debug("X data:  min=%5.3f  max=%5.3f  avg=%5.3f" %(minX, ssdataX.max(), avgX))
                 logger.debug("Y data:  min=%5.3f  max=%5.3f  avg=%5.3f" %(minY, ssdataY.max(), avgY))
-                                
+
                 for tile in self.hba.tile:
                     if tile.x.rcu_off or tile.y.rcu_off:
                         continue
-                        
+
                     logger.debug("HBA Tile=%d :  X=%3.1fdB  Y=%3.1fdB" %\
                                 (tile.nr, ssdataX[tile.nr], ssdataY[tile.nr]))
-                                    
+
                     tile.x.test_signal[ctrl_nr] = ssdataX[tile.nr]
                     tile.y.test_signal[ctrl_nr] = ssdataY[tile.nr]
-                    
+
                     loginfo = False
                     if ssdataX[tile.nr] < (avgX + low_deviation):
                         if ssdataX[tile.nr] < 2.0:
@@ -974,11 +1218,11 @@ class cHBA:
                         else:
                             tile.x.too_low = 1
                         loginfo = True
-                        
+
                     if ssdataX[tile.nr] > (avgX + high_deviation):
                         tile.x.too_high = 1
                         loginfo = True
-    
+
                     if ssdataY[tile.nr] < (avgY + low_deviation):
                         if ssdataY[tile.nr] < 2.0:
                             tile.y.no_signal = 1
@@ -987,30 +1231,30 @@ class cHBA:
                         else:
                             tile.y.too_low = 1
                         loginfo = True
-                        
+
                     if ssdataY[tile.nr] > (avgY + high_deviation):
                         tile.y.too_high = 1
                         loginfo = True
-                        
-                    if loginfo:    
+
+                    if loginfo:
                         logger.info("HBA Tile=%d  Error:  X=%3.1fdB  Y=%3.1fdB" %\
                                      (tile.nr, ssdataX[tile.nr], ssdataY[tile.nr]))
             else:
                 logger.warn("HBA, No valid test signal")
-                
+
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-        
+
         self.hba.signal_check_done = 1
         self.db.addTestDone('S%d' %(mode))
         logger.info("=== Done HBA signal test ===")
         return
-    
+
     # Next tests are element based
     #
-    # 8bit control word 
-    # 
+    # 8bit control word
+    #
     # bit-7  RF on/off   1 = on
     # bit-6  delay       1 = 8 ns
     # bit-5  delay       1 = 4 ns
@@ -1025,27 +1269,23 @@ class cHBA:
     #
     def checkElements(self, mode, record_time, subband,
                       noise_low_deviation, noise_high_deviation, noise_max_diff,
-                      rf_min_signal, rf_low_deviation, rf_high_deviation,
-                      skip_signal_test=False):
-                      
+                      rf_min_signal, rf_low_deviation, rf_high_deviation):
+
         logger.info("=== Start HBA element based tests ===")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
             return
-        self.db.rcumode = mode
-        swapXY(state=0)
-        turnoffRCUs()
-        turnonRCUs(mode=mode, rcus=self.hba.selectList())
-        self.hba.resetRcuState()
-       
+        
+        self.set_mode(mode)
+
         n_rcus_off  = 0
         for ctrl in ('128', '253'):
             if ctrl == '128': ctrl_nr = 0
             elif ctrl == '253': ctrl_nr = 1
-             
+
             for elem in range(self.hba.tile[0].nr_elements):
                 logger.info("check elements %d, ctrlword=%s" %(elem+1, ctrl))
-                
+
                 if self.db.checkEndTime(duration=45.0) == False:
                     logger.warn("check stopped, end time reached")
                     return
@@ -1058,10 +1298,10 @@ class cHBA:
                         self.turnOffTile(tile.nr)
                         n_rcus_off += 1
                         logger.info("skip tile %d, modem error" %(tile.nr))
-                        
+
                 delay_str = ('2,'*elem + ctrl + ',' + '2,'*15)[:33]
                 rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-                
+
                 clean = False
                 while not clean:
                     if self.db.checkEndTime(duration=(record_time+45.0)) == False:
@@ -1069,9 +1309,8 @@ class cHBA:
                         return
 
                     clean = True
-                    self.rcudata.setActiveRcus(self.hba.selectList())
-                    self.rcudata.record(rec_time=record_time)
-                    
+                    self.record_data(rec_time=record_time)
+
                     clean, n_off = self.checkOscillationElements(elem)
                     n_rcus_off += n_off
                     if n_off > 0: continue
@@ -1079,69 +1318,17 @@ class cHBA:
                     n_rcus_off += n_off
                     if n_off > 0: continue
                     self.checkNoiseElements(elem, noise_low_deviation, noise_high_deviation, noise_max_diff)
-                    if not skip_signal_test:
-                        self.checkSignalElements(elem, ctrl_nr, subband, rf_min_signal, rf_low_deviation, rf_high_deviation)
-                    else:
-                        logger.info("skip signal test for mode %d" %(mode))
+                    self.checkSignalElements(elem, ctrl_nr, subband, rf_min_signal, rf_low_deviation, rf_high_deviation)
 
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down while testing, skip result")
             return
-            
-        self.hba.element_check_done = 1
-        self.db.addTestDone('EHBA')
-        logger.info("=== Done HBA element tests ===")
-        return
-    
-    # Do a complete element test testing only the signal
-    def checkElementsSignal(self, mode, subband, rf_min_signal, rf_low_deviation, rf_high_deviation):
-                      
-        logger.info("=== Start HBA element based signal test in mode %d ===" %(mode))
-        if not checkActiveRSPDriver():
-            logger.warn("RSPDriver down, skip test")
-            return
-        
-        if self.db.checkEndTime(duration=45.0) == False:
-            logger.warn("check stopped, end time reached")
-            return    
-            
-        self.db.rcumode = mode
-        swapXY(state=0)
-        turnoffRCUs()
-        turnonRCUs(mode=mode, rcus=self.hba.selectList())
-        self.hba.resetRcuState()
-        
-        n_rcus_off  = 0
-        for ctrl in ('129', '253'):
-            if ctrl == '129': ctrl_nr = 0
-            elif ctrl == '253': ctrl_nr = 1
-            
-            for elem in range(self.hba.tile[0].nr_elements):
-                logger.info("check elements %d, ctrlword=%s" %(elem+1, ctrl))
-                if n_rcus_off > 0:
-                    rsp_rcu_mode(mode=mode, rcus=self.hba.selectList())
-                    n_rcus_off = 0
-                for tile in self.hba.tile:
-                    if tile.element[elem].no_modem or tile.element[elem].modem_error:
-                        self.turnOffTile(tile.nr)
-                        n_rcus_off += 1
-                        logger.info("skip tile %d, modem error" %(tile.nr))
-                
-                delay_str = ('2,'*elem + ctrl + ',' + '2,'*15)[:33]
-                rsp_hba_delay(delay=delay_str, rcus=self.hba.selectList())
-                self.rcudata.setActiveRcus(self.hba.selectList())
-                self.rcudata.record(rec_time=2)
-                self.checkSignalElements(elem, ctrl_nr, subband, rf_min_signal, rf_low_deviation, rf_high_deviation)
 
-        if not checkActiveRSPDriver():
-            logger.warn("RSPDriver down while testing, skip result")
-            return
-            
         self.hba.element_check_done = 1
-        self.db.addTestDone('ES%d' %(mode))
+        self.db.addTestDone('E%d' %(mode))
         logger.info("=== Done HBA element tests ===")
         return
-        
+
     # check for oscillating tiles and turn off RCU
     # stop one RCU each run
     # elem counts from 0..15 (for user output use 1..16)
@@ -1170,7 +1357,7 @@ class cHBA:
             else:
                 self.hba.tile[tile].element[elem].y.osc = 1
         return (clean, n_rcus_off)
-    
+
     def checkSpuriousElements(self, elem):
         logger.info("--- spurious test ---")
         if not checkActiveRSPDriver():
@@ -1189,8 +1376,8 @@ class cHBA:
                 self.hba.tile[tile].element[elem].x.spurious = 1
             else:
                 self.hba.tile[tile].element[elem].y.spurious = 1
-        return (n_rcus_off)   
-    
+        return (n_rcus_off)
+
     def checkNoiseElements(self, elem, low_deviation, high_deviation, max_diff):
         logger.info("--- noise test ---")
         if not checkActiveRSPDriver():
@@ -1198,17 +1385,17 @@ class cHBA:
             return
         # result is a sorted list on maxvalue
         low_noise, high_noise, jitter = search_noise(self.rcudata, 'XY', low_deviation, high_deviation, max_diff)
-        
+
         for n in low_noise:
             rcu, val, bad_secs, ref, diff = n
             tile = rcu / 2
             logger.info("RCU %d Tile %d Element %d Low-Noise value=%3.1f bad=%d(%d) limit=%3.1f diff=%3.3f" %\
                        (rcu, tile, elem+1, val, bad_secs, self.rcudata.frames, ref, diff))
-            
+
             if rcu%2 == 0:
-                elem_polarity = self.hba.tile[tile].element[elem].x 
+                elem_polarity = self.hba.tile[tile].element[elem].x
             else:
-                elem_polarity = self.hba.tile[tile].element[elem].y 
+                elem_polarity = self.hba.tile[tile].element[elem].y
 
             elem_polarity.low_seconds     += self.rcudata.frames
             elem_polarity.low_bad_seconds += bad_secs
@@ -1217,18 +1404,18 @@ class cHBA:
                 elem_polarity.low_val   = val
                 elem_polarity.low_ref   = ref
                 elem_polarity.low_diff  = diff
-                
-        for n in high_noise:    
+
+        for n in high_noise:
             rcu, val, bad_secs, ref, diff = n
             tile = rcu / 2
             logger.info("RCU %d Tile %d Element %d High-Noise value=%3.1f bad=%d(%d) ref=%3.1f diff=%3.1f" %\
                        (rcu, tile, elem+1, val, bad_secs, self.rcudata.frames, ref, diff))
-            
+
             if rcu%2 == 0:
-                elem_polarity = self.hba.tile[tile].element[elem].x 
+                elem_polarity = self.hba.tile[tile].element[elem].x
             else:
-                elem_polarity = self.hba.tile[tile].element[elem].y 
-            
+                elem_polarity = self.hba.tile[tile].element[elem].y
+
             elem_polarity.high_seconds     += self.rcudata.frames
             elem_polarity.high_bad_seconds += bad_secs
             if val > elem_polarity.high_val:
@@ -1236,28 +1423,28 @@ class cHBA:
                 elem_polarity.high_val   = val
                 elem_polarity.high_ref   = ref
                 elem_polarity.high_diff  = diff
-        
+
         for n in jitter:
             rcu, val, ref, bad_secs = n
             tile = rcu / 2
             logger.info("RCU %d Tile %d Element %d Jitter, fluctuation=%3.1fdB  normal=%3.1fdB" %\
                        (rcu, tile, elem+1, val, ref))
-            
+
             if rcu%2 == 0:
-                elem_polarity = self.hba.tile[tile].element[elem].x 
+                elem_polarity = self.hba.tile[tile].element[elem].x
             else:
-                elem_polarity = self.hba.tile[tile].element[elem].y 
-            
-            elem_polarity.jitter_seconds     += self.rcudata.frames    
-            elem_polarity.jitter_bad_seconds += bad_secs    
+                elem_polarity = self.hba.tile[tile].element[elem].y
+
+            elem_polarity.jitter_seconds     += self.rcudata.frames
+            elem_polarity.jitter_bad_seconds += bad_secs
             if val > elem_polarity.jitter_val:
                 elem_polarity.jitter     = 1
                 elem_polarity.jitter_val = val
                 elem_polarity.jitter_ref = ref
-        return    
-    
+        return
+
     def checkSignalElements(self, elem, ctrl_nr, subband, min_signal, low_deviation, high_deviation):
-        
+
         logger.info("--- RF test ---")
         if not checkActiveRSPDriver():
             logger.warn("RSPDriver down, skip test")
@@ -1265,28 +1452,28 @@ class cHBA:
         self.rcudata.searchTestSignal(subband=subband, minsignal=min_signal, maxsignal=120.0)
         logger.info("HBA, X used test subband=%d  avg_signal=%3.1f" %(self.rcudata.testSubband_X, self.rcudata.testSignal_X))
         logger.info("HBA, Y used test subband=%d  avg_signal=%3.1f" %(self.rcudata.testSubband_Y, self.rcudata.testSignal_Y))
-        
+
         ssdataX = self.rcudata.getSubbandX()
         ssdataY = self.rcudata.getSubbandY()
         avgX = self.rcudata.testSignal_X
         avgY = self.rcudata.testSignal_Y
         minX = ssdataX.min()
         minY = ssdataY.min()
-        
+
         logger.debug("X data:  min=%5.3f  max=%5.3f  avg=%5.3f" %(minX, ssdataX.max(), avgX))
         logger.debug("Y data:  min=%5.3f  max=%5.3f  avg=%5.3f" %(minY, ssdataY.max(), avgY))
-        
+
         for tile in self.hba.tile:
             if tile.x.rcu_off or tile.y.rcu_off:
                 logger.info("skip signal test for tile %d, RCUs are turned off" %(tile.nr))
- 
-        if self.rcudata.testSubband_X == 0 or self.rcudata.testSubband_X == 0:
+
+        if self.rcudata.testSubband_X == 0 or self.rcudata.testSubband_Y == 0:
             logger.warn("HBA, No valid test signal")
             for tile in self.hba.tile:
                 tile.element[elem].x.ref_signal[ctrl_nr] = 0
                 tile.element[elem].y.ref_signal[ctrl_nr] = 0
             return
-        
+
         for tile in self.hba.tile:
             if tile.x.rcu_off or tile.y.rcu_off:
                 continue
@@ -1296,7 +1483,7 @@ class cHBA:
             tile.element[elem].y.test_subband[ctrl_nr] = self.rcudata.testSubband_Y
             tile.element[elem].x.test_signal[ctrl_nr] = ssdataX[tile.nr]
             tile.element[elem].y.test_signal[ctrl_nr] = ssdataY[tile.nr]
-          
+
             #logger.debug("HBA Tile=%d  Element=%d:  X=%3.1fdB  Y=%3.1fdB" %\
             #            (tile.nr, elem+1, ssdataX[tile.nr], ssdataY[tile.nr]))
 
@@ -1309,7 +1496,7 @@ class cHBA:
                 else:
                     tile.element[elem].x.too_low = 1
                 loginfo = True
-                
+
             if ssdataX[tile.nr] > (avgX + high_deviation):
                 tile.element[elem].x.too_high = 1
                 loginfo = True
@@ -1322,15 +1509,15 @@ class cHBA:
                 else:
                     tile.element[elem].y.too_low = 1
                 loginfo = True
-                
+
             if ssdataY[tile.nr] > (avgY + high_deviation):
                 tile.element[elem].y.too_high = 1
                 loginfo = True
-            
-            if loginfo:    
+
+            if loginfo:
                 logger.info("HBA Tile=%d  Element=%d Error:  X=%3.1fdB  Y=%3.1fdB" %\
                              (tile.nr, elem+1, ssdataX[tile.nr], ssdataY[tile.nr]))
         return
-#### end of cHBA class ####        
-        
-        
+#### end of cHBA class ####
+
+
diff --git a/LCU/checkhardware/rtsm.py b/LCU/checkhardware/rtsm.py
index a53785ecd0d9f9032b25c9d0364e8c6a1b8bea19..6562eff80b64a712722e8ec7ffc719dfdf79e215 100755
--- a/LCU/checkhardware/rtsm.py
+++ b/LCU/checkhardware/rtsm.py
@@ -3,6 +3,7 @@
 check_version = '0714'
 
 import sys
+import traceback
 import os
 import numpy as np
 import time
@@ -36,25 +37,6 @@ if not os.access(rtsmPath, os.F_OK):
 
 logger = None
 
-# class holding active function (stage)
-class ERR:
-    stage = ""
-    last_stage = ""
-    @staticmethod
-    def setStage(stage):
-        ERR.last_stage = ERR.stage
-        ERR.stage = stage
-        return
-    @staticmethod
-    def setLastStage():
-        ERR.stage = ERR.last_stage
-        return
-    @staticmethod
-    def log():
-        if logger != None:
-            logger.warn("program error(%s) in stage %s" %(sys.exc_value, ERR.stage))
-        return
-
 def lbaMode(mode):
     if mode in (1, 2, 3, 4):
         return (True)
@@ -187,15 +169,15 @@ def init_logging(args):
     return (_logger)
 
 def getRcuMode():
-    ERR.setStage("getRcuMode")
     rcumode = -1
     rcu_info = {}
     answer = rspctl("--rcu")
     for line in answer.splitlines():
-        rcu   = int(line[4:6].strip())
-        state = line[30:33].strip()
-        mode  = int(line[40])
-        rcu_info[rcu] = (state, mode)
+        rcu   = line[line.find('[')+1 : line.find(']')].strip()
+        state = line[line.find('=>')+2 : line.find(',')].strip()
+        mode  = line[line.find('mode:')+5]
+        if rcu.isdigit() and state in ("OFF", "ON") and mode.isdigit():
+            rcu_info[int(rcu)] = (state, int(mode))
 
     for mode in range(8):
         mode_cnt = answer.count("mode:%d" %(mode))
@@ -206,18 +188,15 @@ def getRcuMode():
         elif (mode_cnt > 32) and answer.count("mode:0") == (96 - mode_cnt):
             logger.debug("Now observing in rcumode %d" %(mode))
             rcumode = mode
-    ERR.setLastStage()
     return (rcumode, rcu_info)
 
 def getAntPol(rcumode, rcu):
-    ERR.setStage("getAntPol")
     pol_str = ('X','Y')
     ant = rcu / 2
     if rcumode == 1:
         pol_str = ('Y','X')
         ant += 48
     pol = pol_str[rcu % 2]
-    ERR.setLastStage()
     return (ant, pol)
 
 class CSV:
@@ -228,30 +207,23 @@ class CSV:
     record_timestamp = 0
     @staticmethod
     def setObsID(obs_id):
-        ERR.setStage("CSV.setObsID")
         CSV.station  = getHostName()
         CSV.obs_id   = obs_id
         CSV.filename = "%s_%s_open.dat" %(CSV.station, CSV.obs_id)
         CSV.rcu_mode = 0
         CSV.rec_timestamp = 0
         CSV.writeHeader()
-        ERR.setLastStage()
         return
     @staticmethod
     def setRcuMode(rcumode):
-        ERR.setStage("CSV.setRcuMode")
         CSV.rcu_mode = rcumode
-        ERR.setLastStage()
         return
     @staticmethod
     def setRecordTimestamp(timestamp):
-        ERR.setStage("CSV.setRecordTimestamp")
         CSV.record_timestamp = timestamp
-        ERR.setLastStage()
         return
     @staticmethod
     def writeHeader():
-        ERR.setStage("CSV.writeHeader")
         full_filename = os.path.join(rtsmPath, CSV.filename)
         # write only if new file
         if not os.path.exists(full_filename):
@@ -260,11 +232,9 @@ class CSV:
             f.write('#\n')
             f.flush()
             f.close()
-        ERR.setLastStage()
         return
     @staticmethod
     def writeSpectra(data, rcu, check):
-        ERR.setStage("CSV.writeSpectra")
         dumpTime = time.gmtime(CSV.record_timestamp)
         date_str = time.strftime("%Y%m%d", dumpTime)
 
@@ -301,11 +271,9 @@ class CSV:
         f.write(bad_spectra)
 
         f.close()
-        ERR.setLastStage()
         return
     @staticmethod
     def writeInfo(start_time, stop_time, obsid_samples):
-        ERR.setStage("CSV.writeInfo")
         full_filename = os.path.join(rtsmPath, CSV.filename)
         logger.debug("add obs_info to %s" %(full_filename))
         f = open(full_filename, 'a')
@@ -313,11 +281,9 @@ class CSV:
         f.write('OBS-ID-INFO=%s,%5.3f,%5.3f,%d\n\n' %(CSV.obs_id, start_time, stop_time, obsid_samples))
         f.flush()
         f.close()
-        ERR.setLastStage()
         return
     @staticmethod
     def closeFile():
-        ERR.setStage("CSV.closeFile")
         full_filename = os.path.join(rtsmPath, CSV.filename)
         filename_new = CSV.filename.replace('open','closed')
         full_filename_new = os.path.join(rtsmPath, filename_new)
@@ -325,11 +291,9 @@ class CSV:
         os.rename(full_filename, full_filename_new)
         CSV.obs_id = ""
         CSV.filename = ""
-        ERR.setLastStage()
         return
 
 def checkForOscillation(data, rcumode, error_list, delta):
-    ERR.setStage("checkForOscillation")
     logger.debug("start oscillation check")
     for pol_nr, pol in enumerate(('X', 'Y')):
         #test_data = data.getAll()[:,:1,:]
@@ -373,7 +337,6 @@ def checkForOscillation(data, rcumode, error_list, delta):
     return
 
 def checkForNoise(data, rcumode, error_list, low_deviation, high_deviation, max_diff):
-    ERR.setStage("checkForNoise")
     logger.debug("start noise check")
     for pol_nr, pol in enumerate(('X', 'Y')):
         low_noise, high_noise, jitter = search_noise(data, pol, low_deviation, high_deviation*1.5, max_diff)
@@ -416,7 +379,6 @@ def checkForNoise(data, rcumode, error_list, low_deviation, high_deviation, max_
     return
 
 def checkForSummatorNoise(data, rcumode, error_list):
-    ERR.setStage("checkForSummatorNoise")
     logger.debug("start summator-noise check")
     for pol_nr, pol in enumerate(('X', 'Y')):
         # sn=SummatorNoise  cr=CableReflections
@@ -442,7 +404,6 @@ def checkForSummatorNoise(data, rcumode, error_list):
     return
 
 def checkForDown(data, rcumode, error_list, subband):
-    ERR.setStage("checkForDown")
     logger.debug("start down check")
     down, shifted = searchDown(data, subband)
     for msg in down:
@@ -455,22 +416,38 @@ def checkForDown(data, rcumode, error_list, subband):
                    (rcumode, rcu, (rcu+1), ant, max_x_offset, max_y_offset))
         if rcu not in error_list:
             error_list.append(rcu)
+            error_list.append(rcu+1)
             CSV.writeSpectra(data, rcu, "DOWN")
             CSV.writeSpectra(data, rcu+1, "DOWN")
+    return
 
-    for msg in shifted:
-        rcu, max_sb, mean_max_sb = i
-        offset = max_sb - mean_max_sb
+def checkForFlat(data, rcumode, error_list):
+    logger.debug("start flat check")
+    flat = searchFlat(data)
+    for msg in flat:
+        rcu, mean_val = msg
         ant, pol = getAntPol(rcumode, rcu)
-        logger.info("Mode-%d RCU-%02d Ant-%02d Shifted, offset=%d" %\
-                   (rcumode, rcu, ant, offset))
+        logger.info("Mode-%d RCU-%02d Ant-%02d Flat, value=%5.1fdB" %\
+                   (rcumode, rcu, ant, mean_val))
         if rcu not in error_list:
             error_list.append(rcu)
-            CSV.writeSpectra(data, rcu, "SHIFT")
+            CSV.writeSpectra(data, rcu, "FLAT")
+    return
+
+def checkForShort(data, rcumode, error_list):
+    logger.debug("start short check")
+    short = searchShort(data)
+    for msg in short:
+        rcu, mean_val = msg
+        ant, pol = getAntPol(rcumode, rcu)
+        logger.info("Mode-%d RCU-%02d Ant-%02d Short, value=%5.1fdB" %\
+                   (rcumode, rcu, ant, mean_val))
+        if rcu not in error_list:
+            error_list.append(rcu)
+            CSV.writeSpectra(data, rcu, "SHORT")
     return
 
 def closeAllOpenFiles():
-    ERR.setStage("closeAllOpenFiles")
     files = os.listdir(rtsmPath)
     for filename in files:
         if filename.find('open') > -1:
@@ -478,7 +455,6 @@ def closeAllOpenFiles():
             filename_new = filename.replace('open','closed')
             full_filename_new = os.path.join(rtsmPath, filename_new)
             os.rename(full_filename, full_filename_new)
-    ERR.setLastStage()
     return
 
 class cDayInfo:
@@ -491,7 +467,6 @@ class cDayInfo:
         self.readFile()
 
     def addSample(self, rcumode=-1):
-        ERR.setStage("cDayInfo.addSample")
         date = time.strftime("%Y%m%d", time.gmtime(time.time()))
         # new day reset data and set new filename
         if self.date != date:
@@ -500,24 +475,18 @@ class cDayInfo:
         if rcumode in range(1,8,1):
             self.samples[rcumode-1] += 1
             self.writeFile()
-        ERR.setLastStage()
 
     def addObsInfo(self, obs_id, start_time, stop_time, rcu_mode, samples):
-        ERR.setStage("cDayInfo.addObsInfo")
         self.obs_info.append([obs_id, start_time, stop_time, rcu_mode, samples])
-        ERR.setLastStage()
 
     def reset(self):
-        ERR.setStage("cDayInfo.reset")
         self.filename = "%s_%s_dayinfo.dat" %(getHostName(), self.date)
         self.samples = [0,0,0,0,0,0,0] # RCU-mode 1..7
         self.obs_info = list()
         self.deleteOldDays()
-        ERR.setLastStage()
 
     # after a restart, earlier data is imported
     def readFile(self):
-        ERR.setStage("cDayInfo.readFile")
         full_filename = os.path.join(rtsmPath, self.filename)
         if os.path.exists(full_filename):
             f = open(full_filename, 'r')
@@ -532,11 +501,9 @@ class cDayInfo:
                 if key == 'OBSID-INFO':
                     d = data.split(',')
                     self.obs_info.append([d[0],float(d[1]),float(d[2]),int(d[3]), int(d[4])])
-        ERR.setLastStage()
 
     # rewrite file every sample
     def writeFile(self):
-        ERR.setStage("cDayInfo.writeFile")
         full_filename = os.path.join(rtsmPath, self.filename)
         f = open(full_filename, 'w')
         f.write('#DAY-INFO date,M1,M2,M3,M4,M5,M6,M7\n')
@@ -547,10 +514,8 @@ class cDayInfo:
             f.write('OBS-ID-INFO=%s,%5.3f,%5.3f,%d,%d\n' %\
                    (i[0],i[1],i[2],i[3],i[4]))
         f.close()
-        ERR.setLastStage()
 
     def deleteOldDays(self):
-        ERR.setStage("cDayInfo.deleteOldDayInfo")
         files = os.listdir(rtsmPath)
         backup = True
         for filename in files:
@@ -562,7 +527,6 @@ class cDayInfo:
                     if filename.split('.')[0].split('_')[1] != self.date:
                         full_filename = os.path.join(rtsmPath, filename)
                         os.remove(full_filename)
-        ERR.setLastStage()
 
         
 def getObsId():
@@ -601,7 +565,6 @@ def getObsIdInfo(obsid):
     
 def main():
     global logger
-    ERR.setStage("main")
     obs_id   = ""
     active_obs_id  = ""
     rcumode  = 0
@@ -691,11 +654,9 @@ def main():
                 data.setActiveRcus(active_rcus)
 
                 rec_timestamp  = time.time()+3.0
-                ERR.setStage("record")
                 data.record(rec_time=1, read=True, slow=True)
                 #data.fetch()
 
-                ERR.setStage("main")
                 CSV.setRcuMode(rcumode)
                 CSV.setRecordTimestamp(rec_timestamp)
                 DI.addSample(rcumode)
@@ -711,6 +672,8 @@ def main():
                 if lbaMode(rcumode):
                     checkForDown(data, rcumode, error_list,
                                   conf.getInt('lbh-test-sb',301))
+                    checkForShort(data, rcumode, error_list)
+                    checkForFlat(data, rcumode, error_list)
                     checkForOscillation(data, rcumode, error_list, 6.0)
                     checkForNoise(data, rcumode, error_list,
                                   conf.getFloat('lba-noise-min-deviation', -3.0),
@@ -744,7 +707,12 @@ def main():
             logger.info("stopped by user")
             sys.exit()
         except:
-            ERR.log()
+            logger.error('Caught %s', str(sys.exc_info()[0]))
+            logger.error(str(sys.exc_info()[1]))
+            logger.error('TRACEBACK:\n%s', traceback.format_exc())
+            logger.error('Aborting NOW')
+            sys.exit(0)
+            
 
     # do test and write result files to log directory
     log_dir = conf.getStr('log-dir-local')
diff --git a/LCU/checkhardware/showTestResult.py b/LCU/checkhardware/showTestResult.py
index 167592b057efffaba237f207a8d858a49616aaa7..b5b9a839cd2f933c7eabad80d725b7fe18772f6a 100755
--- a/LCU/checkhardware/showTestResult.py
+++ b/LCU/checkhardware/showTestResult.py
@@ -1,14 +1,16 @@
 #!/usr/bin/python
-
+"""
 # Show logfile
-
+"""
 import sys
 import os
 import string
-import datetime
-import time
+# import datetime
+# import time
+
 
-def printHelp():
+def print_help():
+    """ print help """
     print "possible option for this script"
     print "-------------------------------"
     print "-h            print this help screen"
@@ -17,90 +19,83 @@ def printHelp():
     print "-------------------------------"
     sys.exit(0)
 
-i = 1
+arg_nr = 1
 args = dict()
-while i < len(sys.argv):
-    if sys.argv[i][0] == '-':
-        opt = sys.argv[i][1].upper()
+while arg_nr < len(sys.argv):
+    if sys.argv[arg_nr][0] == '-':
+        opt = sys.argv[arg_nr][1].upper()
         optval = '-'
-        valpos = sys.argv[i].find('=')
+        valpos = sys.argv[arg_nr].find('=')
         if valpos != -1:
-            optval = sys.argv[i][valpos+1:]
+            optval = sys.argv[arg_nr][valpos+1:]
         args[opt] = optval
-        i += 1       
+        arg_nr += 1
 
-if args.has_key('H'):
-    printHelp()
+if 'H' in args:
+    print_help()
     sys.exit(0)
 
-runPath = r'/opt/stationtest'
-if args.has_key('P'):
-	runPath = args.get('P')
-libPath = runPath+r'/lib'
-sys.path.insert(0, libPath)
+run_path = r'/opt/stationtest'
+if 'P' in args:
+    run_path = args.get('P')
+lib_path = run_path+r'/lib'
+sys.path.insert(0, lib_path)
 
 from general_lib import *
 from lofar_lib import *
 
-StID = getHostName().upper()
+station_id = getHostName().upper()
+
 
 def main():
-    f = open(runPath+r'/checkHardware.conf', 'r')
-    data = f.readlines()
-    f.close()
+    """ main function """
+    fd = open(run_path+r'/checkHardware.conf', 'r')
+    data = fd.readlines()
+    fd.close()
     for line in data:
         if line.find('log-dir-local') != -1:
-            key, logdir = line.strip().split('=')    
-    
-    if args.has_key('F'):
-        fullFilename = args.get('F')
+            key, logdir = line.strip().split('=')
+
+    if 'F' in args:
+        fullfilename = args.get('F')
     else:
-        if args.has_key('D'):
-            testfilename = '%s_StationTestHistory.csv' %(StID)
+        if 'D' in args:
+            testfilename = '%s_L2_StationTestHistory.csv' % station_id
         else:
-            testfilename = '%s_StationTest.csv' %(StID)
-    
+            testfilename = '%s_StationTest.csv' % station_id
+
         if os.path.exists(logdir):
-            fullFilename = os.path.join(logdir, testfilename)
+            fullfilename = os.path.join(logdir, testfilename)
         else:
             print "not a valid log dir"
             sys.exit(-1)
-        
+
     try:
-        f = open(fullFilename, 'r')
-        data = f.readlines()
-        f.close()
+        fd = open(fullfilename, 'r')
+        data = fd.readlines()
+        fd.close()
     except:
-        print "%s not found in %s" %(testfilename, logdir)
+        print "%s not found in %s" % (testfilename, logdir)
         sys.exit(-1)
-        
-    RCUx = RCUy = 0
-    
-    
-    print "\n"+"-"*103
-    print ">"*36+"   LAST STATION-CHECK RESULT   "+"<"*36
-    print "-"*103
+
+    rcu_x = rcu_y = 0
+
+    print "\n" + "-" * 103
+    print ">" * 36 + "   LAST STATION-CHECK RESULT   " + "<" * 36
+    print "-" * 103
 
     _part = ''
     _part_nr = -1
-    _element_nr = -1
-    _c_summator_defect = -1
-    
+
     first_date = 0
-    if args.has_key('D'):
+    if 'D' in args:
         days = int(args.get('D'))
-        #linedate = data[len(data)-1].strip().split(',')[0]
-        #print linedate
-        #dt = datetime.date(int(linedate[:4]), int(linedate[4:6]), int(linedate[6:]))
-        #start_date = dt - datetime.timedelta(days-1)
-        #first_date = int(getShortDateStr(tm=start_date.timetuple()))
-        #print first_date
-        
+
         days_cnt = 1
-        
+
         first_date = data[-1].strip().split(',')[0]
         print first_date
-        for i in range(len(data)-1,-1,-1):
+        for i in range(len(data) - 1, -1, -1):
             line = data[i]
             if line[0] == '#':
                 continue
@@ -112,352 +107,498 @@ def main():
                 break
         print first_date
 
-        
     last_date = first_date
     for line in data:
         partnumber = -1
         if line[0] == '#':
             continue
-            
+
         d = line.strip().split(',')
         if len(d) < 4:
             continue
         date = d[0]
-        
-        if args.has_key('D'):
+
+        if 'D' in args:
             if last_date != date:
                 print '\n'+'#'*103
             last_date = date
-        
+
         if first_date != 0 and int(date) < int(first_date):
             continue
-            
+
         part = d[1]
         if d[2] != '---':
             partnumber = int(d[2])
             if part == 'LBL':
-                if (partnumber < 48):
-                    print "ERROR: LBL %d NOT a legal partnumber" %(partnumber)
-                    RCUx = 0
-                    RCUy = 0
+                if partnumber < 48:
+                    print "ERROR: LBL %d NOT a legal partnumber" % partnumber
+                    rcu_x = 0
+                    rcu_y = 0
                 else:
-                    RCUx = (partnumber - 48) * 2
-                    RCUy = (partnumber - 48) * 2 + 1
+                    rcu_x = (partnumber - 48) * 2
+                    rcu_y = (partnumber - 48) * 2 + 1
             if part in ('LBH', 'HBA'):
-                RCUx = partnumber * 2
-                RCUy = partnumber * 2 + 1    
-        
+                rcu_x = partnumber * 2
+                rcu_y = partnumber * 2 + 1
+
         msg = d[3].strip()
-        kv = dict()
-        for i in range(4,len(d)):
+        msg_info = string.join(d[4:], " ")
+        keyvalue = dict()
+        for i in range(4, len(d)):
             if d[i].find('=') != -1:
                 key, valstr = d[i].split('=')
                 vallist = valstr.split(' ')
                 if len(vallist) == 1:
-                    kv[key] = vallist[0]
+                    keyvalue[key] = vallist[0]
                 elif len(vallist) > 1:
-                    kv[key] = vallist
+                    keyvalue[key] = vallist
             else:
-                kv[d[i]] = '-'
-                
+                keyvalue[d[i]] = '-'
+
         if part == 'NFO':
-            #if args.has_key('D'):
-            #	print
-            #	print '-'*103
-            #    print "   NEW TEST  "*8
-            #    print '-'*103
-            #    
-            if msg == 'VERSIONS':
-                print "Used script versions: checkHardware=%s, test_db=%s, test_lib=%s, search_lib=%s\n" %(kv.get('CHECK'), kv.get('DB'), kv.get('TEST'), kv.get('SEARCH'))
-                
-            if msg == 'STATION':
-                print "-- Station name     : %s" %(kv.get('NAME'))
-            
-            if msg == 'RUNTIME':
-                print "-- Check runtime    : %s .. %s" %(kv.get('START').replace('T',' '), kv.get('STOP').replace('T',' '))
-            
-            if msg == 'DRIVER':
-                if kv.has_key('RSPDRIVER'):
-                    print "-- RSPDriver        : DOWN" 
-                if kv.has_key('TBBDRIVER'):
-                    print "-- TBBDriver        : DOWN"
-            if msg == 'BOARD':
-                boardstr = ""
-                for i in range(24):
-                    if kv.has_key('RSP-%d' %(i)):
-                        boardstr += "%d, " %(i)
-                print "-- RSP board DOWN   : %s" %(boardstr[:-2]) 
-            if msg == 'CHECKS':
-                print "-- Checks done      : %s" %(string.join(d[4:],', ')) 
-            
-            if msg == 'STATISTICS':
-                print "-- Bad antennas     :",
-                if kv.get('BAD_LBL') != '-1':
-                    print "LBL=%s  " %(kv.get('BAD_LBL')),
-                if kv.get('BAD_LBH') != '-1':
-                    print "LBH=%s  " %(kv.get('BAD_LBH')),
-                if kv.get('BAD_HBA') != '-1':
-                    print "HBA=%s  " %(kv.get('BAD_HBA')),
-                if kv.get('BAD_HBA0') != '-1':
-                    print "HBA0=%s  " %(kv.get('BAD_HBA0')),
-                if kv.get('BAD_HBA1') != '-1':
-                    print "HBA1=%s  " %(kv.get('BAD_HBA1')),    
-                print
-                
-            if msg == 'BADLIST':
-                bad_ant_str = string.join(d[4:],';').replace('=','(').replace(' ',',').replace(';',')   ')+')'
-                print "-- bad-antenna-list : %s" %(bad_ant_str)  
-                    
+            print_info(msg, keyvalue, msg_info)
+
+        if part == 'SPU':
+            if part != _part:
+                _part = part
+                hdr = "\n== SPU "
+                print hdr + "=" * (104 - len(hdr))
+            print_spu(partnumber, msg, keyvalue, msg_info)
+
         if part == 'RSP':
             if part != _part:
                 _part = part
                 hdr = "\n== RSP "
-                print hdr + "="*(104-len(hdr))    
-
-            if msg == 'VERSION':
-                if kv.has_key('RSPDRIVER'):
-                    print "    Wrong RSPDriver version, %s" %(kv.get('RSPDRIVER'))
-                if kv.has_key('RSPCTL'):
-                    print "    Wrong rspctl version, %s" %(kv.get('RSPCTL'))    
-                if kv.has_key('AP') or kv.has_key('BP'):
-                    print "    Board %2d wrong firmware version: AP=%s BP=%s" %(partnumber, kv.get('AP'), kv.get('BP'))
-        
+                print hdr + "=" * (104 - len(hdr))
+            print_rsp(partnumber, msg, keyvalue)
+
         if part == 'TBB':
             if part != _part:
                 _part = part
-                
                 hdr = "\n== TBB "
-                print hdr + "="*(104-len(hdr))    
-            
-            if msg == 'VERSION':
-                if kv.has_key('TBBDRIVER'):
-                    print "    Wrong TBBDriver version, %s" %(kv.get('TBBDRIVER'))
-                if kv.has_key('TBBCTL'):
-                    print "    Wrong tbbctl version, %s" %(kv.get('TBBCTL'))    
-                if kv.has_key('TP') or kv.has_key('MP'):
-                    print "    Board %2d wrong firmware version: TP=%s MP=%s" %(partnumber, kv.get('TP'), kv.get('MP'))
-            
-            if msg == 'MEMORY':
-                print "    Board %2d Memory address or dataline error" %(partnumber)
-        
+                print hdr + "="*(104-len(hdr))
+            print_tbb(partnumber, msg, keyvalue)
+
         if part == 'RCU':
             if part != _part:
                 _part = part
                 hdr = "\n== RCU "
-                print hdr + "="*(104-len(hdr))    
-                
-            if msg == 'BROKEN':
-                print "    RCU %d Broken" %(partnumber)
-        
-        
-        if part in ('LBL','LBH'):
+                print hdr + "=" * (104 - len(hdr))
+            print_rcu(partnumber, msg, keyvalue)
+
+        if part in ('LBL', 'LBH'):
             if part != _part:
                 _part = part
                 if part == 'LBL':
                     hdr = "\n== LBA Low "
                 else:
                     hdr = "\n== LBA High "
-                print hdr + "="*(104-len(hdr))    
-            
-            lbaNumber = partnumber
-            #if part == 'LBL':
-            #    lbaNumber += 48
-            
-            if msg == 'NOSIGNAL':
-                print "   NO test signal found"
-            
-            if msg == 'TESTSIGNAL':
-                print
-                print " X test done with subband=%s and ref.signal=%sdB" %\
-                      (kv.get('SUBBANDX'), kv.get('SIGNALX'))
-                print " Y test done with subband=%s and ref.signal=%sdB" %\
-                      (kv.get('SUBBANDY'), kv.get('SIGNALY'))       
-            
-            if msg == 'TOOLOW':
-                print "   Average signal strenght Too Low  AVG %sdB" %\
-                      (kv.get('AVG'))
-            
-            if msg == 'DOWN':
-                    print "   Antenna %2d, %-11s, has Fallen: X=%sdB Xoffset=%s  Y=%sdB Yoffset=%s" %\
-                      (lbaNumber, 'RCU %d/%d' %(RCUx, RCUy), kv.get('X',('?',)), kv.get('Xoff',('?',)), kv.get('Y',('?',)), kv.get('Yoff',('?',)))
-            
-            if msg == 'OSCILLATION':
-                if kv.has_key('X')  or kv.has_key('Xbands'):
-                    print "   Antenna %2d, %-7s, X Oscillation" %(lbaNumber, 'RCU %d' %(RCUx))
-                if kv.has_key('Y')  or kv.has_key('Ybands'):
-                    print "   Antenna %2d, %-7s, Y Oscillation" %(lbaNumber, 'RCU %d' %(RCUy))
-            
-            if msg == 'LOW_NOISE':
-                if kv.has_key('Xproc'):
-                    print "   Antenna %2d, %-7s, X Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUx), kv.get('Xproc'), kv.get('Xval'), kv.get('Xdiff','-'), kv.get('Xref'))
-                if kv.has_key('Yproc'):
-                    print "   Antenna %2d, %-7s, Y Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUy), kv.get('Yproc'), kv.get('Yval'), kv.get('Ydiff','-'), kv.get('Yref'))
-                    
-            if msg == 'HIGH_NOISE':
-                if kv.has_key('Xproc'):
-                    print "   Antenna %2d, %-7s, X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUx), kv.get('Xproc'), kv.get('Xval'), kv.get('Xdiff','-'), kv.get('Xref'))
-                if kv.has_key('Yproc'):
-                    print "   Antenna %2d, %-7s, Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUy), kv.get('Yproc'), kv.get('Yval'), kv.get('Ydiff','-'), kv.get('Yref'))
-            
-            if msg == 'JITTER':
-                if kv.has_key('Xdiff'):
-                    print "   Antenna %2d, %-7s, X Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUx), kv.get('Xproc','-'), kv.get('Xdiff'), kv.get('Xref'))
-                if kv.has_key('Ydiff'):
-                    print "   Antenna %2d, %-7s, Y Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUy), kv.get('Yproc','-'), kv.get('Ydiff'), kv.get('Yref'))
-                          
-            if msg == 'SPURIOUS':
-                if kv.has_key('X'): 
-                    print "   Antenna %2d, %-7s, X Spurious signals found" %(lbaNumber, 'RCU %d' %(RCUx))
-                if kv.has_key('Y'): 
-                    print "   Antenna %2d, %-7s, Y Spurious signals found" %(lbaNumber, 'RCU %d' %(RCUy))
-                    
-            if msg == 'FAIL' or msg == 'RF_FAIL':
-                if kv.has_key('X'):
-                    print "   Antenna %2d, %-7s, X RF fail:    signal=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUx), kv.get('X'))
-                if kv.has_key('Y'):
-                    print "   Antenna %2d, %-7s, Y RF fail:    signal=%sdB" %\
-                          (lbaNumber, 'RCU %d' %(RCUy), kv.get('Y'))    
-        
+                print hdr + "=" * (104 - len(hdr))
+            print_lba(partnumber, msg, keyvalue, rcu_x, rcu_y)
+
         if part == 'HBA':
             if part != _part:
                 _part = part
                 hdr = "\n== HBA "
-                print hdr + "="*(104-len(hdr))    
-            
+                print hdr + "=" * (104 - len(hdr))
+
             if partnumber != -1 and partnumber != _part_nr:
                 _part_nr = partnumber
-                _c_summator_defect = 0
-                header = "Tile %d (RCU %d/%d)" %(partnumber, RCUx, RCUy)
-                print "\n-- %s %s" %(header, '-'*(99-len(header)))
-                
-            if msg == 'NOSIGNAL':
-                print "   NO test signal found"
-                
-            if msg == 'MODEM':
-                for i in range(1,17,1):
-                    key = "E%02d" %(i)
-                    if key in kv:
-                        print "   E%02d modem fault (%s)" %(i, kv[key]) 
-            
-            if msg == 'OSCILLATION':
-                if kv.has_key('X') or kv.has_key('Xbands'):
-                    print "   X Oscillation"
-                if kv.has_key('Y') or kv.has_key('Ybands'):
-                    print "   Y Oscillation"
-                        
-            if msg == 'C_SUMMATOR':
-                _c_summator_defect = 1
-                print "   Modem errors (all elements)"
-            
-            if msg == 'P_SUMMATOR':
-                print "   No RF all elements" 
-            
-            if msg == 'SUMMATOR_NOISE':
-                if kv.has_key('X'):
-                    print "   X Summator noise"
-                if kv.has_key('Y'):
-                    print "   Y Summator noise"
-                    
-            if msg == 'SPURIOUS':
-                if kv.has_key('X'):
-                    print "   X Spurious signals"
-                if kv.has_key('Y'):
-                    print "   Y Spurious signals"
-                            
-            if msg == 'LOW_NOISE':
-                if kv.has_key('Xproc'):
-                    print "   X Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %(kv.get('Xproc'), kv.get('Xval'), kv.get('Xdiff','-'), kv.get('Xref'))
-                if kv.has_key('Yproc'):
-                    print "   Y Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %(kv.get('Yproc'), kv.get('Yval'), kv.get('Ydiff','-'), kv.get('Yref'))
-                    
-            if msg == 'HIGH_NOISE':
-                if kv.has_key('Xproc'):
-                    print "   X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %(kv.get('Xproc'), kv.get('Xval'), kv.get('Xdiff','-'), kv.get('Xref'))
-                if kv.has_key('Yproc'):
-                    print "   Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" %(kv.get('Yproc'), kv.get('Yval'), kv.get('Ydiff','-'), kv.get('Yref'))
-            
-            if msg == 'JITTER':
-                if kv.has_key('Xdiff'):
-                    print "   X Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" %(kv.get('Xproc'), kv.get('Xdiff'), kv.get('Xref'))
-                if kv.has_key('Ydiff'):
-                    print "   Y Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" %(kv.get('Yproc'), kv.get('Ydiff'), kv.get('Yref'))
-            
-            if msg == 'RF_FAIL' or msg == 'RF_TILE_FAIL':
-                if kv.has_key('X'):
-                    signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = kv.get('X')
-                    print "   X RF Fail:    no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" %\
-                          (float(signal_128), float(ref_128), int(sb_128), float(signal_253), float(ref_253), int(sb_253))
-                if kv.has_key('Y'):
-                    signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = kv.get('Y')
-                    print "   Y RF Fail:    no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" %\
-                          (float(signal_128), float(ref_128), int(sb_128), float(signal_253), float(ref_253), int(sb_253))
-            
-            if msg == 'E_FAIL':
-                # loop over number of elements
-                for i in range(1,17,1):
-                    if _c_summator_defect:
-                        continue
-                        
-                    if kv.has_key('M%d' %(i)) or kv.has_key('X%d' %(i)) or kv.has_key('Y%d' %(i)) \
-                       or kv.has_key('OX%d' %(i)) or kv.has_key('OY%d' %(i)) \
-                       or kv.has_key('SPX%d' %(i)) or kv.has_key('SPY%d' %(i)) \
-                       or kv.has_key('LNX%d' %(i)) or kv.has_key('HNX%d' %(i)) or kv.has_key('JX%d' %(i)) \
-                       or kv.has_key('LNY%d' %(i)) or kv.has_key('HNY%d' %(i)) or kv.has_key('JY%d' %(i)):
-                        print "   Element %d" %(i)
-
-                    if kv.has_key('M%d' %(i)):
-                        info = kv.get('M%d' %(i))
-                        if info == 'error':
-                            print "       Modem error"
-                        if info == '??':
-                            print "       No modem communication"
-                    else:
-                        if kv.has_key('OX%d' %(i)):
-                            print "      X Oscillating" 
-                        
-                        if kv.has_key('OY%d' %(i)):
-                            print "      Y Oscillating" 
-                        
-                        if kv.has_key('SPX%d' %(i)):
-                            print "      X Spurious" 
-                        
-                        if kv.has_key('SPY%d' %(i)):
-                            print "      Y Spurious" 
-                                
-                        if kv.has_key('LNX%d' %(i)):
-                            print "      X Low Noise, signal=%sdB fluctuation=%sdB" %(kv.get('LNX%d' %(i))[0], kv.get('LNX%d' %(i))[1])
-                        
-                        if kv.has_key('HNX%d' %(i)):
-                            print "      X High Noise, signal=%sdB fluctuation=%sdB" %(kv.get('HNX%d' %(i))[0], kv.get('HNX%d' %(i))[1])
-                        
-                        if kv.has_key('JX%d' %(i)):
-                            print "      X Jitter, fluctuation=%sdB" %(kv.get('JX%d' %(i)))    
-                            
-                        if kv.has_key('LNY%d' %(i)):
-                            print "      Y Low Noise, signal=%sdB fluctuation=%sdB" %(kv.get('LNY%d' %(i))[0], kv.get('LNY%d' %(i))[1])
-                        
-                        if kv.has_key('HNY%d' %(i)):
-                            print "      Y High Noise, signal=%sdB fluctuation=%sdB" %(kv.get('HNY%d' %(i))[0], kv.get('HNY%d' %(i))[1])
-                        
-                        if kv.has_key('JY%d' %(i)):
-                            print "      Y Jitter, fluctuation=%sdB" %(kv.get('JY%d' %(i)))    
-                                  
-                        if kv.has_key('X%d' %(i)):
-                            signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = kv.get('X%d' %(i))
-                            print "      X RF Fail:  no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" %\
-                                  (float(signal_128), float(ref_128), int(sb_128), float(signal_253), float(ref_253), int(sb_253))          
-                        
-                        if kv.has_key('Y%d' %(i)):
-                            signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = kv.get('Y%d' %(i))
-                            print "      Y RF Fail:  no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" %\
-                                  (float(signal_128), float(ref_128), int(sb_128), float(signal_253), float(ref_253), int(sb_253))
-    print '\n'+'#'*103
+                header = "Tile %d (RCU %d/%d)" % (partnumber, rcu_x, rcu_y)
+                print "\n-- %s %s" % (header, '-' * (99 - len(header)))
+
+            print_hba(partnumber, msg, keyvalue, rcu_x, rcu_y)
+
+    print '\n' + '#' * 103
+
+
+def print_info(msg, keyvalue, msg_info):
+    """
+    print NFO line
+    """
+    if msg == 'VERSIONS':
+        print "Used script versions: checkHardware=%s, test_db=%s, test_lib=%s, search_lib=%s\n" % (
+            keyvalue.get('CHECK'), keyvalue.get('DB'), keyvalue.get('TEST'), keyvalue.get('SEARCH'))
+
+    if msg == 'STATION':
+        print "-- Station name     : %s" % keyvalue.get('NAME')
+
+    if msg == 'RUNTIME':
+        print "-- Check runtime    : %s .. %s" % (
+            keyvalue.get('START').replace('T', ' '), keyvalue.get('STOP'). replace('T', ' '))
+
+    if msg == 'DRIVER':
+        if 'RSPDRIVER' in keyvalue:
+            print "-- RSPDriver        : DOWN"
+        if 'TBBDRIVER' in keyvalue:
+            print "-- TBBDriver        : DOWN"
+    if msg == 'BOARD':
+        boardstr = ""
+        for i in range(24):
+            if 'RSP-%d' % i in keyvalue:
+                boardstr += "%d, " % i
+        print "-- RSP board DOWN   : %s" % boardstr[:-2]
+    if msg == 'CHECKS':
+        """E5"""
+        checks = msg_info.split()
+        info = []
+        if 'RV' in checks:
+            info.append('RSP-version')
+        if 'TV' in checks:
+            info.append('TBB-version')    
+        if 'TM' in checks:
+            info.append('TBB-memory')
+        if len(info):         
+            print "-- Checks done      : %s" % string.join(info, ', ')
+        info = []
+        for mode in '1234567':
+            if 'M%s' % mode in checks:
+                info.append('Modem')
+            if 'SH%s' % mode in checks:
+                info.append('Short')
+            if 'F%s' % mode in checks:
+                info.append('Flat')
+            if 'D%s' % mode in checks:
+                info.append('Down')
+            if 'S%s' % mode in checks:
+                info.append('RF')    
+            if 'O%s' % mode in checks:
+                info.append('Oscillation') 
+            if 'SP%s' % mode in checks:
+                info.append('Spurious')
+            if 'SN%s' % mode in checks:
+                info.append('Summator-noise')
+            for check in checks:
+                if 'NS%s' % mode in check.split('='):
+                    info.append('Noise[%ssec]' % check.split('=')[1])
+            if 'E%s' % mode in checks:
+                info.append('Elements')                       
+            if len(info):         
+                print "-- Checks done M%s   : %s" % (mode, string.join(info, ', '))
+            info = []
+
+    if msg == 'STATISTICS':
+        print "-- Bad antennas     :",
+        if keyvalue.get('BAD_LBL') != '-1':
+            print "LBL=%s  " % keyvalue.get('BAD_LBL'),
+        if keyvalue.get('BAD_LBH') != '-1':
+            print "LBH=%s  " % keyvalue.get('BAD_LBH'),
+        if keyvalue.get('BAD_HBA') != '-1':
+            print "HBA=%s  " % keyvalue.get('BAD_HBA'),
+        if keyvalue.get('BAD_HBA0') != '-1':
+            print "HBA0=%s  " % keyvalue.get('BAD_HBA0'),
+        if keyvalue.get('BAD_HBA1') != '-1':
+            print "HBA1=%s  " % keyvalue.get('BAD_HBA1'),
+        print
+
+    if msg == 'BADLIST':
+        bad_ant_str = string.join(d[4:], ';').replace('=', '(').replace(' ', ',').replace(';', ')   ') + ')'
+        print "-- bad-antenna-list : %s" % bad_ant_str
+    return
+
+
+def print_spu(partnumber, msg, keyvalue, msg_info):
+    """
+    print SPU line
+    """
+    if msg == 'VOLTAGE':
+        print "    Subrack %1d wrong voltage: %s" % (partnumber, msg_info)
+    if msg == 'TEMPERATURE':
+        print "    Subrack %1d high temperature: PCB=%s" % (
+              partnumber, keyvalue.get('PCB'))
+    return
+
+
+def print_rsp(partnumber, msg, keyvalue):
+    """
+    print RSP line
+    """
+    if msg == 'VERSION':
+        if 'RSPDRIVER' in keyvalue:
+            print "    Wrong RSPDriver version, %s" % keyvalue.get('RSPDRIVER')
+        if 'RSPCTL' in keyvalue:
+            print "    Wrong rspctl version, %s" % keyvalue.get('RSPCTL')
+        if 'AP' in keyvalue or 'BP' in keyvalue:
+            print "    Board %2d wrong firmware version: AP=%s BP=%s" % (
+                partnumber, keyvalue.get('AP'), keyvalue.get('BP'))
+    if msg == 'VOLTAGE':
+        print "    Board %2d wrong voltage: 1.2V=%3.1f 2.5V=%3.1f 3.3V=%3.1f" % (
+              partnumber, keyvalue.get('1.2V'), keyvalue.get('2.5V'), keyvalue.get('3.3V'))
+    if msg == 'TEMPERATURE':
+        print "    Board %2d high temperature: PCB=%3.1f BP=%3.1f AP0=%3.1f AP1=%3.1f AP2=%3.1f AP3=%3.1f" % (
+              partnumber, keyvalue.get('PCB'), keyvalue.get('BP'), keyvalue.get('AP0'), keyvalue.get('AP1'),
+              keyvalue.get('AP2'), keyvalue.get('AP3'))
+    return
+
+
+def print_tbb(partnumber, msg, keyvalue):
+    """
+    print TBB line
+    """
+    if msg == 'VERSION':
+        if 'TBBDRIVER' in keyvalue:
+            print "    Wrong TBBDriver version, %s" % keyvalue.get('TBBDRIVER')
+        if 'TBBCTL' in keyvalue:
+            print "    Wrong tbbctl version, %s" % keyvalue.get('TBBCTL')
+        if 'TP' in keyvalue or 'MP' in keyvalue:
+            print "    Board %2d wrong firmware version: TP=%s MP=%s" % (
+                partnumber, keyvalue.get('TP'), keyvalue.get('MP'))
+
+    if msg == 'MEMORY':
+        print "    Board %2d Memory address or dataline error" % partnumber
+    return
+
+
+def print_rcu(partnumber, msg, keyvalue):
+    """
+    print RCU line
+    """
+    if msg == 'BROKEN':
+        print "    RCU %d Broken" % partnumber
+    return
+
+
+def print_lba(partnumber, msg, keyvalue, rcu_x, rcu_y):
+    """
+    print LBA line
+    """
+    lba_number = partnumber
+
+    if msg == 'NOSIGNAL':
+        print "   NO test signal found"
+
+    if msg == 'TESTSIGNAL':
+        print
+        print " X test done with subband=%s and ref.signal=%sdB" % (
+            keyvalue.get('SUBBANDX'), keyvalue.get('SIGNALX'))
+        print " Y test done with subband=%s and ref.signal=%sdB" % (
+            keyvalue.get('SUBBANDY'), keyvalue.get('SIGNALY'))
+
+    if msg == 'TOOLOW':
+        print "   Average signal strenght Too Low  AVG %sdB" % keyvalue.get('AVG')
+
+    if msg == 'DOWN':
+        print "   Antenna %2d, %-11s, Down: X=%sdB Xoffset=%s  Y=%sdB Yoffset=%s" % (
+            lba_number, 'RCU %d/%d' % (rcu_x, rcu_y),
+            keyvalue.get('X', ('?',)), keyvalue.get('Xoff', ('?',)),
+            keyvalue.get('Y', ('?',)), keyvalue.get('Yoff', ('?',)))
+
+    if msg == 'SHORT':
+        if 'Xmean' in keyvalue:
+            print "   Antenna %2d, %-7s, X Short: value=%s" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xmean'))
+        if 'Ymean' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Short: value=%s" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Ymean'))
+
+    if msg == 'FLAT':
+        if 'Xmean' in keyvalue:
+            print "   Antenna %2d, %-7s, X Flat: value=%s" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xmean'))
+        if 'Ymean' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Flat: value=%s" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Ymean'))
+
+    if msg == 'OSCILLATION':
+        if 'X' in keyvalue or 'Xbands' in keyvalue:
+            print "   Antenna %2d, %-7s, X Oscillation" % (lba_number, 'RCU %d' % rcu_x)
+        if 'Y' in keyvalue or 'Ybands' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Oscillation" % (lba_number, 'RCU %d' % rcu_y)
+
+    if msg == 'LOW_NOISE':
+        if 'Xproc' in keyvalue:
+            print "   Antenna %2d, %-7s, X Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc'), keyvalue.get('Xval'),
+                keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))
+        if 'Yproc' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc'), keyvalue.get('Yval'),
+                keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))
+
+    if msg == 'HIGH_NOISE':
+        if 'Xproc' in keyvalue:
+            print "   Antenna %2d, %-7s, X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc'), keyvalue.get('Xval'),
+                keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))
+        if 'Yproc' in keyvalue:
+            print "   Antenna %2d, %-7s, Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc'), keyvalue.get('Yval'),
+                keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))
+
+    if msg == 'JITTER':
+        if 'Xdiff' in keyvalue:
+            print "   Antenna %2d, %-7s, X Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('Xproc', '-'),
+                keyvalue.get('Xdiff'), keyvalue.get('Xref'))
+        if 'Ydiff' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Yproc', '-'),
+                keyvalue.get('Ydiff'), keyvalue.get('Yref'))
+
+    if msg == 'SPURIOUS':
+        if 'X' in keyvalue:
+            print "   Antenna %2d, %-7s, X Spurious signals" % (lba_number, 'RCU %d' % rcu_x)
+        if 'Y' in keyvalue:
+            print "   Antenna %2d, %-7s, Y Spurious signals" % (lba_number, 'RCU %d' % rcu_y)
+
+    if msg == 'FAIL' or msg == 'RF_FAIL':
+        if 'X' in keyvalue:
+            print "   Antenna %2d, %-7s, X RF fail:    signal=%sdB" % (
+                lba_number, 'RCU %d' % rcu_x, keyvalue.get('X'))
+        if 'Y' in keyvalue:
+            print "   Antenna %2d, %-7s, Y RF fail:    signal=%sdB" % (
+                lba_number, 'RCU %d' % rcu_y, keyvalue.get('Y'))
+
+
+def print_hba(partnumber, msg, keyvalue, rcu_x, rcu_y):
+    """
+    print HBA line
+    """
+    _c_summator_defect = 0
+    if msg == 'NOSIGNAL':
+        print "   NO test signal found"
+
+    if msg == 'MODEM':
+        for i in range(1, 17, 1):
+            key = "E%02d" % i
+            if key in keyvalue:
+                print "   E%02d modem fault (%s)" % (i, keyvalue[key])
+
+    if msg == 'OSCILLATION':
+        if 'X' in keyvalue or 'Xbands' in keyvalue:
+            print "   X Oscillation"
+        if 'Y' in keyvalue or 'Ybands' in keyvalue:
+            print "   Y Oscillation"
+
+    if msg == 'C_SUMMATOR':
+        _c_summator_defect = 1
+        print "   Modem errors (all elements)"
+
+    if msg == 'P_SUMMATOR':
+        print "   No RF all elements"
+
+    if msg == 'SUMMATOR_NOISE':
+        if 'X' in keyvalue:
+            print "   X Summator noise"
+        if 'Y' in keyvalue:
+            print "   Y Summator noise"
+
+    if msg == 'SPURIOUS':
+        if 'X' in keyvalue:
+            print "   X Spurious signals"
+        if 'Y' in keyvalue:
+            print "   Y Spurious signals"
+
+    if msg == 'LOW_NOISE':
+        if 'Xproc' in keyvalue:
+            print "   X Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                keyvalue.get('Xproc'), keyvalue.get('Xval'), keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))
+        if 'Yproc' in keyvalue:
+            print "   Y Low Noise:  %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                keyvalue.get('Yproc'), keyvalue.get('Yval'), keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))
+
+    if msg == 'HIGH_NOISE':
+        if 'Xproc' in keyvalue:
+            print "   X High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                keyvalue.get('Xproc'), keyvalue.get('Xval'), keyvalue.get('Xdiff', '-'), keyvalue.get('Xref'))
+        if 'Yproc' in keyvalue:
+            print "   Y High Noise: %s%% bad, signal=%sdB, fluctuation=%sdB, limit=%sdB" % (
+                keyvalue.get('Yproc'), keyvalue.get('Yval'), keyvalue.get('Ydiff', '-'), keyvalue.get('Yref'))
+
+    if msg == 'JITTER':
+        if 'Xdiff' in keyvalue:
+            print "   X Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" % (
+                keyvalue.get('Xproc'), keyvalue.get('Xdiff'), keyvalue.get('Xref'))
+        if 'Ydiff' in keyvalue:
+            print "   Y Jitter:     %s%% bad, fluctuation=%sdB, normal=%sdB" % (
+                keyvalue.get('Yproc'), keyvalue.get('Ydiff'), keyvalue.get('Yref'))
+
+    if msg == 'RF_FAIL' or msg == 'RF_TILE_FAIL':
+        if 'X' in keyvalue:
+            signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('X')
+            print "   X RF Fail:    ",
+            print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  " % (
+                float(signal_128), float(ref_128), int(sb_128)),
+            print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (
+                float(signal_253), float(ref_253), int(sb_253))
+        if 'Y' in keyvalue:
+            signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('Y')
+            print "   Y RF Fail:    ",
+            print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  " % (
+                float(signal_128), float(ref_128), int(sb_128)),
+            print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (
+                float(signal_253), float(ref_253), int(sb_253))
+
+    if msg == 'E_FAIL':
+        # loop over number of elements
+        for i in range(1, 17, 1):
+            if _c_summator_defect:
+                continue
+
+            if 'M%d' % i in keyvalue or 'X%d' % i in keyvalue or 'Y%d' % i in keyvalue \
+                    or 'OX%d' % i in keyvalue or 'OY%d' % i in keyvalue \
+                    or 'SPX%d' % i in keyvalue or 'SPY%d' % i in keyvalue \
+                    or 'LNX%d' % i in keyvalue or 'HNX%d' % i in keyvalue or 'JX%d' % i in keyvalue \
+                    or 'LNY%d' % i in keyvalue or 'HNY%d' % i in keyvalue or 'JY%d' % i in keyvalue:
+                print "   Element %d" % i
+
+            if 'M%d' % i in keyvalue:
+                info = keyvalue.get('M%d' % i)
+                if info == 'error':
+                    print "       Modem error"
+                if info == '??':
+                    print "       No modem communication"
+            else:
+                if 'OX%d' % i in keyvalue:
+                    print "      X Oscillating"
+
+                if 'OY%d' % i in keyvalue:
+                    print "      Y Oscillating"
+
+                if 'SPX%d' % i in keyvalue:
+                    print "      X Spurious"
+
+                if 'SPY%d' % i in keyvalue:
+                    print "      Y Spurious"
+
+                if 'LNX%d' % i in keyvalue:
+                    print "      X Low Noise, signal=%sdB fluctuation=%sdB" % (
+                        keyvalue.get('LNX%d' % i)[0], keyvalue.get('LNX%d' % i)[1])
+
+                if 'HNX%d' % i in keyvalue:
+                    print "      X High Noise, signal=%sdB fluctuation=%sdB" % (
+                        keyvalue.get('HNX%d' % i)[0], keyvalue.get('HNX%d' % i)[1])
+
+                if 'JX%d' % i in keyvalue:
+                    print "      X Jitter, fluctuation=%sdB" % keyvalue.get('JX%d' % i)
+
+                if 'LNY%d' % i in keyvalue:
+                    print "      Y Low Noise, signal=%sdB fluctuation=%sdB" % (
+                        keyvalue.get('LNY%d' % i)[0], keyvalue.get('LNY%d' % i)[1])
+
+                if 'HNY%d' % i in keyvalue:
+                    print "      Y High Noise, signal=%sdB fluctuation=%sdB" % (
+                        keyvalue.get('HNY%d' % i)[0], keyvalue.get('HNY%d' % i)[1])
+
+                if 'JY%d' % i in keyvalue:
+                    print "      Y Jitter, fluctuation=%sdB" % keyvalue.get('JY%d' % i)
+
+                if 'X%d' % i in keyvalue:
+                    signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('X%d' % i)
+                    print "      X RF Fail:  ",
+                    print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  " % (
+                        float(signal_128), float(ref_128), int(sb_128)),
+                    print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (
+                        float(signal_253), float(ref_253), int(sb_253))
+
+                if 'Y%d' % i in keyvalue:
+                    signal_128, sb_128, ref_128, signal_253, sb_253, ref_253 = keyvalue.get('Y%d' % i)
+                    print "      Y RF Fail:  ",
+                    print "no-delay(test=%5.1fdB ref=%5.1fdB sb=%d)  " % (
+                        float(signal_128), float(ref_128), int(sb_128)),
+                    print "full-delay(test=%5.1fdB ref=%5.1fdB sb=%d)" % (
+                        float(signal_253), float(ref_253), int(sb_253))
+
+
 if __name__ == '__main__':
     main()