diff --git a/.gitignore b/.gitignore
index d3a18ae07e5d8898c3e0987b797d85ff2f769df9..969b2d256e20aca8f48ab1e5a40fa1f2eda83f07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 test_data/*.MS
+Docker/scripts
 
 # Byte-compiled / optimized / DLL files
 __pycache__/
diff --git a/Docker/build_docker.sh b/Docker/build_docker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..45d397f27ae40e9026acf46daffcd89eeebf60a4
--- /dev/null
+++ b/Docker/build_docker.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+BRANCH=production
+REPO_URL=https://github.com/lofar-astron/prefactor
+
+# FETCHES THE SCRIPTS ONLY
+svn checkout ${REPO_URL}/branches/${BRANCH}/scripts
+SCRIPT_PATH=$(realpath ${BASH_SOURCE[0]})
+PATH=$(dirname ${SCRIPT_PATH})
+
+docker build $PATH -t prefactor:latest
diff --git a/Docker/scripts/Ateamclipper.py b/Docker/scripts/Ateamclipper.py
deleted file mode 100755
index da0f12ea2efbc4a1b86166f34243800c17a75121..0000000000000000000000000000000000000000
--- a/Docker/scripts/Ateamclipper.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-
-## changelog
-# W.Williams 2014/11/03  add - to give input/output statistics per channel
-# W.Williams 2014/11/03  fix - statistics per correlation
-# A.Drabent 2019/07/24   write fraction of flagged data into output file (for prefactor3)
-
-import numpy
-import pyrap.tables as pt
-import os, sys
-
-msname  = str(sys.argv[1])
-
-cliplevelhba = 5.0
-cliplevellba = 50.0
-
-t = pt.table(msname, readonly=False)
-data = t.getcol('MODEL_DATA')
-flag = t.getcol('FLAG')
-freq_tab= pt.table(msname + '::SPECTRAL_WINDOW')
-freq    = freq_tab.getcol('REF_FREQUENCY')
-
-if freq[0] > 100e6:
- cliplevel = cliplevelhba
-if freq[0] < 100e6:
- cliplevel = cliplevellba
-
-
-print('------------------------------')
-print('SB Frequency [MHz]', freq[0]/1e6)
-for chan in range(0,numpy.size(data[0,:,0])):
-  print('chan %i : %.5f%% input XX flagged' %( chan, 100.*numpy.sum(flag[:,chan,0] == True)/numpy.size(flag[:,chan,0]) ))
-  print('chan %i : %.5f%% input YY flagged' %( chan, 100.*numpy.sum(flag[:,chan,3] == True)/numpy.size(flag[:,chan,3]) ))
-input_flags_xx = 100. * numpy.sum(flag[:,:,0] == True)/numpy.size(flag[:,:,0])
-input_flags_yy = 100. * numpy.sum(flag[:,:,3] == True)/numpy.size(flag[:,:,3])
-print('Total : %.5f%% input XX flagged' %(   input_flags_xx ))
-print('Total : %.5f%% input YY flagged' %(   input_flags_yy ))
-print('')
-print('Cliplevel used [Jy]', cliplevel)
-print('\n\n')
-
-for pol in range(0,numpy.size(data[0,0,:])):
- for chan in range(0,numpy.size(data[0,:,0])):
-  print('Doing polarization,chan', pol, chan)
-  idx = numpy.where(abs(data[:,chan,pol]) > cliplevel)
-  flag[idx,chan,0] = True
-  flag[idx,chan,1] = True
-  flag[idx,chan,2] = True
-  flag[idx,chan,3] = True 
-
-print('')
-for chan in range(0,numpy.size(data[0,:,0])):
-  print('chan %i : %.5f%% output XX flagged' %( chan, 100.*numpy.sum(flag[:,chan,0] == True)/numpy.size(flag[:,chan,0]) ))
-  print('chan %i : %.5f%% output YY flagged' %( chan, 100.*numpy.sum(flag[:,chan,3] == True)/numpy.size(flag[:,chan,3]) ))
-output_flags_xx = 100. * numpy.sum(flag[:,:,0] == True)/numpy.size(flag[:,:,0])
-output_flags_yy = 100. * numpy.sum(flag[:,:,3] == True)/numpy.size(flag[:,:,3])
-print('Total : %.5f%% input XX flagged' %(   output_flags_xx ))
-print('Total : %.5f%% input YY flagged' %(   output_flags_yy ))
-print('')
-t.putcol('FLAG', flag)
-t.close()
-freq_tab.close()
-
-os.system('echo ' + str(freq[0]) + ' ' + str(output_flags_xx - input_flags_xx) + ' ' + str(output_flags_yy - input_flags_yy) + ' >> Ateamclipper.txt')
\ No newline at end of file
diff --git a/Docker/scripts/BLsmooth.py b/Docker/scripts/BLsmooth.py
deleted file mode 100755
index 0bec38e690232e9241c9df0d727b68283a0a8e19..0000000000000000000000000000000000000000
--- a/Docker/scripts/BLsmooth.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2019 - Francesco de Gasperin
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-# Usage: BLavg.py vis.MS
-# Load a MS, average visibilities according to the baseline lenght,
-# i.e. shorter BLs are averaged more, and write a new MS
-
-import os, sys, time
-import optparse, itertools
-import logging
-import numpy as np
-from scipy.ndimage.filters import gaussian_filter1d as gfilter
-import pyrap.tables as pt
-logging.basicConfig(level=logging.DEBUG)
-
-def addcol(ms, incol, outcol):
-    if outcol not in ms.colnames():
-        logging.info('Adding column: '+outcol)
-        coldmi = ms.getdminfo(incol)
-        coldmi['NAME'] = outcol
-        ms.addcols(pt.makecoldesc(outcol, ms.getcoldesc(incol)), coldmi)
-    if outcol != incol:
-        # copy columns val
-        logging.info('Set '+outcol+'='+incol)
-        pt.taql("update $ms set "+outcol+"="+incol)
-
-opt = optparse.OptionParser(usage="%prog [options] MS", version="%prog 0.1")
-opt.add_option('-f', '--ionfactor', help='Gives an indication on how strong is the ionosphere [default: 0.2]', type='float', default=0.2)
-opt.add_option('-s', '--bscalefactor', help='Gives an indication on how the smoothing varies with BL-lenght [default: 0.5]', type='float', default=0.5)
-opt.add_option('-i', '--incol', help='Column name to smooth [default: DATA]', type='string', default='DATA')
-opt.add_option('-o', '--outcol', help='Output column [default: SMOOTHED_DATA]', type="string", default='SMOOTHED_DATA')
-opt.add_option('-w', '--weight', help='Save the newly computed WEIGHT_SPECTRUM, this action permanently modify the MS! [default: False]', action="store_true", default=False)
-opt.add_option('-r', '--restore', help='If WEIGHT_SPECTRUM_ORIG exists then restore it before smoothing [default: False]', action="store_true", default=False)
-opt.add_option('-b', '--nobackup', help='Do not backup the old WEIGHT_SPECTRUM in WEIGHT_SPECTRUM_ORIG [default: do backup if -w]', action="store_true", default=False)
-opt.add_option('-a', '--onlyamp', help='Smooth only amplitudes [default: smooth real/imag]', action="store_true", default=False)
-opt.add_option('-S', '--smooth', help='Performs smoothing (otherwise column will be only copied)', type="string", default=True)
-(options, msfile) = opt.parse_args()
-
-if msfile == []:
-    opt.print_help()
-    sys.exit(0)
-msfile = msfile[0]
-
-if not os.path.exists(msfile):
-    logging.error("Cannot find MS file.")
-    sys.exit(1)
-
-# open input/output MS
-ms = pt.table(msfile, readonly=False, ack=False)
-        
-freqtab = pt.table(msfile + '::SPECTRAL_WINDOW', ack=False)
-freq = freqtab.getcol('REF_FREQUENCY')[0]
-freqtab.close()
-wav = 299792458. / freq
-timepersample = ms.getcell('INTERVAL',0)
-
-# check if ms is time-ordered
-times = ms.getcol('TIME_CENTROID')
-if not all(times[i] <= times[i+1] for i in range(len(times)-1)):
-    logging.critical('This code cannot handle MS that are not time-sorted.')
-    sys.exit(1)
-
-# create column to smooth
-addcol(ms, options.incol, options.outcol)
-# if smoothing should not be performed
-if options.smooth == 'False':
-    sys.exit(0)
-
-# retore WEIGHT_SPECTRUM
-if 'WEIGHT_SPECTRUM_ORIG' in ms.colnames() and options.restore:
-    addcol(ms, 'WEIGHT_SPECTRUM_ORIG', 'WEIGHT_SPECTRUM')
-# backup WEIGHT_SPECTRUM
-elif options.weight and not options.nobackup:
-    addcol(ms, 'WEIGHT_SPECTRUM', 'WEIGHT_SPECTRUM_ORIG')
-
-# iteration on antenna1
-for ms_ant1 in ms.iter(["ANTENNA1"]):
-    ant1 = ms_ant1.getcol('ANTENNA1')[0]
-    a_ant2 = ms_ant1.getcol('ANTENNA2')
-    logging.debug('Working on antenna: %s' % ant1)
-
-    a_uvw = ms_ant1.getcol('UVW')
-    a_data = ms_ant1.getcol(options.outcol)
-    a_weights = ms_ant1.getcol('WEIGHT_SPECTRUM')
-    a_flags = ms_ant1.getcol('FLAG')
- 
-    for ant2 in set(a_ant2):
-        if ant1 == ant2: continue # skip autocorr
-        idx = np.where(a_ant2 == ant2)
-        
-        uvw = a_uvw[idx]
-        data = a_data[idx]
-        weights = a_weights[idx]
-        flags = a_flags[idx]
-   
-        # compute the FWHM
-        uvw_dist = np.sqrt(uvw[:, 0]**2 + uvw[:, 1]**2 + uvw[:, 2]**2)
-        dist = np.mean(uvw_dist) / 1.e3
-        if np.isnan(dist): continue # fix for missing anstennas
-    
-        stddev = options.ionfactor * (25.e3 / dist)**options.bscalefactor * (freq / 60.e6) # in sec
-        stddev = stddev/timepersample # in samples
-        logging.debug("%s - %s: dist = %.1f km: sigma=%.2f samples." % (ant1, ant2, dist, stddev))
-    
-        if stddev == 0: continue # fix for flagged antennas
-        if stddev < 0.5: continue # avoid very small smoothing
-    
-        flags[ np.isnan(data) ] = True # flag NaNs
-        weights[flags] = 0 # set weight of flagged data to 0
-        del flags
-        
-        # Multiply every element of the data by the weights, convolve both the scaled data and the weights, and then
-        # divide the convolved data by the convolved weights (translating flagged data into weight=0). That's basically the equivalent of a
-        # running weighted average with a Gaussian window function.
-        
-        # set bad data to 0 so nans do not propagate
-        data = np.nan_to_num(data*weights)
-        
-        # smear weighted data and weights
-        if options.onlyamp:
-            dataAMP = gfilter(np.abs(data), stddev, axis=0)
-            dataPH = np.angle(data)
-        else:
-            dataR = gfilter(np.real(data), stddev, axis=0)#, truncate=4.)
-            dataI = gfilter(np.imag(data), stddev, axis=0)#, truncate=4.)
-    
-        weights = gfilter(weights, stddev, axis=0)#, truncate=4.)
-    
-        # re-create data
-        if options.onlyamp:
-            data = dataAMP * ( np.cos(dataPH) + 1j*np.sin(dataPH) )
-        else:
-            data = (dataR + 1j * dataI)
-        data[(weights != 0)] /= weights[(weights != 0)] # avoid divbyzero
-    
-        #print np.count_nonzero(data[~flags]), np.count_nonzero(data[flags]), 100*np.count_nonzero(data[flags])/np.count_nonzero(data)
-        #print "NANs in flagged data: ", np.count_nonzero(np.isnan(data[flags]))
-        #print "NANs in unflagged data: ", np.count_nonzero(np.isnan(data[~flags]))
-        #print "NANs in weights: ", np.count_nonzero(np.isnan(weights))
-
-        a_data[idx] = data
-        if options.weight: a_weights[idx] = weights
-    
-    #logging.info('Writing %s column.' % options.outcol)
-    ms_ant1.putcol(options.outcol, a_data)
-
-    if options.weight:
-        #logging.warning('Writing WEIGHT_SPECTRUM column.')
-        ms_ant1.putcol('WEIGHT_SPECTRUM', a_weights)
-
-ms.close()
-logging.info("Done.")
diff --git a/Docker/scripts/InitSubtract_deep_sort_and_compute.py b/Docker/scripts/InitSubtract_deep_sort_and_compute.py
deleted file mode 100755
index 0776b06ac3bc13b9676798e50e02301c140c29ad..0000000000000000000000000000000000000000
--- a/Docker/scripts/InitSubtract_deep_sort_and_compute.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to sort a list of MSs into frequency-bands, and compute additional values needed for initsubtract
-"""
-import casacore.tables as pt
-import sys, os
-import numpy as np
-from lofarpipe.support.data_map import DataMap
-from lofarpipe.support.data_map import DataProduct
-import argparse
-from argparse import RawTextHelpFormatter
-
-class Band(object):
-    """
-    The Band object contains parameters needed for each band
-    """
-    def __init__(self, MSfiles):
-        self.files = MSfiles
-        self.msnames = [ MS.split('/')[-1] for MS in self.files ]
-        self.numMS = len(self.files)
-        # Get the frequency info and set name
-        sw = pt.table(self.files[0]+'::SPECTRAL_WINDOW', ack=False)
-        self.freq = sw.col('REF_FREQUENCY')[0]
-        self.nchan = sw.col('NUM_CHAN')[0]
-        self.chan_freqs_hz = sw.col('CHAN_FREQ')[0]
-        self.chan_width_hz = sw.col('CHAN_WIDTH')[0][0]
-        sw.close()
-        self.name = str(int(self.freq/1e6))
-        # Get the station diameter
-        ant = pt.table(self.files[0]+'::ANTENNA', ack=False)
-        self.diam = float(ant.col('DISH_DIAMETER')[0])
-        ant.close()
-
-    def get_image_sizes(self, cellsize_highres_deg=None, cellsize_lowres_deg=None,
-                        fieldsize_highres=2.5, fieldsize_lowres=6.5):
-        """
-        Sets sizes for initsubtract images
-
-        The image sizes are scaled from the mean primary-beam FWHM. For
-        the high-res image, we use 2.5 * FWHM; for low-res, we use 6.5 * FHWM.
-
-        Parameters
-        ----------
-        cellsize_highres_deg : float, optional
-            cellsize for the high-res images in deg
-        cellsize_lowres_deg : float, optional
-            cellsize for the low-res images in deg
-        fieldsize_highres : float, optional
-            How many FWHM's shall the high-res images be.
-        fieldsize_lowres : float, optional
-            How many FWHM's shall the low-res images be.
-        """
-        if cellsize_highres_deg:
-            self.cellsize_highres_deg = cellsize_highres_deg
-        if cellsize_lowres_deg:
-            self.cellsize_lowres_deg = cellsize_lowres_deg
-        if not hasattr(self, 'mean_el_rad'):
-            for MS_id in range(self.numMS):
-                # calculate mean elevation
-                tab = pt.table(self.files[MS_id], ack=False)
-                el_values = pt.taql("SELECT mscal.azel1()[1] AS el from "
-                                    + self.files[MS_id] + " limit ::10000").getcol("el")
-                if MS_id == 0:
-                    global_el_values = el_values
-                else:
-                    global_el_values = np.hstack( (global_el_values, el_values ) )
-            self.mean_el_rad = np.mean(global_el_values)
-
-        # Calculate mean FOV
-        sec_el = 1.0 / np.sin(self.mean_el_rad)
-        self.fwhm_deg = 1.1 * ((3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el
-        self.imsize_high_res = self.get_optimum_size(self.fwhm_deg
-                                                     /self.cellsize_highres_deg * fieldsize_highres)
-        self.imsize_low_res = self.get_optimum_size(self.fwhm_deg
-                                                    /self.cellsize_lowres_deg * fieldsize_lowres)
-        return (self.imsize_high_res, self.imsize_low_res)
-
-    def get_optimum_size(self, size):
-        """
-        Gets the nearest optimum image size
-
-        Taken from the casa source code (cleanhelper.py)
-
-        Parameters
-        ----------
-        size : int
-            Target image size in pixels
-
-        Returns
-        -------
-        optimum_size : int
-            Optimum image size nearest to target size
-
-        """
-        import numpy
-
-        def prime_factors(n, douniq=True):
-            """ Return the prime factors of the given number. """
-            factors = []
-            lastresult = n
-            sqlast=int(numpy.sqrt(n))+1
-            if n == 1:
-                return [1]
-            c=2
-            while 1:
-                 if (lastresult == 1) or (c > sqlast):
-                     break
-                 sqlast=int(numpy.sqrt(lastresult))+1
-                 while 1:
-                     if(c > sqlast):
-                         c=lastresult
-                         break
-                     if lastresult % c == 0:
-                         break
-                     c += 1
-                 factors.append(c)
-                 lastresult = lastresult // c
-            if (factors==[]): factors=[n]
-            return  numpy.unique(factors).tolist() if douniq else factors
-
-        n = int(size)
-        if (n%2 != 0):
-            n+=1
-        fac=prime_factors(n, False)
-        for k in range(len(fac)):
-            if (fac[k] > 7):
-                val=fac[k]
-                while (numpy.max(prime_factors(val)) > 7):
-                    val +=1
-                fac[k]=val
-        newlarge=numpy.product(fac)
-        for k in range(n, newlarge, 2):
-            if ((numpy.max(prime_factors(k)) < 8)):
-                return k
-        return newlarge
-
-    def get_averaging_steps(self):
-        """
-        Sets the averaging step sizes
-
-        Note: the frequency step must be an even divisor of the number of
-        channels
-
-        """
-        # Get time per sample and number of samples
-        t = pt.table(self.files[0], readonly=True, ack=False)
-        for t2 in t.iter(["ANTENNA1","ANTENNA2"]):
-            if (t2.getcell('ANTENNA1',0)) < (t2.getcell('ANTENNA2',0)):
-                self.timestep_sec = t2[1]['TIME']-t2[0]['TIME'] # sec
-                break
-        t.close()
-        # generate a (numpy-)array with the divisors of nchan
-        tmp_divisors = []
-        for step in range(self.nchan,0,-1):
-            if (self.nchan % step) == 0:
-                tmp_divisors.append(step)
-        freq_divisors = np.array(tmp_divisors)
-
-        # Average to 0.2 MHz per channel and 16 sec per time slot
-        initsubtract_freqstep = max(1, min(int(round(0.2 * 1e6 / self.chan_width_hz)), self.nchan))
-        initsubtract_freqstep = freq_divisors[np.argmin(np.abs(freq_divisors-initsubtract_freqstep))]
-        initsubtract_timestep = max(1, int(round(16.0 / self.timestep_sec)))
-
-        return (initsubtract_freqstep, initsubtract_timestep)
-
-    def get_nwavelengths(self, cellsize_deg, timestep_sec,):
-        """
-        Returns nwavelengths for WSClean BL-based averaging
-        The value depends on the integration time given the specified maximum
-        allowed smearing. We scale it from the imaging cell size assuming normal
-        sampling as:
-        max baseline in nwavelengths = 1 / theta_rad ~= 1 / (cellsize_deg * 3 * pi / 180)
-        nwavelengths = max baseline in nwavelengths * 2 * pi *
-            integration time in seconds / (24 * 60 * 60) / 4
-        Parameters
-        ----------
-        cellsize_deg : float
-            Pixel size of image in degrees
-        timestep_sec : float
-            Length of one timestep in seconds
-        """
-        max_baseline = 1 / (3 * cellsize_deg * np.pi / 180)
-        wsclean_nwavelengths_time = int(max_baseline * 2*np.pi * timestep_sec /
-            (24 * 60 * 60) / 4)
-        return wsclean_nwavelengths_time
-
-
-def main(ms_input, outmapname=None, mapfile_dir=None, cellsize_highres_deg=0.00208, cellsize_lowres_deg=0.00694,
-         fieldsize_highres=2.5, fieldsize_lowres=6.5, image_padding=1., y_axis_stretch=1.):
-    """
-    Check a list of MS files for missing frequencies
-
-    Parameters
-    ----------
-    ms_input : list or str
-        List of MS filenames, or string with list, or path to a mapfile
-    outmapname: str
-        Name of output mapfile
-    mapfile_dir : str
-        Directory for output mapfile
-    cellsize_highres_deg : float, optional
-        cellsize for the high-res images in deg
-    cellsize_lowres_deg : float, optional
-        cellsize for the low-res images in deg
-    fieldsize_highres : float, optional
-        How many FWHM's shall the high-res images be.
-    fieldsize_lowres : float, optional
-        How many FWHM's shall the low-res images be.
-    image_padding : float, optional
-        How much padding shall we add to the padded image sizes.
-    y_axis_stretch : float, optional
-        How much shall the y-axis be stretched or compressed.
-
-    Returns
-    -------
-    result : dict
-        Dict with the name of the generated mapfiles
-
-    """
-
-    if not outmapname or not mapfile_dir:
-        raise ValueError('sort_times_into_freqGroups: outmapname and mapfile_dir are needed!')
-    if type(ms_input) is str:
-        if ms_input.startswith('[') and ms_input.endswith(']'):
-            ms_list = [f.strip(' \'\"') for f in ms_input.strip('[]').split(',')]
-        else:
-            map_in = DataMap.load(ms_input)
-            map_in.iterator = DataMap.SkipIterator
-            ms_list = []
-            for fname in map_in:
-                if fname.startswith('[') and fname.endswith(']'):
-                    for f in fname.strip('[]').split(','):
-                        ms_list.append(f.strip(' \'\"'))
-                else:
-                    ms_list.append(fname.strip(' \'\"'))
-    elif type(ms_input) is list:
-        ms_list = [str(f).strip(' \'\"') for f in ms_input]
-    else:
-        raise TypeError('sort_into_freqBands: type of "ms_input" unknown!')
-
-    cellsize_highres_deg = float(cellsize_highres_deg)
-    cellsize_lowres_deg = float(cellsize_lowres_deg)
-    fieldsize_highres = float(fieldsize_highres)
-    fieldsize_lowres = float(fieldsize_lowres)
-    image_padding = float(image_padding)
-    y_axis_stretch = float(y_axis_stretch)
-
-    msdict = {}
-    for ms in ms_list:
-        # group all MSs by frequency
-        sw = pt.table(ms+'::SPECTRAL_WINDOW', ack=False)
-        msfreq = int(sw.col('REF_FREQUENCY')[0])
-        sw.close()
-        if msfreq in msdict:
-            msdict[msfreq].append(ms)
-        else:
-            msdict[msfreq] = [ms]
-    bands = []
-    bandfreqs = []
-    print("InitSubtract_deep_sort_and_compute.py: Putting files into bands.")
-    for MSkey in msdict.keys():
-        bands.append( Band(msdict[MSkey]) )
-        bandfreqs.append( Band(msdict[MSkey]).freq )
-
-    ## min freq gives largest image size for deep image
-    bandfreqs = np.array(bandfreqs)
-    minfreq = np.min(bandfreqs)
-    bandmin = np.argmin(bandfreqs)
-    ## need to map the output from wsclean channels to the right frequencies
-    ## just put the bands in the right freq order
-    wsclean_channum = np.argsort(bandfreqs)
-    bands = np.array(bands)
-    bands = bands[wsclean_channum]
-
-    #minfreq = 1e9
-    #for ib, band in enumerate(bands):
-        #if band.freq < minfreq:
-            #minfreq = band.freq
-            #bandmin = ib
-
-    group_map = MultiDataMap()
-    file_single_map = DataMap([])
-    high_size_map = DataMap([])
-    low_size_map = DataMap([])
-    high_paddedsize_map = DataMap([])
-    low_paddedsize_map = DataMap([])
-    numfiles = 0
-    nbands = np.int(len(bands)/10)
-    if nbands > 8:
-        nchansout_clean1 = np.int(nbands/4)
-    elif nbands > 4:
-        nchansout_clean1 = np.int(nbands/2)
-    else:
-        nchansout_clean1 = np.int(nbands)
-    if nchansout_clean1 < 2:
-        nchansout_clean1 = 2
-
-    (freqstep, timestep) = bands[0].get_averaging_steps()
-    int_time_sec = bands[0].timestep_sec * timestep   # timestep_sec gets added to band object in get_averaging_steps()
-    nwavelengths_high = bands[0].get_nwavelengths(cellsize_highres_deg, int_time_sec)
-    nwavelengths_low = bands[0].get_nwavelengths(cellsize_lowres_deg, int_time_sec)
-
-    print("InitSubtract_deep_sort_and_compute.py: analyzing data...")
-    for band in bands:
-        group_map.append(MultiDataProduct('localhost', band.files, False))
-        numfiles += len(band.files)
-        for filename in band.files:
-            file_single_map.append(DataProduct('localhost', filename, False))
-        (imsize_high_res, imsize_low_res) = band.get_image_sizes(cellsize_highres_deg, cellsize_lowres_deg,
-                                                                 fieldsize_highres, fieldsize_lowres)
-        imsize_high_res_stretch = band.get_optimum_size(int(imsize_high_res*y_axis_stretch))
-        high_size_map.append(DataProduct('localhost', str(imsize_high_res)+" "+str(imsize_high_res_stretch), False))
-        imsize_low_res_stretch = band.get_optimum_size(int(imsize_low_res*y_axis_stretch))
-        low_size_map.append(DataProduct('localhost', str(imsize_low_res)+" "+str(imsize_low_res_stretch), False))
-        imsize_high_pad = band.get_optimum_size(int(imsize_high_res*image_padding))
-        imsize_high_pad_stretch = band.get_optimum_size(int(imsize_high_res*image_padding*y_axis_stretch))
-        high_paddedsize_map.append(DataProduct('localhost', str(imsize_high_pad)+" "+str(imsize_high_pad_stretch), False))
-        imsize_low_pad = band.get_optimum_size(int(imsize_low_res*image_padding))
-        imsize_low_pad_stretch = band.get_optimum_size(int(imsize_low_res*image_padding*y_axis_stretch))
-        low_paddedsize_map.append(DataProduct('localhost', str(imsize_low_pad)+" "+str(imsize_low_pad_stretch), False))
-
-        if band.freq == minfreq:
-            deep_imsize_high_res = imsize_high_res
-            deep_imsize_high_res_stretch = imsize_high_res_stretch
-            deep_imsize_high_pad = imsize_high_pad
-            deep_imsize_high_pad_stretch = imsize_high_pad_stretch
-            deep_imsize_low_res = imsize_low_res
-            deep_imsize_low_res_stretch = imsize_low_res_stretch
-            deep_imsize_low_pad = imsize_low_pad
-            deep_imsize_low_pad_stretch = imsize_low_pad_stretch
-
-    deep_high_size_map = DataMap([DataProduct('localhost', str(deep_imsize_high_res)+" "+str(deep_imsize_high_res_stretch), False)])
-    deep_high_paddedsize_map = DataMap([DataProduct('localhost', str(deep_imsize_high_pad)+" "+str(deep_imsize_high_pad_stretch), False)])
-    deep_low_size_map = DataMap([DataProduct('localhost', str(deep_imsize_low_res)+" "+str(deep_imsize_low_res_stretch), False)])
-    deep_low_paddedsize_map = DataMap([DataProduct('localhost', str(deep_imsize_low_pad)+" "+str(deep_imsize_low_pad_stretch), False)])
-    nbands_map = DataMap([DataProduct('localhost', str(nbands), False)])
-    nchansout_clean1_map = DataMap([DataProduct('localhost', str(nchansout_clean1), False)])
-
-    # get mapfiles for freqstep and timestep with the length of single_map
-    freqstep_map = DataMap([])
-    timestep_map = DataMap([])
-    nwavelengths_high_map        = DataMap([])
-    nwavelengths_low_map         = DataMap([])
-
-    for index in range(numfiles):
-        # set time and frequency averaging values (in sec and Hz)
-        freqstep_map.append(DataProduct('localhost', str(freqstep*bands[0].chan_width_hz), False))
-        timestep_map.append(DataProduct('localhost', str(timestep*bands[0].timestep_sec), False))
-    nwavelengths_high_map.append(DataProduct('localhost', str(nwavelengths_high), False))
-    nwavelengths_low_map.append(DataProduct('localhost', str(nwavelengths_low), False))
-
-    groupmapname = os.path.join(mapfile_dir, outmapname)
-    group_map.save(groupmapname)
-    file_single_mapname = os.path.join(mapfile_dir, outmapname+'_single')
-    file_single_map.save(file_single_mapname)
-
-    high_sizename = os.path.join(mapfile_dir, outmapname+'_high_size')
-    high_size_map.save(high_sizename)
-    low_sizename = os.path.join(mapfile_dir, outmapname+'_low_size')
-    low_size_map.save(low_sizename)
-    high_padsize_name = os.path.join(mapfile_dir, outmapname+'_high_padded_size')
-    high_paddedsize_map.save(high_padsize_name)
-    low_padsize_name = os.path.join(mapfile_dir, outmapname+'_low_padded_size')
-    low_paddedsize_map.save(low_padsize_name)
-
-    deep_high_sizename = os.path.join(mapfile_dir, outmapname+'_deep_high_size')
-    deep_high_size_map.save(deep_high_sizename)
-    deep_low_sizename = os.path.join(mapfile_dir, outmapname+'_deep_low_size')
-    deep_low_size_map.save(deep_low_sizename)
-    deep_high_padsize_name = os.path.join(mapfile_dir, outmapname+'_deep_high_padded_size')
-    deep_high_paddedsize_map.save(deep_high_padsize_name)
-    deep_low_padsize_name = os.path.join(mapfile_dir, outmapname+'_deep_low_padded_size')
-    deep_low_paddedsize_map.save(deep_low_padsize_name)
-
-    nbands_mapname = os.path.join(mapfile_dir, outmapname+'_nbands')
-    nbands_map.save(nbands_mapname)
-    nchansout_clean1_mapname = os.path.join(mapfile_dir, outmapname+'_nchansout_clean1')
-    nchansout_clean1_map.save(nchansout_clean1_mapname)
-
-    freqstepname = os.path.join(mapfile_dir, outmapname+'_freqstep')
-    freqstep_map.save(freqstepname)
-    timestepname = os.path.join(mapfile_dir, outmapname+'_timestep')
-    timestep_map.save(timestepname)
-    nwavelengths_high_name = os.path.join(mapfile_dir, outmapname+'_nwavelengths_high')
-    nwavelengths_high_map.save(nwavelengths_high_name)
-    nwavelengths_low_name = os.path.join(mapfile_dir, outmapname+'_nwavelengths_low')
-    nwavelengths_low_map.save(nwavelengths_low_name)
-
-    result = {'groupmap': groupmapname, 'single_mapfile' : file_single_mapname,
-              'high_size_mapfile' : high_sizename, 'low_size_mapfile' : low_sizename,
-              'high_padsize_mapfile' : high_padsize_name, 'low_padsize_mapfile' : low_padsize_name,
-              'deep_high_size_mapfile' : deep_high_sizename, 'deep_low_size_mapfile' : deep_low_sizename,
-              'deep_high_padsize_mapfile' : deep_high_padsize_name, 'deep_low_padsize_mapfile' : deep_low_padsize_name,
-              'nbands' : nbands_mapname, 'nchansout_clean1' : nchansout_clean1_mapname,
-              'freqstep' : freqstepname, 'timestep' : timestepname, 'nwavelengths_high_mapfile': nwavelengths_high_name,
-              'nwavelengths_low_mapfile': nwavelengths_low_name}
-    return result
-
-
-class MultiDataProduct(DataProduct):
-    """
-    Class representing multiple files in a DataProduct.
-    """
-    def __init__(self, host=None, file=None, skip=True):
-        super(MultiDataProduct, self).__init__(host, file, skip)
-        if not file:
-            self.file = list()
-        else:
-            self._set_file(file)
-
-    def __repr__(self):
-        """Represent an instance as a Python dict"""
-        return (
-            "{{'host': '{0}', 'file': {1}, 'skip': {2}}}".format(self.host, self.file, str(self.skip))
-        )
-
-    def __str__(self):
-        """Print an instance as 'host:[filelist]'"""
-        return ':'.join((self.host, str(self.file)))
-
-    def _set_file(self, data):
-        try:
-            # Try parsing as a list
-            if isinstance(data, list):
-                self.file = data
-            if isinstance(data, DataProduct):
-                self._from_dataproduct(data)
-            if isinstance(data, DataMap):
-                self._from_datamap(data)
-
-        except TypeError:
-            raise DataProduct("No known method to set a filelist from %s" % str(file))
-
-    def _from_dataproduct(self, prod):
-        self.host = prod.host
-        self.file = prod.file
-        self.skip = prod.skip
-
-    def _from_datamap(self, inmap):
-        filelist = {}
-        for item in inmap:
-            if not item.host in filelist:
-                filelist[item.host] = []
-            filelist[item.host].append(item.file)
-        self.file = filelist['i am']
-
-    def append(self, item):
-        self.file.append(item)
-
-
-class MultiDataMap(DataMap):
-    """
-    Class representing a specialization of data-map, a collection of data
-    products located on the same node, skippable as a set and individually
-    """
-    @DataMap.data.setter
-    def data(self, data):
-        if isinstance(data, DataMap):
-            mdpdict = {}
-            data.iterator = DataMap.SkipIterator
-            for item in data:
-                if not item.host in mdpdict:
-                    mdpdict[item.host] = []
-                mdpdict[item.host].append(item.file)
-            mdplist = []
-            for k, v in mdpdict.iteritems():
-                mdplist.append(MultiDataProduct(k, v, False))
-            self._set_data(mdplist, dtype=MultiDataProduct)
-        elif isinstance(data, MultiDataProduct):
-            self._set_data(data, dtype=MultiDataProduct)
-        elif not data:
-            pass
-        else:
-            self._set_data(data, dtype=MultiDataProduct)
-
-    def split_list(self, number):
-        mdplist = []
-        for item in self.data:
-            for i in range(0, len(item.file), number):
-                chunk = item.file[i:i+number]
-                mdplist.append(MultiDataProduct(item.host, chunk, item.skip))
-        self._set_data(mdplist)
diff --git a/Docker/scripts/InitSubtract_sort_and_compute.py b/Docker/scripts/InitSubtract_sort_and_compute.py
deleted file mode 100755
index 1bd1443662bcb6abc197c2bd7df5661bdb93d751..0000000000000000000000000000000000000000
--- a/Docker/scripts/InitSubtract_sort_and_compute.py
+++ /dev/null
@@ -1,479 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to sort a list of MSs into frequency-bands, and compute additional values needed for initsubtract
-"""
-import pyrap.tables as pt
-import os
-import numpy as np
-from lofarpipe.support.data_map import DataMap
-from lofarpipe.support.data_map import DataProduct
-
-class Band(object):
-    """
-    The Band object contains parameters needed for each band
-    """
-    def __init__(self, MSfiles):
-        self.files = MSfiles
-        self.msnames = [ MS.split('/')[-1] for MS in self.files ]
-        self.numMS = len(self.files)
-        # Get the frequency info and set name
-        sw = pt.table(self.files[0]+'::SPECTRAL_WINDOW', ack=False)
-        self.freq = sw.col('REF_FREQUENCY')[0]
-        self.nchan = sw.col('NUM_CHAN')[0]
-        self.chan_freqs_hz = sw.col('CHAN_FREQ')[0]
-        self.chan_width_hz = sw.col('CHAN_WIDTH')[0][0]
-        sw.close()
-        self.name = str(int(self.freq/1e6))
-        # Get the station diameter
-        ant = pt.table(self.files[0]+'::ANTENNA', ack=False)
-        self.diam = float(ant.col('DISH_DIAMETER')[0])
-        ant.close()
-
-
-
-    def get_image_sizes(self, cellsize_highres_deg=None, cellsize_lowres_deg=None,
-                        fieldsize_highres=2.5, fieldsize_lowres=6.5):
-        """
-        Sets sizes for initsubtract images
-
-        The image sizes are scaled from the mean primary-beam FWHM. For
-        the high-res image, we use 2.5 * FWHM; for low-res, we use 6.5 * FHWM.
-
-        Parameters
-        ----------
-        cellsize_highres_deg : float, optional
-            cellsize for the high-res images in deg
-        cellsize_lowres_deg : float, optional
-            cellsize for the low-res images in deg
-        fieldsize_highres : float, optional
-            How many FWHM's shall the high-res images be.
-        fieldsize_lowres : float, optional
-            How many FWHM's shall the low-res images be.
-        """
-        if cellsize_highres_deg:
-            self.cellsize_highres_deg = cellsize_highres_deg
-        if cellsize_lowres_deg:
-            self.cellsize_lowres_deg = cellsize_lowres_deg
-        if not hasattr(self, 'mean_el_rad'):
-            for MS_id in xrange(self.numMS):
-                # calculate mean elevation
-                tab = pt.table(self.files[MS_id], ack=False)
-                el_values = pt.taql("SELECT mscal.azel1()[1] AS el from "
-                                    + self.files[MS_id] + " limit ::10000").getcol("el")
-                if MS_id == 0:
-                    global_el_values = el_values
-                else:
-                    global_el_values = np.hstack( (global_el_values, el_values ) )
-            self.mean_el_rad = np.mean(global_el_values)
-
-        # Calculate mean FOV
-        sec_el = 1.0 / np.sin(self.mean_el_rad)
-        self.fwhm_deg = 1.1 * ((3.0e8 / self.freq) / self.diam) * 180. / np.pi * sec_el
-        self.imsize_high_res = self.get_optimum_size(self.fwhm_deg
-                                                     /self.cellsize_highres_deg * fieldsize_highres)
-        self.imsize_low_res = self.get_optimum_size(self.fwhm_deg
-                                                    /self.cellsize_lowres_deg * fieldsize_lowres)
-        return (self.imsize_high_res, self.imsize_low_res)
-
-    def get_optimum_size(self, size):
-        """
-        Gets the nearest optimum image size
-
-        Taken from the casa source code (cleanhelper.py)
-
-        Parameters
-        ----------
-        size : int
-            Target image size in pixels
-
-        Returns
-        -------
-        optimum_size : int
-            Optimum image size nearest to target size
-
-        """
-        import numpy
-
-        def prime_factors(n, douniq=True):
-            """ Return the prime factors of the given number. """
-            factors = []
-            lastresult = n
-            sqlast=int(numpy.sqrt(n))+1
-            if n == 1:
-                return [1]
-            c=2
-            while 1:
-                 if (lastresult == 1) or (c > sqlast):
-                     break
-                 sqlast=int(numpy.sqrt(lastresult))+1
-                 while 1:
-                     if(c > sqlast):
-                         c=lastresult
-                         break
-                     if lastresult % c == 0:
-                         break
-                     c += 1
-                 factors.append(c)
-                 lastresult /= c
-            if (factors==[]): factors=[n]
-            return  numpy.unique(factors).tolist() if douniq else factors
-
-        n = int(size)
-        if (n%2 != 0):
-            n+=1
-        fac=prime_factors(n, False)
-        for k in range(len(fac)):
-            if (fac[k] > 7):
-                val=fac[k]
-                while (numpy.max(prime_factors(val)) > 7):
-                    val +=1
-                fac[k]=val
-        newlarge=numpy.product(fac)
-        for k in range(n, newlarge, 2):
-            if ((numpy.max(prime_factors(k)) < 8)):
-                return k
-        return newlarge
-
-    def get_averaging_steps(self):
-        """
-        Sets the averaging step sizes
-
-        Note: the frequency step must be an even divisor of the number of
-        channels
-
-        """
-        # Get time per sample and number of samples
-        t = pt.table(self.files[0], readonly=True, ack=False)
-        for t2 in t.iter(["ANTENNA1","ANTENNA2"]):
-            if (t2.getcell('ANTENNA1',0)) < (t2.getcell('ANTENNA2',0)):
-                self.timestep_sec = t2[1]['TIME']-t2[0]['TIME'] # sec
-                break
-        t.close()
-        # generate a (numpy-)array with the divisors of nchan
-        tmp_divisors = []
-        for step in range(self.nchan,0,-1):
-            if (self.nchan % step) == 0:
-                tmp_divisors.append(step)
-        freq_divisors = np.array(tmp_divisors)
-
-        # For initsubtract, average to 0.5 MHz per channel and 20 sec per time
-        # slot. Since each band is imaged separately and the smearing and image
-        # sizes both scale linearly with frequency, a single frequency and time
-        # step is valid for all bands
-        initsubtract_freqstep = max(1, min(int(round(0.5 * 1e6 / self.chan_width_hz)), self.nchan))
-        initsubtract_freqstep = freq_divisors[np.argmin(np.abs(freq_divisors-initsubtract_freqstep))]
-        initsubtract_timestep = max(1, int(round(20.0 / self.timestep_sec)))
-
-        return (initsubtract_freqstep, initsubtract_timestep)
-
-    def nwavelengths(self, cellsize_highres_deg, cellsize_lowres_deg, initsubtract_timestep):
-        int_time_sec = self.timestep_sec * initsubtract_timestep
-        max_baseline_in_nwavelenghts_h = 1.0/(cellsize_highres_deg*3.0*np.pi/180.0)
-        max_baseline_in_nwavelenghts_l = 1.0/(cellsize_lowres_deg*3.0*np.pi/180.0)
-        self.nwavelengths_high	=	max_baseline_in_nwavelenghts_h*2.0*np.pi*int_time_sec/(24.0*60.0*60.0)/2
-        self.nwavelengths_low	=	max_baseline_in_nwavelenghts_l*2.0*np.pi*int_time_sec/(24.0*60.0*60.0)/2
-        return (self.nwavelengths_high, self.nwavelengths_low)
-
-
-def input2bool(invar):
-    if invar is None:
-        return None
-    if isinstance(invar, bool):
-        return invar
-    elif isinstance(invar, str):
-        if invar.upper() == 'TRUE' or invar == '1':
-            return True
-        elif invar.upper() == 'FALSE' or invar == '0':
-            return False
-        else:
-            raise ValueError('input2bool: Cannot convert string "'+invar+'" to boolean!')
-    elif isinstance(invar, int) or isinstance(invar, float):
-        return bool(invar)
-    else:
-        raise TypeError('input2bool: Unsupported data type:'+str(type(invar)))
-
-
-def main(ms_input, outmapname=None, mapfile_dir=None, cellsize_highres_deg=0.00208, cellsize_lowres_deg=0.00694,
-         fieldsize_highres=2.5, fieldsize_lowres=6.5, image_padding=1., y_axis_stretch=1.,
-         calc_y_axis_stretch=False, apply_y_axis_stretch_highres=True, apply_y_axis_stretch_lowres=True):
-    """
-    Check a list of MS files for missing frequencies
-
-    Parameters
-    ----------
-    ms_input : list or str
-        List of MS filenames, or string with list, or path to a mapfile
-    outmapname: str
-        Name of output mapfile
-    mapfile_dir : str
-        Directory for output mapfile
-    cellsize_highres_deg : float, optional
-        cellsize for the high-res images in deg
-    cellsize_lowres_deg : float, optional
-        cellsize for the low-res images in deg
-    fieldsize_highres : float, optional
-        How many FWHM's shall the high-res images be.
-    fieldsize_lowres : float, optional
-        How many FWHM's shall the low-res images be.
-    image_padding : float, optional
-        How much padding shall we add to the padded image sizes.
-    y_axis_stretch : float, optional
-        How much shall the y-axis be stretched or compressed.
-    calc_y_axis_stretch : bool, optional
-        Adjust the image sizes returned by this script for the mean elevation.
-        If True, the value of y_axis_stretch above is ignored
-    apply_y_axis_stretch_highres : bool, optional
-        Apply the y-axis stretch to the high-res image sizes
-    apply_y_axis_stretch_lowres : bool, optional
-        Apply the y-axis stretch to the low-res image sizes
-
-    Returns
-    -------
-    result : dict
-        Dict with the name of the generated mapfiles
-
-    """
-    if not outmapname or not mapfile_dir:
-        raise ValueError('sort_times_into_freqGroups: outmapname and mapfile_dir are needed!')
-    if type(ms_input) is str:
-        if ms_input.startswith('[') and ms_input.endswith(']'):
-            ms_list = [f.strip(' \'\"') for f in ms_input.strip('[]').split(',')]
-        else:
-            map_in = DataMap.load(ms_input)
-            map_in.iterator = DataMap.SkipIterator
-            ms_list = []
-            for fname in map_in:
-                if fname.startswith('[') and fname.endswith(']'):
-                    for f in fname.strip('[]').split(','):
-                        ms_list.append(f.strip(' \'\"'))
-                else:
-                    ms_list.append(fname.strip(' \'\"'))
-    elif type(ms_input) is list:
-        ms_list = [str(f).strip(' \'\"') for f in ms_input]
-    else:
-        raise TypeError('sort_into_freqBands: type of "ms_input" unknown!')
-
-    cellsize_highres_deg = float(cellsize_highres_deg)
-    cellsize_lowres_deg = float(cellsize_lowres_deg)
-    fieldsize_highres = float(fieldsize_highres)
-    fieldsize_lowres = float(fieldsize_lowres)
-    image_padding = float(image_padding)
-    y_axis_stretch = float(y_axis_stretch)
-    calc_y_axis_stretch = input2bool(calc_y_axis_stretch)
-    apply_y_axis_stretch_highres = input2bool(apply_y_axis_stretch_highres)
-    apply_y_axis_stretch_lowres = input2bool(apply_y_axis_stretch_lowres)
-
-    msdict = {}
-    for ms in ms_list:
-        # group all MSs by frequency
-        sw = pt.table(ms+'::SPECTRAL_WINDOW', ack=False)
-        msfreq = int(sw.col('REF_FREQUENCY')[0])
-        sw.close()
-        if msfreq in msdict:
-            msdict[msfreq].append(ms)
-        else:
-            msdict[msfreq] = [ms]
-    bands = []
-    print "InitSubtract_sort_and_compute.py: Putting files into bands."
-    for MSkey in msdict.keys():
-        bands.append( Band(msdict[MSkey]) )
-
-    group_map = MultiDataMap()
-    file_single_map = DataMap([])
-    high_size_map = DataMap([])
-    low_size_map = DataMap([])
-    high_paddedsize_map = DataMap([])
-    low_paddedsize_map = DataMap([])
-    numfiles = 0
-    for i, band in enumerate(bands):
-        print "InitSubtract_sort_and_compute.py: Working on Band:",band.name
-        group_map.append(MultiDataProduct('localhost', band.files, False))
-        numfiles += len(band.files)
-        for filename in band.files:
-            file_single_map.append(DataProduct('localhost', filename, False))
-        (imsize_high_res, imsize_low_res) = band.get_image_sizes(cellsize_highres_deg, cellsize_lowres_deg,
-                                                                 fieldsize_highres, fieldsize_lowres)
-
-        # Calculate y_axis_stretch if desired
-        if calc_y_axis_stretch:
-            if i == 0:
-                y_axis_stretch = 1.0 / np.sin(band.mean_el_rad)
-                print "InitSubtract_sort_and_compute.py: Using y-axis stretch of:",y_axis_stretch
-                y_axis_stretch_lowres = y_axis_stretch
-                y_axis_stretch_highres = y_axis_stretch
-        else:
-            y_axis_stretch_lowres = 1.0
-            y_axis_stretch_highres = 1.0
-
-        # Adjust sizes so that we get the correct ones below
-        if not apply_y_axis_stretch_highres:
-            y_axis_stretch_highres = 1.0
-        if not apply_y_axis_stretch_lowres:
-            y_axis_stretch_lowres = 1.0
-        imsize_low_res /= y_axis_stretch_lowres
-        imsize_high_res /= y_axis_stretch_highres
-
-        imsize_high_res = band.get_optimum_size(int(imsize_high_res))
-        imsize_high_res_stretch = band.get_optimum_size(int(imsize_high_res*y_axis_stretch_highres))
-        high_size_map.append(DataProduct('localhost', str(imsize_high_res)+" "+str(imsize_high_res_stretch), False))
-
-        imsize_low_res = band.get_optimum_size(int(imsize_low_res))
-        imsize_low_res_stretch = band.get_optimum_size(int(imsize_low_res*y_axis_stretch_lowres))
-        low_size_map.append(DataProduct('localhost', str(imsize_low_res)+" "+str(imsize_low_res_stretch), False))
-
-        imsize_high_pad = band.get_optimum_size(int(imsize_high_res*image_padding))
-        imsize_high_pad_stretch = band.get_optimum_size(int(imsize_high_res*image_padding*y_axis_stretch_highres))
-        high_paddedsize_map.append(DataProduct('localhost', str(imsize_high_pad)+" "+str(imsize_high_pad_stretch), False))
-
-        imsize_low_pad = band.get_optimum_size(int(imsize_low_res*image_padding))
-        imsize_low_pad_stretch = band.get_optimum_size(int(imsize_low_res*image_padding*y_axis_stretch_lowres))
-        low_paddedsize_map.append(DataProduct('localhost', str(imsize_low_pad)+" "+str(imsize_low_pad_stretch), False))
-
-    print "InitSubtract_sort_and_compute.py: Computing averaging steps."
-    (freqstep, timestep) = bands[0].get_averaging_steps()
-    (nwavelengths_high, nwavelengths_low) = bands[0].nwavelengths(cellsize_highres_deg,
-        cellsize_lowres_deg, timestep)
-
-    # get mapfiles for freqstep and timestep with the length of single_map
-    freqstep_map = DataMap([])
-    timestep_map = DataMap([])
-    nwavelengths_high_map = DataMap([])
-    nwavelengths_low_map = DataMap([])
-    for index in xrange(numfiles):
-        freqstep_map.append(DataProduct('localhost', str(freqstep), False))
-        timestep_map.append(DataProduct('localhost', str(timestep), False))
-        freqstep_map.append(DataProduct('localhost', str(freqstep), False))
-        timestep_map.append(DataProduct('localhost', str(timestep), False))
-        nwavelengths_high_map.append(DataProduct('localhost', str(nwavelengths_high), False))
-        nwavelengths_low_map.append(DataProduct('localhost', str(nwavelengths_low), False))
-
-    groupmapname = os.path.join(mapfile_dir, outmapname)
-    group_map.save(groupmapname)
-    file_single_mapname = os.path.join(mapfile_dir, outmapname+'_single')
-    file_single_map.save(file_single_mapname)
-    high_sizename = os.path.join(mapfile_dir, outmapname+'_high_size')
-    high_size_map.save(high_sizename)
-    low_sizename = os.path.join(mapfile_dir, outmapname+'_low_size')
-    low_size_map.save(low_sizename)
-    high_padsize_name = os.path.join(mapfile_dir, outmapname+'_high_padded_size')
-    high_paddedsize_map.save(high_padsize_name)
-    low_padsize_name = os.path.join(mapfile_dir, outmapname+'_low_padded_size')
-    low_paddedsize_map.save(low_padsize_name)
-    freqstepname = os.path.join(mapfile_dir, outmapname+'_freqstep')
-    freqstep_map.save(freqstepname)
-    timestepname = os.path.join(mapfile_dir, outmapname+'_timestep')
-    timestep_map.save(timestepname)
-    nwavelengths_high_name = os.path.join(mapfile_dir, outmapname+'_nwavelengths_high')
-    nwavelengths_high_map.save(nwavelengths_high_name)
-    nwavelengths_low_name = os.path.join(mapfile_dir, outmapname+'_nwavelengths_low')
-    nwavelengths_low_map.save(nwavelengths_low_name)
-
-    result = {'groupmap': groupmapname, 'single_mapfile' : file_single_mapname,
-              'high_size_mapfile' : high_sizename, 'low_size_mapfile' : low_sizename,
-              'high_padsize_mapfile' : high_padsize_name, 'low_padsize_mapfile' : low_padsize_name,
-              'freqstep' : freqstepname, 'timestep' : timestepname, 'nwavelengths_high_mapfile': nwavelengths_high_name,
-              'nwavelengths_low_mapfile': nwavelengths_low_name}
-    return result
-
-
-class MultiDataProduct(DataProduct):
-    """
-    Class representing multiple files in a DataProduct.
-    """
-    def __init__(self, host=None, file=None, skip=True):
-        super(MultiDataProduct, self).__init__(host, file, skip)
-        if not file:
-            self.file = list()
-        else:
-            self._set_file(file)
-
-    def __repr__(self):
-        """Represent an instance as a Python dict"""
-        return (
-            "{{'host': '{0}', 'file': '{1}', 'skip': {2}}}".format(self.host,
-                '[{}]'.format(','.join(self.file)), str(self.skip))
-        )
-
-    def __str__(self):
-        """Print an instance as 'host:[filelist]'"""
-        return ':'.join((self.host, str(self.file)))
-
-    def _set_file(self, data):
-        try:
-            # Try parsing as a list
-            if isinstance(data, list):
-                self.file = data
-            if isinstance(data, DataProduct):
-                self._from_dataproduct(data)
-            if isinstance(data, DataMap):
-                self._from_datamap(data)
-
-        except TypeError:
-            raise DataProduct("No known method to set a filelist from %s" % str(file))
-
-    def _from_dataproduct(self, prod):
-        print 'setting filelist from DataProduct'
-        self.host = prod.host
-        self.file = prod.file
-        self.skip = prod.skip
-
-    def _from_datamap(self, inmap):
-        print 'setting filelist from DataMap'
-        filelist = {}
-        for item in inmap:
-            if not item.host in filelist:
-                filelist[item.host] = []
-            filelist[item.host].append(item.file)
-        self.file = filelist['i am']
-
-    def append(self, item):
-        self.file.append(item)
-
-
-class MultiDataMap(DataMap):
-    """
-    Class representing a specialization of data-map, a collection of data
-    products located on the same node, skippable as a set and individually
-    """
-    def __init__(self, data=list(), iterator=iter):
-        super(MultiDataMap, self).__init__(data, iterator)
-
-    @classmethod
-    def load(cls, filename):
-        """Load a data map from file `filename`. Return a DataMap instance."""
-        with open(filename) as f:
-            datamap = eval(f.read())
-            for i, d in enumerate(datamap):
-                file_entry = d['file']
-                if file_entry.startswith('[') and file_entry.endswith(']'):
-                    file_list = [e.strip(' \'\"') for e in file_entry.strip('[]').split(',')]
-                    datamap[i] = {'host': d['host'], 'file': file_list, 'skip': d['skip']}
-            return cls(datamap)
-
-    @DataMap.data.setter
-    def data(self, data):
-        if isinstance(data, DataMap):
-            mdpdict = {}
-            data.iterator = DataMap.SkipIterator
-            for item in data:
-                if not item.host in mdpdict:
-                    mdpdict[item.host] = []
-                mdpdict[item.host].append(item.file)
-            mdplist = []
-            for k, v in mdpdict.iteritems():
-                mdplist.append(MultiDataProduct(k, v, False))
-            self._set_data(mdplist, dtype=MultiDataProduct)
-        elif isinstance(data, MultiDataProduct):
-            self._set_data(data, dtype=MultiDataProduct)
-        elif not data:
-            pass
-        else:
-            self._set_data(data, dtype=MultiDataProduct)
-
-    def split_list(self, number):
-        mdplist = []
-        for item in self.data:
-            for i in xrange(0, len(item.file), number):
-                chunk = item.file[i:i+number]
-                mdplist.append(MultiDataProduct(item.host, chunk, item.skip))
-        self._set_data(mdplist)
diff --git a/Docker/scripts/add_missing_stations.py b/Docker/scripts/add_missing_stations.py
deleted file mode 100755
index 2801223f8e03faae7b0bcaf7151453073a05885f..0000000000000000000000000000000000000000
--- a/Docker/scripts/add_missing_stations.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/env python
-# -* coding: utf-8 -*-
-
-"""
-Adds phases (=0) and amplitudes (=1) to any missing station if they appear in an h5parm, but not in a particular soltab. 
-
-Created on Tue Mar 14 2019
-
-@author: Alexander Drabent
-"""
-
-import argparse
-import numpy as np
-import os
-from losoto.h5parm import h5parm
-from losoto.lib_operations import *
-import logging
-
-def main(h5parmfile, refh5 = None, solset='sol000', refsolset='sol000', soltab_in='phase000', soltab_out='GSMphase', filter='[CR]S*&', bad_antennas='[CR]S*&'):
-
-
-    if refh5 == None:
-        refh5 = h5parmfile
-        pass
-    
-    if not os.path.exists(h5parmfile) or not os.path.exists(refh5):
-        logging.error("H5parm file %s doesn't exist!" % h5parmfile)
-        return(1)
-
-    if soltab_in == soltab_out:
-        logging.error("Output soltab has to be different from input soltab!")
-        return(1)
-
-    ### Open up the h5parm, get an example value
-    data       = h5parm(h5parmfile, readonly = False)
-    refdata    = h5parm(refh5, readonly = False)
-    solset     = data.getSolset(solset)
-    refsolset  = refdata.getSolset(refsolset)
-    
-    ### Get antenna information of the solset
-    ref_station_names = sorted(refsolset.getAnt().keys())
-    bad_antennas_list = bad_antennas.lstrip(filter).replace('!','').replace('*','').replace('&','').split(';')
-    new_station_names = [ ref_station_name for ref_station_name in ref_station_names if ref_station_name not in bad_antennas_list ]
-    
-    ### Load antenna list of input soltab
-    logging.info('Processing solution table %s'%(soltab_in))
-    soltab            = solset.getSoltab(soltab_in)
-    old_station_names = list(soltab.ant[:])
-    soltab_type       = soltab.getType()
-    out_axes_vals     = []
-    out_axes          = soltab.getAxesNames()
-    out_axes.insert(1, out_axes.pop(out_axes.index('ant'))) ## put antenna table to the second place
-
-    ### resort the val and weights array according to the new axes order
-    for vals, weights, coord, selection in soltab.getValuesIter(returnAxes=out_axes, weight=True):
-        vals = reorderAxes( vals, soltab.getAxesNames(), out_axes)
-        weights = reorderAxes( weights,  soltab.getAxesNames(), out_axes )
-        pass
-
-    ### setting the proper soltab_axis
-    for axis in out_axes:
-        if axis == 'time':
-            out_axes_vals.append(soltab.time)
-        elif axis == 'freq':
-            out_axes_vals.append(soltab.freq)
-        elif axis == 'ant':
-            out_axes_vals.append(new_station_names)
-        elif axis == 'pol':
-            out_axes_vals.append(soltab.pol)
-        elif axis == 'dir':
-            out_axes_vals.append(soltab.dir)
-        else:
-            logging.error('Unknown axis in soltab: ' + str(axis))
-            data.close()
-            refdata.close()
-            return 1           
-
-    ### just copy if number of antennas is the same
-    if len(new_station_names) == len(old_station_names):
-        logging.warning('Station list in soltab ' + str(soltab_in) + ' matches the station list in the selected solset. Data will just be copied.')
-        new_soltab = solset.makeSoltab(soltype=soltab_type, soltabName=soltab_out, axesNames=out_axes, axesVals=out_axes_vals, vals=vals, weights=weights)
-    
-    ### add missing stations with zero phase/uniform amplitudes and uniform weights
-    elif len(new_station_names) > len(old_station_names):
-
-        # define proper shape of array
-        logging.info('Adding missing antennas to the soltab: ' + str(soltab_out))
-        dimension    = list(np.shape(vals))
-        dimension[1] = len(new_station_names)
-        
-        if soltab_type == 'amplitude':
-            new_vals    = np.ones(tuple(dimension))
-        else:
-            new_vals    = np.zeros(tuple(dimension))
-        new_weights     = np.ones(tuple(dimension))
-        
-        for i, new_station in enumerate(new_station_names):
-            if new_station in old_station_names:
-                ant_index        = list(soltab.ant).index(new_station)
-                new_vals[:,i]    = vals[:,ant_index]
-                new_weights[:,i] = weights[:,ant_index]
-            
-        new_soltab = solset.makeSoltab(soltype=soltab_type, soltabName=soltab_out, axesNames=out_axes, axesVals=out_axes_vals, vals=new_vals, weights=new_weights)
-        
-    else:
-        logging.error('There are less antennas in the solset than in the soltab ' + str(soltab_in))
-        data.close()
-        refdata.close()
-        return(1)
-
-    data.close()
-    refdata.close()
-    
-    return(0)
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='Adds phases and amplitudes to any missing station if they appear in an h5parm, but not in a particular soltab.')
-
-    parser.add_argument('h5parm', type=str,
-                        help='H5parm to which this action should be performed .')
-    parser.add_argument('--refh5', type=str,
-                        help='External H5parm from which the full list of antennas is used from.')
-    parser.add_argument('--solset', type=str, default='sol000',
-			help='Input calibration solutions')
-    parser.add_argument('--refsolset', type=str, default='sol000',
-			help='Input calibration solutions of the reference h5parm file')
-    parser.add_argument('--soltab_in', type=str, default='phase000',
-                        help='Input solution table')
-    parser.add_argument('--soltab_out', type=str, default='GSMphase',
-                        help='Output solution table (has to be different from input solution table)')
-
-
-    args = parser.parse_args()
-
-    format_stream = logging.Formatter("%(asctime)s\033[1m %(levelname)s:\033[0m %(message)s","%Y-%m-%d %H:%M:%S")
-    format_file   = logging.Formatter("%(asctime)s %(levelname)s: %(message)s","%Y-%m-%d %H:%M:%S")
-    logging.root.setLevel(logging.INFO)
-
-    log      = logging.StreamHandler()
-    log.setFormatter(format_stream)
-    logging.root.addHandler(log)
-
-    main(h5parmfile=args.h5parm, refh5=args.refh5, solset=args.solset, refsolset=args.refsolset, soltab_in=args.soltab_in, soltab_out=args.soltab_out)
-
diff --git a/Docker/scripts/check_Ateam_separation.py b/Docker/scripts/check_Ateam_separation.py
deleted file mode 100755
index 51ca65a27eda34bfeffb5c2363fd60a47f460004..0000000000000000000000000000000000000000
--- a/Docker/scripts/check_Ateam_separation.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-#
-# Written by Bas van der Tol (vdtol@strw.leidenuniv.nl), March 2011.
-# Adapted for prefactor by Alexander Drabent (alex@tls-tautenburg.de), February 2019.
-
-#from pylab import *
-import matplotlib
-matplotlib.use('Agg') # Force matplotlib to not use any Xwindows backend.
-import pylab
-import pyrap.quanta as qa
-import pyrap.tables as pt
-import pyrap.measures as pm
-import sys
-import numpy
-import os
-
-targets = [ {'name' : 'CasA', 'ra' : 6.123487680622104,  'dec' : 1.0265153995604648},
-            {'name' : 'CygA', 'ra' : 5.233686575770755,  'dec' : 0.7109409582180791},
-            {'name' : 'TauA', 'ra' : 1.4596748493730913, 'dec' : 0.38422502335921294},
-            {'name' : 'HerA', 'ra' : 4.4119087330382163, 'dec' : 0.087135562905816893},
-            {'name' : 'VirA', 'ra' : 3.276086511413598,  'dec' : 0.21626589533567378},
-            {'name' : 'Sun'},
-            {'name' : 'Jupiter'},
-            {'name' : 'Moon'}]
-
-########################################################################
-def input2strlist_nomapfile(invar):
-   """ 
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-########################################################################
-def main(ms_input, min_separation = 30, outputimage = None):
-
-    """
-    Print seperation of the phase reference center of an input MS 
-  
-
-    Parameters
-    ----------
-    ms_input : str
-        String from the list (map) of the calibrator MSs
-        
-    Returns
-    -------
-    0 --just for printing
-    """    
-
-    msname = input2strlist_nomapfile(ms_input)[0]
-  
-
-    # Create a measures object
-    me = pm.measures()
-
-    # Open the measurement set and the antenna and pointing table
-    ms = pt.table(msname)  
-
-    # Get the position of the first antenna and set it as reference frame
-    ant_table = pt.table(msname + '::ANTENNA')  
-    ant_no = 0
-    pos = ant_table.getcol('POSITION')
-    x = qa.quantity( pos[ant_no,0], 'm' )
-    y = qa.quantity( pos[ant_no,1], 'm' )
-    z = qa.quantity( pos[ant_no,2], 'm' )
-    position =  me.position( 'wgs84', x, y, z )
-    me.doframe( position )
-    ant_table.close()
-
-    # Get the first pointing of the first antenna
-    field_table = pt.table(msname + '::FIELD')
-    field_no = 0
-    direction = field_table.getcol('PHASE_DIR')
-    ra = direction[ ant_no, field_no, 0 ]
-    dec = direction[ ant_no, field_no, 1 ]
-    targets.insert(0, {'name' : 'Pointing', 'ra' : ra, 'dec' : dec})
-    field_table.close()
-
-    # Get a ordered list of unique time stamps from the measurement set
-    time_table = pt.taql('select TIME from $1 orderby distinct TIME', tables = [ms])
-    time = time_table.getcol('TIME')
-    time1 = time/3600.0
-    time1 = time1 - pylab.floor(time1[0]/24)*24
-
-    ra_qa  = qa.quantity( targets[0]['ra'], 'rad' )
-    dec_qa = qa.quantity( targets[0]['dec'], 'rad' )
-    pointing =  me.direction('j2000', ra_qa, dec_qa)
-
-    separations = []
-
-    print 'SEPERATION from A-Team sources'
-    print '------------------------------'
-    print 'The minimal accepted distance to an A-Team source is: ' + str(min_separation) + ' deg.'
-    for target in targets:
-   
-        t = qa.quantity(time[0], 's')
-        t1 = me.epoch('utc', t)
-        me.doframe(t1)
-
-        if 'ra' in target.keys():
-            ra_qa  = qa.quantity( target['ra'], 'rad' )
-            dec_qa = qa.quantity( target['dec'], 'rad' )
-            direction =  me.direction('j2000', ra_qa, dec_qa)
-            pass
-        else :
-            direction =  me.direction(target['name'])
-            pass
-      
-        separations.append(me.separation(pointing, direction))
-
-        # Loop through all time stamps and calculate the elevation of the pointing
-        el = []
-        for t in time:
-            t_qa = qa.quantity(t, 's')
-            t1 = me.epoch('utc', t_qa)
-            me.doframe(t1)
-            a = me.measure(direction, 'azel')
-            elevation = a['m1']
-            el.append(elevation['value']/pylab.pi*180)
-            pass
-        
-        el = numpy.array(el)
-        pylab.plot(time1, el)
-        
-        if target['name'] != 'Pointing':
-            print target['name'] + ': ' + str(me.separation(pointing, direction))
-            if int(float(min_separation)) > int(float(str(me.separation(pointing, direction)).split(' deg')[0])):
-                print 'WARNING: The A-Team source ' + target['name'] + ' is closer than ' + str(min_separation) + ' deg to the phase reference center. Calibration might not perform as expected.'
-                pass
-            pass
-        
-        pass
-    print '------------------------------'
-    pylab.title('Pointing Elevation')
-    pylab.title('Elevation')
-    pylab.ylabel('Elevation (deg)');
-    pylab.xlabel('Time (h)');
-    pylab.legend( [ target['name'] + '(' + separation.to_string() + ')' for target, separation in zip(targets, separations) ])
-
-    if outputimage != None:
-        inspection_directory = os.path.dirname(outputimage)
-        if not os.path.exists(inspection_directory):
-            os.makedirs(inspection_directory)
-            print "Directory" , inspection_directory ,  "created." 
-            pass
-        else:
-            print("Directory", inspection_directory,  "already exists.")
-            pass
-        print 'Plotting A-Team elevation to: ' + outputimage
-        pylab.savefig(outputimage)
-        pass
-    return 0
-    pass
-
-   
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Print seperation of the phase reference center of an input MS to an A-team source')
-    
-    parser.add_argument('MSfile', type=str, nargs='+', help='One (or more MSs).')
-    parser.add_argument('--min_separation', type=int, default=30, help='minimal accepted distance to an A-team source on the sky in degrees (will raise a WARNING). Default: 30')
-    parser.add_argument('--outputimage', type=str, default=None, help='location of the elevation plot of the A-Team sources.')
-        
-    args = parser.parse_args()
-    
-    main(args.MSfile, args.min_separation, args.outputimage)
-    
-    pass
diff --git a/Docker/scripts/check_unflagged_fraction.py b/Docker/scripts/check_unflagged_fraction.py
deleted file mode 100755
index 3b1084a163a3c169c399df7fdd8cde3f1297b31e..0000000000000000000000000000000000000000
--- a/Docker/scripts/check_unflagged_fraction.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-"""
-Flag MS if unflagged fraction is too low.
-"""
-import argparse
-import os
-import numpy as np
-
-def find_unflagged_fraction(ms_file):
-    """
-    Finds the fraction of data that is unflagged
-    Parameters
-    ----------
-    ms_file : str
-        Filename of input MS
-    Returns
-    -------
-    unflagged_fraction : float
-        Fraction of unflagged data
-    """
-    import subprocess
-
-    # Call taql. Note that we do not use pt.taql(), as pt.taql() can cause
-    # hanging/locking issues on some systems
-    p = subprocess.Popen("taql 'CALC sum([select nfalse(FLAG) from {0}]) / "
-        "sum([select nelements(FLAG) from {0}])'".format(ms_file),
-        shell=True, stdout=subprocess.PIPE)
-    r = p.communicate()
-    unflagged_fraction = float(r[0])
-
-    return unflagged_fraction
-
-def main(ms_file, min_fraction=0.01, print_fraction=False):
-    """
-    Flag MS if unflagged fraction is too low.
-
-    Parameters
-    ----------
-    ms_file : str
-        Name (path) of input MS
-    min_fraction : float , optional
-        minimum fraction of unflagged data needed to keep this MS
-    print_fraction : bool, optional
-        print the actual fration of unflagged data
-
-    Returns
-    -------
-    result : dict
-        Dict with the name of the input MS or "None"
-
-    """
-    min_fraction = float(min_fraction)
-    unflagged_fraction = find_unflagged_fraction(ms_file)
-    if print_fraction:
-        print("File %s has %.2f%% unflagged data."%(os.path.basename(ms_file),unflagged_fraction*100.))
-    if unflagged_fraction < min_fraction:
-        print('check_unflagged_fraction.py: Unflagged fraction of {0} is: {1}, '
-              'removing file.'.format(os.path.basename(ms_file), str(unflagged_fraction)))
-        return {'flagged': 'None', 'unflagged_fraction':  unflagged_fraction}
-    else:
-        return {'flagged': ms_file, 'unflagged_fraction':  unflagged_fraction}
-
-if __name__ == '__main__':
-    descriptiontext = "Check a MS for a minimum fraction of unflagged data.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=argparse.RawTextHelpFormatter)
-    parser.add_argument('inputms', help='name of the input MS')
-    parser.add_argument('-f', '--min_fraction', help='Minimum fraction of unflagged data needed to keep this MS '
-                        '(default 0.01 = "keep if at least 1%% is not flagged")',  type=float, default=0.01)
-    args = parser.parse_args()
-
-    erg = main(args.inputms, args.min_fraction,print_fraction=True)
diff --git a/Docker/scripts/concat_MS.py b/Docker/scripts/concat_MS.py
deleted file mode 100755
index 4b589b74cdd23855a98c6eb33bd18fdb17a5d9c2..0000000000000000000000000000000000000000
--- a/Docker/scripts/concat_MS.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-import sys
-import glob
-import re
-import pyrap.tables as pt
-import numpy
-import os
-from lofarpipe.support.data_map import DataMap, DataProduct
-
-global_limit = 637871244
-########################################################################
-def input2strlist_nomapfile(invar):
-   """
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-########################################################################
-def getsystemmemory():
-   
-   memory = int(os.popen('cat /proc/meminfo | grep MemAvailable').readlines()[0].split(':')[-1].split()[0])
-   return memory
-   pass
-
-########################################################################
-def getfilesize(MS):
-   
-   size = int(os.popen('du -cks ' + MS).readlines()[0].split()[0])
-   return size
-
-   pass
-
-########################################################################
-def main(ms_input, ms_output, min_length, overhead = 0.8, filename=None, mapfile_dir=None):
-
-    """
-    Virtually concatenate subbands
-
-    Parameters
-    ----------
-    ms_input : str
-        String from the list (map) of the calibrator MSs
-    ms_output : str
-        String from the outut concatenated MS
-    min_length : int
-        minimum amount of subbands to concatenate in frequency necessary to perform the wide-band flagging in the RAM. It data is too big aoflag will use indirect-read.
-    overhead   : float
-        Only use this fraction of the available memory for deriving the amount of data to be concatenated.
-    filename: str
-        Name of output mapfile
-    mapfile_dir : str
-        Directory for output mapfile
-
-    """
-    system_memory = getsystemmemory()
-    filelist      = input2strlist_nomapfile(ms_input)
-    file_size     = getfilesize(filelist[0])
-    overhead      = float(overhead)
-
-    print "Detected available system memory is: " + str(int(((system_memory / 1024. / 1024.) + 0.5))) + " GB" 
-    #print "Detected file size is: " + str(int(((file_size / 1024. / 1024.) + 0.5))) + " GB" 
-    if overhead * system_memory > global_limit:
-        system_memory = global_limit
-        overhead      = 1.0
-        print "Number of files to concat will be limited to the global limit of: " + str(int(((global_limit / 1024. / 1024.) + 0.5))) + " GB" 
-        pass    
-    
-    #i = 1
-    max_space     = overhead * system_memory / file_size
-    max_length    = len(filelist) / int((len(filelist) / max_space) + 1.)
-
-    #while max_length * file_size > overhead * system_memory:
-        #i += 1
-        #max_length = len(filelist) / ((len(filelist) / max_space) + i)
-        #pass
-    
-    if max_length >= int(min_length):
-        memory = '-memory-read'
-        pass
-    else:
-        memory = '-indirect-read'
-        max_length = len(filelist)
-        if max_length * file_size > global_limit:
-            max_space  = global_limit / file_size
-            max_length = len(filelist) / int((len(filelist) / max_space) + 1.)
-            print "Number of files to concat was limited to the global limit of: " + str(int(((global_limit / 1024. / 1024.) + 0.5))) + " GB" 
-            print "WARNING: The number of concatenated files will thus be lower than the min_length of: "  + str(min_length)
-            pass
-        pass
-    
-    print "Applying an overhead of: " + str(overhead)
-    print "The max_length value is: " + str(max_length)
-    set_ranges     = list(numpy.arange(0, len(filelist) + 1, int(max_length)))
-    set_ranges[-1] = len(filelist)
-
-    map_out = DataMap([])
-    for i in numpy.arange(len(set_ranges) - 1):
-        f = ms_output + '_' + str(i)
-        pt.msconcat(filelist[set_ranges[i]:set_ranges[i + 1]], f)
-        map_out.data.append(DataProduct('localhost', f, False))
-
-
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Virtually concatenate subbands')
-
-    parser.add_argument('MSfile', type=str, nargs='+',
-                        help='One (or more MSs) that we want to concatenate.')
-    parser.add_argument('MSout', type=str,
-                        help='Output MS file')
-    parser.add_argument('--min_length', type=str,
-                        help='Minimum amount of subbands to concatenate in frequency.')
-    parser.add_argument('--overhead', type=float, default=0.8,
-                        help='Only use this fraction of the available memory for deriving the amount of data to be concatenated.')
-
-
-
-    args = parser.parse_args()
-
-    main(args.MSfile,args.MSout,args.min_length,args.overhead)
diff --git a/Docker/scripts/convert_npys_to_h5parm.py b/Docker/scripts/convert_npys_to_h5parm.py
deleted file mode 100755
index 499684b13aaf61f409c00a7a118fa0adf29de47c..0000000000000000000000000000000000000000
--- a/Docker/scripts/convert_npys_to_h5parm.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-import numpy as np
-import pyrap.tables as pt
-from losoto.h5parm import h5parm
-from losoto.lib_operations import *
-import logging
-from os.path import join
-
-def makesolset(MS, data, solset_name):
-    solset = data.makeSolset(solset_name)    
-
-    logging.info('Collecting information from the ANTENNA table.')
-    antennaTable = pt.table(MS + "::ANTENNA", ack=False)
-    antennaNames = antennaTable.getcol('NAME')
-    antennaPositions = antennaTable.getcol('POSITION')
-    antennaTable.close()
-    antennaTable = solset.obj._f_get_child('antenna')
-    antennaTable.append(zip(*(antennaNames,antennaPositions)))
-    
-    logging.info('Collecting information from the FIELD table.')
-    fieldTable = pt.table(MS + "::FIELD", ack=False)
-    phaseDir = fieldTable.getcol('PHASE_DIR')
-    pointing = phaseDir[0, 0, :]
-    fieldTable.close()
-
-    sourceTable = solset.obj._f_get_child('source')
-    # add the field centre, that is also the direction for Gain and Common*
-    sourceTable.append([('pointing',pointing)])
-
-    return antennaNames
-    pass
-
-########################################################################
-def main(MSfiles, h5parmfile, store_basename='caldata_transfer', store_directory='.', solset_out = 'calibrator'):
-
-    # select on MS
-    mslist = MSfiles.lstrip('[').rstrip(']').replace(' ','').replace("'","").split(',')
-    
-    if len(mslist) == 0:
-        logging.error("Did not find any existing directory in input MS list!")
-        return(1)
-        pass
-    else:
-        MSfile = mslist[0]
-        pass
-
-    # Open up the h5parm, get an example value
-    data   = h5parm(h5parmfile, readonly = False)
-    
-    # name (path) for parmdb to be written
-    reference_station_names = makesolset(MSfile, data, solset_out)
-    OutSolset = data.getSolset(solset_out)
-
-    # load the numpy arrays written by the previous scripts
-    # (filenames constructed in the same way as in these scripts)
-    freqs_ampl    = np.load(join(store_directory, 'freqs_for_amplitude_array.npy'))
-    amps_array    = np.load(join(store_directory, store_basename + '_amplitude_array.npy'))
-    clock_array   = np.load(join(store_directory, 'fitted_data_dclock_' + store_basename + '_1st.npy'))
-    tec_array     = np.load(join(store_directory, 'fitted_data_dTEC_' + store_basename + '_1st.npy'))
-    freqs_phase   = np.load(join(store_directory, 'freqs_for_phase_array.npy'))
-    phases_array  = np.load(join(store_directory, store_basename + '_phase_array.npy'))
-    station_names = np.load(join(store_directory, store_basename + '_station_names.npy'))
-    
-    if len(reference_station_names) > len(station_names):
-        missing_stations = set(reference_station_names) - set(station_names)
-        logging.warning('CAUTION: For these stations now calibration solutions are available: ' + str(missing_stations))
-        pass
-    
-    # create weights
-    dimensions_amp   = np.shape(amps_array)
-    dimensions_phase = np.shape(phases_array)
-    dimensions_clock = np.shape(clock_array)
-    dimensions_tec   = np.shape(tec_array)
-    weights_amp      = np.ndarray(shape = dimensions_amp)
-    weights_phase    = np.ndarray(shape = dimensions_phase)
-    weights_clock    = np.ndarray(shape = dimensions_clock)
-    weights_tec      = np.ndarray(shape = dimensions_tec)
-    weights_amp.fill(1)
-    weights_phase.fill(1)
-    weights_clock.fill(1)
-    weights_tec.fill(1)
-    
-    OutSolset.makeSoltab(soltype='clock', soltabName='clock',
-                                        axesNames=['ant'],
-                                        axesVals=[station_names],
-                                        vals=clock_array[-1,:], weights=weights_clock[-1,:])
-    OutSolset.makeSoltab(soltype='tec', soltabName='tec',
-                                        axesNames=['ant'],
-                                        axesVals=[station_names],
-                                        vals=tec_array[-1,:], weights=weights_tec[-1,:])
-    OutSolset.makeSoltab(soltype='amplitude', soltabName='amplitude',
-                                        axesNames=['ant', 'freq', 'pol'],
-                                        axesVals=[station_names, freqs_ampl, ['XX','YY']],
-                                        vals=amps_array[:,-1,:,:], weights=weights_amp[:,-1,:,:])
-    OutSolset.makeSoltab(soltype='phase', soltabName='phase',
-                                        axesNames=['freq', 'ant'],
-                                        axesVals=[freqs_phase, station_names],
-                                        vals=phases_array, weights=weights_phase)
-
-    data.close()
-    return(0)
-
-
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Create a parmDB with values from the calibrator.')
-
-    parser.add_argument('MSfiles', type=str, 
-                        help='One or more MSs to use as a reference.')
-    parser.add_argument('h5parmfile', type=str,
-                        help='Output H5parm file.')
-    parser.add_argument('--basename', type=str, default='caldata_transfer',
-                        help='Base-name of the numpy files with the calibrator values. (default: \"caldata_transfer\")')
-    parser.add_argument('--storedir', type=str, default='.',
-                        help='Directory of the numpy files with the calibrator values. (default: \".\")')
-    parser.add_argument('--solset_out', type=str, default='calibrator',
-                        help='Name of the solution set')
-
-    format_stream = logging.Formatter("%(asctime)s\033[1m %(levelname)s:\033[0m %(message)s","%Y-%m-%d %H:%M:%S")
-    format_file   = logging.Formatter("%(asctime)s %(levelname)s: %(message)s","%Y-%m-%d %H:%M:%S")
-    logging.root.setLevel(logging.INFO)
-
-    log      = logging.StreamHandler()
-    log.setFormatter(format_stream)
-    logging.root.addHandler(log)
-
-    args = parser.parse_args()
-    
-    MSfiles = args.MSfiles
-    logging.error(MSfiles)
-    h5parmfile = args.h5parmfile
-
-    main(MSfiles, h5parmfile, store_basename=args.basename, store_directory=args.storedir, solset_out=args.solset_out)
diff --git a/Docker/scripts/createRMh5parm.py b/Docker/scripts/createRMh5parm.py
deleted file mode 100755
index 6e1e5e8c4e20864cb3d762dc8673cbb02d213e4a..0000000000000000000000000000000000000000
--- a/Docker/scripts/createRMh5parm.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-Extract RM values for a LOFAR observation. Fill h5parm
-
-Created on Tue Aug 7 11:46:57 2018
-
-@author: mevius
-"""
-from losoto.h5parm import h5parm
-from RMextract import getRM
-from RMextract import PosTools
-import RMextract.getIONEX as ionex
-import pyrap.tables as pt
-import os
-import numpy as np
-import sys
-import logging
-
-
-def makesolset(MS, data, solset_name):
-    solset = data.makeSolset(solset_name)    
-
-    logging.info('Collecting information from the ANTENNA table.')
-    antennaTable = pt.table(MS + "::ANTENNA", ack=False)
-    antennaNames = antennaTable.getcol('NAME')
-    antennaPositions = antennaTable.getcol('POSITION')
-    antennaTable.close()
-    antennaTable = solset.obj._f_get_child('antenna')
-    antennaTable.append(zip(*(antennaNames,antennaPositions)))
-    
-    logging.info('Collecting information from the FIELD table.')
-    fieldTable = pt.table(MS + "::FIELD", ack=False)
-    phaseDir = fieldTable.getcol('PHASE_DIR')
-    pointing = phaseDir[0, 0, :]
-    fieldTable.close()
-
-    sourceTable = solset.obj._f_get_child('source')
-    # add the field centre, that is also the direction for Gain and Common*
-    sourceTable.append([('pointing',pointing)])
-
-
-
-
-def main(MSfiles, h5parmdb, solset_name = "sol000",timestepRM=300,
-                ionex_server="ftp://ftp.aiub.unibe.ch/CODE/",
-                ionex_prefix='CODG',ionexPath="./",earth_rot=0,proxyServer=None,proxyPort=None,proxyType=None,proxyUser=None,proxyPass=None):
-    '''Add rotation measure to existing h5parmdb
-    
-    Args:
-        MSfiles (string) :  path + filename of Measurement Set 
-        h5parmdb (string) : name of existing h5parm
-        solset_name (string) : optional name of solset in h5parmdb, 
-                            if not set, first one will be chosen
-        timestep (float) : timestep in seconds
-        ionex_server (string) : ftp server for IONEX files
-        ionex_prefix (string) : prefix of IONEX files
-        ionexPath (string) : location where IONEX files are stored
-        earth_rot (float) : parameter to determine how much earth rotation is taken \
-        into account when interpolating IONEX data. (0 is none, 1 is full)
-    '''
-    
-    try:
-        mslist = MSfiles.lstrip('[').rstrip(']').replace(' ','').replace("'","").split(',')
-    except AttributeError:
-        mslist = MSfiles
-    
-    if len(mslist) == 0:
-        raise ValueError("Did not find any existing directory in input MS list!")
-        pass
-    else:
-        MS = mslist[0]
-        pass
-    
-    if not os.path.exists(h5parmdb):
-        logging.error('Could not find h5parmdb: ' + h5parmdb)
-        return(1)
-    
-    data          = h5parm(h5parmdb, readonly=False)
-    if not solset_name in data.getSolsetNames():
-        makesolset(MS,data,solset_name)
-    solset        = data.getSolset(solset_name)
-    soltabs       = solset.getSoltabs()
-    station_names = sorted(solset.getAnt().keys())
-
-    if 'RMextract' in [s.name for s in soltabs]:
-        logging.warning('Soltab RMextract exists already. Skipping...')
-        return(0)
-    
-    #extract the timerange information
-    (timerange,timestep,pointing,stat_names,stat_pos) = PosTools.getMSinfo(MS)
-    start_time = timerange[0]
-    end_time = timerange[1]
-    timerange[0] = start_time - timestep
-    timerange[1] = end_time + timestep
-    times,timerange = PosTools.getIONEXtimerange(timerange, timestep)
-    if len(times[-1]) == 0 or times[-1][-1] < timerange[1]:
-        timestmp = list(times[-1])
-        timestmp.append(timerange[1]) #add one extra step to make sure you have a value for all times in the MS in case timestep hase been changed
-        times[-1] = np.array(timestmp)
-
-    for time_array in times[::-1]:    #check in reverse order, since datamight not be available for latest days
-        starttime = time_array[0]
-        date_parms = PosTools.obtain_observation_year_month_day_fraction(starttime)
-        if not proxyServer:
-            if not "http" in ionex_server:      #ftp server use ftplib
-                ionexf = ionex.getIONEXfile(time=date_parms,
-                                              server  = ionex_server,
-                                              prefix  = ionex_prefix,
-                                              outpath = ionexPath)
-            else:
-                ionexf = ionex.get_urllib_IONEXfile(time  = date_parms,
-                                              server  = ionex_server,
-                                              prefix  = ionex_prefix,
-                                              outpath = ionexPath)
-            
-        else:
-            ionexf = ionex.get_urllib_IONEXfile(time  = date_parms,
-                                              server  = ionex_server,
-                                              prefix  = ionex_prefix,
-                                              outpath = ionexPath,
-                                              proxy_server = proxyServer,
-                                              proxy_type   = proxyType,
-                                              proxy_port   = proxyPort,
-                                              proxy_user   = proxyUser,
-                                              proxy_pass   = proxyPass)
-
-        if ionexf == -1:
-            if not "igsiono.uwm.edu.pl" in ionex_server:
-                logging.info("cannot get IONEX data, try fast product server instead")
-                if not proxyServer:
-                    ionexf = ionex.get_urllib_IONEXfile(time = date_parms,
-                                                     server  = "https://igsiono.uwm.edu.pl",
-                                                     prefix  = "igrg",
-                                                     outpath = ionexPath)
-                else:
-                    ionexf = ionex.get_urllib_IONEXfile(time = date_parms,
-                                                     server  = "https://igsiono.uwm.edu.pl",
-                                                     prefix  = "igrg",
-                                                     outpath = ionexPath,
-                                                  proxy_server = proxyServer,
-                                                  proxy_type   = proxyType,
-                                                  proxy_port   = proxyPort,
-                                                  proxy_user   = proxyUser,
-                                                  proxy_pass   = proxyPass)
-        if ionexf == -1:
-            logging.error("IONEX data not available, even not from fast product server")
-            return -1
-    
-    
-    if not proxyServer:
-	    rmdict = getRM.getRM(MS,
-                         server    = ionex_server, 
-                         prefix    = ionex_prefix, 
-                         ionexPath = ionexPath, 
-                         timestep  = timestepRM,
-                         earth_rot = earth_rot)
-    else:
-	    rmdict = getRM.getRM(MS,
-                         server    = ionex_server, 
-                         prefix    = ionex_prefix, 
-                         ionexPath = ionexPath, 
-                         timestep  = timestepRM,
-                         earth_rot = earth_rot,
-                         proxy_server = proxyServer,
-                         proxy_type   = proxyType,
-                         proxy_port   = proxyPort,
-                         proxy_user   = proxyUser,
-                         proxy_pass   = proxyPass)
-
-    
-    if not rmdict:
-        if not ionex_server:
-            raise ValueError("One or more IONEX files is not found on disk and download is disabled!\n"
-                                 "(You can run \"bin/download_IONEX.py\" outside the pipeline if needed.)")
-        else:
-            raise ValueError("Couldn't get RM information from RMextract! (But I don't know why.)")
-        
-    logging.info('Adding rotation measure values to: ' + solset_name + ' of ' + h5parmdb)
-    rm_vals=np.array([rmdict["RM"][stat].flatten() for stat in station_names])
-    new_soltab = solset.makeSoltab(soltype='rotationmeasure', soltabName='RMextract',
-                                   axesNames=['ant', 'time'], axesVals=[station_names, rmdict['times']],
-                                   vals=rm_vals,
-                                   weights=np.ones_like(rm_vals, dtype=np.float16))
-    
-    return(0)
-
-    data.close()
-
-    
-    ########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Adds CommonRotationAngle to an H5parm from RMextract.')
-
-    parser.add_argument('MSfiles', type=str, nargs='+',
-                        help='MS for which the parmdb should be created.')
-    parser.add_argument('h5parm', type=str,
-                        help='H5parm to which the results of the CommonRotationAngle is added.')
-    parser.add_argument('--server', type=str, default='ftp://ftp.aiub.unibe.ch/CODE/',
-                        help='URL of the server to use. (default: ftp://ftp.aiub.unibe.ch/CODE/)')
-    parser.add_argument('--prefix', type=str, default='CODG',
-                        help='Prefix of the IONEX files. (default: \"CODG\")')
-    parser.add_argument('--ionexpath', '--path', type=str, default='./',
-                        help='Directory where to store the IONEX files. (default: \"./\")')
-    parser.add_argument('--solsetName', '--solset', type=str, default='sol000',
-                        help='Name of the h5parm solution set (default: sol000)')
-    parser.add_argument('-t','--timestep', help=
-                        'timestep in seconds. for values <=0 (default) the timegrid of the MS is used ',
-                        dest="timestep",type=float, default=300.)
-    parser.add_argument('-e','--smart_interpol', type=float, default=0, help=
-                        'float parameter describing how much of Earth rotation is taken in to account \
-                        in interpolation of the IONEX files. 1.0 means time interpolation assumes \
-                        ionosphere rotates in opposite direction of the Earth. 0.0 (default) means \
-                        no rotation applied',dest="earth_rot",)
-
-    args = parser.parse_args()
-
-    MS = args.MSfiles
-    h5parmdb = args.h5parm
-    logging.info("Working on: %s %s" % (MS, h5parmdb))
-    main(MS, h5parmdb, ionex_server=args.server, ionex_prefix=args.prefix, 
-                 ionexPath=args.ionexpath, solset_name=args.solsetName, 
-                 timestepRM=args.timestep, earth_rot=args.earth_rot)
-    
diff --git a/Docker/scripts/download_skymodel_target.py b/Docker/scripts/download_skymodel_target.py
deleted file mode 100755
index 3475c19c2b5bd791b9d59d41366ca46f9343f62c..0000000000000000000000000000000000000000
--- a/Docker/scripts/download_skymodel_target.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-import os,sys
-import glob
-import pyrap.tables as pt
-import numpy as np
-import time
-import lsmtool
-
-########################################################################
-def grab_coord_MS(MS):
-    """
-    Read the coordinates of a field from one MS corresponding to the selection given in the parameters
-
-    Parameters
-    ----------
-    MS : str
-        Full name (with path) to one MS of the field
-
-    Returns
-    -------
-    RA, Dec : "tuple"
-        coordinates of the field (RA, Dec in deg , J2000)
-    """
-
-    # reading the coordinates ("position") from the MS
-    # NB: they are given in rad,rad (J2000)
-    [[[ra,dec]]] = pt.table(MS+'::FIELD', readonly=True, ack=False).getcol('PHASE_DIR')
-
-    # RA is stocked in the MS in [-pi;pi]
-    # => shift for the negative angles before the conversion to deg (so that RA in [0;2pi])
-    if ra<0:
-        ra=ra+2*np.pi
-
-    # convert radians to degrees
-    ra_deg =  ra/np.pi*180.
-    dec_deg = dec/np.pi*180.
-
-    # and sending the coordinates in deg
-    return ra_deg,dec_deg
-
-
-########################################################################
-def input2strlist_nomapfile(invar):
-    """ from bin/download_IONEX.py
-    give the list of MSs from the list provided as a string
-    """
-
-    str_list = None
-    if type(invar) is str:
-        if invar.startswith('[') and invar.endswith(']'):
-            str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-        else:
-            str_list = [invar.strip(' \'\"')]
-    elif type(invar) is list:
-        str_list = [str(f).strip(' \'\"') for f in invar]
-    else:
-        raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-    return str_list
-
-
-########################################################################
-def main(ms_input, SkymodelPath, Radius="5.", DoDownload="True", Source="TGSS"):
-    """
-    Download the skymodel for the target field
-
-    Parameters
-    ----------
-    ms_input : str
-        String from the list (map) of the target MSs
-    SkymodelPath : str
-        Full name (with path) to the skymodel; if YES is true, the skymodel will be downloaded here
-    Radius : string with float (default = "5.")
-        Radius for the TGSS/GSM cone search in degrees
-    DoDownload : str ("Force" or "True" or "False")
-        Download or not the TGSS skymodel or GSM.
-        "Force": download skymodel from TGSS or GSM, delete existing skymodel if needed.
-        "True" or "Yes": use existing skymodel file if it exists, download skymodel from
-                         TGSS or GSM if it does not.
-        "False" or "No": Do not download skymodel, raise an exception if skymodel
-                         file does not exist.
-
-    """
-
-    FileExists = os.path.isfile(SkymodelPath)
-    if (not FileExists and os.path.exists(SkymodelPath)):
-        raise ValueError("download_tgss_skymodel_target: Path: \"%s\" exists but is not a file!"%(SkymodelPath))
-    download_flag = False
-    if not os.path.exists(os.path.dirname(SkymodelPath)):
-        os.makedirs(os.path.dirname(SkymodelPath))
-    if DoDownload.upper() == "FORCE":
-        if FileExists:
-            os.remove(SkymodelPath)
-        download_flag = True
-    elif DoDownload.upper() == "TRUE" or DoDownload.upper() == "YES":
-        if FileExists:
-            print "USING the exising skymodel in "+ SkymodelPath
-            return
-        else:
-            download_flag = True
-    elif DoDownload.upper() == "FALSE" or DoDownload.upper() == "NO":
-         if FileExists:
-            print "USING the exising skymodel in "+ SkymodelPath
-            return
-         else:
-            raise ValueError("download_tgss_skymodel_target: Path: \"%s\" does not exist and skymodel download is disabled!"%(SkymodelPath))
-
-    # If we got here, then we are supposed to download the skymodel.
-    assert download_flag is True # Jaja, belts and suspenders...
-    print "DOWNLOADING skymodel for the target into "+ SkymodelPath
-
-    # Reading a MS to find the coordinate (pyrap)
-    [RATar,DECTar]=grab_coord_MS(input2strlist_nomapfile(ms_input)[0])
-
-    # Downloading the skymodel, skip after five tries
-    errorcode = 1
-    tries     = 0
-    while errorcode != 0 and tries < 5:
-        if Source == 'TGSS':
-            errorcode = os.system("wget -O "+SkymodelPath+ " \'http://tgssadr.strw.leidenuniv.nl/cgi-bin/gsmv3.cgi?coord="+str(RATar)+","+str(DECTar)+"&radius="+str(Radius)+"&unit=deg&deconv=y\' ")
-            pass
-        elif Source == 'GSM':
-            errorcode = os.system("wget -O "+SkymodelPath+ " \'https://lcs165.lofar.eu/cgi-bin/gsmv1.cgi?coord="+str(RATar)+","+str(DECTar)+"&radius="+str(Radius)+"&unit=deg&deconv=y\' ")
-            pass
-        time.sleep(5)
-        tries += 1
-        pass
-
-    if not os.path.isfile(SkymodelPath):
-        raise IOError("download_tgss_skymodel_target: Path: \"%s\" does not exist after trying to download the skymodel."%(SkymodelPath))
-
-    # Treat all sources as one group (direction)
-    skymodel = lsmtool.load(SkymodelPath)
-    skymodel.group('single')
-    skymodel.write(clobber=True)
-    
-    return
-
-
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description=' Download the TGSS or GSM skymodel for the target field')
-
-    parser.add_argument('MSfile', type=str, nargs='+',
-                        help='One (or more MSs) for which a TGSS/GSM skymodel will be download.')
-    parser.add_argument('SkyTar', type=str,
-                        help='Full name (with path) to the skymodel; the TGSS/GSM skymodel will be downloaded here')
-    parser.add_argument('--Radius', type=float, default=5.,
-                        help='Radius for the TGSS/GSM cone search in degrees')
-    parser.add_argument('--Source', type=str, default='TGSS',
-                        help='Choose source for skymodel: TGSS or GSM')
-    parser.add_argument('--DoDownload', type=str, default="True",
-                        help='Download or not the TGSS skymodel or GSM ("Force" or "True" or "False").')
-
-    args = parser.parse_args()
-    radius=5
-    if args.Radius:
-        radius=args.Radius
-
-    main(args.MSfile, args.SkyTar, str(radius), args.DoDownload, args.Source)
diff --git a/Docker/scripts/find_skymodel_cal.py b/Docker/scripts/find_skymodel_cal.py
deleted file mode 100755
index 9f3ae967dbc63d08f9f4d40ed37cd002d771ba67..0000000000000000000000000000000000000000
--- a/Docker/scripts/find_skymodel_cal.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#!/usr/bin/env python
-import os
-import glob
-import pyrap.tables as pt
-import math
-import lsmtool
-import numpy
-    
-def grab_pointing(MS):
-    """
-    Read the name of the calibrator from one MS corresponding to the selection given in the parameters
-
-    Parameters
-    ----------
-    MS : str
-        Full name (with path) to one MS of the field
-
-
-    Returns
-    -------
-    nameCal : str
-        Name of the calibrator as provided in the MS
-        NB: we suppose that all the calibrators' observations have this field filled in (MS/Observation, column LOFAR_TARGET)
-    """
-    
-    [ra, dec] = pt.table(MS+'::FIELD', readonly=True, ack=False).getcol('PHASE_DIR')[0][0] * 180 / math.pi
-    return ra, dec
-
-    
-
-########################################################################
-
-def check_skymodel(skymodel, ra, dec, max_separation_arcmin = 1.0):
-    """
-    Searches for an appropriate sky model
-    """
-    s = lsmtool.load(skymodel)
-    dist_deg = s.getDistance(ra, dec)
-    if any(dist_deg * 60.0 < max_separation_arcmin):
-        patch_position = int(numpy.where(dist_deg * 60 < max_separation_arcmin)[0][0])
-        patch_name = s.getPatchNames()[patch_position]
-        return (True, patch_name)
-        pass
-    else:
-        return (False, '')
-        pass
-    pass
-
-########################################################################
-def find_skymodel(ra, dec, PathSkyMod, extensionSky = ".skymodel", max_separation_arcmin = 1.0):
-    """
-    Find in the provided folder the correponding skymodel for the given source
-
-    Parameters
-    ----------
-    NameSouce : str
-        Name of the source for which we want to find the skymodel
-    PathSkyMod : str
-        Path to the folder containing the skymodels in use
-        (with Pattern, will enable to read and get the info from a MS)
-    [extensionSky] :  str
-        Default: ".skymodel"
-        extension of the skymodel files
- 
-    NB: we suppose that the name of the calibrator is included in the name of the skymodel
-
-    Returns
-    -------
-    list_skymodel[0] : str
-        Full name (with path) to the matching skymodel 
-    """
-    
-    if os.path.isfile(PathSkyMod):
-        print("Checking the skymodel provided: " + PathSkyMod)
-        skymodels = [PathSkyMod]
-    else:
-        skymodels = glob.glob(PathSkyMod + "/*" + extensionSky)
-        
-    for skymodel in skymodels:
-        check = check_skymodel(skymodel, ra, dec, max_separation_arcmin)
-        if check[0]:
-            print "The following skymodel will be used for the calibrator: " + skymodel.split("/")[-1] + " (in " + PathSkyMod + ")"
-            return (skymodel, check[-1])
-            pass
-        else:
-            pass
-        pass
-    
-    raise TypeError('find_skymodel: SKYMODEL FOR THE CALIBRATOR NOT FOUND IN ' + PathSkyMod)
-    pass
-            
-########################################################################
-def input2strlist_nomapfile(invar):
-   """ 
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-########################################################################
-def main(ms_input, DirSkymodelCal, extensionSky=".skymodel", max_separation_arcmin = 1.0):
-
-    """
-    Find automatically the skymodel to use for the Calibrator 
-  
-
-    Parameters
-    ----------
-    ms_input : str
-        String from the list (map) of the calibrator MSs
-    DirSkymodelCal : str
-        Path to the skymodel file, or to the folder where the skymodels are stored    
-    [extensionSky] :  str
-        Default: ".skymodel"
-        extension of the skymodel files
- 
-        
-    Returns
-    -------
-    {'SkymodelCal':skymodelCal} : "dict"
-        Path to the skymodel of the calibrator
-    """    
-
-    if os.path.isfile(DirSkymodelCal) or os.path.isdir(DirSkymodelCal):
-        ra, dec = grab_pointing(input2strlist_nomapfile(ms_input)[0])
-        skymodelCal, skymodelName  = find_skymodel(ra, dec, DirSkymodelCal, extensionSky, float(max_separation_arcmin))
-        return { 'SkymodelCal' : skymodelCal, 'SkymodelName': skymodelName}
-    else:
-        raise ValueError("find_skymodel_cal: The path \"%s\" is neither a file nor a directory!"%(DirSkymodelCal))
-
-
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Find automatically between skymodels the one to use (for the Calibrator)')
-    
-    parser.add_argument('MSfile', type=str, nargs='+',
-                        help='One (or more MSs) for which we search the matching skymodel.')
-    parser.add_argument('DirSky', type=str, 
-                        help='Path to the skymodel file, or to the folder where the skymodels are stored.')
-    parser.add_argument('--extsky', type=str, 
-                        help='extension of the skymodel files. (default: \".skymodel\")')
-        
-    args = parser.parse_args()
-    extensionSky='.skymodel'
-    if args.extsky:
-        extensionSky=args.extsky
-    
-    main(args.MSfile,args.DirSky, extensionSky)
-    
-    pass
diff --git a/Docker/scripts/fits2sky.py b/Docker/scripts/fits2sky.py
deleted file mode 100755
index 1359429038d419ceb0d50d88cbcb84653dfa92aa..0000000000000000000000000000000000000000
--- a/Docker/scripts/fits2sky.py
+++ /dev/null
@@ -1,195 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to make a sky model from fits model images
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-from astropy.io import fits
-from astropy import wcs
-import numpy as np
-import scipy.interpolate
-import casacore.tables as pt
-import sys
-import os
-import glob
-
-
-def ra2hhmmss(deg):
-    """Convert RA coordinate (in degrees) to HH MM SS"""
-
-    from math import modf
-    if deg < 0:
-        deg += 360.0
-    x, hh = modf(deg/15.)
-    x, mm = modf(x*60)
-    ss = x*60
-
-    return (int(hh), int(mm), ss)
-
-
-def dec2ddmmss(deg):
-    """Convert DEC coordinate (in degrees) to DD MM SS"""
-
-    from math import modf
-    sign = (-1 if deg < 0 else 1)
-    x, dd = modf(abs(deg))
-    x, ma = modf(x*60)
-    sa = x*60
-
-    return (int(dd), int(ma), sa, sign)
-
-
-def convert_radec_str(ra, dec):
-    """Takes ra, dec in degrees and returns makesourcedb strings"""
-    ra = ra2hhmmss(ra)
-    sra = str(ra[0]).zfill(2)+':'+str(ra[1]).zfill(2)+':'+str("%.3f" % (ra[2])).zfill(6)
-    dec = dec2ddmmss(dec)
-    decsign = ('-' if dec[3] < 0 else '+')
-    sdec = decsign+str(dec[0]).zfill(2)+'.'+str(dec[1]).zfill(2)+'.'+str("%.3f" % (dec[2])).zfill(6)
-
-    return sra, sdec
-
-
-def main(fits_models, ms_file, skymodel, fits_masks, min_flux_jy=0.005, interp='linear'):
-    """
-    Make a makesourcedb sky model for input MS from WSClean fits model images
-
-    Parameters
-    ----------
-    fits_models : str
-        Filename of FITS model images. Can be a list of files (e.g.,
-        '[mod1.fits,mod2.fits,...]')
-    ms_file : str
-        Filename of MS for which sky model is to be made. Can be a list of files
-        (e.g., '[ms1,ms2,...]', in which case they should all have the same
-        frequency
-    skymodel : str
-        Filename of the output makesourcedb sky model
-    fits_masks : str
-        Filename of FITS mask images. Can be a list of files (e.g.,
-        '[msk1.fits,msk2.fits,...]')
-    min_flux_jy : float, optional
-        Minimum value of flux in Jy of a source to include in output model
-    interp : str, optional
-        Interpolation method. Can be any supported by scipy.interpolate.interp1d:
-            'linear', 'nearest', 'zero', 'slinear', 'quadratic', 'cubic'
-
-    """
-    min_flux_jy = float(min_flux_jy)
-
-    # Get filenames of model images and masks
-    if '[' in fits_models and ']' in fits_models:
-        fits_models = fits_models.strip('[] ').split(',')
-        fits_models = [f.strip('\'\" ') for f in fits_models]
-    else:
-        fits_models = [fits_models.strip('\'\" ')]
-    if '[' in fits_masks and ']' in fits_masks:
-        fits_masks = fits_masks.strip('[]').split(',')
-        fits_masks = [f.strip('\'\" ') for f in fits_masks]
-    else:
-        fits_masks = [fits_masks.strip('\'\" ')]
-
-    # Read (first) MS file and get the frequency info
-    if '[' in ms_file and ']' in ms_file:
-        files = ms_file.strip('[] ').split(',')
-        #files = [f.strip() for f in files]
-        ms_file = files[0].strip('\'\" ')
-    sw = pt.table(ms_file+'::SPECTRAL_WINDOW', ack=False)
-    ms_freq = sw.col('REF_FREQUENCY')[0]
-    ms_freq_low = sw.col('CHAN_FREQ')[0][0]
-    ms_freq_high = sw.col('CHAN_FREQ')[0][-1]
-    sw.close()
-
-    # Get frequencies and data of model images and masks
-    freqs = []
-    model_images = []
-    mask_images = []
-    for f in fits_models:
-        hdr = fits.getheader(f, 0)
-        freqs.append(hdr['CRVAL3']) # Hz
-        model_images.append(fits.getdata(f, 0))
-    for f in fits_masks:
-        mask_images.append(fits.getdata(f, 0))
-
-    # Sort by freq
-    sorted_ind = np.argsort(freqs)
-    freqs = np.array(freqs)[sorted_ind]
-    fits_models = np.array(fits_models)[sorted_ind]
-    model_images = np.array(model_images)[sorted_ind]
-    mask_images = np.array(mask_images)[sorted_ind]
-
-    # Check if there is a model at the ms frequency. If so, just use that one
-    ind = np.where( np.logical_and(freqs >= ms_freq_low, freqs <= ms_freq_high) )
-    if len(ind[0]) == 1:
-        freqs = freqs[ind]
-        fits_models = fits_models[ind]
-        model_images = model_images[ind]
-        mask_images = mask_images[ind]
-
-    # Set the WCS reference
-    hdr = fits.getheader(fits_models[0], 0)
-    w = wcs.WCS(hdr)
-
-    # Find nonzero pixels in stacked image
-    stacked_model = np.zeros(model_images[0].shape)
-    stacked_mask = np.zeros(mask_images[0].shape)
-    for im, ma in zip(model_images, mask_images):
-        stacked_model += im
-        stacked_mask += ma
-    nonzero_ind = np.where((stacked_model != 0.0) & (stacked_mask > 0))
-
-    # Interpolate the fluxes to the frequency of the MS
-    nsources = len(nonzero_ind[0])
-    fluxes = []
-    names = []
-    ras = []
-    decs = []
-    for i in range(nsources):
-        flux_array = []
-        freq_array = []
-        for ind, (im, ma) in enumerate(zip(model_images, mask_images)):
-            index = [nonzero_ind[j][i] for j in range(4)]
-            if ma[tuple(index)] > 0:
-                flux_array.append(im[tuple(index)])
-                freq_array.append(freqs[ind])
-
-        if len(flux_array) > 0:
-            # Only create a source entry if MS frequency is within +/- 4 MHz of
-            # the sampled frequency range to prevent large extrapolations when
-            # the primary beam may cause rapid spectral changes
-            if ms_freq > freq_array[0]-4e6 and ms_freq < freq_array[-1]+4e6:
-                # If MS frequency lies outside range, just use nearest freq
-                if ms_freq < freq_array[0]:
-                    flux = flux_array[0]
-                elif ms_freq > freq_array[-1]:
-                    flux = flux_array[-1]
-                else:
-                    # Otherwise interpolate
-                    flux = scipy.interpolate.interp1d(freq_array, flux_array, kind=interp)(ms_freq)
-                if flux > min_flux_jy:
-                    index.reverse() # change to WCS coords
-                    ras.append(w.wcs_pix2world(np.array([index]), 0, ra_dec_order=True)[0][0])
-                    decs.append(w.wcs_pix2world(np.array([index]), 0, ra_dec_order=True)[0][1])
-                    names.append('cc{}'.format(i))
-                    fluxes.append(flux)
-
-    # Write sky model
-    with open(skymodel, 'w') as outfile:
-        outfile.write('FORMAT = Name, Type, Ra, Dec, I, Q, U, V, ReferenceFrequency\n')
-        for name, ra, dec, flux in zip(names, ras, decs, fluxes):
-            ra_str, dec_str = convert_radec_str(ra, dec)
-            outfile.write('{0}, POINT, {1}, {2}, {3}, 0.0, 0.0, 0.0, {4}\n'
-                .format(name, ra_str, dec_str, flux, ms_freq))
-
-
-if __name__ == '__main__':
-    descriptiontext = "Make a makesourcedb sky model from WSClean fits model images.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('fits_models', help='Model images')
-    parser.add_argument('msfile', help='MS file')
-    parser.add_argument('skymodel', help='Filename of output sky model')
-    parser.add_argument('fits_masks', help='Mask images')
-
-    args = parser.parse_args()
-    main(args.fits_models, args.msfile, args.skymodel, args.fits_masks)
diff --git a/Docker/scripts/getStructure_from_phases.py b/Docker/scripts/getStructure_from_phases.py
deleted file mode 100755
index fcfe1b5b4081bc468681b1a753082c6201c038ef..0000000000000000000000000000000000000000
--- a/Docker/scripts/getStructure_from_phases.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env python
-
-##########################################################################
-#
-# Written my Maaijke Mevius -- see Radio Science publication DOI: 10.1002/2016RS006028
-#
-##########################################################################
-# History
-# 20/07/2016 Outlier rejection and argparse added -- Tim Shimwell
-# 06/06/2019 Changed for the use with h5parms -- Alexander Drabent
-
-import matplotlib as mpl
-mpl.use("Agg")
-from losoto.h5parm import h5parm
-from losoto.lib_operations import *
-from pylab import *
-import scipy
-from scipy.optimize import leastsq
-import argparse
-
-def mad(arr):
-    """ Median Absolute Deviation: a "Robust" version of standard deviation.
-        Indices variabililty of the sample.
-        https://en.wikipedia.org/wiki/Median_absolute_deviation 
-    """
-    arr = np.ma.array(arr).compressed() # should be faster to not use masked arrays.
-    med = np.median(arr)
-    return np.median(np.abs(arr - med))
-
-def model(t, coeffs):
-    coeffs[0] = abs(coeffs[0])
-    return coeffs[0] + (t**coeffs[2])/coeffs[1]
-def residuals(coeffs, y, t):
-    coeffs[0] = abs(coeffs[0])
-    return y - model(t, coeffs)
-
-def main(h5parmfile,solset='sol000',soltab='phase000',nr_grid=1,doplot=True,outbasename='ionosphere',output_dir='./',dofilter=True):
-    outfile = open(str(output_dir) + '/' + outbasename +'_structure.txt','w')
-    data    = h5parm(h5parmfile)
-    solset  = data.getSolset(solset)
-    soltab  = solset.getSoltab(soltab)
-    soltype = soltab.getType()
-    if soltype != 'phase':
-        logging.warning("Soltab is of type " + soltype + ", but should be phase. Skipping.")
-        data.close()
-        return(0)
-    vals  = soltab.val
-    station_names = soltab.ant[:]
-    stations = solset.getAnt()
-    phx=[]
-    phy=[]
-    allposx=[]
-    allposy=[]
-    nrtimes = len(soltab.time)
-    nrfreqss = len(soltab.freq)
-    timestep=int(nrtimes/nr_grid)
-    for vals, coord, selection in soltab.getValuesIter(returnAxes=soltab.getAxesNames(), weight=False):
-        try:
-            vals = reorderAxes( vals, soltab.getAxesNames(), ['pol', 'ant', 'time', 'freq', 'dir'])
-            vals = vals[:,:,:,:,0]
-        except:
-            vals = reorderAxes( vals, soltab.getAxesNames(), ['pol', 'ant', 'time', 'freq'])
-            
-    valx = vals[0]
-    valy = vals[1]
-    for i,station_name in enumerate(station_names):
-        if not "CS" in station_name:
-            continue
-        phx.append(valx[i,:,0].flatten())
-        allposx.append(stations[station_name])
-        phy.append(valy[i,:,0].flatten())
-        allposy.append(stations[station_name])
-
-    phx=np.array(phx)
-    phy=np.array(phy)   
-    allposx=np.array(allposx)
-    allposy=np.array(allposy)
-    D=allposx[:,np.newaxis,:]-allposx[np.newaxis,:]
-    D2=np.sqrt(np.sum(D**2,axis=-1))
-    Dy=allposy[:,np.newaxis,:]-allposy[np.newaxis,:]
-    D2y=np.sqrt(np.sum(Dy**2,axis=-1))
-    S0s=[]
-    betas=[]
-    for itime in xrange(nr_grid+1):
-        tm=[0,1000000000]
-        if itime<nr_grid:
-            tm[0]=int(itime*timestep)
-            tm[1]=int(tm[0]+timestep)
-        dphx=phx[:,np.newaxis,tm[0]:tm[1]]-phx[np.newaxis,:,tm[0]:tm[1]]
-        dphy=phy[:,np.newaxis,tm[0]:tm[1]]-phy[np.newaxis,:,tm[0]:tm[1]]
-        dphx=np.unwrap(np.remainder(dphx-dphx[:,:,0][:,:,np.newaxis]+np.pi,2*np.pi))
-        dvarx=np.var(dphx,axis=-1)
-        dphy=np.unwrap(np.remainder(dphy-dphy[:,:,0][:,:,np.newaxis]+np.pi,2*np.pi))
-        dvary=np.var(dphy,axis=-1)
-        myselect=np.logical_and(D2>0,np.logical_and(np.any(np.logical_and(dvarx>1e-7,dvarx<.1),axis=0)[np.newaxis],np.any(np.logical_and(dvarx>1e-7,dvarx<.1),axis=1)[:,np.newaxis]))
-        if dofilter:
-            x=D2[myselect]
-            y=dvarx[myselect]
-            # Seems like real values dont occur above 1.0
-            flagselect = np.where(y > 1.0)
-            xplot = np.delete(x,flagselect) 
-            yplot = np.delete(y,flagselect)
-            
-
-            bins = np.logspace(np.log10(np.min(xplot)),np.log10(np.max(xplot)),10)
-            binys = []
-            binxs = []
-            for i in range(0,len(bins)-1):
-                binmin = bins[i]
-                binmax = bins[i+1]
-                inbin = np.intersect1d(np.where(xplot > binmin),np.where(xplot < binmax))
-                binxs.append((binmin+binmax)/2.0)
-                binys.append(np.median(yplot[inbin])+10*mad(yplot[inbin]))
-            x0 = [0.1,1.0,1.0]
-            xfit, flag = scipy.optimize.leastsq(residuals, x0, args=(binys,binxs))
-            flagselect = np.where(y > model(x,xfit))
-            print xfit,'fitting'
-        if doplot:
-            x=D2[myselect]
-            y=dvarx[myselect]
-            subplot(3,1,1)
-            scatter(x,y,color='b')
-            if dofilter:
-                y2 = y[flagselect]
-                x2 = x[flagselect]
-                scatter(x2,y2,color='r')
-                scatter(x,model(x,xfit),color='gray',linestyle='-')#,'gray',linestyle='-',linewidth=3)
-        x=D2[np.logical_and(D2>1e3,myselect)]
-        y=dvarx[np.logical_and(D2>1e3,myselect)]
-        if dofilter:
-            flagselect = np.where(y > model(x,xfit))
-            x = np.delete(x,flagselect)
-            y = np.delete(y,flagselect)
-        A=np.ones((2,x.shape[0]),dtype=float)
-        A[1,:]=np.log10(x)
-        par=np.dot(np.linalg.inv(np.dot(A,A.T)),np.dot(A,np.log10(y)))
-        S0=10**(-1*np.array(par)[0]/np.array(par)[1])
-        if doplot:
-            plot(x,10**(par[0]+par[1]*np.log10(x)),'r-')
-            xscale("log")
-            yscale("log")
-            xlim(30,4000)
-            xlabel('baseline length [m]')
-            ylabel('XX phase variance [rad$^2$]')
-            title('XX diffractive scale:  %3.1f km'%(float(S0)/1000.))
-        myselect=np.logical_and(D2y>0,np.logical_and(np.any(np.logical_and(dvary>1e-7,dvary<.1),axis=0)[np.newaxis],np.any(np.logical_and(dvary>1e-7,dvary<.1),axis=1)[:,np.newaxis]))
-        if dofilter:
-            x=D2y[myselect]
-            y=dvary[myselect]
-            # seems like real values dont occur above 1.0
-            flagselect = np.where(y > 1.0)
-            xplot = np.delete(x,flagselect) 
-            yplot = np.delete(y,flagselect)
-            bins = np.logspace(np.log10(np.min(xplot)),np.log10(np.max(xplot)),20)
-            binys = []
-            binxs = []
-            for i in range(0,len(bins)-1):
-                binmin = bins[i]
-                binmax = bins[i+1]
-                inbin = np.intersect1d(np.where(xplot > binmin),np.where(xplot < binmax))
-                binxs.append((binmin+binmax)/2.0)
-                binys.append(np.median(yplot[inbin])+10*mad(yplot[inbin]))
-            x0 = [0.1,1.0,1.0]
-            xfit, flag = scipy.optimize.leastsq(residuals, x0, args=(binys,binxs))
-            flagselect = np.where(y > model(x,xfit))
-            print xfit,'fitting'
-        if doplot:
-            x=D2y[myselect]
-            y=dvary[myselect]
-            subplot(3,1,3)
-            scatter(x,y,color='b')
-            if dofilter:
-                y2 = y[flagselect]
-                x2 = x[flagselect]
-                scatter(x2,y2,color='r')
-                scatter(x,model(x,xfit),color='gray',linestyle='-')#,'gray',linestyle='-',linewidth=3)
-        x=D2y[np.logical_and(D2y>1e3,myselect)]
-        y=dvary[np.logical_and(D2y>1e3,myselect)]
-        if dofilter:
-            flagselect = np.where(y > model(x,xfit))
-            x = np.delete(x,flagselect)
-            y = np.delete(y,flagselect)
-        A=np.ones((2,x.shape[0]),dtype=float)
-        A[1,:]=np.log10(x)
-        pary=np.dot(np.linalg.inv(np.dot(A,A.T)),np.dot(A,np.log10(y)))
-        S0y=10**(-1*np.array(pary)[0]/np.array(pary)[1])
-        if doplot:
-            plot(x,10**(pary[0]+pary[1]*np.log10(x)),'r-')
-            xscale("log")
-            yscale("log")
-            xlim(30,4000)
-            xlabel('baseline length [m]')
-            ylabel('YY phase variance [rad$^2$]')
-            title('YY diffractive scale:  %3.1f km'%(float(S0y)/1000.))
-            savefig(output_dir + '/' + outbasename + '_structure.png')
-            close()
-            cla()
-        S0s.append([S0,S0y])
-        betas.append([par[1],pary[1]])
-        outfile.write('S0s ****%s**** %s beta %s %s\n'%(S0,S0y,par[1],pary[1]))
-    data.close()
-    return(0)
-
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser()
-    parser.add_argument('h5parmfile',help='Name of input h5parm file')
-    parser.add_argument('--solset',help='Name of solution set to use')
-    parser.add_argument('--soltab',help='Name of solution table to use')
-    parser.add_argument('--outbasename',help='Outfile base name')
-    parser.add_argument('--output_dir', help='Output directory', default='./')
-    parser.add_argument('-p',dest='doplot',default=True,help='Do plotting')
-    parser.add_argument('-f',dest='dofilter',default=True,help='Attempt to filter out odd solutions')
-    parser.add_argument('-nr_grid',dest='nr_grid',default=1,help='Time step')
-
-    args = parser.parse_args()
-    h5parmfile = args.h5parmfile
-    solset = args.solset
-    soltab = args.soltab
-    dofilter = args.dofilter
-    doplot = args.doplot
-    outbasename = args.outbasename
-    output_dir = args.output_dir
-    nr_grid = args.nr_grid
-    
-    main(h5parmfile,solset,soltab,nr_grid,doplot,outbasename,output_dir,dofilter)
diff --git a/Docker/scripts/h5parm_pointingname.py b/Docker/scripts/h5parm_pointingname.py
deleted file mode 100755
index 60d7a879b9541ad280d0ba872abc009f3ec1e630..0000000000000000000000000000000000000000
--- a/Docker/scripts/h5parm_pointingname.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-
-from losoto.h5parm import h5parm
-from losoto.lib_operations import *
-
-import numpy
-########################################################################
-def main(h5parmdb, solsetName='sol000', pointing='POINTING'):
-
-
-    data          = h5parm(h5parmdb, readonly = False)       
-    solset        = data.getSolset(solsetName)
-    
-    sources = solset.obj._f_get_child('source')
-    direction = list(sources[0][-1])
-    
-    for i in numpy.arange(len(sources)):
-        sources[i] = (pointing, direction)
-        pass
-    
-    data.close()
-    return 0
-
-    
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Define the pointing direction of an h5parm.')
-
-    parser.add_argument('h5parmdb', type=str,
-                        help='H5parm of which pointing will be set.')
-    parser.add_argument('--solsetName', '--solset', type=str, default='sol000',
-                        help='Name of the h5parm solution set (default: sol000)')
-    parser.add_argument('--pointing', type=str, default='POINTING',
-                        help='Name of the h5parm solution set (default: POINTING)')
-
-    args = parser.parse_args()
-
-    h5parmdb = args.h5parmdb
-    logging.info("Working on: %s" % (h5parmdb))
-    main(h5parmdb, solsetName=args.solsetName, pointing=args.pointing)
diff --git a/Docker/scripts/make_clean_mask.py b/Docker/scripts/make_clean_mask.py
deleted file mode 100755
index b504be4a1ff077cc21f06e527fb24f909c7b0074..0000000000000000000000000000000000000000
--- a/Docker/scripts/make_clean_mask.py
+++ /dev/null
@@ -1,793 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to make a clean mask
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-import casacore.images as pim
-from astropy.io import fits as pyfits
-from astropy.coordinates import Angle
-import pickle
-import numpy as np
-import sys
-import os
-
-# I copy&pasted that into this file
-#from factor.lib.polygon import Polygon
-
-# workaround for a bug / ugly behavior in matplotlib / pybdsf
-# (some installtaions of matplotlib.pyplot fail if there is no X-Server available
-# which is not caught in pybdsf.)
-try:
-    import matplotlib
-    matplotlib.use('Agg')
-except (RuntimeError, ImportError):
-    pass
-try:
-    import bdsf
-except ImportError:
-    from lofar import bdsm as bdsf
-
-class Polygon:
-    """
-    Generic polygon class
-
-    Polygons are used to define the facet boundaries.
-
-    Parameters
-    ----------
-    x : array
-        A sequence of nodal x-coords.
-    y : array
-        A sequence of nodal y-coords.
-
-    """
-    def __init__(self, x, y):
-        if len(x) != len(y):
-            raise IndexError('x and y must be equally sized.')
-        self.x = np.asfarray(x)
-        self.y = np.asfarray(y)
-
-        # Closes the polygon if were open
-        x1, y1 = x[0], y[0]
-        xn, yn = x[-1], y[-1]
-        if x1 != xn or y1 != yn:
-            self.x = np.concatenate((self.x, [x1]))
-            self.y = np.concatenate((self.y, [y1]))
-
-        # Anti-clockwise coordinates
-        if _det(self.x, self.y) < 0:
-            self.x = self.x[::-1]
-            self.y = self.y[::-1]
-
-
-    def is_inside(self, xpoint, ypoint, smalld=1e-12):
-        """
-        Check if point is inside a general polygon.
-
-        An improved version of the algorithm of Nordbeck and Rydstedt.
-
-        REF: SLOAN, S.W. (1985): A point-in-polygon program. Adv. Eng.
-        Software, Vol 7, No. 1, pp 45-47.
-
-        Parameters
-        ----------
-        xpoint : array or float
-            The x-coord of the point to be tested.
-        ypoint : array or float
-            The y-coords of the point to be tested.
-        smalld : float
-            Tolerance within which point is considered to be on a side.
-
-        Returns
-        -------
-        mindst : array or float
-            The distance from the point to the nearest point of the polygon:
-
-            If mindst < 0 then point is outside the polygon.
-            If mindst = 0 then point in on a side of the polygon.
-            If mindst > 0 then point is inside the polygon.
-
-        """
-        xpoint = np.asfarray(xpoint)
-        ypoint = np.asfarray(ypoint)
-
-        # Scalar to array
-        if xpoint.shape is tuple():
-            xpoint = np.array([xpoint], dtype=float)
-            ypoint = np.array([ypoint], dtype=float)
-            scalar = True
-        else:
-            scalar = False
-        # Check consistency
-        if xpoint.shape != ypoint.shape:
-            raise IndexError('x and y  must be equally sized.')
-
-        # If snear = True: Dist to nearest side < nearest vertex
-        # If snear = False: Dist to nearest vertex < nearest side
-        snear = np.ma.masked_all(xpoint.shape, dtype=bool)
-
-        # Initialize arrays
-        mindst = np.ones_like(xpoint, dtype=float) * np.inf
-        j = np.ma.masked_all(xpoint.shape, dtype=int)
-        x = self.x
-        y = self.y
-        n = len(x) - 1  # Number of sides/vertices defining the polygon
-
-        # Loop over each side defining polygon
-        for i in range(n):
-            d = np.ones_like(xpoint, dtype=float) * np.inf
-
-            # Start of side has coords (x1, y1)
-            # End of side has coords (x2, y2)
-            # Point has coords (xpoint, ypoint)
-            x1 = x[i]
-            y1 = y[i]
-            x21 = x[i + 1] - x1
-            y21 = y[i + 1] - y1
-            x1p = x1 - xpoint
-            y1p = y1 - ypoint
-
-            # Points on infinite line defined by
-            #     x = x1 + t * (x1 - x2)
-            #     y = y1 + t * (y1 - y2)
-            # where
-            #     t = 0    at (x1, y1)
-            #     t = 1    at (x2, y2)
-            # Find where normal passing through (xpoint, ypoint) intersects
-            # infinite line
-            t = -(x1p * x21 + y1p * y21) / (x21 ** 2 + y21 ** 2)
-            tlt0 = t < 0
-            tle1 = (0 <= t) & (t <= 1)
-
-            # Normal intersects side
-            d[tle1] = ((x1p[tle1] + t[tle1] * x21) ** 2 +
-                       (y1p[tle1] + t[tle1] * y21) ** 2)
-
-            # Normal does not intersects side
-            # Point is closest to vertex (x1, y1)
-            # Compute square of distance to this vertex
-            d[tlt0] = x1p[tlt0] ** 2 + y1p[tlt0] ** 2
-
-            # Store distances
-            mask = d < mindst
-            mindst[mask] = d[mask]
-            j[mask] = i
-
-            # Point is closer to (x1, y1) than any other vertex or side
-            snear[mask & tlt0] = False
-
-            # Point is closer to this side than to any other side or vertex
-            snear[mask & tle1] = True
-
-        if np.ma.count(snear) != snear.size:
-            raise IndexError('Error computing distances')
-        mindst **= 0.5
-
-        # Point is closer to its nearest vertex than its nearest side, check if
-        # nearest vertex is concave.
-        # If the nearest vertex is concave then point is inside the polygon,
-        # else the point is outside the polygon.
-        jo = j.copy()
-        jo[j == 0] -= 1
-        area = _det([x[j + 1], x[j], x[jo - 1]], [y[j + 1], y[j], y[jo - 1]])
-        mindst[~snear] = np.copysign(mindst, area)[~snear]
-
-        # Point is closer to its nearest side than to its nearest vertex, check
-        # if point is to left or right of this side.
-        # If point is to left of side it is inside polygon, else point is
-        # outside polygon.
-        area = _det([x[j], x[j + 1], xpoint], [y[j], y[j + 1], ypoint])
-        mindst[snear] = np.copysign(mindst, area)[snear]
-
-        # Point is on side of polygon
-        mindst[np.fabs(mindst) < smalld] = 0
-
-        # If input values were scalar then the output should be too
-        if scalar:
-            mindst = float(mindst)
-        return mindst
-
-
-
-def read_vertices(filename):
-    """
-    Returns facet vertices stored in input file
-    """
-    with open(filename, 'r') as f:
-        direction_dict = pickle.load(f)
-    return direction_dict['vertices']
-
-
-def read_casa_polys(filename, image):
-    """
-    Reads casa region file and returns polys
-
-    Note: only regions of type "poly" are supported
-    """
-    with open(filename, 'r') as f:
-        lines = f.readlines()
-
-    polys = []
-    for line in lines:
-        if line.startswith('poly'):
-            poly_str_temp = line.split('[[')[1]
-            poly_str = poly_str_temp.split(']]')[0]
-            poly_str_list = poly_str.split('], [')
-            ra = []
-            dec = []
-            for pos in poly_str_list:
-                RAstr, Decstr = pos.split(',')
-                ra.append(Angle(RAstr, unit='hourangle').to('deg').value)
-                dec.append(Angle(Decstr.replace('.', ':', 2), unit='deg').to('deg').value)
-            poly_vertices = [np.array(ra), np.array(dec)]
-
-            # Convert to image-plane polygon
-            xvert = []
-            yvert = []
-            for RAvert, Decvert in zip(np.array(ra), np.array(dec)):
-                try:
-                    pixels = image.topixel([0, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                except:
-                    pixels = image.topixel([1, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                xvert.append(pixels[2]) # x -> Dec
-                yvert.append(pixels[3]) # y -> RA
-            polys.append(Polygon(xvert, yvert))
-
-        elif line.startswith('ellipse'):
-            ell_str_temp = line.split('[[')[1]
-            if '], 0.0' not in ell_str_temp and '], 90.0' not in ell_str_temp:
-                print('Only position angles of 0.0 and 90.0 are support for CASA '
-                    'regions of type "ellipse"')
-                sys.exit(1)
-            if '], 0.0' in ell_str_temp:
-                ell_str = ell_str_temp.split('], 0.0')[0]
-                pa = 0
-            else:
-                ell_str = ell_str_temp.split('], 90.0')[0]
-                pa = 90
-            ell_str_list = ell_str.split('], [')
-
-            # Ellipse center
-            RAstr, Decstr = ell_str_list[0].split(',')
-            ra_center = Angle(RAstr, unit='hourangle').to('deg').value
-            dec_center = Angle(Decstr.replace('.', ':', 2), unit='deg').to('deg').value
-            pixels = image.topixel([0, 1, dec_center*np.pi/180.0,
-                ra_center*np.pi/180.0])
-            x_center = pixels[2] # x -> Dec
-            y_center = pixels[3] # y -> RA
-
-            # Ellipse semimajor and semiminor axes
-            a_str, b_str = ell_str_list[1].split(',')
-            a_deg = float(a_str.split('arcsec')[0])/3600.0
-            b_deg = float(b_str.split('arcsec')[0])/3600.0
-            pixels1 = image.topixel([0, 1, (dec_center-a_deg/2.0)*np.pi/180.0,
-                ra_center*np.pi/180.0])
-            a_pix1 = pixels1[2]
-            pixels2 = image.topixel([0, 1, (dec_center+a_deg/2.0)*np.pi/180.0,
-                ra_center*np.pi/180.0])
-            a_pix2 = pixels2[2]
-            a_pix = abs(a_pix2 - a_pix1)
-            ex = []
-            ey = []
-            for th in range(0, 360, 1):
-                if pa == 0:
-                    # semimajor axis is along x-axis
-                    ex.append(a_pix * np.cos(th * np.pi / 180.0)
-                        + x_center) # x -> Dec
-                    ey.append(a_pix * b_deg / a_deg * np.sin(th * np.pi / 180.0) + y_center) # y -> RA
-                elif pa == 90:
-                    # semimajor axis is along y-axis
-                    ex.append(a_pix * b_deg / a_deg * np.cos(th * np.pi / 180.0)
-                        + x_center) # x -> Dec
-                    ey.append(a_pix * np.sin(th * np.pi / 180.0) + y_center) # y -> RA
-            polys.append(Polygon(ex, ey))
-
-        elif line.startswith('box'):
-            poly_str_temp = line.split('[[')[1]
-            poly_str = poly_str_temp.split(']]')[0]
-            poly_str_list = poly_str.split('], [')
-            ra = []
-            dec = []
-            for pos in poly_str_list:
-                RAstr, Decstr = pos.split(',')
-                ra.append(Angle(RAstr, unit='hourangle').to('deg').value)
-                dec.append(Angle(Decstr.replace('.', ':', 2), unit='deg').to('deg').value)
-            ra.insert(1, ra[0])
-            dec.insert(1, dec[1])
-            ra.append(ra[2])
-            dec.append(dec[0])
-            poly_vertices = [np.array(ra), np.array(dec)]
-
-            # Convert to image-plane polygon
-            xvert = []
-            yvert = []
-            for RAvert, Decvert in zip(np.array(ra), np.array(dec)):
-                try:
-                    pixels = image.topixel([0, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                except:
-                    pixels = image.topixel([1, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                xvert.append(pixels[2]) # x -> Dec
-                yvert.append(pixels[3]) # y -> RA
-            polys.append(Polygon(xvert, yvert))
-
-        elif line.startswith('#'):
-            pass
-
-        else:
-            print('Only CASA regions of type "poly", "box", or "ellipse" are supported')
-            sys.exit(1)
-
-    return polys
-
-
-def make_template_image(image_name, reference_ra_deg, reference_dec_deg,
-    imsize=512, cellsize_deg=0.000417):
-    """
-    Make a blank image and save it to disk
-
-    Parameters
-    ----------
-    image_name : str
-        Filename of output image
-    reference_ra_deg : float, optional
-        RA for center of output mask image
-    reference_dec_deg : float, optional
-        Dec for center of output mask image
-    imsize : int, optional
-        Size of output image
-    cellsize_deg : float, optional
-        Size of a pixel in degrees
-
-    """
-    shape_out = [1, 1, imsize, imsize]
-    hdu = pyfits.PrimaryHDU(np.zeros(shape_out, dtype=np.float32))
-    hdulist = pyfits.HDUList([hdu])
-    header = hdulist[0].header
-
-    # Add WCS info
-    header['CRVAL1'] = reference_ra_deg
-    header['CDELT1'] = -cellsize_deg
-    header['CRPIX1'] = imsize/2.0
-    header['CUNIT1'] = 'deg'
-    header['CTYPE1'] = 'RA---SIN'
-    header['CRVAL2'] = reference_dec_deg
-    header['CDELT2'] = cellsize_deg
-    header['CRPIX2'] = imsize/2.0
-    header['CUNIT2'] = 'deg'
-    header['CTYPE2'] = 'DEC--SIN'
-
-    # Add STOKES info
-    header['CRVAL3'] = 1.0
-    header['CDELT3'] = 1.0
-    header['CRPIX3'] = 1.0
-    header['CUNIT3'] = ''
-    header['CTYPE3'] = 'STOKES'
-
-    # Add frequency info
-    header['RESTFRQ'] = 15036
-    header['CRVAL4'] = 150e6
-    header['CDELT4'] = 3e8
-    header['CRPIX4'] = 1.0
-    header['CUNIT4'] = 'HZ'
-    header['CTYPE4'] = 'FREQ'
-    header['SPECSYS'] = 'TOPOCENT'
-
-    # Add equinox
-    header['EQUINOX'] = 2000.0
-
-    # Add telescope
-    header['TELESCOP'] = 'LOFAR'
-
-    hdulist[0].header = header
-
-    hdulist.writeto(image_name, clobber=True)
-    hdulist.close()
-
-
-
-def main(image_name, mask_name, atrous_do=False, threshisl=0.0, threshpix=0.0, rmsbox=None,
-         rmsbox_bright=(35, 7), iterate_threshold=False, adaptive_rmsbox=False, img_format='fits',
-         threshold_format='float', trim_by=0.0, vertices_file=None, atrous_jmax=6,
-         pad_to_size=None, skip_source_detection=False, region_file=None, nsig=1.0,
-         reference_ra_deg=None, reference_dec_deg=None, cellsize_deg=0.000417,
-         use_adaptive_threshold=False, adaptive_thresh=150.0):
-    """
-    Make a clean mask and return clean threshold
-
-    Parameters
-    ----------
-    image_name : str
-        Filename of input image from which mask will be made. If the image does
-        not exist, a template image with center at (reference_ra_deg,
-        reference_dec_deg) will be made internally
-    mask_name : str
-        Filename of output mask image
-    atrous_do : bool, optional
-        Use wavelet module of PyBDSF?
-    threshisl : float, optional
-        Value of thresh_isl PyBDSF parameter
-    threshpix : float, optional
-        Value of thresh_pix PyBDSF parameter
-    rmsbox : tuple of floats, optional
-        Value of rms_box PyBDSF parameter
-    rmsbox_bright : tuple of floats, optional
-        Value of rms_box_bright PyBDSF parameter
-    iterate_threshold : bool, optional
-        If True, threshold will be lower in 20% steps until
-        at least one island is found
-    adaptive_rmsbox : tuple of floats, optional
-        Value of adaptive_rms_box PyBDSF parameter
-    img_format : str, optional
-        Format of output mask image (one of 'fits' or 'casa')
-    threshold_format : str, optional
-        Format of output threshold (one of 'float' or 'str_with_units')
-    trim_by : float, optional
-        Fraction by which the perimeter of the output mask will be
-        trimmed (zeroed)
-    vertices_file : str, optional
-        Filename of file with vertices (must be a pickle file containing
-        a dictionary with the vertices in the 'vertices' entry)
-    atrous_jmax : int, optional
-        Value of atrous_jmax PyBDSF parameter
-    pad_to_size : int, optional
-        Pad output mask image to a size of pad_to_size x pad_to_size
-    skip_source_detection : bool, optional
-        If True, source detection is not run on the input image
-    region_file : str, optional
-        Filename of region file in CASA format. If given, no mask image
-        is made (the region file is used as the clean mask)
-    nsig : float, optional
-        Number of sigma of returned threshold value
-    reference_ra_deg : float, optional
-        RA for center of output mask image
-    reference_dec_deg : float, optional
-        Dec for center of output mask image
-    cellsize_deg : float, optional
-        Size of a pixel in degrees
-    use_adaptive_threshold : bool, optional
-        If True, use an adaptive threshold estimated from the negative values in
-        the image
-    adaptive_thresh : float, optional
-        If adaptive_rmsbox is True, this value sets the threshold above
-        which a source will use the small rms box
-
-    Returns
-    -------
-    result : dict
-        Dict with nsig-sigma rms threshold
-
-    """
-    if rmsbox is not None and type(rmsbox) is str:
-        rmsbox = eval(rmsbox)
-
-    if type(rmsbox_bright) is str:
-        rmsbox_bright = eval(rmsbox_bright)
-
-    if pad_to_size is not None and type(pad_to_size) is str:
-        pad_to_size = int(pad_to_size)
-
-    if type(atrous_do) is str:
-        if atrous_do.lower() == 'true':
-            atrous_do = True
-            threshisl = 4.0 # override user setting to ensure proper source fitting
-        else:
-            atrous_do = False
-
-    if type(iterate_threshold) is str:
-        if iterate_threshold.lower() == 'true':
-            iterate_threshold = True
-        else:
-            iterate_threshold = False
-
-    if type(adaptive_rmsbox) is str:
-        if adaptive_rmsbox.lower() == 'true':
-            adaptive_rmsbox = True
-        else:
-            adaptive_rmsbox = False
-
-    if type(skip_source_detection) is str:
-        if skip_source_detection.lower() == 'true':
-            skip_source_detection = True
-        else:
-            skip_source_detection = False
-
-    if type(use_adaptive_threshold) is str:
-        if use_adaptive_threshold.lower() == 'true':
-            use_adaptive_threshold = True
-        else:
-            use_adaptive_threshold = False
-
-    if reference_ra_deg is not None and reference_dec_deg is not None:
-        reference_ra_deg = float(reference_ra_deg)
-        reference_dec_deg = float(reference_dec_deg)
-
-    if not os.path.exists(image_name):
-        print('Input image not found. Making empty image...')
-        if not skip_source_detection:
-            print('ERROR: Source detection cannot be done on an empty image')
-            sys.exit(1)
-        if reference_ra_deg is not None and reference_dec_deg is not None:
-            image_name = mask_name + '.tmp'
-            make_template_image(image_name, reference_ra_deg, reference_dec_deg,
-                cellsize_deg=float(cellsize_deg))
-        else:
-            print('ERROR: if image not found, a refernce position must be given')
-            sys.exit(1)
-
-    trim_by = float(trim_by)
-    atrous_jmax = int(atrous_jmax)
-    threshpix = float(threshpix)
-    threshisl = float(threshisl)
-    nsig = float(nsig)
-    adaptive_thresh = float(adaptive_thresh)
-    threshold = 0.0
-
-    if not skip_source_detection:
-        if vertices_file is not None:
-            # Modify the input image to blank the regions outside of the polygon
-            temp_img = pim.image(image_name)
-            image_name += '.blanked'
-            temp_img.saveas(image_name, overwrite=True)
-            input_img = pim.image(image_name)
-            data = input_img.getdata()
-
-            vertices = read_vertices(vertices_file)
-            RAverts = vertices[0]
-            Decverts = vertices[1]
-            xvert = []
-            yvert = []
-            for RAvert, Decvert in zip(RAverts, Decverts):
-                pixels = input_img.topixel([1, 1, Decvert*np.pi/180.0,
-                    RAvert*np.pi/180.0])
-                xvert.append(pixels[2]) # x -> Dec
-                yvert.append(pixels[3]) # y -> RA
-            poly = Polygon(xvert, yvert)
-
-            # Find masked regions
-            masked_ind = np.where(data[0, 0])
-
-            # Find distance to nearest poly edge and set to NaN those that
-            # are outside the facet (dist < 0)
-            dist = poly.is_inside(masked_ind[0], masked_ind[1])
-            outside_ind = np.where(dist < 0.0)
-            if len(outside_ind[0]) > 0:
-                data[0, 0, masked_ind[0][outside_ind], masked_ind[1][outside_ind]] = np.nan
-
-            # Save changes
-            input_img.putdata(data)
-
-        if use_adaptive_threshold:
-            # Get an estimate of the rms
-            img = bdsf.process_image(image_name, mean_map='zero', rms_box=rmsbox,
-                                     thresh_pix=threshpix, thresh_isl=threshisl,
-                                     atrous_do=atrous_do, ini_method='curvature', thresh='hard',
-                                     adaptive_rms_box=adaptive_rmsbox, adaptive_thresh=adaptive_thresh,
-                                     rms_box_bright=rmsbox_bright, rms_map=True, quiet=True,
-                                     atrous_jmax=atrous_jmax, stop_at='isl')
-
-            # Find min and max pixels
-            max_neg_val = abs(np.min(img.ch0_arr))
-            max_neg_pos = np.where(img.ch0_arr == np.min(img.ch0_arr))
-            max_pos_val = abs(np.max(img.ch0_arr))
-            max_pos_pos = np.where(img.ch0_arr == np.max(img.ch0_arr))
-
-            # Estimate new thresh_isl from min pixel value's sigma, but don't let
-            # it get higher than 1/2 of the peak's sigma
-            threshisl_neg = 2.0 * max_neg_val / img.rms_arr[max_neg_pos][0]
-            max_sigma = max_pos_val / img.rms_arr[max_pos_pos][0]
-            if threshisl_neg > max_sigma / 2.0:
-                threshisl_neg = max_sigma / 2.0
-
-            # Use the new threshold only if it is larger than the user-specified one
-            if threshisl_neg > threshisl:
-                threshisl = threshisl_neg
-
-        if iterate_threshold:
-            # Start with given threshold and lower it until we get at least one island
-            nisl = 0
-            while nisl == 0:
-                img = bdsf.process_image(image_name, mean_map='zero', rms_box=rmsbox,
-                                         thresh_pix=threshpix, thresh_isl=threshisl,
-                                         atrous_do=atrous_do, ini_method='curvature', thresh='hard',
-                                         adaptive_rms_box=adaptive_rmsbox, adaptive_thresh=adaptive_thresh,
-                                         rms_box_bright=rmsbox_bright, rms_map=True, quiet=True,
-                                         atrous_jmax=atrous_jmax)
-                nisl = img.nisl
-                threshpix /= 1.2
-                threshisl /= 1.2
-                if threshpix < 5.0:
-                    break
-        else:
-            img = bdsf.process_image(image_name, mean_map='zero', rms_box=rmsbox,
-                                     thresh_pix=threshpix, thresh_isl=threshisl,
-                                     atrous_do=atrous_do, ini_method='curvature', thresh='hard',
-                                     adaptive_rms_box=adaptive_rmsbox, adaptive_thresh=adaptive_thresh,
-                                     rms_box_bright=rmsbox_bright, rms_map=True, quiet=True,
-                                     atrous_jmax=atrous_jmax)
-
-        if img.nisl == 0:
-            if region_file is None or region_file == '[]':
-                print('No islands found. Clean mask cannot be made.')
-                sys.exit(1)
-            else:
-                # Continue on and use user-supplied region file
-                skip_source_detection = True
-                threshold = nsig * img.clipped_rms
-
-        # Check if there are large islands preset (indicating that multi-scale
-        # clean is needed)
-        has_large_isl = False
-        for isl in img.islands:
-            if isl.size_active > 100:
-                # Assuming normal sampling, a size of 100 pixels would imply
-                # a source of ~ 10 beams
-                has_large_isl = True
-
-    if (region_file is not None and region_file != '[]' and skip_source_detection):
-        # Copy region file and return if source detection was not done
-        os.system('cp {0} {1}'.format(region_file.strip('[]"'), mask_name))
-        if threshold_format == 'float':
-            return {'threshold_5sig': threshold}
-        elif threshold_format == 'str_with_units':
-            # This is done to get around the need for quotes around strings in casapy scripts
-            # 'casastr/' is removed by the generic pipeline
-            return {'threshold_5sig': 'casastr/{0}Jy'.format(threshold)}
-    elif not skip_source_detection:
-        img.export_image(img_type='island_mask', mask_dilation=0, outfile=mask_name,
-                         img_format=img_format, clobber=True)
-
-    if (vertices_file is not None or trim_by > 0 or pad_to_size is not None
-        or (region_file is not None and region_file != '[]')
-        or skip_source_detection):
-        # Alter the mask in various ways
-        if skip_source_detection:
-            # Read the image
-            mask_im = pim.image(image_name)
-        else:
-            # Read the PyBDSF mask
-            mask_im = pim.image(mask_name)
-        data = mask_im.getdata()
-        coordsys = mask_im.coordinates()
-        if reference_ra_deg is not None and reference_dec_deg is not None:
-            values = coordsys.get_referencevalue()
-            values[2][0] = reference_dec_deg/180.0*np.pi
-            values[2][1] = reference_ra_deg/180.0*np.pi
-            coordsys.set_referencevalue(values)
-        imshape = mask_im.shape()
-        del(mask_im)
-
-        if pad_to_size is not None:
-            imsize = pad_to_size
-            coordsys['direction'].set_referencepixel([imsize/2, imsize/2])
-            pixmin = (imsize - imshape[2]) / 2
-            if pixmin < 0:
-                print("The padded size must be larger than the original size.")
-                sys.exit(1)
-            pixmax = pixmin + imshape[2]
-            data_pad = np.zeros((1, 1, imsize, imsize), dtype=np.float32)
-            data_pad[0, 0, pixmin:pixmax, pixmin:pixmax] = data[0, 0]
-            new_mask = pim.image('', shape=(1, 1, imsize, imsize), coordsys=coordsys)
-            new_mask.putdata(data_pad)
-        else:
-            new_mask = pim.image('', shape=imshape, coordsys=coordsys)
-            new_mask.putdata(data)
-
-        data = new_mask.getdata()
-
-        if skip_source_detection:
-            # Mask all pixels
-            data[:] = 1
-
-        if vertices_file is not None:
-            # Modify the clean mask to exclude regions outside of the polygon
-            vertices = read_vertices(vertices_file)
-            RAverts = vertices[0]
-            Decverts = vertices[1]
-            xvert = []
-            yvert = []
-            for RAvert, Decvert in zip(RAverts, Decverts):
-                try:
-                    pixels = new_mask.topixel([0, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                except:
-                    pixels = new_mask.topixel([1, 1, Decvert*np.pi/180.0,
-                                               RAvert*np.pi/180.0])
-                xvert.append(pixels[2]) # x -> Dec
-                yvert.append(pixels[3]) # y -> RA
-            poly = Polygon(xvert, yvert)
-
-            # Find masked regions
-            masked_ind = np.where(data[0, 0])
-
-            # Find distance to nearest poly edge and unmask those that
-            # are outside the facet (dist < 0)
-            dist = poly.is_inside(masked_ind[0], masked_ind[1])
-            outside_ind = np.where(dist < 0.0)
-            if len(outside_ind[0]) > 0:
-                data[0, 0, masked_ind[0][outside_ind], masked_ind[1][outside_ind]] = 0
-
-        if trim_by > 0.0:
-            sh = np.shape(data)
-            margin = int(sh[2] * trim_by / 2.0 )
-            data[0, 0, 0:sh[2], 0:margin] = 0
-            data[0, 0, 0:margin, 0:sh[3]] = 0
-            data[0, 0, 0:sh[2], sh[3]-margin:sh[3]] = 0
-            data[0, 0, sh[2]-margin:sh[2], 0:sh[3]] = 0
-
-        if region_file is not None and region_file != '[]':
-            # Merge the CASA regions with the mask
-            casa_polys = read_casa_polys(region_file.strip('[]"'), new_mask)
-            for poly in casa_polys:
-                # Find unmasked regions
-                unmasked_ind = np.where(data[0, 0] == 0)
-
-                # Find distance to nearest poly edge and mask those that
-                # are inside the casa region (dist > 0)
-                dist = poly.is_inside(unmasked_ind[0], unmasked_ind[1])
-                inside_ind = np.where(dist > 0.0)
-                if len(inside_ind[0]) > 0:
-                    data[0, 0, unmasked_ind[0][inside_ind], unmasked_ind[1][inside_ind]] = 1
-
-        # Save changes
-        new_mask.putdata(data)
-        if img_format == 'fits':
-            new_mask.tofits(mask_name, overwrite=True)
-        elif img_format == 'casa':
-            new_mask.saveas(mask_name, overwrite=True)
-        else:
-            print('Output image format "{}" not understood.'.format(img_format))
-            sys.exit(1)
-
-    if not skip_source_detection:
-        if threshold_format == 'float':
-            return {'threshold_5sig': nsig * img.clipped_rms, 'multiscale': has_large_isl}
-        elif threshold_format == 'str_with_units':
-            # This is done to get around the need for quotes around strings in casapy scripts
-            # 'casastr/' is removed by the generic pipeline
-            return {'threshold_5sig': 'casastr/{0}Jy'.format(nsig * img.clipped_rms),
-                'multiscale': has_large_isl}
-    else:
-        return {'threshold_5sig': '0.0'}
-
-
-if __name__ == '__main__':
-    descriptiontext = "Make a clean mask.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('image_name', help='Image name')
-    parser.add_argument('mask_name', help='Mask name')
-    parser.add_argument('-a', '--atrous_do', help='use wavelet fitting', type=bool, default=False)
-    parser.add_argument('-i', '--threshisl', help='', type=float, default=3.0)
-    parser.add_argument('-p', '--threshpix', help='', type=float, default=5.0)
-    parser.add_argument('-r', '--rmsbox', help='rms box width and step (e.g., "(60, 20)")',
-        type=str, default='(60, 20)')
-    parser.add_argument('--rmsbox_bright', help='rms box for bright sources(?) width and step (e.g., "(60, 20)")',
-        type=str, default='(60, 20)')
-    parser.add_argument('-t', '--iterate_threshold', help='iteratively decrease threshold until at least '
-        'one island is found', type=bool, default=False)
-    parser.add_argument('-o', '--adaptive_rmsbox', help='use an adaptive rms box', type=bool, default=False)
-    parser.add_argument('-f', '--img_format', help='format of output mask', type=str, default='casa')
-    parser.add_argument('-d', '--threshold_format', help='format of return value', type=str, default='float')
-    parser.add_argument('-b', '--trim_by', help='Trim masked region by this number of pixels', type=float, default=0.0)
-    parser.add_argument('-v', '--vertices_file', help='file containing facet polygon vertices', type=str, default=None)
-    parser.add_argument('--region_file', help='File containing casa regions to be merged with the detected mask', type=str, default=None)
-    parser.add_argument('-j', '--atrous_jmax', help='Max wavelet scale', type=int, default=3)
-    parser.add_argument('-z', '--pad_to_size', help='pad mask to this size', type=int, default=None)
-    parser.add_argument('-s', '--skip_source_detection', help='skip source detection', type=bool, default=False)
-
-    args = parser.parse_args()
-    erg = main(args.image_name, args.mask_name, atrous_do=args.atrous_do,
-               threshisl=args.threshisl, threshpix=args.threshpix, rmsbox=args.rmsbox,
-               rmsbox_bright=args.rmsbox_bright,
-               iterate_threshold=args.iterate_threshold,
-               adaptive_rmsbox=args.adaptive_rmsbox, img_format=args.img_format,
-               threshold_format=args.threshold_format, trim_by=args.trim_by,
-               vertices_file=args.vertices_file, atrous_jmax=args.atrous_jmax,
-               pad_to_size=args.pad_to_size, skip_source_detection=args.skip_source_detection,
-               region_file=args.region_file)
-    print erg
diff --git a/Docker/scripts/make_source_list.py b/Docker/scripts/make_source_list.py
deleted file mode 100755
index 3ce987507c2497694dad1ac79098e780e0452043..0000000000000000000000000000000000000000
--- a/Docker/scripts/make_source_list.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to make a source catalog for an image
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-import sys
-import os
-try:
-    import matplotlib
-    matplotlib.use('Agg')
-except (RuntimeError, ImportError):
-    pass
-import bdsf
-import lsmtool
-
-
-def main(image_name, catalog_name, atrous_do=False, threshisl=3.0, threshpix=5.0, rmsbox=(60, 20),
-         rmsbox_bright=(35, 7), adaptive_rmsbox=False, atrous_jmax=6, adaptive_thresh=150.0,
-         compare_dir=None, format='png'):
-    """
-    Make a source catalog for an image
-
-    Parameters
-    ----------
-    image_name : str
-        Filename of input image from which catalog will be made
-    catalog_name : str
-        Filename of output source catalog in FITS format
-    atrous_do : bool, optional
-        Use wavelet module of PyBDSF?
-    threshisl : float, optional
-        Value of thresh_isl PyBDSF parameter
-    threshpix : float, optional
-        Value of thresh_pix PyBDSF parameter
-    rmsbox : tuple of floats, optional
-        Value of rms_box PyBDSF parameter
-    rmsbox_bright : tuple of floats, optional
-        Value of rms_box_bright PyBDSF parameter
-    adaptive_rmsbox : tuple of floats, optional
-        Value of adaptive_rms_box PyBDSF parameter
-    atrous_jmax : int, optional
-        Value of atrous_jmax PyBDSF parameter
-    adaptive_thresh : float, optional
-        If adaptive_rmsbox is True, this value sets the threshold above
-        which a source will use the small rms box
-    compare_dir : str, optional
-        Directory for output plots/info of comparison of source properties to surveys
-    format : str, optional
-        Format of output plots: 'png' or 'pdf'
-    """
-    if type(rmsbox) is str:
-        rmsbox = eval(rmsbox)
-
-    if type(rmsbox_bright) is str:
-        rmsbox_bright = eval(rmsbox_bright)
-
-    if type(atrous_do) is str:
-        if atrous_do.lower() == 'true':
-            atrous_do = True
-            threshisl = 4.0  # override user setting to ensure proper source fitting
-        else:
-            atrous_do = False
-
-    if type(adaptive_rmsbox) is str:
-        if adaptive_rmsbox.lower() == 'true':
-            adaptive_rmsbox = True
-        else:
-            adaptive_rmsbox = False
-
-    if not os.path.exists(image_name):
-        print('ERROR: input image not found')
-        sys.exit(1)
-
-    atrous_jmax = int(atrous_jmax)
-    threshpix = float(threshpix)
-    threshisl = float(threshisl)
-    adaptive_thresh = float(adaptive_thresh)
-
-    img = bdsf.process_image(image_name, mean_map='zero', rms_box=rmsbox,
-                             thresh_pix=threshpix, thresh_isl=threshisl,
-                             atrous_do=atrous_do, ini_method='curvature', thresh='hard',
-                             adaptive_rms_box=adaptive_rmsbox, adaptive_thresh=adaptive_thresh,
-                             rms_box_bright=rmsbox_bright, rms_map=True, quiet=True,
-                             atrous_jmax=atrous_jmax)
-    srcroot = 'prefactor'
-    img.write_catalog(outfile=catalog_name, bbs_patches='source', srcroot=srcroot, clobber=True)
-
-    # Use LSMTool to make some basic comparisons to surveys
-    if compare_dir is not None:
-        s = lsmtool.load(catalog_name)
-        s.setPatchPositions(method='wmean')
-        _, _, refRA, refDec = s._getXY()
-        def_dict = s.getDefaultValues()
-        if 'ReferenceFrequency' in def_dict:
-            ref_freq_hz = def_dict['ReferenceFrequency']
-        else:
-            ref_freq_hz = 0.0
-        if ref_freq_hz > 140e6 and ref_freq_hz < 160e6:
-            # use TGSS
-            vocat = 'TGSS'
-            ignspec = None
-        else:
-            # too far in freq from TGSS -> use GSM, ignoring sources that lack spectral
-            # information (spec_indx = -0.7)
-            vocat = 'GSM'
-            ignspec = -0.7
-        s_vo = lsmtool.load(vocat, VOPosition=[refRA, refDec], VORadius='5 deg')
-        s_vo.group('threshold', FWHM='30 arcsec', threshold=0.001)
-        s.compare(s_vo, radius='30 arcsec', excludeMultiple=False, outDir=compare_dir,
-                  name1='LOFAR', name2=vocat, format=format, ignoreSpec=ignspec)
-
-
-if __name__ == '__main__':
-    descriptiontext = "Make a source catalog from an image.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('image_name', help='Image name')
-    parser.add_argument('catalog_name', help='Output catalog name')
-    parser.add_argument('-a', '--atrous_do', help='use wavelet fitting', type=bool, default=False)
-    parser.add_argument('-i', '--threshisl', help='', type=float, default=3.0)
-    parser.add_argument('-p', '--threshpix', help='', type=float, default=5.0)
-    parser.add_argument('-r', '--rmsbox', help='rms box width and step (e.g., "(60, 20)")',
-                        type=str, default='(60, 20)')
-    parser.add_argument('--rmsbox_bright', help='rms box for bright sources(?) width and step (e.g., "(60, 20)")',
-                        type=str, default='(60, 20)')
-    parser.add_argument('-o', '--adaptive_rmsbox', help='use an adaptive rms box', type=bool, default=False)
-    parser.add_argument('-j', '--atrous_jmax', help='Max wavelet scale', type=int, default=3)
-    parser.add_argument('-c', '--compare_dir', help='', type=str, default=None)
-    parser.add_argument('-f', '--format', help='', type=str, default='pdf')
-
-    args = parser.parse_args()
-    main(args.image_name, args.catalog_name, atrous_do=args.atrous_do,
-         threshisl=args.threshisl, threshpix=args.threshpix, rmsbox=args.rmsbox,
-         rmsbox_bright=args.rmsbox_bright, adaptive_rmsbox=args.adaptive_rmsbox,
-         atrous_jmax=args.atrous_jmax, compare_dir=args.compare_dir, format=args.format)
diff --git a/Docker/scripts/make_summary.py b/Docker/scripts/make_summary.py
deleted file mode 100755
index 70c230b217a9ff27281c643e666c5e60729671f0..0000000000000000000000000000000000000000
--- a/Docker/scripts/make_summary.py
+++ /dev/null
@@ -1,226 +0,0 @@
-#! /usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import os,sys
-import argparse
-import subprocess, platform
-import numpy, re
-import multiprocessing
-
-########################################################################
-def input2strlist_nomapfile(invar):
-   """ 
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-###############################################################################
-def find_flagged_fraction(ms_file):
-    
-   outputs  = os.popen('DPPP msin=' + ms_file + ' msout=. steps=[count] count.type=counter count.warnperc=0.0000001 | grep NOTE').readlines()
-   fraction_flagged = { output.split('(')[-1].rstrip(')\n'):output.split('%')[0][-5:].strip() for output in outputs if 'station' in output }
-   return fraction_flagged
-
-###############################################################################
-def main(observation_directory = '/data/share/pipeline/Observation', logfile = '/data/share/pipeline/Observation/logs/pipeline.log', h5parmdb = 'solutions.h5', MSfile = '[]'):
-	"""
-	Creates summary of a given prefactor3 run
-	
-	Parameters
-	----------
-	observation_directory: directory where all the processed data and solutions are stored
-	logfile: directory where all the log files are stored
-	h5parmdb: name of the solutions h5parm database
-	MSfile: pattern of the final MS files
-	
-	"""
-	ID = os.path.basename(observation_directory)
-	summary = os.path.normpath(observation_directory + '/../' + ID + '.log')
-	f_summary = open(summary, 'w')
-	
-	# location of logfile
-	print('Summary logfile is written to ' + summary)
-	
-	if not os.path.exists(logfile):
-		f_summary.write(logfile + ' does not exist. Skipping!')
-		f_summary.close()
-		return(1)
-		pass
-	
-	## check for the h5parm
-	if os.path.exists(observation_directory  + '/results/cal_values/' + h5parmdb):
-		h5parmdb = observation_directory + '/results/cal_values/' + h5parmdb
-		pass
-	elif os.path.exists(observation_directory + '/results/cal_values/cal_' + h5parmdb):
-		h5parmdb =  observation_directory + '/results/cal_values/cal_' + h5parmdb
-	else:
-		f_summary.write('No h5parm solutions file found in ' + observation_directory + '/results/cal_values/' + h5parmdb)
-		f_summary.close()
-		return(1)
-		pass
-	
-	## convert stringlist to list
-	mslist = input2strlist_nomapfile(MSfile)
-	
-	## get proper solset
-	from losoto.h5parm import h5parm
-	data = h5parm(h5parmdb, readonly = True)
-	if 'target' in data.getSolsetNames():
-		solset = 'target'
-		pass
-	elif 'calibrator' in data.getSolsetNames():
-		solset = 'calibrator'
-		pass
-	else:
-		f_summary.write('Neither calibrator or target solset has been found in ' + h5parmdb)
-		f_summary.close()
-		return(1)
-		pass
-	
-	## get antenna information
-	solset       = data.getSolset(solset)
-	soltabs      = list([soltab.name for soltab in solset.getSoltabs()])
-	source       = solset.obj._f_get_child('source')[0][0]
-	antenna_len  = '{:<' + str(max([ len(antenna)     for antenna     in solset.getAnt()])) + '}'
-	soltab_len   = '{:^' + str(max([ len(soltab_name) for soltab_name in soltabs        ])) + '}'
-	
-	## get software versions
-	try:
-		DPPP_version      =             subprocess.Popen(['DPPP', '-v'], stdout=subprocess.PIPE).stdout.read()
-		losoto_version    = 'losoto ' + subprocess.Popen(['losoto', '--version'], stderr=subprocess.PIPE).stderr.read()
-		lsmtool_version   =             subprocess.Popen(['lsmtool', '--version'], stdout=subprocess.PIPE).stdout.read()
-		aoflagger_version =             subprocess.Popen(['aoflagger', '--version'], stdout=subprocess.PIPE).stdout.read()
-		wsclean_version   =             subprocess.Popen(['wsclean', '--version'], stdout=subprocess.PIPE).stdout.read().split('\n')[1] + '\n'
-		python_version    =             subprocess.Popen(['python', '--version'], stderr=subprocess.PIPE).stderr.read()
-		
-		import matplotlib, scipy, astropy
-		modules_version   = 'matplotlib ' + str(matplotlib.__version__) + ', scipy ' + str(scipy.__version__) + ', astropy ' + str(astropy.__version__) + '\n'
-		os_version        = ' '.join(platform.linux_distribution()) + ' ' + platform.release() + ' ' + platform.version() + '\n'
-		f_summary.write('Software versions currently used:\n' + os_version        \
-                                                           + DPPP_version      \
-                                                           + aoflagger_version \
-                                                           + losoto_version    \
-                                                           + lsmtool_version   \
-                                                           + wsclean_version   \
-                                                           + python_version    \
-                                                           + modules_version   )
-	except OSError:
-		f_summary.write('Could not find all LOFAR or related software packages. Could not determine the used software versions.\n')
-		pass
-	
-	## get the list of removed stations:
-	baseline_list = list(set([ str(line.split(";")[1:]) for line in open(logfile) if 'baseline:' in line and ';' in line ]))
-	bad_antennas  = list(set(re.sub("[\[\]\"\ '!*]", "", str(baseline_list)).replace('\\n','').replace('\\','').split(',')))
-	if len(bad_antennas) == 1 and bad_antennas[0] == '':
-		bad_antennas = 'NONE'
-		pass
-	
-	## check for A-Team warning:
-	Ateam_list = list(set([ str(line.split('source ')[-1]).split(' is')[0] for line in open(logfile) if 'WARNING: The A-Team source' in line ]))
-	if len(Ateam_list) == 0:
-		Ateam_list = 'NONE'
-		pass
-	
-	f_summary.write('\n')
-	f_summary.write('Antennas removed from the data: ' + re.sub("[\[\]']", "", str(bad_antennas)) + '\n')
-	f_summary.write('A-Team sources close to the phase reference center: ' + re.sub("[\[\]']", "", str(Ateam_list)) + '\n')
-	f_summary.write('\n')
-	
-	## diffractive scale
-	structure_file = observation_directory + '/results/inspection/' + source + '_structure.txt'
-	if os.path.exists(structure_file):
-		with open(structure_file, 'r') as infile:
-			for line in infile:
-				diffractive_scale_XX = float(line.split()[2])
-				diffractive_scale_YY = float(line.split()[2])
-		f_summary.write('XX diffractive scale: %3.1f km'%(diffractive_scale_XX/1000.) + '\n')
-		f_summary.write('YY diffractive scale: %3.1f km'%(diffractive_scale_YY/1000.) + '\n') 
-	
-	## check whether reference has been used
-	if 'bandpass' in soltabs:
-		soltab  = solset.getSoltab('bandpass')
-		history = soltab.getHistory()
-		if not history.strip('\n') == '':
-			f_summary.write(history + '\n')
-			pass
-	
-	## get table of flagged solutions
-	f_summary.write('\n')
-	flagged_solutions = {}
-	import losoto.lib_operations as losoto
-	for soltab_name in soltabs:
-		soltab   = solset.getSoltab(soltab_name)
-		antennas = soltab.ant
-		axes     = soltab.getAxesNames()
-		axes.insert(0, axes.pop(axes.index('ant'))) ## put antenna table to the second place
-		flagged_solutions[soltab_name] = {}
-		for vals, weights, coord, selection in soltab.getValuesIter(returnAxes=axes, weight=True):
-			vals    = losoto.reorderAxes(vals,    soltab.getAxesNames(), axes)
-			weights = losoto.reorderAxes(weights, soltab.getAxesNames(), axes)
-		for i, antenna in enumerate(antennas):
-			flagged_fraction = 1. - float(numpy.mean(weights[i]))
-			flagged_solutions[soltab_name][antenna] = soltab_len.format('{:.2f}'.format(100 * flagged_fraction) + '%')
-	soltab_names = ' '.join([ soltab_len.format(soltab_name) for soltab_name in soltabs ])
-	f_summary.write('Amount of flagged solutions per station and solution table:\n')
-	f_summary.write(antenna_len.format('Station') + ' ' + soltab_names + '\n')
-	for antenna in antennas:
-		values_to_print = []
-		for soltab_name in soltabs:
-			try:
-				values_to_print.append(flagged_solutions[soltab_name][antenna])
-			except KeyError:
-				values_to_print.append(soltab_len.format(' '))
-		values_to_print = ' '.join(values_to_print)
-		f_summary.write(antenna_len.format(antenna) + ' ' + values_to_print + '\n')
-		
-	
-	## derive the fraction of flagged data of the entire observation
-	pool = multiprocessing.Pool(processes = multiprocessing.cpu_count())
-	flagged_fraction_list = pool.map(find_flagged_fraction, mslist)
-	
-	flagged_fraction_data = {}
-	for entry in flagged_fraction_list:
-		antennas = entry.keys()
-		for antenna in antennas:
-			try:
-				flagged_fraction_data[antenna].append(float(entry[antenna]))
-			except KeyError:
-				flagged_fraction_data[antenna] = [float(entry[antenna])]
-	
-	f_summary.write('\n')
-	f_summary.write('Overall amount of flagged data in the final data:\n')
-	f_summary.write(antenna_len.format('Station') + '\n')
-	for antenna in sorted(flagged_fraction_data.keys()):
-		flagged_fraction_data[antenna] = sum(flagged_fraction_data[antenna]) / len(flagged_fraction_data[antenna])
-		f_summary.write(antenna_len.format(antenna) + ' ' + '{:>10}'.format('{:.2f}'.format(flagged_fraction_data[antenna]) + '%') + '\n')
-	
-	print('Summary has been created.')
-	return 0
-
-
-if __name__=='__main__':
-    
-	parser = argparse.ArgumentParser(description='Creates summary of a given prefactor3 run.') 
-	parser.add_argument('--obsdir', type=str, default='/data/scratch/pipeline/Observation', help='Directory where to find the processed data and solutions.')
-	parser.add_argument('--logfile', type=str, default='/data/share/pipeline/Observation/logs/pipeline.log', help='Location of the pipeline logfile.')
-	parser.add_argument('--h5parm', '--h5parm', type=str, default='solutions.h5', help='Name of the h5parm solutions file (default: solutions.h5)')
-	parser.add_argument('--MSfile', '--MSfile', type=str, default='[]', help='List of MS to be analysed (default: [])')
-	
-	args = parser.parse_args()
-	
-	# start running script
-	main(args.obsdir, args.logfile, args.h5parm, args.MSfile)
-	
-	sys.exit(0)
-	pass
diff --git a/Docker/scripts/merge_skymodels.py b/Docker/scripts/merge_skymodels.py
deleted file mode 100755
index 20ce30f8b35d3f5c2bedf298b0b4b384d65595ea..0000000000000000000000000000000000000000
--- a/Docker/scripts/merge_skymodels.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-"""
-Script to merge two sky models
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-import os
-import lsmtool
-import sys
-
-
-def main(inmodel1, inmodel2, outmodel, match_by='name', radius=0.0, keep='all'):
-    """
-    Creates mosaic
-
-    Parameters
-    ----------
-    inmodel1 : str
-        Filename of input model 1
-    inmodel2 : str
-        Filename of input model 2
-    outmodel : str
-        Filename of output model
-    match_by : str, optional
-        The match_by parameter of LSMTool
-    radius : float, optional
-        Radius in degrees for cross match
-    keep : str, optional
-        The keep parameter of LSMTool
-
-    """
-    s1 = lsmtool.load(inmodel1)
-    s2 = lsmtool.load(inmodel2)
-
-    s1.concatenate(s2, matchBy=match_by, radius=float(radius), keep=keep,
-        inheritPatches=True)
-    s1.group('every')
-    s1.write(fileName=outmodel, clobber=True)
-
-
-if __name__ == '__main__':
-    descriptiontext = "Merge two sky models.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('inmodel1', help='input model 1 filename')
-    parser.add_argument('inmodel2', help='input model 2 filename')
-    parser.add_argument('outmodel', help='output model filename')
-    parser.add_argument('-m', '--match_by', help='match type', type=str, default='name')
-    parser.add_argument('-r', '--radius', help='radius in degrees for matching', type=float, default=0.0)
-    parser.add_argument('-k', '--keep', help='', type=str, default='all')
-
-    args = parser.parse_args()
-    main(args.inmodel1, args.inmodel2, args.outmodel, match_by=args.match_by,
-         radius=args.radius, keep=args.keep)
diff --git a/Docker/scripts/pad_image.py b/Docker/scripts/pad_image.py
deleted file mode 100755
index 15f81dce17ba53392bb35e66e1c2427a2d2d78ef..0000000000000000000000000000000000000000
--- a/Docker/scripts/pad_image.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to pad a FITS image
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-from astropy.io import fits as pyfits
-import numpy as np
-import sys
-import os
-
-
-def main(infile, xypadsize):
-    """Pad a fits image with zeros to padsize"""
-    pad_xsize, pad_ysize = [int(s) for s in xypadsize.split(' ')]
-
-    hdu = pyfits.open(infile)
-    imdata = hdu[0].data[0, 0]
-    (ysize, xsize) = imdata.shape
-    if xsize > pad_xsize or ysize > pad_ysize:
-        raise ValueError('pad_image: padded size is smaller than current size!')
-    if xsize == pad_xsize and ysize == pad_ysize:
-        return
-
-    xoffset = (pad_xsize - xsize) / 2
-    yoffset = (pad_ysize - ysize) / 2
-    newdata=np.zeros((1, 1, pad_ysize, pad_xsize))
-
-    newdata[0, 0, yoffset:yoffset+ysize, xoffset:xoffset+xsize] = imdata
-    hdu[0].data = newdata
-    hdu[0].header['CRPIX1'] += xoffset
-    hdu[0].header['CRPIX2'] += yoffset
-    hdu.writeto(infile, clobber=True)
-
-
-if __name__ == '__main__':
-    descriptiontext = "Pad FITS image.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('infile', help='filename of input image')
-    parser.add_argument('xypadsize', help='padded size as "xsize ysize"')
-    args = parser.parse_args()
-
-    main(args.infile, args.xypadsize)
diff --git a/Docker/scripts/plot_Ateamclipper.py b/Docker/scripts/plot_Ateamclipper.py
deleted file mode 100755
index 56e5d169a2da5e7846dd0e777cd4765bcb15049c..0000000000000000000000000000000000000000
--- a/Docker/scripts/plot_Ateamclipper.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# -* coding: utf-8 -*-
-
-"""
-Adds phases (=0) and amplitudes (=1) to any missing station if they appear in an h5parm, but not in a particular soltab. 
-
-Created on Tue Jul 24 2019
-
-@author: Alexander Drabent
-"""
-
-import argparse
-import matplotlib as mpl
-mpl.use('Agg')
-import matplotlib
-import matplotlib.pyplot as plt
-import numpy
-
-def main(txtfile = 'Ateamclipper.txt', outfile = 'Ateamclipper.png'):
-
-    frac_list_xx = []
-    frac_list_yy = []
-    freq_list    = []
-    with open(txtfile, 'r') as infile:
-        for line in infile:
-            freq_list.append(float(line.split()[0]))
-            frac_list_xx.append(float(line.split()[1]))
-            frac_list_yy.append(float(line.split()[2]))
-    
-    # Plot the amount of clipped data vs. frequency potentially contaminated by the A-team
-    plt.scatter(numpy.array(freq_list) / 1e6, numpy.array(frac_list_xx), marker = '.', s = 10)
-    plt.xlabel('frequency [MHz]')
-    plt.ylabel('A-team clipping fraction [%]')
-    plt.savefig(outfile)
-    return(0)
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='Adds phases and amplitudes to any missing station if they appear in an h5parm, but not in a particular soltab.')
-
-    parser.add_argument('txtfile', type=str,
-                        help='Input text file containing frequency and flag fraction of the XX and YY polarization.')
-    parser.add_argument('outfile', type=str,
-                        help='Input text file containing frequency and flag fraction of the XX and YY polarization.')
-
-
-    args = parser.parse_args()
-
-    main(txtfile = args.txtfile, outfile = args.outfile)
-
diff --git a/Docker/scripts/plot_image.py b/Docker/scripts/plot_image.py
deleted file mode 100755
index 460865968769d15b33a3de15c420d47bc65682e2..0000000000000000000000000000000000000000
--- a/Docker/scripts/plot_image.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env python
-"""
-plot image
-Original code from Reinout
-"""
-import os
-import matplotlib as mpl
-mpl.use('Agg')
-import aplpy
-import numpy
-import astropy.io.fits
-
-
-def meanclip(indata, clipsig=4.0, maxiter=10, converge_num=0.001, verbose=0):
-    """
-    Computes an iteratively sigma-clipped mean on a
-    data set. Clipping is done about median, but mean
-    is returned.
-
-    .. note:: MYMEANCLIP routine from ACS library.
-
-    :History:
-        * 21/10/1998 Written by RSH, RITSS
-        * 20/01/1999 Added SUBS, fixed misplaced paren on float call, improved doc. RSH
-        * 24/11/2009 Converted to Python. PLL.
-
-    Examples
-    --------
-    >>> mean, sigma = meanclip(indata)
-
-    Parameters
-    ----------
-    indata: array_like
-        Input data.
-
-    clipsig: float
-        Number of sigma at which to clip.
-
-    maxiter: int
-        Ceiling on number of clipping iterations.
-
-    converge_num: float
-        If the proportion of rejected pixels is less than
-        this fraction, the iterations stop.
-
-    verbose: {0, 1}
-        Print messages to screen?
-
-    Returns
-    -------
-    mean: float
-        N-sigma clipped mean.
-
-    sigma: float
-        Standard deviation of remaining pixels.
-
-    """
-    # Flatten array
-    skpix = indata.reshape(indata.size,)
-
-    ct = indata.size
-    iter = 0
-    c1 = 1.0
-    c2 = 0.0
-
-    while (c1 >= c2) and (iter < maxiter):
-        lastct = ct
-        medval = numpy.median(skpix)
-        sig = numpy.std(skpix)
-        wsm = numpy.where(abs(skpix-medval) < clipsig*sig)
-        ct = len(wsm[0])
-        if ct > 0:
-            skpix = skpix[wsm]
-
-        c1 = abs(ct - lastct)
-        c2 = converge_num * lastct
-        iter += 1
-
-    mean = numpy.mean(skpix)
-    sigma = robust_sigma(skpix)
-
-    return mean, sigma
-
-
-def find_imagenoise(data):
-    mean, rms = meanclip(data)
-    return rms
-
-
-def robust_sigma(in_y, zero=0):
-    """
-    Calculate a resistant estimate of the dispersion of
-    a distribution. For an uncontaminated distribution,
-    this is identical to the standard deviation.
-
-    Use the median absolute deviation as the initial
-    estimate, then weight points using Tukey Biweight.
-    See, for example, Understanding Robust and
-    Exploratory Data Analysis, by Hoaglin, Mosteller
-    and Tukey, John Wiley and Sons, 1983.
-
-    .. note:: ROBUST_SIGMA routine from IDL ASTROLIB.
-
-    Examples
-    --------
-    >>> result = robust_sigma(in_y, zero=1)
-
-    Parameters
-    ----------
-    in_y : array_like
-        Vector of quantity for which the dispersion is
-        to be calculated
-
-    zero : int
-        If set, the dispersion is calculated w.r.t. 0.0
-        rather than the central value of the vector. If
-        Y is a vector of residuals, this should be set.
-
-    Returns
-    -------
-    out_val : float
-        Dispersion value. If failed, returns -1.
-
-    """
-    # Flatten array
-    y = in_y.ravel()
-
-    eps = 1.0E-20
-    c1 = 0.6745
-    c2 = 0.80
-    c3 = 6.0
-    c4 = 5.0
-    c_err = -1.0
-    min_points = 3
-
-    if zero:
-        y0 = 0.0
-    else:
-        y0 = numpy.median(y)
-
-    dy = y - y0
-    del_y = abs(dy)
-
-    # First, the median absolute deviation MAD about the median:
-    mad = numpy.median(del_y) / c1
-
-    # If the MAD=0, try the MEAN absolute deviation:
-    if mad < eps:
-        mad = del_y.mean() / c2
-    if mad < eps:
-        return 0.0
-
-    # Now the biweighted value:
-    u = dy / (c3 * mad)
-    uu = u * u
-    q = numpy.where(uu <= 1.0)
-    count = len(q[0])
-    if count < min_points:
-        print('ROBUST_SIGMA: This distribution is TOO WEIRD! '
-              'Returning {}'.format(c_err))
-        return c_err
-
-    numerator = numpy.sum((y[q] - y0)**2.0 * (1.0 - uu[q])**4.0)
-    n = y.size
-    den1 = numpy.sum((1.0 - uu[q]) * (1.0 - c4 * uu[q]))
-    siggma = n * numerator / (den1 * (den1 - 1.0))
-
-    if siggma > 0:
-        out_val = numpy.sqrt(siggma)
-    else:
-        out_val = 0.0
-
-    return out_val
-
-
-def main(fitsimage, outfilename, outdir=None):
-
-    # find image noise
-    hdulist = astropy.io.fits.open(fitsimage, mode='update')
-    data = hdulist[0].data
-    imagenoise = find_imagenoise(data)
-    dynamicrange = numpy.max(data) / imagenoise
-
-    # Store the rms value in the image header, for later reference by metadata.py (see
-    # CEP/Pipeline/recipes/sip/helpers/metadata.py in the LOFAR software repository)
-    header = hdulist[0].header
-    header['MEANRMS'] = imagenoise
-    beammaj = header['BMAJ']
-    beammin = header['BMIN']
-    beampa = header['BPA']
-    hdulist.close()
-
-    # plot
-    f = aplpy.FITSFigure(fitsimage, slices=[0, 0])
-    f.show_colorscale(vmax=16*imagenoise, vmin=-4*imagenoise, cmap='bone')
-    f.add_grid()
-    f.grid.set_color('white')
-    f.grid.set_alpha(0.5)
-    f.grid.set_linewidth(0.2)
-    f.add_colorbar()
-    f.colorbar.set_axis_label_text('Flux Density (Jy/beam)')
-    f.add_beam()
-    f.beam.set_frame(True)
-    f.set_title('Mean rms = {0:1.2e} Jy/beam; Dynamic range = {1:1.2e}; \n '
-                'Restoring beam = ({2:3.1f} x {3:3.1f}) arcsec, PA = {4:3.1f} deg'.format(
-                imagenoise, dynamicrange, beammaj*3600.0, beammin*3600.0, beampa))
-
-    if outdir is not None:
-        if not os.path.exists(outdir):
-            os.makedirs(outdir)
-        outfilename = os.path.join(outdir, os.path.basename(outfilename))
-    f.save('{}.png'.format(outfilename), dpi=400)
-
diff --git a/Docker/scripts/plot_subtract_images.py b/Docker/scripts/plot_subtract_images.py
deleted file mode 100755
index 3ffd2bad58f2abbc67d7aec4f7a8f323bde9a947..0000000000000000000000000000000000000000
--- a/Docker/scripts/plot_subtract_images.py
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/env python
-"""
-plot image overlaid with mask contours
-Original code from Reinout
-"""
-import argparse
-from argparse import RawTextHelpFormatter
-#import pyrap.images as pim
-#import pyrap.tables as pt
-#import numpy as np
-import matplotlib as mpl
-mpl.use('Agg')
-import aplpy
-import numpy
-import astropy.io.fits
-
-def meanclip(indata, clipsig=4.0, maxiter=10, converge_num=0.001, verbose=0):
-   """
-   Computes an iteratively sigma-clipped mean on a
-   data set. Clipping is done about median, but mean
-   is returned.
-
-   .. note:: MYMEANCLIP routine from ACS library.
-
-   :History:
-       * 21/10/1998 Written by RSH, RITSS
-       * 20/01/1999 Added SUBS, fixed misplaced paren on float call, improved doc. RSH
-       * 24/11/2009 Converted to Python. PLL.
-
-   Examples
-   --------
-   >>> mean, sigma = meanclip(indata)
-
-   Parameters
-   ----------
-   indata: array_like
-       Input data.
-
-   clipsig: float
-       Number of sigma at which to clip.
-
-   maxiter: int
-       Ceiling on number of clipping iterations.
-
-   converge_num: float
-       If the proportion of rejected pixels is less than
-       this fraction, the iterations stop.
-
-   verbose: {0, 1}
-       Print messages to screen?
-
-   Returns
-   -------
-   mean: float
-       N-sigma clipped mean.
-
-   sigma: float
-       Standard deviation of remaining pixels.
-
-   """
-   # Flatten array
-   skpix = indata.reshape( indata.size, )
- 
-   ct = indata.size
-   iter = 0; c1 = 1.0 ; c2 = 0.0
- 
-   while (c1 >= c2) and (iter < maxiter):
-       lastct = ct
-       medval = numpy.median(skpix)
-       sig = numpy.std(skpix)
-       wsm = numpy.where( abs(skpix-medval) < clipsig*sig )
-       ct = len(wsm[0])
-       if ct > 0:
-           skpix = skpix[wsm]
- 
-       c1 = abs(ct - lastct)
-       c2 = converge_num * lastct
-       iter += 1
-   # End of while loop
- 
-   mean  = numpy.mean( skpix )
-   sigma = robust_sigma( skpix )
- 
-   if verbose:
-       prf = 'MEANCLIP:'
-       print '%s %.1f-sigma clipped mean' % (prf, clipsig)
-       print '%s Mean computed in %i iterations' % (prf, iter)
-       print '%s Mean = %.6f, sigma = %.6f' % (prf, mean, sigma)
- 
-   return mean, sigma
-
-
-def find_imagenoise(data):
-  mean, rms =  meanclip(data)
-  return rms
-
-def robust_sigma(in_y, zero=0):
-    """
-    Calculate a resistant estimate of the dispersion of
-    a distribution. For an uncontaminated distribution,
-    this is identical to the standard deviation.
-
-    Use the median absolute deviation as the initial
-    estimate, then weight points using Tukey Biweight.
-    See, for example, Understanding Robust and
-    Exploratory Data Analysis, by Hoaglin, Mosteller
-    and Tukey, John Wiley and Sons, 1983.
-
-    .. note:: ROBUST_SIGMA routine from IDL ASTROLIB.
-
-    Examples
-    --------
-    >>> result = robust_sigma(in_y, zero=1)
-
-    Parameters
-    ----------
-    in_y : array_like
-        Vector of quantity for which the dispersion is
-        to be calculated
-
-    zero : int
-        If set, the dispersion is calculated w.r.t. 0.0
-        rather than the central value of the vector. If
-        Y is a vector of residuals, this should be set.
-
-    Returns
-    -------
-    out_val : float
-        Dispersion value. If failed, returns -1.
-
-    """
-    # Flatten array
-    y = in_y.ravel()
-
-    eps = 1.0E-20
-    c1 = 0.6745
-    c2 = 0.80
-    c3 = 6.0
-    c4 = 5.0
-    c_err = -1.0
-    min_points = 3
-
-    if zero:
-        y0 = 0.0
-    else:
-        y0 = numpy.median(y)
-
-    dy    = y - y0
-    del_y = abs( dy )
-
-    # First, the median absolute deviation MAD about the median:
-
-    mad = numpy.median( del_y ) / c1
-
-    # If the MAD=0, try the MEAN absolute deviation:
-    if mad < eps:
-        mad = del_y.mean() / c2
-    if mad < eps:
-        return 0.0
-
-    # Now the biweighted value:
-    u  = dy / (c3 * mad)
-    uu = u * u
-    q  = numpy.where(uu <= 1.0)
-    count = len(q[0])
-    if count < min_points:
-        module_logger.warn('ROBUST_SIGMA: This distribution is TOO WEIRD! '
-                           'Returning {}'.format(c_err))
-        return c_err
-
-    numerator = numpy.sum( (y[q] - y0)**2.0 * (1.0 - uu[q])**4.0 )
-    n    = y.size
-    den1 = numpy.sum( (1.0 - uu[q]) * (1.0 - c4 * uu[q]) )
-    siggma = n * numerator / ( den1 * (den1 - 1.0) )
-
-    if siggma > 0:
-        out_val = numpy.sqrt( siggma )
-    else:
-        out_val = 0.0
-
-    return out_val
-
-
-
-
-def main(fitsimage, maskfits, outfilename):
-
-    #imagenoise = 5E-3
-    
-    #f = aplpy.FITSFigure(fitsimage,slices=[0,0])
-    #f.show_colorscale(vmax=10*imagenoise,vmin=-3*imagenoise)
-    ##outplotname = fitsimage.replace('.fits','.png')
-    #f.add_colorbar()
-    #f.save('%s.png'%(outfilename),dpi=750)
-    #f.show_contour(maskfits, levels=[0.5], colors='m')
-    #f.save('%s_mask.png'%(outfilename),dpi=750)
-    
-    ##f = aplpy.FITSFigure(maskfits,slices=[0,0])
-    ##f.show_colorscale(vmax=0,vmin=1)
-    ###f.show_contour(maskfits, levels=[0.5], colors='w')
-    ###outplotname = fitsimage.replace('.fits','.png')
-    ##f.add_colorbar()
-    ##f.save('%s-mask.png'%(outfilename),dpi=500)
-
-
-
-    #outplotname = fitsimage.replace('.fits','.png')
-
-    # find image noise
-    hdulist = astropy.io.fits.open(fitsimage)
-    data    = hdulist[0].data
-    imagenoise = find_imagenoise(data)
-    hdulist.close()
-    print 'Image noise is: ', imagenoise*1e3, ' mJy'
-
-
-    f = aplpy.FITSFigure(fitsimage,slices=[0,0])
-    f.show_colorscale(vmax=16*imagenoise,vmin=-4*imagenoise, cmap='bone')
-
-
-    #f.add_beam()
-    #f.beam.set_color('white')
-    #f.beam.set_hatch('.')
-
-
-    f.add_grid()
-    f.grid.set_color('white')
-    f.grid.set_alpha(0.5)
-    f.grid.set_linewidth(0.2)
-
-    f.add_colorbar()
-
-
-    f.show_contour(maskfits, colors='red', levels=[0.0],filled=False, smooth=1,alpha=0.6, linewidths=0.25)
-    f.colorbar.set_axis_label_text('Flux (Jy beam$^{-1}$)')
-
-    f.save('%s.png'%(outfilename),dpi=400)
-
-
-
-
-if __name__ == '__main__':
-    descriptiontext = "Convert a fits image to a CASA image.\n"
-
-    parser = argparse.ArgumentParser(description=descriptiontext, formatter_class=RawTextHelpFormatter)
-    parser.add_argument('fitsimage', help='name of the image')
-    parser.add_argument('maskfits', help='name of the mask')
-    parser.add_argument('outname', help='name for the output')
-    args = parser.parse_args()
-
-    main(args.fitsimage, args.maskfits, args.outname)
diff --git a/Docker/scripts/plot_unflagged_fraction.py b/Docker/scripts/plot_unflagged_fraction.py
deleted file mode 100755
index 49485b265db30a0e84eae39a0e663eaa869322f5..0000000000000000000000000000000000000000
--- a/Docker/scripts/plot_unflagged_fraction.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-import argparse
-import glob
-import signal
-import os
-import sys
-import matplotlib as mpl
-mpl.use('Agg')
-import matplotlib
-import matplotlib.pyplot as plt
-import numpy as np
-import casacore.tables as pt
-from matplotlib import cm
-
-
-def input2strlist_nomapfile(invar):
-   """
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-
-def main(ms_list, frac_list, outfile='unflagged_fraction.png'):
-
-    ms_list = input2strlist_nomapfile(ms_list)
-    frac_list = input2strlist_nomapfile(frac_list)
-    frac_list = np.array([float(f) for f in frac_list])
-    outdir = os.path.dirname(outfile)
-    if not os.path.exists(outdir):
-        os.makedirs(outdir)
-
-    # Get frequencies
-    freq_list = []
-    for ms in ms_list:
-        # open the main table and print some info about the MS
-        t = pt.table(ms, readonly=True, ack=False)
-        tfreq = pt.table(t.getkeyword('SPECTRAL_WINDOW'),readonly=True,ack=False)
-        ref_freq = tfreq.getcol('REF_FREQUENCY',nrow=1)[0]
-        freq_list.append(ref_freq)
-    freq_list = np.array(freq_list) / 1e6  # MHz
-
-    # Plot the unflagged fraction vs. frequency
-    plt.scatter(freq_list, frac_list)
-    plt.xlabel('frequency [MHz]')
-    plt.ylabel('unflagged fraction')
-    plt.savefig(outfile)
diff --git a/Docker/scripts/plot_uvcov.py b/Docker/scripts/plot_uvcov.py
deleted file mode 100755
index f752725b12096d78df85cf08e93cb8457f4d46db..0000000000000000000000000000000000000000
--- a/Docker/scripts/plot_uvcov.py
+++ /dev/null
@@ -1,224 +0,0 @@
-#!/usr/bin/env python
-import argparse
-import glob
-import signal
-import os
-import sys
-import matplotlib as mpl
-mpl.use('Agg')
-import matplotlib
-import matplotlib.pyplot as plt
-import numpy
-import casacore.tables as pt
-from matplotlib import cm
-
-
-def input2strlist_nomapfile(invar):
-   """
-   from bin/download_IONEX.py
-   give the list of MSs from the list provided as a string
-   """
-   str_list = None
-   if type(invar) is str:
-       if invar.startswith('[') and invar.endswith(']'):
-           str_list = [f.strip(' \'\"') for f in invar.strip('[]').split(',')]
-       else:
-           str_list = [invar.strip(' \'\"')]
-   elif type(invar) is list:
-       str_list = [str(f).strip(' \'\"') for f in invar]
-   else:
-       raise TypeError('input2strlist: Type '+str(type(invar))+' unknown!')
-   return str_list
-
-
-def string2bool(instring):
-    if isinstance(instring, bool):
-        return instring
-    if instring.upper() == 'TRUE' or instring == '1':
-        return True
-    elif instring.upper() == 'FALSE' or instring == '0':
-        return False
-    else:
-        raise ValueError('string2bool: Cannot convert string "'+instring+'" to boolean!')
-
-
-def main(input, output, title='uv coverage', limits=',,,', timeslots='0,10,0', antennas='-1',
-         wideband=True):
-
-        MSlist = input2strlist_nomapfile(input)
-        if len(MSlist) == 0:
-            print('Error: You must specify at least one MS name.')
-            sys.exit(1)
-        plottitle = title
-        fileformat = output.split('.')[-1]
-        if fileformat not in ['png','pdf','eps','ps']:
-            print('Error: Unknown file extension')
-            sys.exit(1)
-        axlimits = limits.strip().split(',')
-        if len(axlimits) == 4:
-            xmin,xmax,ymin,ymax = axlimits
-        else:
-            print('Error: You must specify four axis limits')
-            sys.exit(1)
-        timeslots = timeslots.split(',')
-        if len(timeslots) != 3:
-            print('Error: Timeslots format is start,skip,end')
-            sys.exit(1)
-        for i in range(len(timeslots)):
-            timeslots[i] = int(timeslots[i])
-            if timeslots[i] < 0:
-                print('Error: timeslots values must not be negative')
-                sys.exit(1)
-        antToPlotSpl = antennas.split(',')
-        antToPlot = []
-        for i in range(len(antToPlotSpl)):
-            tmpspl = antToPlotSpl[i].split('..')
-            if len(tmpspl) == 1:
-                antToPlot.append(int(antToPlotSpl[i]))
-            elif len(tmpspl) == 2:
-                for j in range(int(tmpspl[0]),int(tmpspl[1])+1):
-                    antToPlot.append(j)
-            else:
-                print('Error: Could not understand antenna list.')
-                sys.exit(1)
-        wideband = string2bool(wideband)
-
-        outdir = os.path.dirname(output)
-        if not os.path.exists(outdir):
-            os.makedirs(outdir)
-
-        badval = 0.0
-        xaxisvals = []
-        yaxisvals = []
-        flagvals = []
-        savex = numpy.array([])
-        savey = numpy.array([])
-        prev_firstTime = None
-        prev_lastTime = None
-        prev_intTime = None
-        for inputMS in MSlist:
-            # open the main table and print some info about the MS
-            t = pt.table(inputMS, readonly=True, ack=False)
-            tfreq = pt.table(t.getkeyword('SPECTRAL_WINDOW'),readonly=True,ack=False)
-            ref_freq = tfreq.getcol('REF_FREQUENCY',nrow=1)[0]
-            ch_freq = tfreq.getcol('CHAN_FREQ',nrow=1)[0]
-            if wideband:
-                ref_wavelength = 2.99792458e8/ch_freq
-            else:
-                ref_wavelength = [2.99792458e8/ref_freq]
-
-            firstTime = t.getcell("TIME", 0)
-            lastTime = t.getcell("TIME", t.nrows()-1)
-            intTime = t.getcell("INTERVAL", 0)
-            nTimeslots = (lastTime - firstTime) / intTime
-            if timeslots[1] == 0:
-                    timeskip = 1
-            else:
-                    timeskip = int(timeslots[1])
-            if timeslots[2] == 0:
-                    timeslots[2] = nTimeslots
-            # open the antenna subtable
-            tant = pt.table(t.getkeyword('ANTENNA'), readonly=True, ack=False)
-
-            # Station names
-            antList = tant.getcol('NAME')
-            if len(antToPlot)==1 and antToPlot[0]==-1:
-                    antToPlot = list(range(len(antList)))
-
-            # select by time from the beginning, and only use specified antennas
-            tsel = t.query('TIME >= %f AND TIME <= %f AND ANTENNA1 IN %s AND ANTENNA2 IN %s' % (firstTime+timeslots[0]*intTime,firstTime+timeslots[2]*intTime,str(antToPlot),str(antToPlot)), columns='ANTENNA1,ANTENNA2,UVW,FLAG_ROW')
-
-            # Now we loop through the baselines
-            i = 0
-            nb = (len(antToPlot)*(len(antToPlot)-1))/2
-            for tpart in tsel.iter(["ANTENNA1","ANTENNA2"]):
-                ant1 = tpart.getcell("ANTENNA1", 0)
-                ant2 = tpart.getcell("ANTENNA2", 0)
-                if ant1 not in antToPlot or ant2 not in antToPlot: continue
-                if ant1 == ant2: continue
-                i += 1
-                # Get the values to plot (only need to read again if this ms has new times)
-                if prev_firstTime != firstTime or prev_lastTime != lastTime or prev_intTime != intTime:
-                    uvw = tpart.getcol('UVW', rowincr=timeskip)
-                    savex = numpy.append(savex,[uvw[:,0],-uvw[:,0]])
-                    savey = numpy.append(savey,[uvw[:,1],-uvw[:,1]])
-
-                # Get the flags
-                flags = tpart.getcol('FLAG_ROW', rowincr=timeskip)
-                for w in ref_wavelength:
-                    flagvals.extend(flags.tolist())
-                    flagvals.extend(flags.tolist())
-            for w in ref_wavelength:
-                xaxisvals.extend((savex/w/1000.).tolist())
-                yaxisvals.extend((savey/w/1000.).tolist())
-            prev_firstTime = firstTime
-            prev_lastTime = lastTime
-            prev_intTime = intTime
-
-        # Plot the uv coverage
-        xaxisvals = numpy.array(xaxisvals)
-        yaxisvals = numpy.array(yaxisvals)
-        zvals = numpy.zeros(xaxisvals.shape)
-        flagvals = numpy.array(flagvals)
-        flagged_ind = numpy.where(flagvals)
-        zvals[flagged_ind] = 1.0
-        uvmax = max(xaxisvals.max(),yaxisvals.max())
-        uvmin = min(xaxisvals.min(),yaxisvals.min())
-        uvuplim = 0.02*(uvmax-uvmin)+uvmax
-        uvlolim = uvmin-0.02*(uvmax-uvmin)
-        if xmin == '':
-            minx = uvlolim
-        else:
-            minx = float(xmin)
-        if xmax == '':
-            maxx = uvuplim
-        else:
-            maxx = float(xmax)
-        if ymin == '':
-            miny = uvlolim
-        else:
-            miny = float(ymin)
-        if ymax == '':
-            maxy = uvuplim
-        else:
-            maxy = float(ymax)
-        if minx == maxx:
-            minx = -1.0
-            maxx = 1.0
-        if miny == maxy:
-            miny = -1.0
-            maxy = 1.0
-        plt.xlabel(r'u [k$\lambda$]')
-        plt.ylabel(r'v [k$\lambda$]')
-        plt.xlim([minx,maxx])
-        plt.ylim([miny,maxy])
-        gridsize = 300
-        plt.hexbin(xaxisvals, yaxisvals, C=zvals, gridsize=gridsize, cmap=cm.jet, bins=None)
-        plt.title(plottitle)
-        plt.axes().set_aspect('equal')
-        plt.grid(True)
-        cb = plt.colorbar()
-        cb.set_label('flagged fraction')
-        plt.savefig(output)
-
-        # Plot histogram of the flagged fraction vs. uv distance
-        uvdist = numpy.sqrt(xaxisvals**2 + yaxisvals**2)
-        sorted_ind = numpy.argsort(uvdist)
-        uvdist = uvdist[sorted_ind]
-        zvals = 1.0-zvals[sorted_ind]
-        hist, bins = numpy.histogram(uvdist, 50)
-        bins_mean = [0.5 * (bins[i] + bins[i+1]) for i in range(len(bins)-1)]
-        inds = []
-        for b in bins[:-1]:
-            inds.append(numpy.where(uvdist > b)[0][0])
-        inds.append(len(bins))
-        flagged_mean = [numpy.mean(zvals[inds[i]:inds[i+1]]) for i in range(len(inds)-1)]
-        plt.clf()
-        plt.bar(bins_mean, flagged_mean, (bins[1]-bins[0])/2.0)
-        plt.xlabel(r'uv distance [k$\lambda$]')
-        plt.ylabel('unflagged fraction')
-        plt.savefig('{0}_uvdist{1}'.format(*os.path.splitext(output)))
-
-
-
-
diff --git a/Docker/scripts/sort_times_into_freqGroups.py b/Docker/scripts/sort_times_into_freqGroups.py
deleted file mode 100755
index b97e2b0ce533cff3f55e0a67bc2814ad7f522bd8..0000000000000000000000000000000000000000
--- a/Docker/scripts/sort_times_into_freqGroups.py
+++ /dev/null
@@ -1,422 +0,0 @@
-#! /usr/bin/env python
-"""
-Script to sort a list of MSs by into frequency groups by time-stamp
-"""
-import pyrap.tables as pt
-import sys, os
-import numpy as np
-from lofarpipe.support.data_map import DataMap
-from lofarpipe.support.data_map import DataProduct
-
-def _calc_edge_chans(inmap, numch, edgeFactor=32):
-    """
-    Generates a map with strings that can be used as input for NDPPP to flag the edges 
-    of the input MSs during (or after) concatenation.
-    
-    inmap      - MultiDataMap (not mapfilename!) with the files to be concatenated.
-    numch      - Number of channels per input file (All files are assumed to have the same number 
-                 of channels.)
-    edgeFactor - Divisor to compute how many channels are to be flagged at beginning and end. 
-                 (numch=64 and edgeFactor=32 means "flag two channels at beginning and two at end")
-    """
-    outmap = DataMap([])
-    for group in inmap:
-        flaglist = []
-        for i in xrange(len(group.file)):
-            flaglist.extend(range(i*numch,i*numch+numch/edgeFactor))
-            flaglist.extend(range((i+1)*numch-numch/edgeFactor,(i+1)*numch))
-        outmap.append(DataProduct(group.host,str(flaglist).replace(' ',''),group.skip))
-        print '_calc_edge_chans: flaglist:', str(flaglist).replace(' ','')
-    return outmap
-
-def input2bool(invar):
-    if invar == None:
-        return None
-    if isinstance(invar, bool):
-        return invar
-    elif isinstance(invar, str):
-        if invar.upper() == 'TRUE' or invar == '1':
-            return True
-        elif invar.upper() == 'FALSE' or invar == '0':
-            return False
-        else:
-            raise ValueError('input2bool: Cannot convert string "'+invar+'" to boolean!')
-    elif isinstance(invar, int) or isinstance(invar, float):
-        return bool(invar)
-    else:
-        raise TypeError('input2bool: Unsupported data type:'+str(type(invar)))
-  
-def input2int(invar):
-    if invar == None:
-        return None
-    if isinstance(invar, int):
-        return invar
-    elif isinstance(invar, float):
-        return int(invar)
-    elif isinstance(invar, str):
-        if invar.strip().upper() == 'NONE' or invar == 'FALSE':
-            return None
-        else:
-            return int(invar)
-    else:
-        raise TypeError('input2int: Unsupported data type:'+str(type(invar)))
-
-
-    
-def main(ms_input, filename=None, mapfile_dir=None, numSB=-1, hosts=None, NDPPPfill=True, target_path=None, stepname=None,
-         mergeLastGroup=False, truncateLastSBs=True, firstSB=None):
-    """
-    Check a list of MS files for missing frequencies
-
-    Parameters
-    ----------
-    ms_input : list or str
-        List of MS filenames, or string with list, or path to a mapfile
-    filename: str
-        Name of output mapfile
-    mapfile_dir : str
-        Directory for output mapfile
-    numSB : int, optional 
-        How many files should go into one frequency group. Values <= 0 mean put 
-        all files of the same time-step into one group.
-        default = -1
-    hosts : list or str
-        List of hostnames or string with list of hostnames
-    NDPPPfill : bool, optional
-        Add dummy file-names for missing frequencies, so that NDPPP can
-        fill the data with flagged dummy data.
-        default = True
-    target_path : str, optional
-        Change the path of the "groups" files to this. (I.e. write output files 
-        into this directory with the subsequent NDPPP call.)
-        default = keep path of input files
-    stepname : str, optional
-        Add this step-name into the file-names of the output files.
-    mergeLastGroup, truncateLastSBs : bool, optional
-        mergeLastGroup = True, truncateLastSBs = True:
-          not allowed
-        mergeLastGroup = True, truncateLastSBs = False:
-          put the files from the last group that doesn't have SBperGroup subbands 
-          into the second last group (which will then have more than SBperGroup entries). 
-        mergeLastGroup = False, truncateLastSBs = True:
-          ignore last files, that don't make for a full group (not all files are used).
-        mergeLastGroup = False, truncateLastSBs = False:
-          keep inclomplete last group, or - with NDPPPfill=True - fill
-          last group with dummies.      
-    firstSB : int, optional
-        If set, then reference the grouping of files to this station-subband. As if a file 
-        with this station-subband would be included in the input files.
-        (For HBA-low, i.e. 0 -> 100MHz, 55 -> 110.74MHz, 512 -> 200MHz)
-
-    Returns
-    -------
-    result : dict
-        Dict with the name of the generated mapfile
-
-    """
-
-    NDPPPfill = input2bool(NDPPPfill)
-    mergeLastGroup = input2bool(mergeLastGroup)
-    truncateLastSBs = input2bool(truncateLastSBs)
-    firstSB = input2int(firstSB)
-    numSB = int(numSB)
-
-    if not filename or not mapfile_dir:
-        raise ValueError('sort_times_into_freqGroups: filename and mapfile_dir are needed!')
-    if mergeLastGroup and truncateLastSBs:
-        raise ValueError('sort_times_into_freqGroups: Can either merge the last partial group or truncate at last full group, not both!')
-#    if mergeLastGroup:
-#        raise ValueError('sort_times_into_freqGroups: mergeLastGroup is not (yet) implemented!')
-    if type(ms_input) is str:
-        if ms_input.startswith('[') and ms_input.endswith(']'):
-            ms_list = [f.strip(' \'\"') for f in ms_input.strip('[]').split(',')]
-        else:
-            map_in = DataMap.load(ms_input)
-            map_in.iterator = DataMap.SkipIterator
-            ms_list = []
-            for fname in map_in:
-                if fname.startswith('[') and fname.endswith(']'):
-                    for f in fname.strip('[]').split(','):
-                        ms_list.append(f.strip(' \'\"'))
-                else:
-                    ms_list.append(fname.strip(' \'\"'))  
-    elif type(ms_input) is list:
-        ms_list = [str(f).strip(' \'\"') for f in ms_input]
-    else:
-        raise TypeError('sort_times_into_freqGroups: type of "ms_input" unknown!')
-
-    if type(hosts) is str:
-        hosts = [h.strip(' \'\"') for h in hosts.strip('[]').split(',')]
-    if not hosts:
-        hosts = ['localhost']
-    numhosts = len(hosts)
-    print "sort_times_into_freqGroups: Working on",len(ms_list),"files (including flagged files)."
-
-    time_groups = {}
-    # sort by time
-    for i, ms in enumerate(ms_list):
-        # work only on files selected by a previous step
-        if ms.lower() != 'none':
-            # use the slower but more reliable way:
-            obstable = pt.table(ms, ack=False)
-            timestamp = int(round(np.min(obstable.getcol('TIME'))))
-            #obstable = pt.table(ms+'::OBSERVATION', ack=False)
-            #timestamp = int(round(obstable.col('TIME_RANGE')[0][0]))
-            obstable.close()
-            if timestamp in time_groups:
-                time_groups[timestamp]['files'].append(ms)
-            else:
-                time_groups[timestamp] = {'files': [ ms ], 'basename' : os.path.splitext(ms)[0] }
-    print "sort_times_into_freqGroups: found",len(time_groups),"time-groups"
-
-    # sort time-groups by frequency
-    timestamps = time_groups.keys()
-    timestamps.sort()   # not needed now, but later
-    first = True
-    nchans = 0
-    for time in timestamps:
-        freqs = []
-        for ms in time_groups[time]['files']:
-            # Get the frequency info
-            sw = pt.table(ms+'::SPECTRAL_WINDOW', ack=False)
-            freq = sw.col('REF_FREQUENCY')[0]            
-            if first:
-                file_bandwidth = sw.col('TOTAL_BANDWIDTH')[0]
-                nchans = sw.col('CHAN_WIDTH')[0].shape[0]
-                chwidth = sw.col('CHAN_WIDTH')[0][0]
-                freqset = set([freq])
-                first = False
-            else:
-                assert file_bandwidth == sw.col('TOTAL_BANDWIDTH')[0]
-                assert nchans == sw.col('CHAN_WIDTH')[0].shape[0]
-                assert chwidth == sw.col('CHAN_WIDTH')[0][0]
-                freqset.add(freq)
-            freqs.append(freq)
-            sw.close()
-        time_groups[time]['freq_names'] = zip(freqs,time_groups[time]['files'])
-        time_groups[time]['freq_names'].sort(key=lambda pair: pair[0])
-        #time_groups[time]['files'] = [name for (freq,name) in freq_names]
-        #time_groups[time]['freqs'] = [freq for (freq,name) in freq_names]
-    print "sort_times_into_freqGroups: Collected the frequencies for the time-groups"
-
-    freqliste = np.array(list(freqset))
-    freqliste.sort()
-    freq_width = np.min(freqliste[1:]-freqliste[:-1])
-    if file_bandwidth > freq_width:
-        raise ValueError("Bandwidth of files is larger than minimum frequency step between two files!")
-    if file_bandwidth < (freq_width*0.51):
-        raise ValueError("Bandwidth of files is smaller than 51% of the minimum frequency step between two files! (More than about half the data is missing.)")
-    #the new output map
-    filemap = MultiDataMap()
-    groupmap = DataMap()
-    # add 1% of the SB badwidth in case maxfreq might be "exactly" on a group-border
-    maxfreq = np.max(freqliste)+freq_width*0.51
-    if firstSB != None:
-        if freqliste[0] < 100e6:
-            # LBA Data
-            minfreq = (float(firstSB)/512.*100e6)-freq_width/2.
-        elif freqliste[0] > 100e6 and freqliste[0] < 200e6:
-            # HBA-Low
-            minfreq = (float(firstSB)/512.*100e6)+100e6-freq_width/2.
-        elif freqliste[0] > 200e6 and freqliste[0] < 300e6:
-            # HBA-high
-            minfreq = (float(firstSB)/512.*100e6)+200e6-freq_width/2.
-        else:
-            raise ValueError('sort_times_into_freqGroups: Frequency of lowest input data is higher than 300MHz!')        
-        if np.min(freqliste) < minfreq:
-            raise ValueError('sort_times_into_freqGroups: Frequency of lowest input data is lower than reference frequency!')
-    else:
-        minfreq = np.min(freqliste)-freq_width/2.
-    groupBW = freq_width*numSB
-    if groupBW < 1e6 and groupBW > 0:
-        print 'sort_times_into_freqGroups: ***WARNING***: Bandwidth of concatenated MS is lower than 1 MHz. This may cause conflicts with the concatenated file names!'
-    if groupBW < 0:
-	# this is the case for concatenating all subbands
-	groupBW = maxfreq-minfreq
-	truncateLastSBs = input2bool(False)
-	NDPPPfill = input2bool(True)
-    freqborders = np.arange(minfreq,maxfreq,groupBW)
-    if mergeLastGroup:
-        freqborders[-1] = maxfreq
-    elif truncateLastSBs:
-        pass #nothing to do! # left to make the logic more clear!
-    elif not truncateLastSBs and NDPPPfill:
-        freqborders = np.append(freqborders,(freqborders[-1]+groupBW))
-    elif not truncateLastSBs and not NDPPPfill:
-        freqborders = np.append(freqborders,maxfreq)
-
-    freqborders = freqborders[freqborders>(np.min(freqliste)-groupBW)]
-    ngroups = len(freqborders)-1
-    if ngroups == 0:
-        raise ValueError('sort_times_into_freqGroups: Not enough input subbands to create at least one full (frequency-)group!')
-    
-    print "sort_times_into_freqGroups: Will create",ngroups,"group(s) with",numSB,"file(s) each."
-
-    hostID = 0
-    for time in timestamps:
-        (freq,fname) = time_groups[time]['freq_names'].pop(0)
-        for groupIdx in xrange(ngroups):
-            files = []
-            skip_this = True
-            filefreqs_low = np.arange(freqborders[groupIdx],freqborders[groupIdx+1],freq_width)
-            for lower_freq in filefreqs_low:
-                if freq > lower_freq and freq < lower_freq+freq_width:
-                    assert freq!=1e12
-                    files.append(fname)
-                    if len(time_groups[time]['freq_names'])>0:
-                        (freq,fname) = time_groups[time]['freq_names'].pop(0)
-                    else:
-                        (freq,fname) = (1e12,'This_shouldn\'t_show_up')
-                    skip_this = False
-                elif NDPPPfill:
-                    files.append('dummy.ms')
-            if not skip_this:
-                filemap.append(MultiDataProduct(hosts[hostID%numhosts], files, skip_this))
-                freqID = int((freqborders[groupIdx]+freqborders[groupIdx+1])/2e6)
-                groupname = time_groups[time]['basename']+'_%Xt_%dMHz.ms'%(time,freqID)
-                if type(stepname) is str:
-                    groupname += stepname
-                if type(target_path) is str:
-                    groupname = os.path.join(target_path,os.path.basename(groupname))
-                groupmap.append(DataProduct(hosts[hostID%numhosts],groupname, skip_this))
-        orphan_files = len(time_groups[time]['freq_names'])
-        if freq < 1e12:
-            orphan_files += 1
-        if orphan_files > 0:
-            print "sort_times_into_freqGroups: Had %d unassigned files in time-group %xt."%(orphan_files, time)
-    filemapname = os.path.join(mapfile_dir, filename)
-    filemap.save(filemapname)
-    groupmapname = os.path.join(mapfile_dir, filename+'_groups')
-    groupmap.save(groupmapname)
-    # genertate map with edge-channels to flag
-    flagmap = _calc_edge_chans(filemap, nchans)
-    flagmapname = os.path.join(mapfile_dir, filename+'_flags')
-    flagmap.save(flagmapname)
-    result = {'mapfile': filemapname, 'groupmapfile': groupmapname, 'flagmapfile': flagmapname}
-    return result
-
-class MultiDataProduct(DataProduct):
-    """
-    Class representing multiple files in a DataProduct.
-    """
-    def __init__(self, host=None, file=None, skip=True):
-        super(MultiDataProduct, self).__init__(host, file, skip)
-        if not file:
-            self.file = list()
-        else:
-            self._set_file(file)
-
-    def __repr__(self):
-        """Represent an instance as a Python dict"""
-        return (
-            "{{'host': '{0}', 'file': {1}, 'skip': {2}}}".format(self.host, self.file, str(self.skip))
-        )
-
-    def __str__(self):
-        """Print an instance as 'host:[filelist]'"""
-        return ':'.join((self.host, str(self.file)))
-
-    def _set_file(self, data):
-        try:
-            # Try parsing as a list
-            if isinstance(data, list):
-                self.file = data
-            if isinstance(data, DataProduct):
-                self._from_dataproduct(data)
-            if isinstance(data, DataMap):
-                self._from_datamap(data)
-
-        except TypeError:
-            raise DataProduct("No known method to set a filelist from %s" % str(file))
-
-    def _from_dataproduct(self, prod):
-        print 'setting filelist from DataProduct'
-        self.host = prod.host
-        self.file = prod.file
-        self.skip = prod.skip
-
-    def _from_datamap(self, inmap):
-        print 'setting filelist from DataMap'
-        filelist = {}
-        for item in inmap:
-            if not item.host in filelist:
-                filelist[item.host] = []
-            filelist[item.host].append(item.file)
-        self.file = filelist['i am']
-
-    def append(self, item):
-        self.file.append(item)
-
-
-class MultiDataMap(DataMap):
-    """
-    Class representing a specialization of data-map, a collection of data
-    products located on the same node, skippable as a set and individually
-    """
-    @DataMap.data.setter
-    def data(self, data):
-        if isinstance(data, DataMap):
-            mdpdict = {}
-            data.iterator = DataMap.SkipIterator
-            for item in data:
-                if not item.host in mdpdict:
-                    mdpdict[item.host] = []
-                mdpdict[item.host].append(item.file)
-            mdplist = []
-            for k, v in mdpdict.iteritems():
-                mdplist.append(MultiDataProduct(k, v, False))
-            self._set_data(mdplist, dtype=MultiDataProduct)
-        elif isinstance(data, MultiDataProduct):
-            self._set_data(data, dtype=MultiDataProduct)
-        elif not data:
-            pass
-        else:
-            self._set_data(data, dtype=MultiDataProduct)
-
-    def split_list(self, number):
-        mdplist = []
-        for item in self.data:
-            for i in xrange(0, len(item.file), number):
-                chunk = item.file[i:i+number]
-                mdplist.append(MultiDataProduct(item.host, chunk, item.skip))
-        self._set_data(mdplist)
-
-
-
-if __name__ == '__main__':
-    import optparse
-    import glob
-    import random
-
-    opt = optparse.OptionParser(usage='%prog [options] <MSPattern> \n')
-    opt.add_option('-v', '--verbose', help='Go Vebose! (default=False)', action='store_true', default=False)
-    opt.add_option('-r', '--randomize', help='Randomize order of the input files. (default=False)', action='store_true', default=False)
-    opt.add_option('-d', '--decimate', help='Remove every 10th file (after randomization if that is done). (default=False)', action='store_true', default=False)
-    opt.add_option('-n', '--numbands', help='Number of how many files should be grouped together in frequency. (default=all files in one group)', type='int', default=-1)
-    opt.add_option('-f', '--filename', help='Name for the mapfiles to write. (default=\"test.mapfile\")', type='string', default='test.mapfile')
-
-    (options, args) = opt.parse_args()
-
-    # Check options
-    if len(args) != 1:
-        opt.print_help()
-        sys.exit()
-
-    # first argument: pattern for measurement-sets
-    inMSs = glob.glob(args[0])
-    if options.randomize:
-        random.shuffle(inMSs)
-    if options.decimate:
-        for i in range((len(inMSs)-1),-1,-10):
-            inMSs.pop(i)
-
-    ergdict = main(inMSs, options.filename, '.', numSB=options.numbands, hosts=None, NDPPPfill=True)
-
-    groupmap = DataMap.load(ergdict['groupmapfile'])
-    filemap = MultiDataMap.load(ergdict['mapfile'])
-    print "len(groupmap) : %d , len(filemap) : %d " % (len(groupmap),len(filemap)) 
-    if len(groupmap) != len(filemap):
-        print "groupmap and filemap have different length!"
-        sys.exit(1)
-    for i in xrange(len(groupmap)):
-        print "Group \"%s\" has %d entries."%(groupmap[i].file,len(filemap[i].file))
diff --git a/Docker/scripts/transfer_solutions.py b/Docker/scripts/transfer_solutions.py
deleted file mode 100755
index 6b59e3e7e236a12ed7421bf96d270d72d9932943..0000000000000000000000000000000000000000
--- a/Docker/scripts/transfer_solutions.py
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/usr/bin/env python
-# Written for prefactor by Alexander Drabent (alex@tls-tautenburg.de), 19th July 2019.
-
-from losoto.h5parm import h5parm
-from losoto.lib_operations import *
-
-import os
-import re
-import numpy
-import subprocess
-########################################################################
-def main(h5parmdb, refh5parm, insolset='sol000', outsolset='sol000', insoltab='amplitude000', outsoltab='amplitude000', antenna = '[FUSPID].*', trusted_sources = ['3C48', '3C147'], parset = None):
-
-    
-    ### Open up the h5parm, get an example value
-    data           = h5parm(h5parmdb, readonly=False)
-    refdata        = h5parm(refh5parm, readonly=True)
-    insolset       = refdata.getSolset(insolset)
-    outsolset      = data.getSolset(outsolset)
-    insoltab       = insolset.getSoltab(insoltab)
-    outsoltab      = outsolset.getSoltab(outsoltab, useCache = True)
-    
-    ### Get the calibrator information from the target solset and check whether it is trusted or not.
-    calibrators = []
-    sources     = outsolset.obj._f_get_child('source')
-    for i in numpy.arange(len(sources)):
-        calibrators.append(sources[i][0])
-    calibrator = numpy.unique(calibrators)
-    if len(calibrator) > 1:
-        logging.error('There is more than one calibrator used in the target solution set: ' + str(calibrator) + '. No solutions will be transferred.')
-        data.close()
-        refdata.close()
-        return(1)
-    if calibrator[0].upper() in trusted_sources:
-        logging.info(calibrator[0] + ' is a trusted calibrator source. No solutions from a reference solution set will be transferred!')
-        data.close()
-        refdata.close()
-        return(0)
-    else:
-        logging.info(calibrator[0] + ' is not a trusted calibrator source. Solutions from a reference solution set will be transferred!')
-    
-  
-    ### check for matching antennas
-    station_names      = outsoltab.ant
-    stations_to_transfer = [ station_name for station_name in station_names if re.match(antenna, station_name) ]           
-    if len(stations_to_transfer) == 0:
-        logging.warning('No stations found matching the regular expression: ' + antenna)
-        data.close()
-        refdata.close()
-        return(0)
-    
-    ### Properly define axes order
-    out_axes          = outsoltab.getAxesNames()
-    out_axes.insert(0, out_axes.pop(out_axes.index('time'))) ## put time table to the first place
-    out_axes.insert(1, out_axes.pop(out_axes.index('freq'))) ## put frequency table to the second place
-    out_axes.insert(2, out_axes.pop(out_axes.index('ant')))  ## put antenna table to the third place
-    in_axes           = insoltab.getAxesNames()
-    in_axes.insert(0, in_axes.pop(in_axes.index('freq'))) ## put frequency table to the second place
-    in_axes.insert(1, in_axes.pop(in_axes.index('ant')))  ## put antenna table to the third place
-    
-    if 'time' in in_axes:
-        logging.warning('Reference solution table provides a time axis. The bandpass is assumed to be constant in time. Thus, only the first time step will be transferred.')
-        in_axes.insert(2, in_axes.pop(in_axes.index('time')))  ## put time table to the third place
-
-    ### resort the val and weights array according to the new axes order
-    for outvals, outweights, coord, selection in outsoltab.getValuesIter(returnAxes=out_axes, weight=True):
-        outvals = reorderAxes( outvals, outsoltab.getAxesNames(), out_axes)
-        outweights = reorderAxes( outweights,  outsoltab.getAxesNames(), out_axes )
-        pass
-    
-    ### resort the val and weights array according to the new axes order
-    for invals, inweights, coord, selection in insoltab.getValuesIter(returnAxes=in_axes, weight=True):
-        invals = reorderAxes( invals, insoltab.getAxesNames(), in_axes)
-        inweights = reorderAxes( inweights,  insoltab.getAxesNames(), in_axes )
-        pass
-    
-    ### check for equistance in frequency
-    freq_resolution = numpy.unique(numpy.diff(outsoltab.freq))
-    if len(freq_resolution) > 1:
-        logging.error('Frequency axis is not equidistant!')
-        data.close()
-        refdata.close()
-        return(1)
-    
-    ### look for nearest neighbours in frequency and write them into a dictionary
-    nearest_freq = {}
-    freq_idx = []
-    for i, frequency in enumerate(numpy.array(outsoltab.freq)):
-        nearest_freq[i] = numpy.abs(frequency - numpy.array(insoltab.freq)).argmin()
-        freq_idx.append(nearest_freq[i])
-    
-    ### do the job!
-    for station_to_transfer in stations_to_transfer:
-        logging.info('Transferring solutions for antenna: ' + str(station_to_transfer))
-        unique_elements, counts_elements = numpy.unique(freq_idx, return_counts = True)
-        ant_index     = list(outsoltab.ant).index(station_to_transfer)
-        try:
-            ref_ant_index = list(insoltab.ant).index(station_to_transfer)
-        except ValueError:
-            logging.warning('Station ' + station_to_transfer + ' does not exist in reference soltab. No solutions will be transferred!')
-            continue
-        for j, frequency in enumerate(numpy.array(outsoltab.freq)):
-            if 'time' in in_axes:
-                weight = inweights[nearest_freq[j], ref_ant_index, 0]
-            else:
-                weight = inweights[nearest_freq[j], ref_ant_index]
-            if counts_elements[nearest_freq[j]] > 1:
-                if frequency < insoltab.freq[0] or frequency > insoltab.freq[-1]:
-                    counts_elements[nearest_freq[j]] -= 1
-                    logging.warning('No entry for frequency ' + str(frequency) + '. Solution will be flagged.')
-                    weight = 0
-            for i, time in enumerate(outsoltab.time):
-                outweights[i,j,ant_index] = weight
-                if 'time' in in_axes:
-                    outvals[i,j,ant_index] = invals[nearest_freq[j], ref_ant_index, 0]
-                else:
-                    outvals[i,j,ant_index] = invals[nearest_freq[j], ref_ant_index]
-                
-
-    ### writing to the soltab
-    outsoltab.setValues(outvals, selection)
-    outsoltab.setValues(outweights, selection, weight = True)
-    outsoltab.addHistory('Transferred solutions from ' + os.path.basename(refh5parm) + ' for the stations ' + str(stations_to_transfer).lstrip('[').rstrip(']') )
-    outsoltab.flush()
-    
-    ### plotting new tables if provided
-    if parset:
-        if os.path.exists(parset):
-            download  = subprocess.Popen(['losoto',  '-v', h5parmdb, parset], stdout=subprocess.PIPE)
-            errorcode = download.wait()
-            if errorcode != 0:
-                logging.error('An error has occured while plotting.')
-                data.close()
-                refdata.close()
-                return(1)
-        else:
-            logging.error('Parset file ' + parset + ' has not been found.')
-            data.close()
-            refdata.close()
-            return(1)
-
-    data.close()
-    refdata.close()
-    return(0)
-    
-########################################################################
-if __name__ == '__main__':
-    import argparse
-    parser = argparse.ArgumentParser(description='Transfer solutions from a solution table of a reference h5parm to a solution table of a target h5parm.')
-
-    parser.add_argument('h5parm', type=str,
-                        help='H5parm to which the solutions should be transferred.')
-    parser.add_argument('--refh5parm', '--outh5parm', type=str,
-                        help='Name of the h5parm from which the solutions should be transferred.')
-    parser.add_argument('--insolset', '--insolset', type=str, default='sol000',
-                        help='Name of the input h5parm solution set (default: sol000)')
-    parser.add_argument('--outsolset', '--outsolset', type=str, default='sol000',
-                        help='Name of the output h5parm solution set (default: sol000)')
-    parser.add_argument('--insoltab', '--insoltab', type=str, default='amplitude000',
-                        help='Name of the input h5parm solution set (default: amplitude000)')
-    parser.add_argument('--outsoltab', '--outsoltab', type=str, default='amplitude000',
-                        help='Name of the output h5parm solution set (default: amplitude000)')
-    parser.add_argument('--antenna', '--antenna', type=str, default='[FUSPID].*',
-                        help='Regular expression of antenna solutions to be transferred (default: [FUSPID].*)')
-
-    args = parser.parse_args()
-    
-    format_stream = logging.Formatter("%(asctime)s\033[1m %(levelname)s:\033[0m %(message)s","%Y-%m-%d %H:%M:%S")
-    format_file   = logging.Formatter("%(asctime)s %(levelname)s: %(message)s","%Y-%m-%d %H:%M:%S")
-    logging.root.setLevel(logging.INFO)
-
-    log      = logging.StreamHandler()
-    log.setFormatter(format_stream)
-    logging.root.addHandler(log)
-
-    logging.info('Transferring solutions from ' +  args.refh5parm + ' to ' + args.h5parm + '.')
-    logging.info('Solutions will be transferred from soltab ' + str(args.insoltab) + ' to ' + str(args.outsoltab) + '.')
-    main(args.h5parm, refh5parm = args.refh5parm, insolset=args.insolset, outsolset=args.outsolset, insoltab=args.insoltab, outsoltab=args.outsoltab, antenna = args.antenna, parset = None)