diff --git a/.gitattributes b/.gitattributes
index b0dfd153a02cc8bddbc473169ebc74115d52224c..d51baf3a67922a967ede3fb7becccc158ed2145a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2052,6 +2052,7 @@ CEP/PyBDSM/src/python/multi_proc.py -text
 CEP/PyBDSM/test/tbdsm_process_image.in -text
 CEP/PyBDSM/test/tbdsm_process_image.in_fits -text svneol=unset#image/x-fits
 CEP/PyBDSM/test/tbdsm_process_image.py -text
+CMake/FindALGLIB.cmake -text
 CMake/FindCUDADriver.cmake -text
 CMake/FindCasarest.cmake -text
 CMake/FindJNI.cmake -text
@@ -2283,6 +2284,7 @@ LCS/MSLofar/test/tBeamTables.in_during_filled -text
 LCS/MSLofar/test/tBeamTables.in_hd/CS001-iHBADeltas.conf -text
 LCS/MSLofar/test/tBeamTables.in_hd/DE601-iHBADeltas.conf -text
 LCS/MSLofar/test/tBeamTables.in_hd/RS106-iHBADeltas.conf -text
+LCS/Stream/include/Stream/SocketStream.tcc -text
 LCS/Tools/src/checkcomp.py -text
 LCS/Tools/src/countalllines -text
 LCS/Tools/src/countlines -text
@@ -3803,15 +3805,20 @@ RTCP/Cobalt/GPUProc/doc/rtcp-usage.txt -text
 RTCP/Cobalt/GPUProc/doc/scripts.txt -text
 RTCP/Cobalt/GPUProc/etc/CMakeLists.txt -text
 RTCP/Cobalt/GPUProc/etc/default.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/CobaltHardwareMap.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/FinalMetaDataGatherer.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/MAC-feedback.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/OutputProc.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationCalibration.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationStreams.parset -text
-RTCP/Cobalt/GPUProc/etc/parset-additions.d/generateHardwareMap.sh -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/FinalMetaDataGatherer.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareList.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareUsed.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/OutputProc.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationCalibration.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationStreams.parset -text
+RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/generateStationStreams.sh -text
 RTCP/Cobalt/GPUProc/links_gcrypt.sh eol=lf
 RTCP/Cobalt/GPUProc/share/gpu/kernels/IntToFloat.cuh -text
+RTCP/Cobalt/GPUProc/src/Station/station_stream.cc -text
+RTCP/Cobalt/GPUProc/src/Station/station_stream.log_prop -text
+RTCP/Cobalt/GPUProc/src/SysInfoLogger.cc -text
+RTCP/Cobalt/GPUProc/src/SysInfoLogger.h -text
 RTCP/Cobalt/GPUProc/src/backward/CL/cl.hpp -text
 RTCP/Cobalt/GPUProc/src/cpu_utils.cc -text
 RTCP/Cobalt/GPUProc/src/cpu_utils.h -text
@@ -3913,6 +3920,8 @@ RTCP/Cobalt/GPUProc/test/tstartBGL.sh -text
 RTCP/Cobalt/InputProc/doc/capture-station-input.txt -text
 RTCP/Cobalt/InputProc/doc/cobalt-interfaces.txt -text
 RTCP/Cobalt/InputProc/doc/cobalt-station-mapping-interfaces.txt -text
+RTCP/Cobalt/InputProc/src/Delays/printDelays.cc -text
+RTCP/Cobalt/InputProc/src/Delays/printDelays.log_prop -text
 RTCP/Cobalt/InputProc/test/tBlockReader.in_16bit -text
 RTCP/Cobalt/InputProc/test/tBlockReader.in_8bit -text
 RTCP/Cobalt/InputProc/test/tBlockReader.sh eol=lf
diff --git a/CMake/FindALGLIB.cmake b/CMake/FindALGLIB.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..ed0a77508f953844559997887d3991f1352d057d
--- /dev/null
+++ b/CMake/FindALGLIB.cmake
@@ -0,0 +1,48 @@
+# - Try to find ALGLIB.
+# Variables used by this module:
+#  ALGLIB_ROOT_DIR     - ALGLIB root directory
+# Variables defined by this module:
+#  ALGLIB_FOUND        - system has ALGLIB
+#  ALGLIB_INCLUDE_DIR  - the ALGLIB include directory (cached)
+#  ALGLIB_INCLUDE_DIRS - the ALGLIB include directories
+#                       (identical to ALGLIB_INCLUDE_DIR)
+#  ALGLIB_LIBRARY      - the ALGLIB library (cached)
+#  ALGLIB_LIBRARIES    - the ALGLIB libraries
+#                       (identical to ALGLIB_LIBRARY)
+
+# Copyright (C) 2009
+# ASTRON (Netherlands Institute for Radio Astronomy)
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This file is part of the LOFAR software suite.
+# The LOFAR software suite is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+#
+# $Id: FindALGLIB.cmake 21886 2012-09-04 11:57:26Z mol $
+
+if(NOT ALGLIB_FOUND)
+
+  find_path(ALGLIB_INCLUDE_DIR bessel.h
+    HINTS ${ALGLIB_ROOT_DIR} PATH_SUFFIXES include)
+  find_library(ALGLIB_LIBRARY alglib
+    HINTS ${ALGLIB_ROOT_DIR} PATH_SUFFIXES lib)
+  mark_as_advanced(ALGLIB_INCLUDE_DIR ALGLIB_LIBRARY)
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(ALGLIB DEFAULT_MSG 
+    ALGLIB_LIBRARY ALGLIB_INCLUDE_DIR)
+
+  set(ALGLIB_INCLUDE_DIRS ${ALGLIB_INCLUDE_DIR})
+  set(ALGLIB_LIBRARIES ${ALGLIB_LIBRARY})
+
+endif(NOT ALGLIB_FOUND)
diff --git a/LCS/Common/include/Common/Thread/Thread.h b/LCS/Common/include/Common/Thread/Thread.h
index a8f9c5140ef7c89a86cc3e74c70d40c508feb9a6..7d4db91669f7caef91e8741a2174adc9c350ea69 100644
--- a/LCS/Common/include/Common/Thread/Thread.h
+++ b/LCS/Common/include/Common/Thread/Thread.h
@@ -29,6 +29,7 @@
 
 #include <pthread.h>
 #include <signal.h>
+#include <sched.h>
 
 #include <Common/LofarLogger.h>
 #include <Common/SystemCallException.h>
@@ -79,6 +80,70 @@ class Thread
     // to finish.
     bool      caughtException();
 
+    class ScopedPriority
+    {
+    public:
+      /* see man pthread_setschedparam */
+      ScopedPriority(int policy, int priority)
+      {
+        int retval;
+
+        if ((retval = pthread_getschedparam(pthread_self(), &origPolicy, &origParam)) != 0)
+          throw SystemCallException("pthread_getschedparam", retval, THROW_ARGS);
+
+        struct sched_param newParam;
+        newParam.sched_priority = priority;
+
+        if ((retval = pthread_setschedparam(pthread_self(), policy, &newParam)) != 0)
+          try {
+            throw SystemCallException("pthread_setschedparam", retval, THROW_ARGS);
+          } catch (Exception &ex) {
+            LOG_WARN_STR("Could not change thread priority to policy " << policyName(policy) << " priority " << priority << ": " << ex.what());
+          }
+      }
+
+      ~ScopedPriority()
+      {
+        int retval;
+
+        if ((retval = pthread_setschedparam(pthread_self(), origPolicy, &origParam)) != 0)
+          try {
+            throw SystemCallException("pthread_setschedparam", retval, THROW_ARGS);
+          } catch (Exception &ex) {
+            LOG_FATAL_STR("Exception in destructor: " << ex);
+          }
+      }
+
+    private:
+      int origPolicy;
+      struct sched_param origParam;
+
+      std::string policyName(int policy) const
+      {
+        switch(policy) {
+          case SCHED_OTHER:
+            return "SCHED_OTHER (normal)";
+
+          case SCHED_BATCH:
+            return "SCHED_BATCH (cpu intensive)";
+
+#ifdef SCHED_IDLE
+          case SCHED_IDLE:
+            return "SCHED_IDLE (idle)";
+#endif
+
+          case SCHED_FIFO:
+            return "SCHED_FIFO (real time)";
+
+          case SCHED_RR:
+            return "SCHED_RR (real time)";
+
+          default:
+            return "(unknown)";
+        };
+      }
+    };
+
   private:
     Thread(const Thread&);
     Thread& operator=(const Thread&);
diff --git a/LCS/Common/test/tThread.cc b/LCS/Common/test/tThread.cc
index 1d4b1117bb1b779ce13650a18b8602d9ed0d5728..0bb901a456137f25a97459d2c826f2c454a786c4 100644
--- a/LCS/Common/test/tThread.cc
+++ b/LCS/Common/test/tThread.cc
@@ -179,6 +179,26 @@ void test_mt() {
 }
 
 
+void test_prio()
+{
+  /*
+   * Note: Failure to set thread priority
+   * merely results in a warning, so there
+   * isn't really anything to test except
+   * not freezing or crashing.
+   */
+  {
+    // normal priority
+    Thread::ScopedPriority sp(SCHED_OTHER, 0);
+  }
+
+  {
+    // real-time priority
+    Thread::ScopedPriority sp(SCHED_FIFO, 1);
+  }
+}
+
+
 int main()
 {
   INIT_LOGGER("tThread");
@@ -189,6 +209,7 @@ int main()
 
   test_simple();
   test_mt();
+  test_prio();
 
   LOG_INFO("Program terminated successfully");
   return 0;
diff --git a/LCS/Stream/include/Stream/SocketStream.h b/LCS/Stream/include/Stream/SocketStream.h
index d85922ea5684b21c029d970e3c150f7e8fe4b672..a8b6e0a2f21525c6076ed3d4da262d06f2e2a231 100644
--- a/LCS/Stream/include/Stream/SocketStream.h
+++ b/LCS/Stream/include/Stream/SocketStream.h
@@ -30,6 +30,7 @@
 
 #include <time.h>
 #include <string>
+#include <vector>
 
 namespace LOFAR {
 
@@ -57,6 +58,8 @@ class SocketStream : public FileDescriptorBasedStream
     const Protocol protocol;
     const Mode mode;
 
+    template<typename T> size_t recvmmsg( std::vector<T> &buffers, bool oneIsEnough ); // only for UDP server socket
+
   private:
     const std::string hostname;
     uint16 port;
@@ -74,4 +77,6 @@ class SocketStream : public FileDescriptorBasedStream
 
 } // namespace LOFAR
 
+#include "SocketStream.tcc"
+
 #endif
diff --git a/LCS/Stream/include/Stream/SocketStream.tcc b/LCS/Stream/include/Stream/SocketStream.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..a6f22679f06f5af6ca3b373e3c26e3a1ef1db70c
--- /dev/null
+++ b/LCS/Stream/include/Stream/SocketStream.tcc
@@ -0,0 +1,72 @@
+#include "SocketStream.h"
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#if defined __linux__ && __GLIBC_PREREQ(2,12)
+// Actually, recvmmsg is supported by Linux 2.6.32+ using glibc 2.12+
+#define HAVE_RECVMMSG
+#endif
+
+namespace LOFAR {
+
+template<typename T> size_t SocketStream::recvmmsg( std::vector<T> &buffers, bool oneIsEnough )
+{
+  ASSERT(protocol == UDP);
+  ASSERT(mode == Server);
+
+#ifdef HAVE_RECVMMSG
+  const size_t n = buffers.size();
+
+  // set of receive buffers
+  std::vector<struct iovec> iov(n);
+
+  for(size_t i = 0; i < n; ++i) {
+    iov[i].iov_base = &buffers[i];
+    iov[i].iov_len  = sizeof (T);
+  }
+
+  // recvmsg parameter struct
+  std::vector<struct mmsghdr> msgs(n);
+
+  // register our receive buffers
+  for(size_t i = 0; i < n; ++i) {
+    msgs[i].msg_hdr.msg_iov     = &iov[i];
+    msgs[i].msg_hdr.msg_iovlen  = 1;
+    msgs[i].msg_hdr.msg_name    = NULL; // we don't need to know who sent the data
+    msgs[i].msg_hdr.msg_control = NULL; // we're not interested in OoB data
+  }
+
+  // receive data
+  int numRead = ::recvmmsg(fd, &msgs[0], n, oneIsEnough ? MSG_WAITFORONE : 0, 0);
+
+  if (numRead < 0)
+    THROW_SYSCALL("recvmmsg");
+
+  /* msgs[i].msg_len contains the number of bytes received for packet i */
+
+  return numRead;
+#else
+  // recvmmsg not available: use recvmsg fall-back
+  (void)oneIsEnough;
+
+  struct iovec iov;
+  iov.iov_base = &buffers[0];
+  iov.iov_len  = sizeof (T);
+
+  struct msghdr msg;
+  msg.msg_iov     = &iov;
+  msg.msg_iovlen  = 1;
+  msg.msg_name    = NULL; // we don't need to know who sent the data
+  msg.msg_control = NULL; // we're not interested in OoB data
+
+  if (recvmsg(fd, &msg, 0) < 0)
+    THROW_SYSCALL("recvmsg");
+
+  /* the recvmsg return value is the number of bytes received */
+
+  return 1;
+#endif
+}
+
+} // namespace LOFAR
+
diff --git a/LCS/Stream/src/SocketStream.cc b/LCS/Stream/src/SocketStream.cc
index 7da18c7c18d7066344e4321b16b47e39cb07a020..5077d4310c3669b96dac2e76c09139993c64ab49 100644
--- a/LCS/Stream/src/SocketStream.cc
+++ b/LCS/Stream/src/SocketStream.cc
@@ -40,12 +40,15 @@
 #include <cstdlib>
 
 #include <boost/lexical_cast.hpp>
+#include <boost/format.hpp>
 
 //# AI_NUMERICSERV is not defined on OS-X
 #ifndef AI_NUMERICSERV
 # define AI_NUMERICSERV 0
 #endif
 
+using boost::format;
+
 
 namespace LOFAR {
 
@@ -105,8 +108,11 @@ SocketStream::SocketStream(const std::string &hostname, uint16 _port, Protocol p
 
         snprintf(portStr, sizeof portStr, "%hu", port);
 
-        if ((retval = getaddrinfo(hostname.c_str(), portStr, &hints, &result)) != 0)
-          throw SystemCallException("getaddrinfo", retval, THROW_ARGS); // TODO: getaddrinfo does not return errno; needs gai_strerror() to stringify
+        if ((retval = getaddrinfo(hostname.c_str(), portStr, &hints, &result)) != 0) {
+          const string errorstr = gai_strerror(retval);
+
+          throw SystemCallException(str(format("getaddrinfo(%s): %s") % hostname % errorstr), 0, THROW_ARGS); // TODO: SystemCallException also adds strerror(0), which is useless here
+        }
 
         // make sure result will be freed
         struct D {
diff --git a/RTCP/Cobalt/CoInterface/src/Parset.cc b/RTCP/Cobalt/CoInterface/src/Parset.cc
index f7caf0ea552d6b9d8711213b9f7780f432299bac..061701fbd30cec54bc7a2d1af2c0a91cf3cff3d3 100644
--- a/RTCP/Cobalt/CoInterface/src/Parset.cc
+++ b/RTCP/Cobalt/CoInterface/src/Parset.cc
@@ -24,7 +24,9 @@
 #include <CoInterface/Parset.h>
 
 #include <cstdio>
+#include <cstring>
 #include <set>
+#include <algorithm>
 #include <boost/format.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/lexical_cast.hpp>
@@ -265,6 +267,29 @@ namespace LOFAR
       return newname;
     }
 
+    /*
+     * operator<() for station names.
+     *
+     * Sorts in the following order:
+     *   1. Core stations (CSxxx)
+     *   2. Remote stations (RSxxx)
+     *   3. International stations (others)
+     *
+     * Within each group, the stations are
+     * sorted lexicographically. For group 3
+     * we skip the first 2 chars when sorting.
+     */
+    bool compareStationNames( const string &a, const string &b ) {
+      if (a.size() >= 5 && b.size() >= 5) { // common case
+        if ( (a[0] == 'C' || a[0] == 'R') && a[1] == 'S' &&
+             (b[0] == 'C' || b[0] == 'R') && b[1] == 'S' ) {
+          return a < b; // both CS/RS stations; 'C'<'R'
+        } else { // at least 1 non-CS/RS name; cmp (presumed) nrs
+          return std::strcmp(&a.c_str()[2], &b.c_str()[2]) < 0;
+        }
+      }
+      return a < b; // at least 1 short name
+    }
 
     struct ObservationSettings Parset::observationSettings() const
     {
@@ -351,6 +376,10 @@ namespace LOFAR
       // Station information (used pointing information to verify settings)
       vector<string> stations = getStringVector("Observation.VirtualInstrument.stationList", emptyVectorString, true);
 
+      // Sort stations (CS, RS, intl), to get a consistent and predictable
+      // order in the MeasurementSets.
+      std::sort(stations.begin(), stations.end(), compareStationNames);
+
       vector<ObservationSettings::AntennaFieldName> fieldNames = ObservationSettings::antennaFields(stations, settings.antennaSet);
 
       size_t nrStations = fieldNames.size();
@@ -360,12 +389,19 @@ namespace LOFAR
         struct ObservationSettings::Station &station = settings.stations[i];
 
         station.name              = fieldNames[i].fullName();
+        station.inputStreams      = getStringVector(
+            renamedKey(str(format("PIC.Core.%s.RSP.ports") % station.name),
+                       str(format("PIC.Core.Station.%s.RSP.ports") % station.name)),
+            emptyVectorString, true);
+        station.receiver          = getString(str(format("PIC.Core.%s.RSP.receiver") % station.name), "");
+
         station.clockCorrection   = getDouble(str(format("PIC.Core.%s.clockCorrectionTime") % station.name), 0.0);
         station.phaseCenter       = getDoubleVector(str(format("PIC.Core.%s.phaseCenter") % station.name), emptyVectorDouble, true);
-        station.phaseCorrection.x = getDouble(str(format("PIC.Core.%s.%s.%s.phaseCorrection.X") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
-        station.phaseCorrection.y = getDouble(str(format("PIC.Core.%s.%s.%s.phaseCorrection.Y") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
-        station.delayCorrection.x = getDouble(str(format("PIC.Core.%s.%s.%s.delayCorrection.X") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
-        station.delayCorrection.y = getDouble(str(format("PIC.Core.%s.%s.%s.delayCorrection.Y") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
+        station.phase0.x = getDouble(str(format("PIC.Core.%s.%s.%s.phase0.X") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
+        station.phase0.y = getDouble(str(format("PIC.Core.%s.%s.%s.phase0.Y") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
+        station.delay.x = getDouble(str(format("PIC.Core.%s.%s.%s.delay.X") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
+        station.delay.y = getDouble(str(format("PIC.Core.%s.%s.%s.delay.Y") % fieldNames[i].station % settings.antennaSet % settings.bandFilter), 0.0);
+
 
         string key = std::string(str(format("Observation.Dataslots.%s.RSPBoardList") % station.name));
         if (!isDefined(key)) key = "Observation.rspBoardList";
@@ -381,27 +417,21 @@ namespace LOFAR
       }
 
       // Resource information
-      size_t nrNodes = getUint32("Cobalt.Hardware.nrNodes",1);
-      settings.nodes.resize(nrNodes);
-      for (size_t i = 0; i < nrNodes; ++i) {
-        struct ObservationSettings::Node &node = settings.nodes[i];
+      vector<string> nodes = getStringVector("Cobalt.Nodes", emptyVectorString, true);
+      settings.nodes.resize(nodes.size());
 
-        string prefix = str(format("Cobalt.Hardware.Node[%u].") % i);
+      for (size_t i = 0; i < nodes.size(); ++i) {
+        struct ObservationSettings::Node &node = settings.nodes[i];
 
         node.rank     = i;
+        node.name     = nodes[i];
+
+        string prefix = str(format("PIC.Core.Cobalt.%s.") % node.name);
+
         node.hostName = getString(prefix + "host", "localhost");
         node.cpu      = getUint32(prefix + "cpu",  0);
         node.nic      = getString(prefix + "nic",  "");
         node.gpus     = getUint32Vector(prefix + "gpus", vector<unsigned>(1,0)); // default to [0]
-
-        vector<string> stationNames = getStringVector(prefix + "stations", emptyVectorString, true);
-
-        for (size_t j = 0; j < stationNames.size(); ++j) {
-          ssize_t index = settings.stationIndex(stationNames[j]);
-
-          if (index >= 0)
-            node.stations.push_back(index);
-        }
       }
 
       /* ===============================
@@ -412,6 +442,7 @@ namespace LOFAR
       settings.correlator.enabled = getBool("Observation.DataProducts.Output_Correlated.enabled", false);
       if (settings.correlator.enabled) {
         settings.correlator.nrChannels = getUint32(renamedKey("Cobalt.Correlator.nrChannelsPerSubband", "Observation.channelsPerSubband"), 64);
+        //settings.correlator.nrChannels = getUint32("Observation.channelsPerSubband", 64);
         settings.correlator.channelWidth = settings.subbandWidth() / settings.correlator.nrChannels;
         settings.correlator.nrSamplesPerChannel = settings.blockSize / settings.correlator.nrChannels;
         settings.correlator.nrBlocksPerIntegration = getUint32(renamedKey("Cobalt.Correlator.nrBlocksPerIntegration", "OLAP.IONProc.integrationSteps"), 1);
@@ -710,20 +741,6 @@ namespace LOFAR
     }
 
 
-    string Parset::getInputStreamName(const string &stationName, unsigned rspBoardNumber) const
-    {
-      string key = string("PIC.Core.Station.") + stationName + ".RSP.ports";
-
-      if (!isDefined(key)) {
-        LOG_ERROR_STR("Key not found: " << key << ", falling back to reading from /dev/null");
-
-        return "file:/dev/null";
-      }
-
-      return getStringVector(key, true)[rspBoardNumber];
-    }
-
-
     std::string Parset::keyPrefix(OutputType outputType)
     {
       switch (outputType) {
diff --git a/RTCP/Cobalt/CoInterface/src/Parset.h b/RTCP/Cobalt/CoInterface/src/Parset.h
index 6a5658988ec4c6ca309461453c83a5e60b4f847d..a16913aadaa2379f6da420b84f36b5b7af8a97ec 100644
--- a/RTCP/Cobalt/CoInterface/src/Parset.h
+++ b/RTCP/Cobalt/CoInterface/src/Parset.h
@@ -161,6 +161,16 @@ namespace LOFAR
         // key: OLAP.storageStationNames[stationIdx]
         std::string name;
 
+        // The input streams descriptors
+        //
+        // key: PIC.Core.CS001LBA.RSP.ports
+        std::vector<std::string> inputStreams;
+
+        // The node name on which this station is received
+        //
+        // key: PIC.Core.CS001LBA.RSP.receiver
+        std::string receiver;
+
         // Correction on the station clock, in seconds
         //
         // key: PIC.Core.CS001LBA.clockCorrectionTime
@@ -174,21 +184,21 @@ namespace LOFAR
 
         // The phase correction for this station, in radians.
         //
-        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.phaseCorrection.X
-        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.phaseCorrection.Y
+        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.phase0.X
+        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.phase0.Y
         struct {
           double x;
           double y;
-        } phaseCorrection;
+        } phase0;
 
         // The delay correction for this station, in seconds
         //
-        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.delayCorrection.X
-        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.delayCorrection.Y
+        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.delay.X
+        // key: PIC.Core.CS001.LBA_INNER.LBA_30_70.delay.Y
         struct {
           double x;
           double y;
-        } delayCorrection;
+        } delay;
 
 
         // The RSP board to which each subband is mapped
@@ -214,7 +224,6 @@ namespace LOFAR
       /*
        * Resources information:
        *   - what hardware we use (cpus/gpus)
-       *   - which nodes receive which stations
        */ 
 
       struct Node {
@@ -222,6 +231,9 @@ namespace LOFAR
         // same as the index in the `nodes' vector.
         int rank;
 
+        // (Symbolic) name
+        std::string name;
+
         // Host name
         std::string hostName;
 
@@ -235,9 +247,6 @@ namespace LOFAR
         //
         // F.e. 'mlx4_0', 'mlx_4_1', 'eth0', etc
         std::string nic;
-
-        // Station indices to forward data for
-        std::vector<size_t> stations;
       };
 
       std::vector<struct Node> nodes;
@@ -677,8 +686,6 @@ namespace LOFAR
       std::vector<double>         getAnaBeamDirection() const;
       std::string                 getAnaBeamDirectionType() const;
 
-      std::string                 getInputStreamName(const string &stationName, unsigned rspBoardNumber) const;
-
       std::vector<double>         itsStPositions;
 
       std::string                 PVSS_TempObsName() const;
diff --git a/RTCP/Cobalt/GPUProc/CMakeLists.txt b/RTCP/Cobalt/GPUProc/CMakeLists.txt
index 454ba0122ab87bc28f19d2d13b896701042f8cea..62440d8f0a39084ee8ef3db34b4091befbbba70a 100644
--- a/RTCP/Cobalt/GPUProc/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/CMakeLists.txt
@@ -50,6 +50,7 @@ lofar_package(GPUProc 1.0 DEPENDS ${_gpuproc_deps})
 lofar_find_package(OpenMP REQUIRED)
 lofar_find_package(Boost REQUIRED)
 lofar_find_package(MPI)
+#lofar_find_package(ALGLIB)
 lofar_find_package(LibNuma)
 lofar_find_package(FFTW3 COMPONENTS single double threads REQUIRED)  # 'double threads' for FFT unit test refs
 lofar_find_package(UnitTest++)
diff --git a/RTCP/Cobalt/GPUProc/doc/rtcp-usage.txt b/RTCP/Cobalt/GPUProc/doc/rtcp-usage.txt
index 534e23037b84a2c6ed793d1b20f951068b643850..cc2e6a85ae30fe5d6b6f8495d76fbec15c64dab4 100644
--- a/RTCP/Cobalt/GPUProc/doc/rtcp-usage.txt
+++ b/RTCP/Cobalt/GPUProc/doc/rtcp-usage.txt
@@ -171,21 +171,21 @@ The Hardware Node list
 
 The list
 
-  Cobalt.Hardware.nrNodes = x
-  Cobalt.Hardware.Node[y]
+  Cobalt.Nodes = [cbt001_0, cbt001_1, XXXXX, ...]
   
 should be added to a parset, which bind MPI rank x to hardware (including
 stations that send to that rank). MPI ranks not mentioned in the list use the
-default configuration. Each node contains:
+default configuration. Nodes are described in separate keys (see 
+$LOFARROOT/etc/parset-additions.d/default/HardwareList.parset):
 
-  Cobalt.Hardware.Node[rank].host
+  PIC.Core.Cobalt.XXXXX.host
     Type:    string
     Default: (none)
-    Typical: cbm001..cbm009
+    Typical: cbt001..cbt009, localhost
 
     Host name to run on.
 
-  Cobalt.Hardware.Node[rank].cpu
+  PIC.Core.Cobalt.XXXXX.cpu
     Type:    integer
     Default: 0
     Typical: 0, 1
@@ -193,7 +193,7 @@ default configuration. Each node contains:
     Socket/NUMA node number to bind to. To print the list of available sockets:
         lscpu -p=socket | sort | grep -v ^# | uniq
 
-  Cobalt.Hardware.Node[rank].gpus
+  PIC.Core.Cobalt.XXXXX.gpus
     Type:    list of integers
     Default: [0]
     Typical: [0,1] or [2,3]
@@ -202,7 +202,7 @@ default configuration. Each node contains:
     To print the list of available GPUs:
         lspci | grep NVIDIA | nl -v 0
 
-  Cobalt.Hardware.Node[rank].nic
+  PIC.Core.Cobalt.XXXXX.nic
     Type:    string
     Default: ""
     Typical: mlx4_0, mlx4_1
@@ -211,21 +211,6 @@ default configuration. Each node contains:
     To print the list of InfiniBand devices:
         ibstatus
 
-  Cobalt.Hardware.Node[rank].stations
-    Type:    list of strings
-    Default: []
-    Typical: ["CS001LBA", "CS001HBA0", "CS001HBA"]
-    
-    Antenna fields that are received on this rank. This list is allowed to
-    contain fields that are not part of the observation.
-
-    Antenna fields not mentioned in the hardware list are distributed
-    round-robin over the MPI ranks.
-
-    Note that this key needs to be compatible with the
-    PIC.Core.Station.xxxxx.RSP.ports keys below, which specify from which
-    streams data should be read for the individual boards.
-
 Antenna field configuration
 ===========================
 
@@ -238,12 +223,13 @@ data over 1 to 4 RSP boards.
 Each antenna field needs several keys. We'll use CS001LBA as an example. First,
 the input:
 
-  PIC.Core.Station.CS001LBA.RSP.ports = [udp:0.0.0.0:10000, udp:0.0.0.0:10001,
-                                         udp:0.0.0.0:10002, udp:0.0.0.0:10003]
+  PIC.Core.CS001LBA.RSP.ports = [udp:0.0.0.0:10000, udp:0.0.0.0:10001,
+                                 udp:0.0.0.0:10002, udp:0.0.0.0:10003]
+  PIC.Core.CS001LBA.RSP.receiver = cbt001_0
 
 configures the CS001LBA antenna field to receive beamlets from 4 RSP boards on
-the given ports.  The host on which the antenna field is received is configured
-in the Cobalt.Hardware.Node list.
+the given ports. The host on which the antenna field is received is configured
+in the .receiver key.
 
 Beamlet <-> Subband mapping
 -------------------------------
diff --git a/RTCP/Cobalt/GPUProc/etc/CMakeLists.txt b/RTCP/Cobalt/GPUProc/etc/CMakeLists.txt
index c6c5aa007c79ec682001d44c25ccbb305e31a65f..463f85895895205ac9aa1970c927860d23cff19c 100644
--- a/RTCP/Cobalt/GPUProc/etc/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/etc/CMakeLists.txt
@@ -2,11 +2,13 @@
 
 
 install(FILES
-  parset-additions.d/CobaltHardwareMap.parset
-  parset-additions.d/FinalMetaDataGatherer.parset
-  parset-additions.d/MAC-feedback.parset
-  parset-additions.d/OutputProc.parset
-  parset-additions.d/StationCalibration.parset
-  parset-additions.d/StationStreams.parset
-  DESTINATION etc/parset-additions.d)
+  parset-additions.d/default/HardwareList.parset
+  parset-additions.d/default/HardwareUsed.parset
+  parset-additions.d/default/FinalMetaDataGatherer.parset
+  parset-additions.d/default/MAC-feedback.parset
+  parset-additions.d/default/OutputProc.parset
+  parset-additions.d/default/StationCalibration.parset
+  parset-additions.d/default/StationStreams.parset
+  DESTINATION etc/parset-additions.d/default)
 
+INSTALL(CODE "FILE(MAKE_DIRECTORY \${ENV}\${CMAKE_INSTALL_PREFIX}etc/parset-additions.d/override)")
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/CobaltHardwareMap.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/CobaltHardwareMap.parset
deleted file mode 100644
index 6caf65aa44cc42e0eb886a0952393438ef5eb63e..0000000000000000000000000000000000000000
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/CobaltHardwareMap.parset
+++ /dev/null
@@ -1,65 +0,0 @@
-Cobalt.Hardware.nrNodes=16
-Cobalt.Hardware.Node[0].host=cbm001
-Cobalt.Hardware.Node[0].cpu=0
-Cobalt.Hardware.Node[0].gpus=[0, 1]
-Cobalt.Hardware.Node[0].stations=[CS005LBA, CS005HBA, CS005HBA0, CS005HBA1, CS021LBA, CS021HBA, CS021HBA0, CS021HBA1]
-Cobalt.Hardware.Node[1].host=cbm001
-Cobalt.Hardware.Node[1].cpu=1
-Cobalt.Hardware.Node[1].gpus=[2, 3]
-Cobalt.Hardware.Node[1].stations=[CS101LBA, CS101HBA, CS101HBA0, CS101HBA1, RS208LBA, RS208HBA, RS407LBA, RS407HBA]
-Cobalt.Hardware.Node[2].host=cbm002
-Cobalt.Hardware.Node[2].cpu=0
-Cobalt.Hardware.Node[2].gpus=[0, 1]
-Cobalt.Hardware.Node[2].stations=[CS017LBA, CS017HBA, CS017HBA0, CS017HBA1, CS032LBA, CS032HBA, CS032HBA0, CS032HBA1]
-Cobalt.Hardware.Node[3].host=cbm002
-Cobalt.Hardware.Node[3].cpu=1
-Cobalt.Hardware.Node[3].gpus=[2, 3]
-Cobalt.Hardware.Node[3].stations=[RS104LBA, RS104HBA, RS310LBA, RS310HBA, RS409LBA, RS409HBA, RS410LBA, RS410HBA]
-Cobalt.Hardware.Node[4].host=cbm003
-Cobalt.Hardware.Node[4].cpu=0
-Cobalt.Hardware.Node[4].gpus=[0, 1]
-Cobalt.Hardware.Node[4].stations=[CS002LBA, CS002HBA, CS002HBA0, CS002HBA1, CS011LBA, CS011HBA, CS011HBA0, CS011HBA1, DE604LBA, DE604HBA]
-Cobalt.Hardware.Node[5].host=cbm003
-Cobalt.Hardware.Node[5].cpu=1
-Cobalt.Hardware.Node[5].gpus=[2, 3]
-Cobalt.Hardware.Node[5].stations=[CS028LBA, CS028HBA, CS028HBA0, CS028HBA1, CS201LBA, CS201HBA, CS201HBA0, CS201HBA1, DE602LBA, DE602HBA]
-Cobalt.Hardware.Node[6].host=cbm004
-Cobalt.Hardware.Node[6].cpu=0
-Cobalt.Hardware.Node[6].gpus=[0, 1]
-Cobalt.Hardware.Node[6].stations=[CS006LBA, CS006HBA, CS006HBA0, CS006HBA1, CS026LBA, CS026HBA, CS026HBA0, CS026HBA1]
-Cobalt.Hardware.Node[7].host=cbm004
-Cobalt.Hardware.Node[7].cpu=1
-Cobalt.Hardware.Node[7].gpus=[2, 3]
-Cobalt.Hardware.Node[7].stations=[CS031LBA, CS031HBA, CS031HBA0, CS031HBA1, CS302LBA, CS302HBA, CS302HBA0, CS302HBA1, DE603LBA, DE603HBA]
-Cobalt.Hardware.Node[8].host=cbm005
-Cobalt.Hardware.Node[8].cpu=0
-Cobalt.Hardware.Node[8].gpus=[0, 1]
-Cobalt.Hardware.Node[8].stations=[CS003LBA, CS003HBA, CS003HBA0, CS003HBA1, CS013LBA, CS013HBA, CS013HBA0, CS013HBA1, RS306LBA, RS306HBA]
-Cobalt.Hardware.Node[9].host=cbm005
-Cobalt.Hardware.Node[9].cpu=1
-Cobalt.Hardware.Node[9].gpus=[2, 3]
-Cobalt.Hardware.Node[9].stations=[CS301LBA, CS301HBA, CS301HBA0, CS301HBA1, RS210LBA, RS210HBA, FR606LBA, FR606HBA, UK608LBA, UK608HBA]
-Cobalt.Hardware.Node[10].host=cbm006
-Cobalt.Hardware.Node[10].cpu=0
-Cobalt.Hardware.Node[10].gpus=[0, 1]
-Cobalt.Hardware.Node[10].stations=[CS007LBA, CS007HBA, CS007HBA0, CS007HBA1, CS030LBA, CS030HBA, CS030HBA0, CS030HBA1]
-Cobalt.Hardware.Node[11].host=cbm006
-Cobalt.Hardware.Node[11].cpu=1
-Cobalt.Hardware.Node[11].gpus=[2, 3]
-Cobalt.Hardware.Node[11].stations=[CS501LBA, CS501HBA, CS501HBA0, CS501HBA1, RS305LBA, RS305HBA, RS503LBA, RS503HBA, SE607LBA, SE607HBA]
-Cobalt.Hardware.Node[12].host=cbm007
-Cobalt.Hardware.Node[12].cpu=0
-Cobalt.Hardware.Node[12].gpus=[0, 1]
-Cobalt.Hardware.Node[12].stations=[CS001LBA, CS001HBA, CS001HBA0, CS001HBA1, CS024LBA, CS024HBA, CS024HBA0, CS024HBA1]
-Cobalt.Hardware.Node[13].host=cbm007
-Cobalt.Hardware.Node[13].cpu=1
-Cobalt.Hardware.Node[13].gpus=[2, 3]
-Cobalt.Hardware.Node[13].stations=[CS401LBA, CS401HBA, CS401HBA0, CS401HBA1, RS205LBA, RS205HBA, RS406LBA, RS406HBA, RS509LBA, RS509HBA]
-Cobalt.Hardware.Node[14].host=cbm008
-Cobalt.Hardware.Node[14].cpu=0
-Cobalt.Hardware.Node[14].gpus=[0, 1]
-Cobalt.Hardware.Node[14].stations=[CS004LBA, CS004HBA, CS004HBA0, CS004HBA1, CS103LBA, CS103HBA, CS103HBA0, CS103HBA1]
-Cobalt.Hardware.Node[15].host=cbm008
-Cobalt.Hardware.Node[15].cpu=1
-Cobalt.Hardware.Node[15].gpus=[2, 3]
-Cobalt.Hardware.Node[15].stations=[RS106LBA, RS106HBA, RS307LBA, RS307HBA, RS508LBA, RS508HBA, DE601LBA, DE601HBA, DE605LBA, DE605HBA]
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationStreams.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationStreams.parset
deleted file mode 100644
index 11bd9de9664e36be41d5ecedf0b97064e34a6ced..0000000000000000000000000000000000000000
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationStreams.parset
+++ /dev/null
@@ -1,192 +0,0 @@
-PIC.Core.Station.CS001LBA.RSP.ports = [udp:10.168.102.1:10010, udp:10.168.102.1:10011, udp:10.168.102.1:10012, udp:10.168.102.1:10013]
-PIC.Core.Station.CS001HBA.RSP.ports = [udp:10.168.102.1:10010, udp:10.168.102.1:10011, udp:10.168.102.1:10012, udp:10.168.102.1:10013]
-PIC.Core.Station.CS001HBA0.RSP.ports = [udp:10.168.102.1:10010, udp:10.168.102.1:10011, udp:10.168.102.1:10012, udp:10.168.102.1:10013]
-PIC.Core.Station.CS001HBA1.RSP.ports = [udp:10.168.102.1:10016, udp:10.168.102.1:10017, udp:10.168.102.1:10018, udp:10.168.102.1:10019]
-
-PIC.Core.Station.CS002LBA.RSP.ports = [udp:10.168.98.1:10020, udp:10.168.98.1:10021, udp:10.168.98.1:10022, udp:10.168.98.1:10023]
-PIC.Core.Station.CS002HBA.RSP.ports = [udp:10.168.98.1:10020, udp:10.168.98.1:10021, udp:10.168.98.1:10022, udp:10.168.98.1:10023]
-PIC.Core.Station.CS002HBA0.RSP.ports = [udp:10.168.98.1:10020, udp:10.168.98.1:10021, udp:10.168.98.1:10022, udp:10.168.98.1:10023]
-PIC.Core.Station.CS002HBA1.RSP.ports = [udp:10.168.98.1:10026, udp:10.168.98.1:10027, udp:10.168.98.1:10028, udp:10.168.98.1:10029]
-
-PIC.Core.Station.CS003LBA.RSP.ports = [udp:10.168.100.1:10030, udp:10.168.100.1:10031, udp:10.168.100.1:10032, udp:10.168.100.1:10033]
-PIC.Core.Station.CS003HBA.RSP.ports = [udp:10.168.100.1:10030, udp:10.168.100.1:10031, udp:10.168.100.1:10032, udp:10.168.100.1:10033]
-PIC.Core.Station.CS003HBA0.RSP.ports = [udp:10.168.100.1:10030, udp:10.168.100.1:10031, udp:10.168.100.1:10032, udp:10.168.100.1:10033]
-PIC.Core.Station.CS003HBA1.RSP.ports = [udp:10.168.100.1:10036, udp:10.168.100.1:10037, udp:10.168.100.1:10038, udp:10.168.100.1:10039]
-
-PIC.Core.Station.CS004LBA.RSP.ports = [udp:10.168.103.1:10040, udp:10.168.103.1:10041, udp:10.168.103.1:10042, udp:10.168.103.1:10043]
-PIC.Core.Station.CS004HBA.RSP.ports = [udp:10.168.103.1:10040, udp:10.168.103.1:10041, udp:10.168.103.1:10042, udp:10.168.103.1:10043]
-PIC.Core.Station.CS004HBA0.RSP.ports = [udp:10.168.103.1:10040, udp:10.168.103.1:10041, udp:10.168.103.1:10042, udp:10.168.103.1:10043]
-PIC.Core.Station.CS004HBA1.RSP.ports = [udp:10.168.103.1:10046, udp:10.168.103.1:10047, udp:10.168.103.1:10048, udp:10.168.103.1:10049]
-
-PIC.Core.Station.CS005LBA.RSP.ports = [udp:10.168.96.1:10050, udp:10.168.96.1:10051, udp:10.168.96.1:10052, udp:10.168.96.1:10053]
-PIC.Core.Station.CS005HBA.RSP.ports = [udp:10.168.96.1:10050, udp:10.168.96.1:10051, udp:10.168.96.1:10052, udp:10.168.96.1:10053]
-PIC.Core.Station.CS005HBA0.RSP.ports = [udp:10.168.96.1:10050, udp:10.168.96.1:10051, udp:10.168.96.1:10052, udp:10.168.96.1:10053]
-PIC.Core.Station.CS005HBA1.RSP.ports = [udp:10.168.96.1:10056, udp:10.168.96.1:10057, udp:10.168.96.1:10058, udp:10.168.96.1:10059]
-
-PIC.Core.Station.CS006LBA.RSP.ports = [udp:10.168.99.1:10060, udp:10.168.99.1:10061, udp:10.168.99.1:10062, udp:10.168.99.1:10063]
-PIC.Core.Station.CS006HBA.RSP.ports = [udp:10.168.99.1:10060, udp:10.168.99.1:10061, udp:10.168.99.1:10062, udp:10.168.99.1:10063]
-PIC.Core.Station.CS006HBA0.RSP.ports = [udp:10.168.99.1:10060, udp:10.168.99.1:10061, udp:10.168.99.1:10062, udp:10.168.99.1:10063]
-PIC.Core.Station.CS006HBA1.RSP.ports = [udp:10.168.99.1:10066, udp:10.168.99.1:10067, udp:10.168.99.1:10068, udp:10.168.99.1:10069]
-
-PIC.Core.Station.CS007LBA.RSP.ports = [udp:10.168.101.1:10070, udp:10.168.101.1:10071, udp:10.168.101.1:10072, udp:10.168.101.1:10073]
-PIC.Core.Station.CS007HBA.RSP.ports = [udp:10.168.101.1:10070, udp:10.168.101.1:10071, udp:10.168.101.1:10072, udp:10.168.101.1:10073]
-PIC.Core.Station.CS007HBA0.RSP.ports = [udp:10.168.101.1:10070, udp:10.168.101.1:10071, udp:10.168.101.1:10072, udp:10.168.101.1:10073]
-PIC.Core.Station.CS007HBA1.RSP.ports = [udp:10.168.101.1:10076, udp:10.168.101.1:10077, udp:10.168.101.1:10078, udp:10.168.101.1:10079]
-
-PIC.Core.Station.CS011LBA.RSP.ports = [udp:10.168.98.2:10110, udp:10.168.98.2:10111, udp:10.168.98.2:10112, udp:10.168.98.2:10113]
-PIC.Core.Station.CS011HBA.RSP.ports = [udp:10.168.98.2:10110, udp:10.168.98.2:10111, udp:10.168.98.2:10112, udp:10.168.98.2:10113]
-PIC.Core.Station.CS011HBA0.RSP.ports = [udp:10.168.98.2:10110, udp:10.168.98.2:10111, udp:10.168.98.2:10112, udp:10.168.98.2:10113]
-PIC.Core.Station.CS011HBA1.RSP.ports = [udp:10.168.98.2:10116, udp:10.168.98.2:10117, udp:10.168.98.2:10118, udp:10.168.98.2:10119]
-
-PIC.Core.Station.CS013LBA.RSP.ports = [udp:10.168.100.2:10130, udp:10.168.100.2:10131, udp:10.168.100.2:10132, udp:10.168.100.2:10133]
-PIC.Core.Station.CS013HBA.RSP.ports = [udp:10.168.100.2:10130, udp:10.168.100.2:10131, udp:10.168.100.2:10132, udp:10.168.100.2:10133]
-PIC.Core.Station.CS013HBA0.RSP.ports = [udp:10.168.100.2:10130, udp:10.168.100.2:10131, udp:10.168.100.2:10132, udp:10.168.100.2:10133]
-PIC.Core.Station.CS013HBA1.RSP.ports = [udp:10.168.100.2:10136, udp:10.168.100.2:10137, udp:10.168.100.2:10138, udp:10.168.100.2:10139]
-
-PIC.Core.Station.CS017LBA.RSP.ports = [udp:10.168.97.1:10170, udp:10.168.97.1:10171, udp:10.168.97.1:10172, udp:10.168.97.1:10173]
-PIC.Core.Station.CS017HBA.RSP.ports = [udp:10.168.97.1:10170, udp:10.168.97.1:10171, udp:10.168.97.1:10172, udp:10.168.97.1:10173]
-PIC.Core.Station.CS017HBA0.RSP.ports = [udp:10.168.97.1:10170, udp:10.168.97.1:10171, udp:10.168.97.1:10172, udp:10.168.97.1:10173]
-PIC.Core.Station.CS017HBA1.RSP.ports = [udp:10.168.97.1:10176, udp:10.168.97.1:10177, udp:10.168.97.1:10178, udp:10.168.97.1:10179]
-
-PIC.Core.Station.CS021LBA.RSP.ports = [udp:10.168.96.2:10210, udp:10.168.96.2:10211, udp:10.168.96.2:10212, udp:10.168.96.2:10213]
-PIC.Core.Station.CS021HBA.RSP.ports = [udp:10.168.96.2:10210, udp:10.168.96.2:10211, udp:10.168.96.2:10212, udp:10.168.96.2:10213]
-PIC.Core.Station.CS021HBA0.RSP.ports = [udp:10.168.96.2:10210, udp:10.168.96.2:10211, udp:10.168.96.2:10212, udp:10.168.96.2:10213]
-PIC.Core.Station.CS021HBA1.RSP.ports = [udp:10.168.96.2:10216, udp:10.168.96.2:10217, udp:10.168.96.2:10218, udp:10.168.96.2:10219]
-
-PIC.Core.Station.CS024LBA.RSP.ports = [udp:10.168.102.2:10240, udp:10.168.102.2:10241, udp:10.168.102.2:10242, udp:10.168.102.2:10243]
-PIC.Core.Station.CS024HBA.RSP.ports = [udp:10.168.102.2:10240, udp:10.168.102.2:10241, udp:10.168.102.2:10242, udp:10.168.102.2:10243]
-PIC.Core.Station.CS024HBA0.RSP.ports = [udp:10.168.102.2:10240, udp:10.168.102.2:10241, udp:10.168.102.2:10242, udp:10.168.102.2:10243]
-PIC.Core.Station.CS024HBA1.RSP.ports = [udp:10.168.102.2:10246, udp:10.168.102.2:10247, udp:10.168.102.2:10248, udp:10.168.102.2:10249]
-
-PIC.Core.Station.CS026LBA.RSP.ports = [udp:10.168.99.2:10260, udp:10.168.99.2:10261, udp:10.168.99.2:10262, udp:10.168.99.2:10263]
-PIC.Core.Station.CS026HBA.RSP.ports = [udp:10.168.99.2:10260, udp:10.168.99.2:10261, udp:10.168.99.2:10262, udp:10.168.99.2:10263]
-PIC.Core.Station.CS026HBA0.RSP.ports = [udp:10.168.99.2:10260, udp:10.168.99.2:10261, udp:10.168.99.2:10262, udp:10.168.99.2:10263]
-PIC.Core.Station.CS026HBA1.RSP.ports = [udp:10.168.99.2:10266, udp:10.168.99.2:10267, udp:10.168.99.2:10268, udp:10.168.99.2:10269]
-
-PIC.Core.Station.CS028LBA.RSP.ports = [udp:10.168.98.3:10280, udp:10.168.98.3:10281, udp:10.168.98.3:10282, udp:10.168.98.3:10283]
-PIC.Core.Station.CS028HBA.RSP.ports = [udp:10.168.98.3:10280, udp:10.168.98.3:10281, udp:10.168.98.3:10282, udp:10.168.98.3:10283]
-PIC.Core.Station.CS028HBA0.RSP.ports = [udp:10.168.98.3:10280, udp:10.168.98.3:10281, udp:10.168.98.3:10282, udp:10.168.98.3:10283]
-PIC.Core.Station.CS028HBA1.RSP.ports = [udp:10.168.98.3:10286, udp:10.168.98.3:10287, udp:10.168.98.3:10288, udp:10.168.98.3:10289]
-
-PIC.Core.Station.CS030LBA.RSP.ports = [udp:10.168.101.2:10300, udp:10.168.101.2:10301, udp:10.168.101.2:10302, udp:10.168.101.2:10303]
-PIC.Core.Station.CS030HBA.RSP.ports = [udp:10.168.101.2:10300, udp:10.168.101.2:10301, udp:10.168.101.2:10302, udp:10.168.101.2:10303]
-PIC.Core.Station.CS030HBA0.RSP.ports = [udp:10.168.101.2:10300, udp:10.168.101.2:10301, udp:10.168.101.2:10302, udp:10.168.101.2:10303]
-PIC.Core.Station.CS030HBA1.RSP.ports = [udp:10.168.101.2:10306, udp:10.168.101.2:10307, udp:10.168.101.2:10308, udp:10.168.101.2:10309]
-
-PIC.Core.Station.CS031LBA.RSP.ports = [udp:10.168.99.3:10310, udp:10.168.99.3:10311, udp:10.168.99.3:10312, udp:10.168.99.3:10313]
-PIC.Core.Station.CS031HBA.RSP.ports = [udp:10.168.99.3:10310, udp:10.168.99.3:10311, udp:10.168.99.3:10312, udp:10.168.99.3:10313]
-PIC.Core.Station.CS031HBA0.RSP.ports = [udp:10.168.99.3:10310, udp:10.168.99.3:10311, udp:10.168.99.3:10312, udp:10.168.99.3:10313]
-PIC.Core.Station.CS031HBA1.RSP.ports = [udp:10.168.99.3:10316, udp:10.168.99.3:10317, udp:10.168.99.3:10318, udp:10.168.99.3:10319]
-
-PIC.Core.Station.CS032LBA.RSP.ports = [udp:10.168.97.2:10320, udp:10.168.97.2:10321, udp:10.168.97.2:10322, udp:10.168.97.2:10323]
-PIC.Core.Station.CS032HBA.RSP.ports = [udp:10.168.97.2:10320, udp:10.168.97.2:10321, udp:10.168.97.2:10322, udp:10.168.97.2:10323]
-PIC.Core.Station.CS032HBA0.RSP.ports = [udp:10.168.97.2:10320, udp:10.168.97.2:10321, udp:10.168.97.2:10322, udp:10.168.97.2:10323]
-PIC.Core.Station.CS032HBA1.RSP.ports = [udp:10.168.97.2:10326, udp:10.168.97.2:10327, udp:10.168.97.2:10328, udp:10.168.97.2:10329]
-
-PIC.Core.Station.CS101LBA.RSP.ports = [udp:10.168.96.3:11010, udp:10.168.96.3:11011, udp:10.168.96.3:11012, udp:10.168.96.3:11013]
-PIC.Core.Station.CS101HBA.RSP.ports = [udp:10.168.96.3:11010, udp:10.168.96.3:11011, udp:10.168.96.3:11012, udp:10.168.96.3:11013]
-PIC.Core.Station.CS101HBA0.RSP.ports = [udp:10.168.96.3:11010, udp:10.168.96.3:11011, udp:10.168.96.3:11012, udp:10.168.96.3:11013]
-PIC.Core.Station.CS101HBA1.RSP.ports = [udp:10.168.96.3:11016, udp:10.168.96.3:11017, udp:10.168.96.3:11018, udp:10.168.96.3:11019]
-
-PIC.Core.Station.CS103LBA.RSP.ports = [udp:10.168.103.2:11030, udp:10.168.103.2:11031, udp:10.168.103.2:11032, udp:10.168.103.2:11033]
-PIC.Core.Station.CS103HBA.RSP.ports = [udp:10.168.103.2:11030, udp:10.168.103.2:11031, udp:10.168.103.2:11032, udp:10.168.103.2:11033]
-PIC.Core.Station.CS103HBA0.RSP.ports = [udp:10.168.103.2:11030, udp:10.168.103.2:11031, udp:10.168.103.2:11032, udp:10.168.103.2:11033]
-PIC.Core.Station.CS103HBA1.RSP.ports = [udp:10.168.103.2:11036, udp:10.168.103.2:11037, udp:10.168.103.2:11038, udp:10.168.103.2:11039]
-
-PIC.Core.Station.CS201LBA.RSP.ports = [udp:10.168.98.4:12010, udp:10.168.98.4:12011, udp:10.168.98.4:12012, udp:10.168.98.4:12013]
-PIC.Core.Station.CS201HBA.RSP.ports = [udp:10.168.98.4:12010, udp:10.168.98.4:12011, udp:10.168.98.4:12012, udp:10.168.98.4:12013]
-PIC.Core.Station.CS201HBA0.RSP.ports = [udp:10.168.98.4:12010, udp:10.168.98.4:12011, udp:10.168.98.4:12012, udp:10.168.98.4:12013]
-PIC.Core.Station.CS201HBA1.RSP.ports = [udp:10.168.98.4:12016, udp:10.168.98.4:12017, udp:10.168.98.4:12018, udp:10.168.98.4:12019]
-
-PIC.Core.Station.CS301LBA.RSP.ports = [udp:10.168.100.3:13010, udp:10.168.100.3:13011, udp:10.168.100.3:13012, udp:10.168.100.3:13013]
-PIC.Core.Station.CS301HBA.RSP.ports = [udp:10.168.100.3:13010, udp:10.168.100.3:13011, udp:10.168.100.3:13012, udp:10.168.100.3:13013]
-PIC.Core.Station.CS301HBA0.RSP.ports = [udp:10.168.100.3:13010, udp:10.168.100.3:13011, udp:10.168.100.3:13012, udp:10.168.100.3:13013]
-PIC.Core.Station.CS301HBA1.RSP.ports = [udp:10.168.100.3:13016, udp:10.168.100.3:13017, udp:10.168.100.3:13018, udp:10.168.100.3:13019]
-
-PIC.Core.Station.CS302LBA.RSP.ports = [udp:10.168.99.4:13020, udp:10.168.99.4:13021, udp:10.168.99.4:13022, udp:10.168.99.4:13023]
-PIC.Core.Station.CS302HBA.RSP.ports = [udp:10.168.99.4:13020, udp:10.168.99.4:13021, udp:10.168.99.4:13022, udp:10.168.99.4:13023]
-PIC.Core.Station.CS302HBA0.RSP.ports = [udp:10.168.99.4:13020, udp:10.168.99.4:13021, udp:10.168.99.4:13022, udp:10.168.99.4:13023]
-PIC.Core.Station.CS302HBA1.RSP.ports = [udp:10.168.99.4:13026, udp:10.168.99.4:13027, udp:10.168.99.4:13028, udp:10.168.99.4:13029]
-
-PIC.Core.Station.CS401LBA.RSP.ports = [udp:10.168.102.3:14010, udp:10.168.102.3:14011, udp:10.168.102.3:14012, udp:10.168.102.3:14013]
-PIC.Core.Station.CS401HBA.RSP.ports = [udp:10.168.102.3:14010, udp:10.168.102.3:14011, udp:10.168.102.3:14012, udp:10.168.102.3:14013]
-PIC.Core.Station.CS401HBA0.RSP.ports = [udp:10.168.102.3:14010, udp:10.168.102.3:14011, udp:10.168.102.3:14012, udp:10.168.102.3:14013]
-PIC.Core.Station.CS401HBA1.RSP.ports = [udp:10.168.102.3:14016, udp:10.168.102.3:14017, udp:10.168.102.3:14018, udp:10.168.102.3:14019]
-
-PIC.Core.Station.CS501LBA.RSP.ports = [udp:10.168.101.3:15010, udp:10.168.101.3:15011, udp:10.168.101.3:15012, udp:10.168.101.3:15013]
-PIC.Core.Station.CS501HBA.RSP.ports = [udp:10.168.101.3:15010, udp:10.168.101.3:15011, udp:10.168.101.3:15012, udp:10.168.101.3:15013]
-PIC.Core.Station.CS501HBA0.RSP.ports = [udp:10.168.101.3:15010, udp:10.168.101.3:15011, udp:10.168.101.3:15012, udp:10.168.101.3:15013]
-PIC.Core.Station.CS501HBA1.RSP.ports = [udp:10.168.101.3:15016, udp:10.168.101.3:15017, udp:10.168.101.3:15018, udp:10.168.101.3:15019]
-
-PIC.Core.Station.RS104LBA.RSP.ports = [udp:10.168.97.3:11040, udp:10.168.97.3:11041, udp:10.168.97.3:11042, udp:10.168.97.3:11043]
-PIC.Core.Station.RS104HBA.RSP.ports = [udp:10.168.97.3:11040, udp:10.168.97.3:11041, udp:10.168.97.3:11042, udp:10.168.97.3:11043]
-
-PIC.Core.Station.RS106LBA.RSP.ports = [udp:10.168.103.3:11060, udp:10.168.103.3:11061, udp:10.168.103.3:11062, udp:10.168.103.3:11063]
-PIC.Core.Station.RS106HBA.RSP.ports = [udp:10.168.103.3:11060, udp:10.168.103.3:11061, udp:10.168.103.3:11062, udp:10.168.103.3:11063]
-
-PIC.Core.Station.RS205LBA.RSP.ports = [udp:10.168.102.4:12050, udp:10.168.102.4:12051, udp:10.168.102.4:12052, udp:10.168.102.4:12053]
-PIC.Core.Station.RS205HBA.RSP.ports = [udp:10.168.102.4:12050, udp:10.168.102.4:12051, udp:10.168.102.4:12052, udp:10.168.102.4:12053]
-
-PIC.Core.Station.RS208LBA.RSP.ports = [udp:10.168.96.4:12080, udp:10.168.96.4:12081, udp:10.168.96.4:12082, udp:10.168.96.4:12083]
-PIC.Core.Station.RS208HBA.RSP.ports = [udp:10.168.96.4:12080, udp:10.168.96.4:12081, udp:10.168.96.4:12082, udp:10.168.96.4:12083]
-
-PIC.Core.Station.RS210LBA.RSP.ports = [udp:10.168.100.4:12100, udp:10.168.100.4:12101, udp:10.168.100.4:12102, udp:10.168.100.4:12103]
-PIC.Core.Station.RS210HBA.RSP.ports = [udp:10.168.100.4:12100, udp:10.168.100.4:12101, udp:10.168.100.4:12102, udp:10.168.100.4:12103]
-
-PIC.Core.Station.RS305LBA.RSP.ports = [udp:10.168.101.4:13050, udp:10.168.101.4:13051, udp:10.168.101.4:13052, udp:10.168.101.4:13053]
-PIC.Core.Station.RS305HBA.RSP.ports = [udp:10.168.101.4:13050, udp:10.168.101.4:13051, udp:10.168.101.4:13052, udp:10.168.101.4:13053]
-
-PIC.Core.Station.RS306LBA.RSP.ports = [udp:10.168.100.1:13060, udp:10.168.100.1:13061, udp:10.168.100.1:13062, udp:10.168.100.1:13063]
-PIC.Core.Station.RS306HBA.RSP.ports = [udp:10.168.100.1:13060, udp:10.168.100.1:13061, udp:10.168.100.1:13062, udp:10.168.100.1:13063]
-
-PIC.Core.Station.RS307LBA.RSP.ports = [udp:10.168.103.4:13070, udp:10.168.103.4:13071, udp:10.168.103.4:13072, udp:10.168.103.4:13073]
-PIC.Core.Station.RS307HBA.RSP.ports = [udp:10.168.103.4:13070, udp:10.168.103.4:13071, udp:10.168.103.4:13072, udp:10.168.103.4:13073]
-
-PIC.Core.Station.RS310LBA.RSP.ports = [udp:10.168.97.4:13100, udp:10.168.97.4:13101, udp:10.168.97.4:13102, udp:10.168.97.4:13103]
-PIC.Core.Station.RS310HBA.RSP.ports = [udp:10.168.97.4:13100, udp:10.168.97.4:13101, udp:10.168.97.4:13102, udp:10.168.97.4:13103]
-
-PIC.Core.Station.RS406LBA.RSP.ports = [udp:10.168.102.3:14060, udp:10.168.102.3:14061, udp:10.168.102.3:14062, udp:10.168.102.3:14063]
-PIC.Core.Station.RS406HBA.RSP.ports = [udp:10.168.102.3:14060, udp:10.168.102.3:14061, udp:10.168.102.3:14062, udp:10.168.102.3:14063]
-
-PIC.Core.Station.RS407LBA.RSP.ports = [udp:10.168.96.4:14070, udp:10.168.96.4:14071, udp:10.168.96.4:14072, udp:10.168.96.4:14073]
-PIC.Core.Station.RS407HBA.RSP.ports = [udp:10.168.96.4:14070, udp:10.168.96.4:14071, udp:10.168.96.4:14072, udp:10.168.96.4:14073]
-
-PIC.Core.Station.RS409LBA.RSP.ports = [udp:10.168.97.3:14090, udp:10.168.97.3:14091, udp:10.168.97.3:14092, udp:10.168.97.3:14093]
-PIC.Core.Station.RS409HBA.RSP.ports = [udp:10.168.97.3:14090, udp:10.168.97.3:14091, udp:10.168.97.3:14092, udp:10.168.97.3:14093]
-
-PIC.Core.Station.RS410LBA.RSP.ports = [udp:10.168.97.4:14100, udp:10.168.97.4:14101, udp:10.168.97.4:14102, udp:10.168.97.4:14103]
-PIC.Core.Station.RS410HBA.RSP.ports = [udp:10.168.97.4:14100, udp:10.168.97.4:14101, udp:10.168.97.4:14102, udp:10.168.97.4:14103]
-
-PIC.Core.Station.RS503LBA.RSP.ports = [udp:10.168.101.4:15030, udp:10.168.101.4:15031, udp:10.168.101.4:15032, udp:10.168.101.4:15033]
-PIC.Core.Station.RS503HBA.RSP.ports = [udp:10.168.101.4:15030, udp:10.168.101.4:15031, udp:10.168.101.4:15032, udp:10.168.101.4:15033]
-
-PIC.Core.Station.RS508LBA.RSP.ports = [udp:10.168.103.3:15080, udp:10.168.103.3:15081, udp:10.168.103.3:15082, udp:10.168.103.3:15083]
-PIC.Core.Station.RS508HBA.RSP.ports = [udp:10.168.103.3:15080, udp:10.168.103.3:15081, udp:10.168.103.3:15082, udp:10.168.103.3:15083]
-
-PIC.Core.Station.RS509LBA.RSP.ports = [udp:10.168.102.4:15090, udp:10.168.102.4:15091, udp:10.168.102.4:15092, udp:10.168.102.4:15093]
-PIC.Core.Station.RS509HBA.RSP.ports = [udp:10.168.102.4:15090, udp:10.168.102.4:15091, udp:10.168.102.4:15092, udp:10.168.102.4:15093]
-
-PIC.Core.Station.DE601LBA.RSP.ports = [udp:10.168.103.4:16010, udp:10.168.103.4:16011, udp:10.168.103.4:16012, udp:10.168.103.4:16013]
-PIC.Core.Station.DE601HBA.RSP.ports = [udp:10.168.103.4:16010, udp:10.168.103.4:16011, udp:10.168.103.4:16012, udp:10.168.103.4:16013]
-
-PIC.Core.Station.DE602LBA.RSP.ports = [udp:10.168.98.4:16020, udp:10.168.98.4:16021, udp:10.168.98.4:16022, udp:10.168.98.4:16023]
-PIC.Core.Station.DE602HBA.RSP.ports = [udp:10.168.98.4:16020, udp:10.168.98.4:16021, udp:10.168.98.4:16022, udp:10.168.98.4:16023]
-
-PIC.Core.Station.DE603LBA.RSP.ports = [udp:10.168.99.4:16030, udp:10.168.99.4:16031, udp:10.168.99.4:16032, udp:10.168.99.4:16033]
-PIC.Core.Station.DE603HBA.RSP.ports = [udp:10.168.99.4:16030, udp:10.168.99.4:16031, udp:10.168.99.4:16032, udp:10.168.99.4:16033]
-
-PIC.Core.Station.DE604LBA.RSP.ports = [udp:10.168.98.2:16040, udp:10.168.98.2:16041, udp:10.168.98.2:16042, udp:10.168.98.2:16043]
-PIC.Core.Station.DE604HBA.RSP.ports = [udp:10.168.98.2:16040, udp:10.168.98.2:16041, udp:10.168.98.2:16042, udp:10.168.98.2:16043]
-
-PIC.Core.Station.DE605LBA.RSP.ports = [udp:10.168.103.4:16050, udp:10.168.103.4:16051, udp:10.168.103.4:16052, udp:10.168.103.4:16053]
-PIC.Core.Station.DE605HBA.RSP.ports = [udp:10.168.103.4:16050, udp:10.168.103.4:16051, udp:10.168.103.4:16052, udp:10.168.103.4:16053]
-
-PIC.Core.Station.FR606LBA.RSP.ports = [udp:10.168.100.4:16060, udp:10.168.100.4:16061, udp:10.168.100.4:16062, udp:10.168.100.4:16063]
-PIC.Core.Station.FR606HBA.RSP.ports = [udp:10.168.100.4:16060, udp:10.168.100.4:16061, udp:10.168.100.4:16062, udp:10.168.100.4:16063]
-
-PIC.Core.Station.SE607LBA.RSP.ports = [udp:10.168.101.4:16070, udp:10.168.101.4:16071, udp:10.168.101.4:16072, udp:10.168.101.4:16073]
-PIC.Core.Station.SE607HBA.RSP.ports = [udp:10.168.101.4:16070, udp:10.168.101.4:16071, udp:10.168.101.4:16072, udp:10.168.101.4:16073]
-
-PIC.Core.Station.UK608LBA.RSP.ports = [udp:10.168.100.3:16080, udp:10.168.100.3:16081, udp:10.168.100.3:16082, udp:10.168.100.3:16083]
-PIC.Core.Station.UK608HBA.RSP.ports = [udp:10.168.100.3:16080, udp:10.168.100.3:16081, udp:10.168.100.3:16082, udp:10.168.100.3:16083]
-
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/FinalMetaDataGatherer.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/FinalMetaDataGatherer.parset
similarity index 93%
rename from RTCP/Cobalt/GPUProc/etc/parset-additions.d/FinalMetaDataGatherer.parset
rename to RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/FinalMetaDataGatherer.parset
index 182a44b7e1203c016c1cf18f854d93c207bac6b3..318a87778eec49e850119a8ef4c5e9d69f1d091d 100644
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/FinalMetaDataGatherer.parset
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/FinalMetaDataGatherer.parset
@@ -16,5 +16,5 @@ Cobalt.FinalMetaDataGatherer.executable = FinalMetaDataGatherer
 # The database to connect to:
 #   Development: sasdbtest
 #   Production:  sasdb
-OLAP.FinalMetaDataGatherer.database.host = 
+OLAP.FinalMetaDataGatherer.database.host = sasdb
 
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareList.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareList.parset
new file mode 100644
index 0000000000000000000000000000000000000000..715096e4805a7dc4a46a4b0f13afec3d5bf29c24
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareList.parset
@@ -0,0 +1,116 @@
+#
+# HardwareList.parset describes the properties of each node
+# known to Cobalt. 
+#
+
+# A generic configuration for 'localhost'
+
+PIC.Core.Cobalt.localhost.host=localhost
+PIC.Core.Cobalt.localhost.cpu=0
+PIC.Core.Cobalt.localhost.nic=
+PIC.Core.Cobalt.localhost.gpus=
+
+# DAS-4 nodes
+
+PIC.Core.Cobalt.gpu01_0.host=gpu01
+PIC.Core.Cobalt.gpu01_0.cpu=0
+PIC.Core.Cobalt.gpu01_0.nic=
+PIC.Core.Cobalt.gpu01_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.gpu01_1.host=gpu01
+PIC.Core.Cobalt.gpu01_1.cpu=1
+PIC.Core.Cobalt.gpu01_1.nic=
+PIC.Core.Cobalt.gpu01_1.gpus=[2, 3]
+
+# The Cobalt cluster
+
+PIC.Core.Cobalt.cbt001_0.host=cbt001
+PIC.Core.Cobalt.cbt001_0.cpu=0
+PIC.Core.Cobalt.cbt001_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt001_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt001_1.host=cbt001
+PIC.Core.Cobalt.cbt001_1.cpu=1
+PIC.Core.Cobalt.cbt001_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt001_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt002_0.host=cbt002
+PIC.Core.Cobalt.cbt002_0.cpu=0
+PIC.Core.Cobalt.cbt002_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt002_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt002_1.host=cbt002
+PIC.Core.Cobalt.cbt002_1.cpu=1
+PIC.Core.Cobalt.cbt002_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt002_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt003_0.host=cbt003
+PIC.Core.Cobalt.cbt003_0.cpu=0
+PIC.Core.Cobalt.cbt003_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt003_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt003_1.host=cbt003
+PIC.Core.Cobalt.cbt003_1.cpu=1
+PIC.Core.Cobalt.cbt003_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt003_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt004_0.host=cbt004
+PIC.Core.Cobalt.cbt004_0.cpu=0
+PIC.Core.Cobalt.cbt004_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt004_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt004_1.host=cbt004
+PIC.Core.Cobalt.cbt004_1.cpu=1
+PIC.Core.Cobalt.cbt004_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt004_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt005_0.host=cbt005
+PIC.Core.Cobalt.cbt005_0.cpu=0
+PIC.Core.Cobalt.cbt005_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt005_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt005_1.host=cbt005
+PIC.Core.Cobalt.cbt005_1.cpu=1
+PIC.Core.Cobalt.cbt005_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt005_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt006_0.host=cbt006
+PIC.Core.Cobalt.cbt006_0.cpu=0
+PIC.Core.Cobalt.cbt006_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt006_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt006_1.host=cbt006
+PIC.Core.Cobalt.cbt006_1.cpu=1
+PIC.Core.Cobalt.cbt006_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt006_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt007_0.host=cbt007
+PIC.Core.Cobalt.cbt007_0.cpu=0
+PIC.Core.Cobalt.cbt007_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt007_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt007_1.host=cbt007
+PIC.Core.Cobalt.cbt007_1.cpu=1
+PIC.Core.Cobalt.cbt007_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt007_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt008_0.host=cbt008
+PIC.Core.Cobalt.cbt008_0.cpu=0
+PIC.Core.Cobalt.cbt008_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt008_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt008_1.host=cbt008
+PIC.Core.Cobalt.cbt008_1.cpu=1
+PIC.Core.Cobalt.cbt008_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt008_1.gpus=[2, 3]
+
+PIC.Core.Cobalt.cbt009_0.host=cbt009
+PIC.Core.Cobalt.cbt009_0.cpu=0
+PIC.Core.Cobalt.cbt009_0.nic=mlx4_0
+PIC.Core.Cobalt.cbt009_0.gpus=[0, 1]
+
+PIC.Core.Cobalt.cbt009_1.host=cbt009
+PIC.Core.Cobalt.cbt009_1.cpu=1
+PIC.Core.Cobalt.cbt009_1.nic=mlx4_1
+PIC.Core.Cobalt.cbt009_1.gpus=[2, 3]
+
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareUsed.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareUsed.parset
new file mode 100644
index 0000000000000000000000000000000000000000..ce1d90580d06d1edca26a5863e3f74d4a954e694
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/HardwareUsed.parset
@@ -0,0 +1,24 @@
+# The list of Cobalt nodes to use for this observation
+# 
+# Node XXXX is configured through the keys in
+#   PIC.Core.Cobalt.XXXX.*
+
+Cobalt.Nodes = [
+  cbt001_0,
+  cbt001_1,
+  cbt002_0,
+  cbt002_1,
+  cbt003_0,
+  cbt003_1,
+  cbt004_0,
+  cbt004_1,
+  cbt005_0,
+  cbt005_1,
+  cbt006_0,
+  cbt006_1,
+  cbt007_0,
+  cbt007_1,
+  cbt008_0,
+  cbt008_1
+]
+
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/MAC-feedback.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset
similarity index 100%
rename from RTCP/Cobalt/GPUProc/etc/parset-additions.d/MAC-feedback.parset
rename to RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/MAC-feedback.parset
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/OutputProc.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/OutputProc.parset
similarity index 100%
rename from RTCP/Cobalt/GPUProc/etc/parset-additions.d/OutputProc.parset
rename to RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/OutputProc.parset
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationCalibration.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationCalibration.parset
similarity index 70%
rename from RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationCalibration.parset
rename to RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationCalibration.parset
index 919d1ceda82de8ed7377a20d9e309ddbc59943d0..b906625befd5816db511c3c739bbb714fe963f6e 100644
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/StationCalibration.parset
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationCalibration.parset
@@ -4,178 +4,197 @@
 # Fibre length corrections for core stations using
 # a single clock. 
 #
-
-PIC.Core.CS001LBA.clockCorrectionTime = 4.640447e-06
-PIC.Core.CS001HBA0.clockCorrectionTime = 4.644254e-06
-PIC.Core.CS001HBA1.clockCorrectionTime = 4.644254e-06
-PIC.Core.CS001HBA.clockCorrectionTime = 4.644254e-06
-
-PIC.Core.CS002LBA.clockCorrectionTime = 6.951830e-06
-PIC.Core.CS002HBA0.clockCorrectionTime = 6.948334e-06
-PIC.Core.CS002HBA1.clockCorrectionTime = 6.947804e-06
-PIC.Core.CS002HBA.clockCorrectionTime = 6.948069e-06
-
-PIC.Core.CS003LBA.clockCorrectionTime = 5.550944e-06
-PIC.Core.CS003HBA0.clockCorrectionTime = 5.547426e-06
-PIC.Core.CS003HBA1.clockCorrectionTime = 5.547372e-06
-PIC.Core.CS003HBA.clockCorrectionTime = 5.547399e-06
-
-PIC.Core.CS004LBA.clockCorrectionTime = 6.514347e-06
-PIC.Core.CS004HBA0.clockCorrectionTime = 6.519461e-06
-PIC.Core.CS004HBA1.clockCorrectionTime = 6.519005e-06
-PIC.Core.CS004HBA.clockCorrectionTime = 6.519233e-06
-
-PIC.Core.CS005LBA.clockCorrectionTime = 7.167328e-06
-PIC.Core.CS005HBA0.clockCorrectionTime = 7.171593e-06
-PIC.Core.CS005HBA1.clockCorrectionTime = 7.171291e-06
-PIC.Core.CS005HBA.clockCorrectionTime = 7.171442e-06
-
-PIC.Core.CS006LBA.clockCorrectionTime = 6.510205e-06
-PIC.Core.CS006HBA0.clockCorrectionTime = 6.512392e-06
-PIC.Core.CS006HBA1.clockCorrectionTime = 6.512896e-06
-PIC.Core.CS006HBA.clockCorrectionTime = 6.512650e-06
-
-PIC.Core.CS007LBA.clockCorrectionTime = 6.545958e-06
-PIC.Core.CS007HBA0.clockCorrectionTime = 6.542520e-06
-PIC.Core.CS007HBA1.clockCorrectionTime = 6.542760e-06
-PIC.Core.CS007HBA.clockCorrectionTime = 6.542640e-06
-
-PIC.Core.CS011LBA.clockCorrectionTime = 7.439500e-06
-PIC.Core.CS011HBA0.clockCorrectionTime = 7.443020e-06
-PIC.Core.CS011HBA1.clockCorrectionTime = 7.443020e-06
-PIC.Core.CS011HBA.clockCorrectionTime = 7.443020e-06
-
-PIC.Core.CS013LBA.clockCorrectionTime = 8.683600e-06
-PIC.Core.CS013HBA0.clockCorrectionTime = 8.683600e-06
-PIC.Core.CS013HBA1.clockCorrectionTime = 8.683600e-06
-PIC.Core.CS013HBA.clockCorrectionTime = 8.683600e-06
-
-PIC.Core.CS017LBA.clockCorrectionTime = 1.529262e-05
-PIC.Core.CS017HBA0.clockCorrectionTime = 1.529545e-05
-PIC.Core.CS017HBA1.clockCorrectionTime = 1.529545e-05
-PIC.Core.CS017HBA.clockCorrectionTime = 1.529545e-05
-
-PIC.Core.CS021LBA.clockCorrectionTime = 5.928835e-06
-PIC.Core.CS021HBA0.clockCorrectionTime = 5.934130e-06
-PIC.Core.CS021HBA1.clockCorrectionTime = 5.934130e-06
-PIC.Core.CS021HBA.clockCorrectionTime = 5.934130e-06
-
-PIC.Core.CS024LBA.clockCorrectionTime = 4.547850e-06
-PIC.Core.CS024HBA0.clockCorrectionTime = 4.543070e-06
-PIC.Core.CS024HBA1.clockCorrectionTime = 4.543070e-06
-PIC.Core.CS024HBA.clockCorrectionTime = 4.543070e-06
-
-PIC.Core.CS026LBA.clockCorrectionTime = 1.608932e-05
-PIC.Core.CS026HBA0.clockCorrectionTime = 1.608398e-05
-PIC.Core.CS026HBA1.clockCorrectionTime = 1.608398e-05
-PIC.Core.CS026HBA.clockCorrectionTime = 1.608398e-05
-
-PIC.Core.CS028LBA.clockCorrectionTime = 1.685155e-05
-PIC.Core.CS028HBA0.clockCorrectionTime = 1.684707e-05
-PIC.Core.CS028HBA1.clockCorrectionTime = 1.684707e-05
-PIC.Core.CS028HBA.clockCorrectionTime = 1.684707e-05
-
-PIC.Core.CS030LBA.clockCorrectionTime = 9.595558e-06
-PIC.Core.CS030HBA0.clockCorrectionTime = 9.600558e-06
-PIC.Core.CS030HBA1.clockCorrectionTime = 9.600558e-06
-PIC.Core.CS030HBA.clockCorrectionTime = 9.600558e-06
-
-PIC.Core.CS031LBA.clockCorrectionTime = 6.260033e-06
-PIC.Core.CS031HBA0.clockCorrectionTime = 6.254590e-06
-PIC.Core.CS031HBA1.clockCorrectionTime = 6.254590e-06
-PIC.Core.CS031HBA.clockCorrectionTime = 6.254590e-06
-
-PIC.Core.CS032LBA.clockCorrectionTime = 8.426175e-06
-PIC.Core.CS032HBA0.clockCorrectionTime = 8.430755e-06
-PIC.Core.CS032HBA1.clockCorrectionTime = 8.430755e-06
-PIC.Core.CS032HBA.clockCorrectionTime = 8.430755e-06
-
-PIC.Core.CS101LBA.clockCorrectionTime = 1.503997e-05
-PIC.Core.CS101HBA0.clockCorrectionTime = 1.504247e-05
-PIC.Core.CS101HBA1.clockCorrectionTime = 1.504247e-05
-PIC.Core.CS101HBA.clockCorrectionTime = 1.504247e-05
-
-PIC.Core.CS103LBA.clockCorrectionTime = 3.538771e-05
-PIC.Core.CS103HBA0.clockCorrectionTime = 3.538542e-05
-PIC.Core.CS103HBA1.clockCorrectionTime = 3.538542e-05
-PIC.Core.CS103HBA.clockCorrectionTime = 3.538542e-05
-
-PIC.Core.CS201LBA.clockCorrectionTime = 1.733889e-05
-PIC.Core.CS201HBA0.clockCorrectionTime = 1.733374e-05
-PIC.Core.CS201HBA1.clockCorrectionTime = 1.733374e-05
-PIC.Core.CS201HBA.clockCorrectionTime = 1.733374e-05
-
-PIC.Core.CS301LBA.clockCorrectionTime = 7.569749e-06
-PIC.Core.CS301HBA0.clockCorrectionTime = 7.574931e-06
-PIC.Core.CS301HBA1.clockCorrectionTime = 7.574931e-06
-PIC.Core.CS301HBA.clockCorrectionTime = 7.574931e-06
-
-PIC.Core.CS302LBA.clockCorrectionTime = 1.220150e-05
-PIC.Core.CS302HBA0.clockCorrectionTime = 1.220610e-05
-PIC.Core.CS302HBA1.clockCorrectionTime = 1.220610e-05
-PIC.Core.CS302HBA.clockCorrectionTime = 1.220610e-05
-
-PIC.Core.CS401LBA.clockCorrectionTime = 7.936700e-06
-PIC.Core.CS401HBA0.clockCorrectionTime = 7.942004e-06
-PIC.Core.CS401HBA1.clockCorrectionTime = 7.942270e-06
-PIC.Core.CS401HBA.clockCorrectionTime = 7.942137e-06
-
-PIC.Core.CS501LBA.clockCorrectionTime = 1.646420e-05
-PIC.Core.CS501HBA0.clockCorrectionTime = 1.646870e-05
-PIC.Core.CS501HBA1.clockCorrectionTime = 1.646870e-05
-PIC.Core.CS501HBA.clockCorrectionTime = 1.646870e-05
+PIC.Core.CS001LBA.clockCorrectionTime  = 4.755947e-06
+PIC.Core.CS001HBA0.clockCorrectionTime = 4.759754e-06
+PIC.Core.CS001HBA1.clockCorrectionTime = 4.759754e-06
+PIC.Core.CS001HBA.clockCorrectionTime  = 4.759754e-06
+
+PIC.Core.CS002LBA.clockCorrectionTime  = 8.32233e-06
+PIC.Core.CS002HBA0.clockCorrectionTime = 8.318834e-06
+PIC.Core.CS002HBA1.clockCorrectionTime = 8.318304e-06
+PIC.Core.CS002HBA.clockCorrectionTime  = 8.318569e-06
+
+PIC.Core.CS003LBA.clockCorrectionTime  = 6.921444e-06
+PIC.Core.CS003HBA0.clockCorrectionTime = 6.917926e-06
+PIC.Core.CS003HBA1.clockCorrectionTime = 6.917872e-06
+PIC.Core.CS003HBA.clockCorrectionTime  = 6.917899e-06
+
+PIC.Core.CS004LBA.clockCorrectionTime  = 7.884847e-06
+PIC.Core.CS004HBA0.clockCorrectionTime = 7.889961e-06
+PIC.Core.CS004HBA1.clockCorrectionTime = 7.889505e-06
+PIC.Core.CS004HBA.clockCorrectionTime  = 7.889733e-06
+
+PIC.Core.CS005LBA.clockCorrectionTime  = 8.537828e-06
+PIC.Core.CS005HBA0.clockCorrectionTime = 8.542093e-06
+PIC.Core.CS005HBA1.clockCorrectionTime = 8.541791e-06
+PIC.Core.CS005HBA.clockCorrectionTime  = 8.541942e-06
+
+PIC.Core.CS006LBA.clockCorrectionTime  = 7.880705e-06
+PIC.Core.CS006HBA0.clockCorrectionTime = 7.882892e-06
+PIC.Core.CS006HBA1.clockCorrectionTime = 7.883396e-06
+PIC.Core.CS006HBA.clockCorrectionTime  = 7.883150e-06
+
+PIC.Core.CS007LBA.clockCorrectionTime  = 7.916458e-06
+PIC.Core.CS007HBA0.clockCorrectionTime = 7.913020e-06
+PIC.Core.CS007HBA1.clockCorrectionTime = 7.913260e-06
+PIC.Core.CS007HBA.clockCorrectionTime  = 7.913140e-06 
+
+PIC.Core.CS011LBA.clockCorrectionTime  = 7.55500e-06
+PIC.Core.CS011HBA0.clockCorrectionTime = 7.55852e-06
+PIC.Core.CS011HBA1.clockCorrectionTime = 7.55852e-06
+PIC.Core.CS011HBA.clockCorrectionTime  = 7.55852e-06
+
+PIC.Core.CS013LBA.clockCorrectionTime  = 9.47910e-06
+PIC.Core.CS013HBA0.clockCorrectionTime = 9.47910e-06
+PIC.Core.CS013HBA1.clockCorrectionTime = 9.47910e-06
+PIC.Core.CS013HBA.clockCorrectionTime  = 9.47910e-06
+
+PIC.Core.CS017LBA.clockCorrectionTime  = 1.540812e-05
+PIC.Core.CS017HBA0.clockCorrectionTime = 1.541095e-05
+PIC.Core.CS017HBA1.clockCorrectionTime = 1.541095e-05
+PIC.Core.CS017HBA.clockCorrectionTime  = 1.541095e-05
+
+PIC.Core.CS021LBA.clockCorrectionTime  = 6.044335e-06
+PIC.Core.CS021HBA0.clockCorrectionTime = 6.04963e-06
+PIC.Core.CS021HBA1.clockCorrectionTime = 6.04963e-06
+PIC.Core.CS021HBA.clockCorrectionTime  = 6.04963e-06
+
+PIC.Core.CS024LBA.clockCorrectionTime  = 4.66335e-06
+PIC.Core.CS024HBA0.clockCorrectionTime = 4.65857e-06
+PIC.Core.CS024HBA1.clockCorrectionTime = 4.65857e-06
+PIC.Core.CS024HBA.clockCorrectionTime  = 4.65857e-06
+
+PIC.Core.CS026LBA.clockCorrectionTime  = 1.620482e-05
+PIC.Core.CS026HBA0.clockCorrectionTime = 1.619948e-05
+PIC.Core.CS026HBA1.clockCorrectionTime = 1.619948e-05
+PIC.Core.CS026HBA.clockCorrectionTime  = 1.619948e-05
+
+PIC.Core.CS028LBA.clockCorrectionTime  = 1.6967048e-05
+PIC.Core.CS028HBA0.clockCorrectionTime = 1.6962571e-05
+PIC.Core.CS028HBA1.clockCorrectionTime = 1.6962571e-05
+PIC.Core.CS028HBA.clockCorrectionTime  = 1.6962571e-05
+
+PIC.Core.CS030LBA.clockCorrectionTime  = 9.7110576e-06
+PIC.Core.CS030HBA0.clockCorrectionTime = 9.7160576e-06
+PIC.Core.CS030HBA1.clockCorrectionTime = 9.7160576e-06
+PIC.Core.CS030HBA.clockCorrectionTime  = 9.7160576e-06
+
+PIC.Core.CS031LBA.clockCorrectionTime  = 6.375533e-06
+PIC.Core.CS031HBA0.clockCorrectionTime = 6.370090e-06
+PIC.Core.CS031HBA1.clockCorrectionTime = 6.370090e-06
+PIC.Core.CS031HBA.clockCorrectionTime  = 6.370090e-06
+
+PIC.Core.CS032LBA.clockCorrectionTime  = 8.541675e-06
+PIC.Core.CS032HBA0.clockCorrectionTime = 8.546255e-06
+PIC.Core.CS032HBA1.clockCorrectionTime = 8.546255e-06
+PIC.Core.CS032HBA.clockCorrectionTime  = 8.546255e-06
+
+PIC.Core.CS101LBA.clockCorrectionTime  = 1.5155471e-05
+PIC.Core.CS101HBA0.clockCorrectionTime = 1.5157971e-05
+PIC.Core.CS101HBA1.clockCorrectionTime = 1.5157971e-05
+PIC.Core.CS101HBA.clockCorrectionTime  = 1.5157971e-05
+
+PIC.Core.CS103LBA.clockCorrectionTime  = 3.5503206e-05
+PIC.Core.CS103HBA0.clockCorrectionTime = 3.5500922e-05
+PIC.Core.CS103HBA1.clockCorrectionTime = 3.5500922e-05
+PIC.Core.CS103HBA.clockCorrectionTime  = 3.5500922e-05
+
+PIC.Core.CS201LBA.clockCorrectionTime  = 1.745439e-05
+PIC.Core.CS201HBA0.clockCorrectionTime = 1.744924e-05
+PIC.Core.CS201HBA1.clockCorrectionTime = 1.744924e-05
+PIC.Core.CS201HBA.clockCorrectionTime  = 1.744924e-05
+
+PIC.Core.CS301LBA.clockCorrectionTime  = 7.685249e-06
+PIC.Core.CS301HBA0.clockCorrectionTime = 7.690431e-06
+PIC.Core.CS301HBA1.clockCorrectionTime = 7.690431e-06
+PIC.Core.CS301HBA.clockCorrectionTime  = 7.690431e-06
+
+PIC.Core.CS302LBA.clockCorrectionTime  = 1.2317004e-05
+PIC.Core.CS302HBA0.clockCorrectionTime = 1.2321604e-05
+PIC.Core.CS302HBA1.clockCorrectionTime = 1.2321604e-05
+PIC.Core.CS302HBA.clockCorrectionTime  = 1.2321604e-05
+
+PIC.Core.CS401LBA.clockCorrectionTime  = 8.052200e-06
+PIC.Core.CS401HBA0.clockCorrectionTime = 8.057504e-06
+PIC.Core.CS401HBA1.clockCorrectionTime = 8.057770e-06
+PIC.Core.CS401HBA.clockCorrectionTime  = 8.057637e-06
+
+PIC.Core.CS501LBA.clockCorrectionTime  = 1.65797e-05
+PIC.Core.CS501HBA0.clockCorrectionTime = 1.65842e-05
+PIC.Core.CS501HBA1.clockCorrectionTime = 1.65842e-05
+PIC.Core.CS501HBA.clockCorrectionTime  = 1.65842e-05
 
 #
 # Stations outside of the core (no correction needed)
 #
+
 PIC.Core.RS106LBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.clockCorrectionTime = 0
+
 PIC.Core.RS205LBA.clockCorrectionTime = 0
 PIC.Core.RS205HBA.clockCorrectionTime = 0
+
 PIC.Core.RS208LBA.clockCorrectionTime = 0
 PIC.Core.RS208HBA.clockCorrectionTime = 0
+
 PIC.Core.RS210LBA.clockCorrectionTime = 0
 PIC.Core.RS210HBA.clockCorrectionTime = 0
+
 PIC.Core.RS305LBA.clockCorrectionTime = 0
 PIC.Core.RS305HBA.clockCorrectionTime = 0
+
 PIC.Core.RS306LBA.clockCorrectionTime = 0
 PIC.Core.RS306HBA.clockCorrectionTime = 0
+
 PIC.Core.RS307LBA.clockCorrectionTime = 0
 PIC.Core.RS307HBA.clockCorrectionTime = 0
+
 PIC.Core.RS310LBA.clockCorrectionTime = 0
 PIC.Core.RS310HBA.clockCorrectionTime = 0
+
 PIC.Core.RS406LBA.clockCorrectionTime = 0
 PIC.Core.RS406HBA.clockCorrectionTime = 0
+
 PIC.Core.RS407LBA.clockCorrectionTime = 0
 PIC.Core.RS407HBA.clockCorrectionTime = 0
+
 PIC.Core.RS409LBA.clockCorrectionTime = 0
 PIC.Core.RS409HBA.clockCorrectionTime = 0
+
 PIC.Core.RS503LBA.clockCorrectionTime = 0
 PIC.Core.RS503HBA.clockCorrectionTime = 0
+
 PIC.Core.RS508LBA.clockCorrectionTime = 0
 PIC.Core.RS508HBA.clockCorrectionTime = 0
+
 PIC.Core.RS509LBA.clockCorrectionTime = 0
 PIC.Core.RS509HBA.clockCorrectionTime = 0
 
 # DE601 has a clock offset for unknown reasons
 PIC.Core.DE601LBA.clockCorrectionTime = 1.1e-6
 PIC.Core.DE601HBA.clockCorrectionTime = 1.1e-6
+
 PIC.Core.DE602LBA.clockCorrectionTime = 0
 PIC.Core.DE602HBA.clockCorrectionTime = 0
+
 PIC.Core.DE603LBA.clockCorrectionTime = 0
 PIC.Core.DE603HBA.clockCorrectionTime = 0
+
 PIC.Core.DE604LBA.clockCorrectionTime = 0
 PIC.Core.DE604HBA.clockCorrectionTime = 0
+
 PIC.Core.DE605LBA.clockCorrectionTime = 0
 PIC.Core.DE605HBA.clockCorrectionTime = 0
+
 PIC.Core.FR606LBA.clockCorrectionTime = 0
 PIC.Core.FR606HBA.clockCorrectionTime = 0
+
 PIC.Core.SE607LBA.clockCorrectionTime = 0
 PIC.Core.SE607HBA.clockCorrectionTime = 0
+
 PIC.Core.UK608LBA.clockCorrectionTime = 0
 PIC.Core.UK608HBA.clockCorrectionTime = 0
 
-
 #
 # Phase centers
 #
@@ -366,3 +385,4 @@ PIC.Core.SE607HBA.phaseCenter = [3370271.657, 712125.881, 5349991.165]
 
 PIC.Core.UK608LBA.phaseCenter = [4008438.457, -100309.725, 4943735.828]
 PIC.Core.UK608HBA.phaseCenter = [4008461.941, -100376.609, 4943716.874]
+
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationStreams.parset b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationStreams.parset
new file mode 100644
index 0000000000000000000000000000000000000000..2da60e245c556fb819121fdea99f53ab6fef53f9
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/StationStreams.parset
@@ -0,0 +1,336 @@
+PIC.Core.CS001LBA.RSP.receiver  = cbt007_0
+PIC.Core.CS001LBA.RSP.ports     = [udp:cbt007-10GB01:10010, udp:cbt007-10GB01:10011, udp:cbt007-10GB01:10012, udp:cbt007-10GB01:10013]
+PIC.Core.CS001HBA.RSP.receiver  = cbt007_0
+PIC.Core.CS001HBA.RSP.ports     = [udp:cbt007-10GB01:10010, udp:cbt007-10GB01:10011, udp:cbt007-10GB01:10012, udp:cbt007-10GB01:10013]
+PIC.Core.CS001HBA0.RSP.receiver = cbt007_0
+PIC.Core.CS001HBA0.RSP.ports    = [udp:cbt007-10GB01:10010, udp:cbt007-10GB01:10011, udp:cbt007-10GB01:10012, udp:cbt007-10GB01:10013]
+PIC.Core.CS001HBA1.RSP.receiver = cbt007_0
+PIC.Core.CS001HBA1.RSP.ports    = [udp:cbt007-10GB01:10016, udp:cbt007-10GB01:10017, udp:cbt007-10GB01:10018, udp:cbt007-10GB01:10019]
+
+PIC.Core.CS002LBA.RSP.receiver  = cbt003_0
+PIC.Core.CS002LBA.RSP.ports     = [udp:cbt003-10GB01:10020, udp:cbt003-10GB01:10021, udp:cbt003-10GB01:10022, udp:cbt003-10GB01:10023]
+PIC.Core.CS002HBA.RSP.receiver  = cbt003_0
+PIC.Core.CS002HBA.RSP.ports     = [udp:cbt003-10GB01:10020, udp:cbt003-10GB01:10021, udp:cbt003-10GB01:10022, udp:cbt003-10GB01:10023]
+PIC.Core.CS002HBA0.RSP.receiver = cbt003_0
+PIC.Core.CS002HBA0.RSP.ports    = [udp:cbt003-10GB01:10020, udp:cbt003-10GB01:10021, udp:cbt003-10GB01:10022, udp:cbt003-10GB01:10023]
+PIC.Core.CS002HBA1.RSP.receiver = cbt003_0
+PIC.Core.CS002HBA1.RSP.ports    = [udp:cbt003-10GB01:10026, udp:cbt003-10GB01:10027, udp:cbt003-10GB01:10028, udp:cbt003-10GB01:10029]
+
+PIC.Core.CS003LBA.RSP.receiver  = cbt005_0
+PIC.Core.CS003LBA.RSP.ports     = [udp:cbt005-10GB01:10030, udp:cbt005-10GB01:10031, udp:cbt005-10GB01:10032, udp:cbt005-10GB01:10033]
+PIC.Core.CS003HBA.RSP.receiver  = cbt005_0
+PIC.Core.CS003HBA.RSP.ports     = [udp:cbt005-10GB01:10030, udp:cbt005-10GB01:10031, udp:cbt005-10GB01:10032, udp:cbt005-10GB01:10033]
+PIC.Core.CS003HBA0.RSP.receiver = cbt005_0
+PIC.Core.CS003HBA0.RSP.ports    = [udp:cbt005-10GB01:10030, udp:cbt005-10GB01:10031, udp:cbt005-10GB01:10032, udp:cbt005-10GB01:10033]
+PIC.Core.CS003HBA1.RSP.receiver = cbt005_0
+PIC.Core.CS003HBA1.RSP.ports    = [udp:cbt005-10GB01:10036, udp:cbt005-10GB01:10037, udp:cbt005-10GB01:10038, udp:cbt005-10GB01:10039]
+
+PIC.Core.CS004LBA.RSP.receiver  = cbt008_0
+PIC.Core.CS004LBA.RSP.ports     = [udp:cbt008-10GB01:10040, udp:cbt008-10GB01:10041, udp:cbt008-10GB01:10042, udp:cbt008-10GB01:10043]
+PIC.Core.CS004HBA.RSP.receiver  = cbt008_0
+PIC.Core.CS004HBA.RSP.ports     = [udp:cbt008-10GB01:10040, udp:cbt008-10GB01:10041, udp:cbt008-10GB01:10042, udp:cbt008-10GB01:10043]
+PIC.Core.CS004HBA0.RSP.receiver = cbt008_0
+PIC.Core.CS004HBA0.RSP.ports    = [udp:cbt008-10GB01:10040, udp:cbt008-10GB01:10041, udp:cbt008-10GB01:10042, udp:cbt008-10GB01:10043]
+PIC.Core.CS004HBA1.RSP.receiver = cbt008_0
+PIC.Core.CS004HBA1.RSP.ports    = [udp:cbt008-10GB01:10046, udp:cbt008-10GB01:10047, udp:cbt008-10GB01:10048, udp:cbt008-10GB01:10049]
+
+PIC.Core.CS005LBA.RSP.receiver  = cbt001_0
+PIC.Core.CS005LBA.RSP.ports     = [udp:cbt001-10GB01:10050, udp:cbt001-10GB01:10051, udp:cbt001-10GB01:10052, udp:cbt001-10GB01:10053]
+PIC.Core.CS005HBA.RSP.receiver  = cbt001_0
+PIC.Core.CS005HBA.RSP.ports     = [udp:cbt001-10GB01:10050, udp:cbt001-10GB01:10051, udp:cbt001-10GB01:10052, udp:cbt001-10GB01:10053]
+PIC.Core.CS005HBA0.RSP.receiver = cbt001_0
+PIC.Core.CS005HBA0.RSP.ports    = [udp:cbt001-10GB01:10050, udp:cbt001-10GB01:10051, udp:cbt001-10GB01:10052, udp:cbt001-10GB01:10053]
+PIC.Core.CS005HBA1.RSP.receiver = cbt001_0
+PIC.Core.CS005HBA1.RSP.ports    = [udp:cbt001-10GB01:10056, udp:cbt001-10GB01:10057, udp:cbt001-10GB01:10058, udp:cbt001-10GB01:10059]
+
+PIC.Core.CS006LBA.RSP.receiver  = cbt004_0
+PIC.Core.CS006LBA.RSP.ports     = [udp:cbt004-10GB01:10060, udp:cbt004-10GB01:10061, udp:cbt004-10GB01:10062, udp:cbt004-10GB01:10063]
+PIC.Core.CS006HBA.RSP.receiver  = cbt004_0
+PIC.Core.CS006HBA.RSP.ports     = [udp:cbt004-10GB01:10060, udp:cbt004-10GB01:10061, udp:cbt004-10GB01:10062, udp:cbt004-10GB01:10063]
+PIC.Core.CS006HBA0.RSP.receiver = cbt004_0
+PIC.Core.CS006HBA0.RSP.ports    = [udp:cbt004-10GB01:10060, udp:cbt004-10GB01:10061, udp:cbt004-10GB01:10062, udp:cbt004-10GB01:10063]
+PIC.Core.CS006HBA1.RSP.receiver = cbt004_0
+PIC.Core.CS006HBA1.RSP.ports    = [udp:cbt004-10GB01:10066, udp:cbt004-10GB01:10067, udp:cbt004-10GB01:10068, udp:cbt004-10GB01:10069]
+
+PIC.Core.CS007LBA.RSP.receiver  = cbt006_0
+PIC.Core.CS007LBA.RSP.ports     = [udp:cbt006-10GB01:10070, udp:cbt006-10GB01:10071, udp:cbt006-10GB01:10072, udp:cbt006-10GB01:10073]
+PIC.Core.CS007HBA.RSP.receiver  = cbt006_0
+PIC.Core.CS007HBA.RSP.ports     = [udp:cbt006-10GB01:10070, udp:cbt006-10GB01:10071, udp:cbt006-10GB01:10072, udp:cbt006-10GB01:10073]
+PIC.Core.CS007HBA0.RSP.receiver = cbt006_0
+PIC.Core.CS007HBA0.RSP.ports    = [udp:cbt006-10GB01:10070, udp:cbt006-10GB01:10071, udp:cbt006-10GB01:10072, udp:cbt006-10GB01:10073]
+PIC.Core.CS007HBA1.RSP.receiver = cbt006_0
+PIC.Core.CS007HBA1.RSP.ports    = [udp:cbt006-10GB01:10076, udp:cbt006-10GB01:10077, udp:cbt006-10GB01:10078, udp:cbt006-10GB01:10079]
+
+PIC.Core.CS011LBA.RSP.receiver  = cbt003_0
+PIC.Core.CS011LBA.RSP.ports     = [udp:cbt003-10GB02:10110, udp:cbt003-10GB02:10111, udp:cbt003-10GB02:10112, udp:cbt003-10GB02:10113]
+PIC.Core.CS011HBA.RSP.receiver  = cbt003_0
+PIC.Core.CS011HBA.RSP.ports     = [udp:cbt003-10GB02:10110, udp:cbt003-10GB02:10111, udp:cbt003-10GB02:10112, udp:cbt003-10GB02:10113]
+PIC.Core.CS011HBA0.RSP.receiver = cbt003_0
+PIC.Core.CS011HBA0.RSP.ports    = [udp:cbt003-10GB02:10110, udp:cbt003-10GB02:10111, udp:cbt003-10GB02:10112, udp:cbt003-10GB02:10113]
+PIC.Core.CS011HBA1.RSP.receiver = cbt003_0
+PIC.Core.CS011HBA1.RSP.ports    = [udp:cbt003-10GB02:10116, udp:cbt003-10GB02:10117, udp:cbt003-10GB02:10118, udp:cbt003-10GB02:10119]
+
+PIC.Core.CS013LBA.RSP.receiver  = cbt005_0
+PIC.Core.CS013LBA.RSP.ports     = [udp:cbt005-10GB02:10130, udp:cbt005-10GB02:10131, udp:cbt005-10GB02:10132, udp:cbt005-10GB02:10133]
+PIC.Core.CS013HBA.RSP.receiver  = cbt005_0
+PIC.Core.CS013HBA.RSP.ports     = [udp:cbt005-10GB02:10130, udp:cbt005-10GB02:10131, udp:cbt005-10GB02:10132, udp:cbt005-10GB02:10133]
+PIC.Core.CS013HBA0.RSP.receiver = cbt005_0
+PIC.Core.CS013HBA0.RSP.ports    = [udp:cbt005-10GB02:10130, udp:cbt005-10GB02:10131, udp:cbt005-10GB02:10132, udp:cbt005-10GB02:10133]
+PIC.Core.CS013HBA1.RSP.receiver = cbt005_0
+PIC.Core.CS013HBA1.RSP.ports    = [udp:cbt005-10GB02:10136, udp:cbt005-10GB02:10137, udp:cbt005-10GB02:10138, udp:cbt005-10GB02:10139]
+
+PIC.Core.CS017LBA.RSP.receiver  = cbt002_0
+PIC.Core.CS017LBA.RSP.ports     = [udp:cbt002-10GB01:10170, udp:cbt002-10GB01:10171, udp:cbt002-10GB01:10172, udp:cbt002-10GB01:10173]
+PIC.Core.CS017HBA.RSP.receiver  = cbt002_0
+PIC.Core.CS017HBA.RSP.ports     = [udp:cbt002-10GB01:10170, udp:cbt002-10GB01:10171, udp:cbt002-10GB01:10172, udp:cbt002-10GB01:10173]
+PIC.Core.CS017HBA0.RSP.receiver = cbt002_0
+PIC.Core.CS017HBA0.RSP.ports    = [udp:cbt002-10GB01:10170, udp:cbt002-10GB01:10171, udp:cbt002-10GB01:10172, udp:cbt002-10GB01:10173]
+PIC.Core.CS017HBA1.RSP.receiver = cbt002_0
+PIC.Core.CS017HBA1.RSP.ports    = [udp:cbt002-10GB01:10176, udp:cbt002-10GB01:10177, udp:cbt002-10GB01:10178, udp:cbt002-10GB01:10179]
+
+PIC.Core.CS021LBA.RSP.receiver  = cbt001_0
+PIC.Core.CS021LBA.RSP.ports     = [udp:cbt001-10GB02:10210, udp:cbt001-10GB02:10211, udp:cbt001-10GB02:10212, udp:cbt001-10GB02:10213]
+PIC.Core.CS021HBA.RSP.receiver  = cbt001_0
+PIC.Core.CS021HBA.RSP.ports     = [udp:cbt001-10GB02:10210, udp:cbt001-10GB02:10211, udp:cbt001-10GB02:10212, udp:cbt001-10GB02:10213]
+PIC.Core.CS021HBA0.RSP.receiver = cbt001_0
+PIC.Core.CS021HBA0.RSP.ports    = [udp:cbt001-10GB02:10210, udp:cbt001-10GB02:10211, udp:cbt001-10GB02:10212, udp:cbt001-10GB02:10213]
+PIC.Core.CS021HBA1.RSP.receiver = cbt001_0
+PIC.Core.CS021HBA1.RSP.ports    = [udp:cbt001-10GB02:10216, udp:cbt001-10GB02:10217, udp:cbt001-10GB02:10218, udp:cbt001-10GB02:10219]
+
+PIC.Core.CS024LBA.RSP.receiver  = cbt007_0
+PIC.Core.CS024LBA.RSP.ports     = [udp:cbt007-10GB02:10240, udp:cbt007-10GB02:10241, udp:cbt007-10GB02:10242, udp:cbt007-10GB02:10243]
+PIC.Core.CS024HBA.RSP.receiver  = cbt007_0
+PIC.Core.CS024HBA.RSP.ports     = [udp:cbt007-10GB02:10240, udp:cbt007-10GB02:10241, udp:cbt007-10GB02:10242, udp:cbt007-10GB02:10243]
+PIC.Core.CS024HBA0.RSP.receiver = cbt007_0
+PIC.Core.CS024HBA0.RSP.ports    = [udp:cbt007-10GB02:10240, udp:cbt007-10GB02:10241, udp:cbt007-10GB02:10242, udp:cbt007-10GB02:10243]
+PIC.Core.CS024HBA1.RSP.receiver = cbt007_0
+PIC.Core.CS024HBA1.RSP.ports    = [udp:cbt007-10GB02:10246, udp:cbt007-10GB02:10247, udp:cbt007-10GB02:10248, udp:cbt007-10GB02:10249]
+
+PIC.Core.CS026LBA.RSP.receiver  = cbt004_0
+PIC.Core.CS026LBA.RSP.ports     = [udp:cbt004-10GB02:10260, udp:cbt004-10GB02:10261, udp:cbt004-10GB02:10262, udp:cbt004-10GB02:10263]
+PIC.Core.CS026HBA.RSP.receiver  = cbt004_0
+PIC.Core.CS026HBA.RSP.ports     = [udp:cbt004-10GB02:10260, udp:cbt004-10GB02:10261, udp:cbt004-10GB02:10262, udp:cbt004-10GB02:10263]
+PIC.Core.CS026HBA0.RSP.receiver = cbt004_0
+PIC.Core.CS026HBA0.RSP.ports    = [udp:cbt004-10GB02:10260, udp:cbt004-10GB02:10261, udp:cbt004-10GB02:10262, udp:cbt004-10GB02:10263]
+PIC.Core.CS026HBA1.RSP.receiver = cbt004_0
+PIC.Core.CS026HBA1.RSP.ports    = [udp:cbt004-10GB02:10266, udp:cbt004-10GB02:10267, udp:cbt004-10GB02:10268, udp:cbt004-10GB02:10269]
+
+PIC.Core.CS028LBA.RSP.receiver  = cbt003_1
+PIC.Core.CS028LBA.RSP.ports     = [udp:cbt003-10GB03:10280, udp:cbt003-10GB03:10281, udp:cbt003-10GB03:10282, udp:cbt003-10GB03:10283]
+PIC.Core.CS028HBA.RSP.receiver  = cbt003_1
+PIC.Core.CS028HBA.RSP.ports     = [udp:cbt003-10GB03:10280, udp:cbt003-10GB03:10281, udp:cbt003-10GB03:10282, udp:cbt003-10GB03:10283]
+PIC.Core.CS028HBA0.RSP.receiver = cbt003_1
+PIC.Core.CS028HBA0.RSP.ports    = [udp:cbt003-10GB03:10280, udp:cbt003-10GB03:10281, udp:cbt003-10GB03:10282, udp:cbt003-10GB03:10283]
+PIC.Core.CS028HBA1.RSP.receiver = cbt003_1
+PIC.Core.CS028HBA1.RSP.ports    = [udp:cbt003-10GB03:10286, udp:cbt003-10GB03:10287, udp:cbt003-10GB03:10288, udp:cbt003-10GB03:10289]
+
+PIC.Core.CS030LBA.RSP.receiver  = cbt006_0
+PIC.Core.CS030LBA.RSP.ports     = [udp:cbt006-10GB02:10300, udp:cbt006-10GB02:10301, udp:cbt006-10GB02:10302, udp:cbt006-10GB02:10303]
+PIC.Core.CS030HBA.RSP.receiver  = cbt006_0
+PIC.Core.CS030HBA.RSP.ports     = [udp:cbt006-10GB02:10300, udp:cbt006-10GB02:10301, udp:cbt006-10GB02:10302, udp:cbt006-10GB02:10303]
+PIC.Core.CS030HBA0.RSP.receiver = cbt006_0
+PIC.Core.CS030HBA0.RSP.ports    = [udp:cbt006-10GB02:10300, udp:cbt006-10GB02:10301, udp:cbt006-10GB02:10302, udp:cbt006-10GB02:10303]
+PIC.Core.CS030HBA1.RSP.receiver = cbt006_0
+PIC.Core.CS030HBA1.RSP.ports    = [udp:cbt006-10GB02:10306, udp:cbt006-10GB02:10307, udp:cbt006-10GB02:10308, udp:cbt006-10GB02:10309]
+
+PIC.Core.CS031LBA.RSP.receiver  = cbt004_1
+PIC.Core.CS031LBA.RSP.ports     = [udp:cbt004-10GB03:10310, udp:cbt004-10GB03:10311, udp:cbt004-10GB03:10312, udp:cbt004-10GB03:10313]
+PIC.Core.CS031HBA.RSP.receiver  = cbt004_1
+PIC.Core.CS031HBA.RSP.ports     = [udp:cbt004-10GB03:10310, udp:cbt004-10GB03:10311, udp:cbt004-10GB03:10312, udp:cbt004-10GB03:10313]
+PIC.Core.CS031HBA0.RSP.receiver = cbt004_1
+PIC.Core.CS031HBA0.RSP.ports    = [udp:cbt004-10GB03:10310, udp:cbt004-10GB03:10311, udp:cbt004-10GB03:10312, udp:cbt004-10GB03:10313]
+PIC.Core.CS031HBA1.RSP.receiver = cbt004_1
+PIC.Core.CS031HBA1.RSP.ports    = [udp:cbt004-10GB03:10316, udp:cbt004-10GB03:10317, udp:cbt004-10GB03:10318, udp:cbt004-10GB03:10319]
+
+PIC.Core.CS032LBA.RSP.receiver  = cbt002_0
+PIC.Core.CS032LBA.RSP.ports     = [udp:cbt002-10GB02:10320, udp:cbt002-10GB02:10321, udp:cbt002-10GB02:10322, udp:cbt002-10GB02:10323]
+PIC.Core.CS032HBA.RSP.receiver  = cbt002_0
+PIC.Core.CS032HBA.RSP.ports     = [udp:cbt002-10GB02:10320, udp:cbt002-10GB02:10321, udp:cbt002-10GB02:10322, udp:cbt002-10GB02:10323]
+PIC.Core.CS032HBA0.RSP.receiver = cbt002_0
+PIC.Core.CS032HBA0.RSP.ports    = [udp:cbt002-10GB02:10320, udp:cbt002-10GB02:10321, udp:cbt002-10GB02:10322, udp:cbt002-10GB02:10323]
+PIC.Core.CS032HBA1.RSP.receiver = cbt002_0
+PIC.Core.CS032HBA1.RSP.ports    = [udp:cbt002-10GB02:10326, udp:cbt002-10GB02:10327, udp:cbt002-10GB02:10328, udp:cbt002-10GB02:10329]
+
+PIC.Core.CS101LBA.RSP.receiver  = cbt001_1
+PIC.Core.CS101LBA.RSP.ports     = [udp:cbt001-10GB03:11010, udp:cbt001-10GB03:11011, udp:cbt001-10GB03:11012, udp:cbt001-10GB03:11013]
+PIC.Core.CS101HBA.RSP.receiver  = cbt001_1
+PIC.Core.CS101HBA.RSP.ports     = [udp:cbt001-10GB03:11010, udp:cbt001-10GB03:11011, udp:cbt001-10GB03:11012, udp:cbt001-10GB03:11013]
+PIC.Core.CS101HBA0.RSP.receiver = cbt001_1
+PIC.Core.CS101HBA0.RSP.ports    = [udp:cbt001-10GB03:11010, udp:cbt001-10GB03:11011, udp:cbt001-10GB03:11012, udp:cbt001-10GB03:11013]
+PIC.Core.CS101HBA1.RSP.receiver = cbt001_1
+PIC.Core.CS101HBA1.RSP.ports    = [udp:cbt001-10GB03:11016, udp:cbt001-10GB03:11017, udp:cbt001-10GB03:11018, udp:cbt001-10GB03:11019]
+
+PIC.Core.CS103LBA.RSP.receiver  = cbt008_0
+PIC.Core.CS103LBA.RSP.ports     = [udp:cbt008-10GB02:11030, udp:cbt008-10GB02:11031, udp:cbt008-10GB02:11032, udp:cbt008-10GB02:11033]
+PIC.Core.CS103HBA.RSP.receiver  = cbt008_0
+PIC.Core.CS103HBA.RSP.ports     = [udp:cbt008-10GB02:11030, udp:cbt008-10GB02:11031, udp:cbt008-10GB02:11032, udp:cbt008-10GB02:11033]
+PIC.Core.CS103HBA0.RSP.receiver = cbt008_0
+PIC.Core.CS103HBA0.RSP.ports    = [udp:cbt008-10GB02:11030, udp:cbt008-10GB02:11031, udp:cbt008-10GB02:11032, udp:cbt008-10GB02:11033]
+PIC.Core.CS103HBA1.RSP.receiver = cbt008_0
+PIC.Core.CS103HBA1.RSP.ports    = [udp:cbt008-10GB02:11036, udp:cbt008-10GB02:11037, udp:cbt008-10GB02:11038, udp:cbt008-10GB02:11039]
+
+PIC.Core.CS201LBA.RSP.receiver  = cbt003_0
+PIC.Core.CS201LBA.RSP.ports     = [udp:cbt003-10GB02:12010, udp:cbt003-10GB02:12011, udp:cbt003-10GB02:12012, udp:cbt003-10GB02:12013]
+PIC.Core.CS201HBA.RSP.receiver  = cbt003_0
+PIC.Core.CS201HBA.RSP.ports     = [udp:cbt003-10GB02:12010, udp:cbt003-10GB02:12011, udp:cbt003-10GB02:12012, udp:cbt003-10GB02:12013]
+PIC.Core.CS201HBA0.RSP.receiver = cbt003_0
+PIC.Core.CS201HBA0.RSP.ports    = [udp:cbt003-10GB02:12010, udp:cbt003-10GB02:12011, udp:cbt003-10GB02:12012, udp:cbt003-10GB02:12013]
+PIC.Core.CS201HBA1.RSP.receiver = cbt003_1
+PIC.Core.CS201HBA1.RSP.ports    = [udp:cbt003-10GB04:12016, udp:cbt003-10GB04:12017, udp:cbt003-10GB04:12018, udp:cbt003-10GB04:12019]
+
+PIC.Core.CS301LBA.RSP.receiver  = cbt005_1
+PIC.Core.CS301LBA.RSP.ports     = [udp:cbt005-10GB03:13010, udp:cbt005-10GB03:13011, udp:cbt005-10GB03:13012, udp:cbt005-10GB03:13013]
+PIC.Core.CS301HBA.RSP.receiver  = cbt005_1
+PIC.Core.CS301HBA.RSP.ports     = [udp:cbt005-10GB03:13010, udp:cbt005-10GB03:13011, udp:cbt005-10GB03:13012, udp:cbt005-10GB03:13013]
+PIC.Core.CS301HBA0.RSP.receiver = cbt005_1
+PIC.Core.CS301HBA0.RSP.ports    = [udp:cbt005-10GB03:13010, udp:cbt005-10GB03:13011, udp:cbt005-10GB03:13012, udp:cbt005-10GB03:13013]
+PIC.Core.CS301HBA1.RSP.receiver = cbt005_1
+PIC.Core.CS301HBA1.RSP.ports    = [udp:cbt005-10GB03:13016, udp:cbt005-10GB03:13017, udp:cbt005-10GB03:13018, udp:cbt005-10GB03:13019]
+
+PIC.Core.CS302LBA.RSP.receiver  = cbt004_1
+PIC.Core.CS302LBA.RSP.ports     = [udp:cbt004-10GB04:13020, udp:cbt004-10GB04:13021, udp:cbt004-10GB04:13022, udp:cbt004-10GB04:13023]
+PIC.Core.CS302HBA.RSP.receiver  = cbt004_1
+PIC.Core.CS302HBA.RSP.ports     = [udp:cbt004-10GB04:13020, udp:cbt004-10GB04:13021, udp:cbt004-10GB04:13022, udp:cbt004-10GB04:13023]
+PIC.Core.CS302HBA0.RSP.receiver = cbt004_1
+PIC.Core.CS302HBA0.RSP.ports    = [udp:cbt004-10GB04:13020, udp:cbt004-10GB04:13021, udp:cbt004-10GB04:13022, udp:cbt004-10GB04:13023]
+PIC.Core.CS302HBA1.RSP.receiver = cbt004_1
+PIC.Core.CS302HBA1.RSP.ports    = [udp:cbt004-10GB04:13026, udp:cbt004-10GB04:13027, udp:cbt004-10GB04:13028, udp:cbt004-10GB04:13029]
+
+PIC.Core.CS401LBA.RSP.receiver  = cbt007_1
+PIC.Core.CS401LBA.RSP.ports     = [udp:cbt007-10GB03:14010, udp:cbt007-10GB03:14011, udp:cbt007-10GB03:14012, udp:cbt007-10GB03:14013]
+PIC.Core.CS401HBA.RSP.receiver  = cbt007_1
+PIC.Core.CS401HBA.RSP.ports     = [udp:cbt007-10GB03:14010, udp:cbt007-10GB03:14011, udp:cbt007-10GB03:14012, udp:cbt007-10GB03:14013]
+PIC.Core.CS401HBA0.RSP.receiver = cbt007_1
+PIC.Core.CS401HBA0.RSP.ports    = [udp:cbt007-10GB03:14010, udp:cbt007-10GB03:14011, udp:cbt007-10GB03:14012, udp:cbt007-10GB03:14013]
+PIC.Core.CS401HBA1.RSP.receiver = cbt007_1
+PIC.Core.CS401HBA1.RSP.ports    = [udp:cbt007-10GB03:14016, udp:cbt007-10GB03:14017, udp:cbt007-10GB03:14018, udp:cbt007-10GB03:14019]
+
+PIC.Core.CS501LBA.RSP.receiver  = cbt006_1
+PIC.Core.CS501LBA.RSP.ports     = [udp:cbt006-10GB03:15010, udp:cbt006-10GB03:15011, udp:cbt006-10GB03:15012, udp:cbt006-10GB03:15013]
+PIC.Core.CS501HBA.RSP.receiver  = cbt006_1
+PIC.Core.CS501HBA.RSP.ports     = [udp:cbt006-10GB03:15010, udp:cbt006-10GB03:15011, udp:cbt006-10GB03:15012, udp:cbt006-10GB03:15013]
+PIC.Core.CS501HBA0.RSP.receiver = cbt006_1
+PIC.Core.CS501HBA0.RSP.ports    = [udp:cbt006-10GB03:15010, udp:cbt006-10GB03:15011, udp:cbt006-10GB03:15012, udp:cbt006-10GB03:15013]
+PIC.Core.CS501HBA1.RSP.receiver = cbt006_1
+PIC.Core.CS501HBA1.RSP.ports    = [udp:cbt006-10GB03:15016, udp:cbt006-10GB03:15017, udp:cbt006-10GB03:15018, udp:cbt006-10GB03:15019]
+
+PIC.Core.RS104LBA.RSP.receiver  = cbt002_1
+PIC.Core.RS104LBA.RSP.ports     = [udp:cbt002-10GB03:11040, udp:cbt002-10GB03:11041, udp:cbt002-10GB03:11042, udp:cbt002-10GB03:11043]
+PIC.Core.RS104HBA.RSP.receiver  = cbt002_1
+PIC.Core.RS104HBA.RSP.ports     = [udp:cbt002-10GB03:11040, udp:cbt002-10GB03:11041, udp:cbt002-10GB03:11042, udp:cbt002-10GB03:11043]
+
+PIC.Core.RS106LBA.RSP.receiver  = cbt008_1
+PIC.Core.RS106LBA.RSP.ports     = [udp:cbt008-10GB03:11060, udp:cbt008-10GB03:11061, udp:cbt008-10GB03:11062, udp:cbt008-10GB03:11063]
+PIC.Core.RS106HBA.RSP.receiver  = cbt008_1
+PIC.Core.RS106HBA.RSP.ports     = [udp:cbt008-10GB03:11060, udp:cbt008-10GB03:11061, udp:cbt008-10GB03:11062, udp:cbt008-10GB03:11063]
+
+PIC.Core.RS205LBA.RSP.receiver  = cbt007_1
+PIC.Core.RS205LBA.RSP.ports     = [udp:cbt007-10GB04:12050, udp:cbt007-10GB04:12051, udp:cbt007-10GB04:12052, udp:cbt007-10GB04:12053]
+PIC.Core.RS205HBA.RSP.receiver  = cbt007_1
+PIC.Core.RS205HBA.RSP.ports     = [udp:cbt007-10GB04:12050, udp:cbt007-10GB04:12051, udp:cbt007-10GB04:12052, udp:cbt007-10GB04:12053]
+
+PIC.Core.RS208LBA.RSP.receiver  = cbt001_1
+PIC.Core.RS208LBA.RSP.ports     = [udp:cbt001-10GB04:12080, udp:cbt001-10GB04:12081, udp:cbt001-10GB04:12082, udp:cbt001-10GB04:12083]
+PIC.Core.RS208HBA.RSP.receiver  = cbt001_1
+PIC.Core.RS208HBA.RSP.ports     = [udp:cbt001-10GB04:12080, udp:cbt001-10GB04:12081, udp:cbt001-10GB04:12082, udp:cbt001-10GB04:12083]
+
+PIC.Core.RS210LBA.RSP.receiver  = cbt005_1
+PIC.Core.RS210LBA.RSP.ports     = [udp:cbt005-10GB03:12100, udp:cbt005-10GB03:12101, udp:cbt005-10GB03:12102, udp:cbt005-10GB03:12103]
+PIC.Core.RS210HBA.RSP.receiver  = cbt005_1
+PIC.Core.RS210HBA.RSP.ports     = [udp:cbt005-10GB03:12100, udp:cbt005-10GB03:12101, udp:cbt005-10GB03:12102, udp:cbt005-10GB03:12103]
+
+PIC.Core.RS305LBA.RSP.receiver  = cbt006_1
+PIC.Core.RS305LBA.RSP.ports     = [udp:cbt006-10GB04:13050, udp:cbt006-10GB04:13051, udp:cbt006-10GB04:13052, udp:cbt006-10GB04:13053]
+PIC.Core.RS305HBA.RSP.receiver  = cbt006_1
+PIC.Core.RS305HBA.RSP.ports     = [udp:cbt006-10GB04:13050, udp:cbt006-10GB04:13051, udp:cbt006-10GB04:13052, udp:cbt006-10GB04:13053]
+
+PIC.Core.RS306LBA.RSP.receiver  = cbt005_0
+PIC.Core.RS306LBA.RSP.ports     = [udp:cbt005-10GB01:13060, udp:cbt005-10GB01:13061, udp:cbt005-10GB01:13062, udp:cbt005-10GB01:13063]
+PIC.Core.RS306HBA.RSP.receiver  = cbt005_0
+PIC.Core.RS306HBA.RSP.ports     = [udp:cbt005-10GB01:13060, udp:cbt005-10GB01:13061, udp:cbt005-10GB01:13062, udp:cbt005-10GB01:13063]
+
+PIC.Core.RS307LBA.RSP.receiver  = cbt008_1
+PIC.Core.RS307LBA.RSP.ports     = [udp:cbt008-10GB04:13070, udp:cbt008-10GB04:13071, udp:cbt008-10GB04:13072, udp:cbt008-10GB04:13073]
+PIC.Core.RS307HBA.RSP.receiver  = cbt008_1
+PIC.Core.RS307HBA.RSP.ports     = [udp:cbt008-10GB04:13070, udp:cbt008-10GB04:13071, udp:cbt008-10GB04:13072, udp:cbt008-10GB04:13073]
+
+PIC.Core.RS310LBA.RSP.receiver  = cbt002_1
+PIC.Core.RS310LBA.RSP.ports     = [udp:cbt002-10GB04:13100, udp:cbt002-10GB04:13101, udp:cbt002-10GB04:13102, udp:cbt002-10GB04:13103]
+PIC.Core.RS310HBA.RSP.receiver  = cbt002_1
+PIC.Core.RS310HBA.RSP.ports     = [udp:cbt002-10GB04:13100, udp:cbt002-10GB04:13101, udp:cbt002-10GB04:13102, udp:cbt002-10GB04:13103]
+
+PIC.Core.RS406LBA.RSP.receiver  = cbt007_1
+PIC.Core.RS406LBA.RSP.ports     = [udp:cbt007-10GB03:14060, udp:cbt007-10GB03:14061, udp:cbt007-10GB03:14062, udp:cbt007-10GB03:14063]
+PIC.Core.RS406HBA.RSP.receiver  = cbt007_1
+PIC.Core.RS406HBA.RSP.ports     = [udp:cbt007-10GB03:14060, udp:cbt007-10GB03:14061, udp:cbt007-10GB03:14062, udp:cbt007-10GB03:14063]
+
+PIC.Core.RS407LBA.RSP.receiver  = cbt001_1
+PIC.Core.RS407LBA.RSP.ports     = [udp:cbt001-10GB04:14070, udp:cbt001-10GB04:14071, udp:cbt001-10GB04:14072, udp:cbt001-10GB04:14073]
+PIC.Core.RS407HBA.RSP.receiver  = cbt001_1
+PIC.Core.RS407HBA.RSP.ports     = [udp:cbt001-10GB04:14070, udp:cbt001-10GB04:14071, udp:cbt001-10GB04:14072, udp:cbt001-10GB04:14073]
+
+PIC.Core.RS409LBA.RSP.receiver  = cbt002_1
+PIC.Core.RS409LBA.RSP.ports     = [udp:cbt002-10GB03:14090, udp:cbt002-10GB03:14091, udp:cbt002-10GB03:14092, udp:cbt002-10GB03:14093]
+PIC.Core.RS409HBA.RSP.receiver  = cbt002_1
+PIC.Core.RS409HBA.RSP.ports     = [udp:cbt002-10GB03:14090, udp:cbt002-10GB03:14091, udp:cbt002-10GB03:14092, udp:cbt002-10GB03:14093]
+
+PIC.Core.RS410LBA.RSP.receiver  = cbt002_1
+PIC.Core.RS410LBA.RSP.ports     = [udp:cbt002-10GB04:14100, udp:cbt002-10GB04:14101, udp:cbt002-10GB04:14102, udp:cbt002-10GB04:14103]
+PIC.Core.RS410HBA.RSP.receiver  = cbt002_1
+PIC.Core.RS410HBA.RSP.ports     = [udp:cbt002-10GB04:14100, udp:cbt002-10GB04:14101, udp:cbt002-10GB04:14102, udp:cbt002-10GB04:14103]
+
+PIC.Core.RS503LBA.RSP.receiver  = cbt006_1
+PIC.Core.RS503LBA.RSP.ports     = [udp:cbt006-10GB04:15030, udp:cbt006-10GB04:15031, udp:cbt006-10GB04:15032, udp:cbt006-10GB04:15033]
+PIC.Core.RS503HBA.RSP.receiver  = cbt006_1
+PIC.Core.RS503HBA.RSP.ports     = [udp:cbt006-10GB04:15030, udp:cbt006-10GB04:15031, udp:cbt006-10GB04:15032, udp:cbt006-10GB04:15033]
+
+PIC.Core.RS508LBA.RSP.receiver  = cbt008_1
+PIC.Core.RS508LBA.RSP.ports     = [udp:cbt008-10GB03:15080, udp:cbt008-10GB03:15081, udp:cbt008-10GB03:15082, udp:cbt008-10GB03:15083]
+PIC.Core.RS508HBA.RSP.receiver  = cbt008_1
+PIC.Core.RS508HBA.RSP.ports     = [udp:cbt008-10GB03:15080, udp:cbt008-10GB03:15081, udp:cbt008-10GB03:15082, udp:cbt008-10GB03:15083]
+
+PIC.Core.RS509LBA.RSP.receiver  = cbt007_1
+PIC.Core.RS509LBA.RSP.ports     = [udp:cbt007-10GB04:15090, udp:cbt007-10GB04:15091, udp:cbt007-10GB04:15092, udp:cbt007-10GB04:15093]
+PIC.Core.RS509HBA.RSP.receiver  = cbt007_1
+PIC.Core.RS509HBA.RSP.ports     = [udp:cbt007-10GB04:15090, udp:cbt007-10GB04:15091, udp:cbt007-10GB04:15092, udp:cbt007-10GB04:15093]
+
+PIC.Core.DE601LBA.RSP.receiver  = cbt008_1
+PIC.Core.DE601LBA.RSP.ports     = [udp:cbt008-10GB04:16010, udp:cbt008-10GB04:16011, udp:cbt008-10GB04:16012, udp:cbt008-10GB04:16013]
+PIC.Core.DE601HBA.RSP.receiver  = cbt008_1
+PIC.Core.DE601HBA.RSP.ports     = [udp:cbt008-10GB04:16010, udp:cbt008-10GB04:16011, udp:cbt008-10GB04:16012, udp:cbt008-10GB04:16013]
+
+PIC.Core.DE602LBA.RSP.receiver  = cbt003_1
+PIC.Core.DE602LBA.RSP.ports     = [udp:cbt003-10GB04:16020, udp:cbt003-10GB04:16021, udp:cbt003-10GB04:16022, udp:cbt003-10GB04:16023]
+PIC.Core.DE602HBA.RSP.receiver  = cbt003_1
+PIC.Core.DE602HBA.RSP.ports     = [udp:cbt003-10GB04:16020, udp:cbt003-10GB04:16021, udp:cbt003-10GB04:16022, udp:cbt003-10GB04:16023]
+
+PIC.Core.DE603LBA.RSP.receiver  = cbt004_1
+PIC.Core.DE603LBA.RSP.ports     = [udp:cbt004-10GB04:16030, udp:cbt004-10GB04:16031, udp:cbt004-10GB04:16032, udp:cbt004-10GB04:16033]
+PIC.Core.DE603HBA.RSP.receiver  = cbt004_1
+PIC.Core.DE603HBA.RSP.ports     = [udp:cbt004-10GB04:16030, udp:cbt004-10GB04:16031, udp:cbt004-10GB04:16032, udp:cbt004-10GB04:16033]
+
+PIC.Core.DE604LBA.RSP.receiver  = cbt003_1
+PIC.Core.DE604LBA.RSP.ports     = [udp:cbt003-10GB04:16040, udp:cbt003-10GB04:16041, udp:cbt003-10GB04:16042, udp:cbt003-10GB04:16043]
+PIC.Core.DE604HBA.RSP.receiver  = cbt003_1
+PIC.Core.DE604HBA.RSP.ports     = [udp:cbt003-10GB04:16040, udp:cbt003-10GB04:16041, udp:cbt003-10GB04:16042, udp:cbt003-10GB04:16043]
+
+PIC.Core.DE605LBA.RSP.receiver  = cbt008_1
+PIC.Core.DE605LBA.RSP.ports     = [udp:cbt008-10GB04:16050, udp:cbt008-10GB04:16051, udp:cbt008-10GB04:16052, udp:cbt008-10GB04:16053]
+PIC.Core.DE605HBA.RSP.receiver  = cbt008_1
+PIC.Core.DE605HBA.RSP.ports     = [udp:cbt008-10GB04:16050, udp:cbt008-10GB04:16051, udp:cbt008-10GB04:16052, udp:cbt008-10GB04:16053]
+
+PIC.Core.FR606LBA.RSP.receiver  = cbt005_1
+PIC.Core.FR606LBA.RSP.ports     = [udp:cbt005-10GB04:16060, udp:cbt005-10GB04:16061, udp:cbt005-10GB04:16062, udp:cbt005-10GB04:16063]
+PIC.Core.FR606HBA.RSP.receiver  = cbt005_1
+PIC.Core.FR606HBA.RSP.ports     = [udp:cbt005-10GB04:16060, udp:cbt005-10GB04:16061, udp:cbt005-10GB04:16062, udp:cbt005-10GB04:16063]
+
+PIC.Core.SE607LBA.RSP.receiver  = cbt006_1
+PIC.Core.SE607LBA.RSP.ports     = [udp:cbt006-10GB04:16070, udp:cbt006-10GB04:16071, udp:cbt006-10GB04:16072, udp:cbt006-10GB04:16073]
+PIC.Core.SE607HBA.RSP.receiver  = cbt006_1
+PIC.Core.SE607HBA.RSP.ports     = [udp:cbt006-10GB04:16070, udp:cbt006-10GB04:16071, udp:cbt006-10GB04:16072, udp:cbt006-10GB04:16073]
+
+PIC.Core.UK608LBA.RSP.receiver  = cbt005_1
+PIC.Core.UK608LBA.RSP.ports     = [udp:cbt005-10GB04:16080, udp:cbt005-10GB04:16081, udp:cbt005-10GB04:16082, udp:cbt005-10GB04:16083]
+PIC.Core.UK608HBA.RSP.receiver  = cbt005_1
+PIC.Core.UK608HBA.RSP.ports     = [udp:cbt005-10GB04:16080, udp:cbt005-10GB04:16081, udp:cbt005-10GB04:16082, udp:cbt005-10GB04:16083]
+
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/generateStationStreams.sh b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/generateStationStreams.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0408c4f8bc9e9acc5061c4b5a4ed2d679df01864
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/default/generateStationStreams.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+#
+# Usage: ./generateStationStreams.sh > StationStreams.parset
+#
+# Requires:
+#   RSPConnections_Cobalt.dat
+#   MAC+IP.dat
+#
+# The RSPConnections_Cobalt.dat and MAC+IP.dat files can be found in
+#   MAC/Deployment/data/StaticMetaData
+#
+
+cat RSPConnections_Cobalt.dat | perl -ne '
+
+/^(\w+) RSP_([01]) (.*)/ || next;
+
+$station = $1;
+$board = $2;
+$host = $3;
+
+$station =~ /^[A-Z][A-Z]([0-9]+)/;
+$nr = $1;
+
+# only parse cobalt nodes
+$host =~ /^cbt/ || next;
+
+if (not $cached) {
+  %lookup = {};
+  %rlookup = {};
+
+  open $fh, "MAC+IP.dat"
+    or die "Cannot open MAC+IP.dat";
+
+  while($line = <$fh>) {
+    next if $line =~ /^#/;
+    ($name, $ip, $mac) = split(/\s+/, $line);
+
+    $lookup{$name} = $ip;
+    $rlookup{$ip}  = $rlookup{$ip} || $name;
+  }
+
+  close $fh;
+
+  $cached = 1;
+}
+
+$dest = $lookup{$host};
+$iface = $rlookup{$dest};
+$baseport = 10000 + $nr * 10;
+
+$portstr = sprintf "[udp:%s:%d, udp:%s:%d, udp:%s:%d, udp:%s:%d]",
+  $iface, $baseport + ($board * 6) + 0,
+  $iface, $baseport + ($board * 6) + 1,
+  $iface, $baseport + ($board * 6) + 2,
+  $iface, $baseport + ($board * 6) + 3;
+
+$iface =~ /(cbt[0-9]+)-10GB0([1234])/;
+$host = $1;
+$ifnr = $2;
+$receiver = sprintf "%s_%u", $host, ($ifnr - 1)/2;
+
+if ($board == 0) {
+  printf "PIC.Core.%sLBA.RSP.receiver  = %s\n",$station,$receiver;
+  printf "PIC.Core.%sLBA.RSP.ports     = %s\n",$station,$portstr;
+
+  printf "PIC.Core.%sHBA.RSP.receiver  = %s\n",$station,$receiver;
+  printf "PIC.Core.%sHBA.RSP.ports     = %s\n",$station,$portstr;
+
+  if ($station =~ /^CS/) {
+    printf "PIC.Core.%sHBA0.RSP.receiver = %s\n",$station,$receiver;
+    printf "PIC.Core.%sHBA0.RSP.ports    = %s\n",$station,$portstr;
+  } else {
+    print "\n";
+  }
+}
+
+if ($board == 1) {
+  printf "PIC.Core.%sHBA1.RSP.receiver = %s\n",$station,$receiver;
+  printf "PIC.Core.%sHBA1.RSP.ports    = %s\n",$station,$portstr;
+  print "\n";
+}
+
+'
+
+
diff --git a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/generateHardwareMap.sh b/RTCP/Cobalt/GPUProc/etc/parset-additions.d/generateHardwareMap.sh
deleted file mode 100755
index 47a649c3d0d5603892785db222c40a3a6a300381..0000000000000000000000000000000000000000
--- a/RTCP/Cobalt/GPUProc/etc/parset-additions.d/generateHardwareMap.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-#
-# Usage: ./generateHardwareMap.sh > CobaltHardwareMap.parset
-
-perl -e '
-
-open $fh, "StationStreams.parset"
-  or die "Cannot open StationStreams.parset";
-
-$numhosts = 8;
-$numranks = $numhosts * 2;
-
-for $rank (1..$numranks) {
-  push @stations, "";
-}
-
-while ($line = <$fh>) {
-  next unless $line =~ /PIC.Core.Station.([A-Z0-9]+).RSP.ports = \[udp:10.168.([0-9]+).([1234])/;
-
-  $station = $1;
-  $hostnr = $2 - 95;
-  $ifacenr = $3;
-
-  if ($ifacenr == 1 or $ifacenr == 2) {
-    $socket = 0;
-  } else {
-    $socket = 1;
-  }
-
-  $rank = ($hostnr - 1) * 2 + $socket;
-
-  if ($stations[$rank] ne "") {
-    $stations[$rank] .= ", ";
-  }
-  $stations[$rank] .= $station;
-}
-
-printf "Cobalt.Hardware.nrNodes=%s\n", $numranks;
-
-for $rank (0 .. $numranks-1) {
-  $hostnr = $rank / 2 + 1;
-  $socket = $rank % 2;
-  $firstgpu = $socket * 2;
-  $secondgpu = $firstgpu + 1;
-
-  printf "Cobalt.Hardware.Node[%s].host=cbm%03d\n", $rank, $hostnr;
-  printf "Cobalt.Hardware.Node[%s].cpu=%d\n", $rank, $socket;
-  printf "Cobalt.Hardware.Node[%s].gpus=[%d, %d]\n", $rank, $firstgpu, $secondgpu;
-  printf "Cobalt.Hardware.Node[%s].stations=[%s]\n", $rank, $stations[$rank];
-}
-'
diff --git a/RTCP/Cobalt/GPUProc/share/gpu/kernels/Correlator.cu b/RTCP/Cobalt/GPUProc/share/gpu/kernels/Correlator.cu
index 2372691841444f99af814537efc5ad689ea49a4b..be9a118b0ef3bc3c94871b6db56a7301a67aa665 100644
--- a/RTCP/Cobalt/GPUProc/share/gpu/kernels/Correlator.cu
+++ b/RTCP/Cobalt/GPUProc/share/gpu/kernels/Correlator.cu
@@ -54,6 +54,16 @@ typedef float4 fcomplex2;
 typedef fcomplex2 (*CorrectedDataType)[NR_STATIONS][NR_CHANNELS][NR_SAMPLES_PER_CHANNEL];
 typedef fcomplex (*VisibilitiesType)[NR_BASELINES][NR_CHANNELS][NR_POLARIZATIONS][NR_POLARIZATIONS];
 
+/*
+ * Return baseline major-minor.
+ *
+ * Note that major >= minor >= 0 must hold.
+ */
+inline __device__ int baseline(int major, int minor)
+{
+  return major * (major + 1) / 2 + minor;
+}
+
 extern "C" {
 
 /*!
@@ -101,7 +111,7 @@ __global__ void correlate(void *visibilitiesPtr, const void *correctedDataPtr)
 
   __shared__ float samples[4][BLOCK_SIZE][NR_STATIONS | 1]; // avoid power-of-2
 
-  uint baseline = blockIdx.x * blockDim.x + threadIdx.x;
+  int baseline = blockIdx.x * blockDim.x + threadIdx.x;
 
 #if NR_CHANNELS == 1
   uint channel = blockIdx.y;
@@ -110,39 +120,46 @@ __global__ void correlate(void *visibilitiesPtr, const void *correctedDataPtr)
 #endif
 
   /*
+   * Baselines are ordered like:
+   *   0-0, 1-0, 1-1, 2-0, 2-1, 2-2, ...
+   *
    * if 
    *   b = baseline
    *   x = stat1
    *   y = stat2
-   *   x <= y
+   *   x >= y
    * then
-   *   b_xy = y * (y + 1) / 2 + x
+   *   b_xy = x * (x + 1) / 2 + y
    * let
-   *   u := b_0y
+   *   u := b_x0
    * then
-   *     u            = y * (y + 1) / 2
-   *     8u           = 4y^2 + 4y
-   *     8u + 1       = 4y^2 + 4y + 1 = (2y + 1)^2
-   *     sqrt(8u + 1) = 2y + 1
-   *                y = (sqrt(8u + 1) - 1) / 2
+   *     u            = x * (x + 1) / 2
+   *     8u           = 4x^2 + 4x
+   *     8u + 1       = 4x^2 + 4x + 1 = (2x + 1)^2
+   *     sqrt(8u + 1) = 2x + 1
+   *                x = (sqrt(8u + 1) - 1) / 2
    *
    * Let us define
-   *   y'(b) = (sqrt(8b + 1) - 1) / 2
+   *   x'(b) = (sqrt(8b + 1) - 1) / 2
    * which increases monotonically and is a continuation of y(b).
    *
    * Because y simply increases by 1 when b increases enough, we
    * can just take the floor function to obtain the discrete y(b):
-   *   y(b) = floor(y'(b))
+   *   x(b) = floor(x'(b))
    *        = floor(sqrt(8b + 1) - 1) / 2)
    */
 
-  uint stat_A = __float2uint_rz(sqrtf(float(8 * baseline + 1)) - 0.99999f) / 2;
+  int x = __float2uint_rz(sqrtf(float(8 * baseline + 1)) - 0.99999f) / 2;
 
   /*
    * And, of course
-   *  x = b - y * (y + 1)/2
+   *  y = b - x * (x + 1)/2
    */
-  uint stat_0 = baseline - stat_A * (stat_A + 1) / 2;
+  int y = baseline - x * (x + 1) / 2;
+
+  // NOTE: stat0 >= statA holds
+  int stat_0 = x;
+  int stat_A = y;
 
   // visR and visI will contain the real and imaginary parts, respectively, of
   // the four visibilities (i.e., the four correlation products between the two
@@ -173,11 +190,12 @@ __global__ void correlate(void *visibilitiesPtr, const void *correctedDataPtr)
     // compute correlations
     if (baseline < NR_BASELINES) {
       for (uint time = 0; time < BLOCK_SIZE; time++) {
-        fcomplex2 sample_1, sample_A;
-        sample_1.x = samples[0][time][stat_0]; // sample1_X_r
-        sample_1.y = samples[1][time][stat_0]; // sample1_X_i
-        sample_1.z = samples[2][time][stat_0]; // sample1_Y_r
-        sample_1.w = samples[3][time][stat_0]; // sample1_Y_i
+        fcomplex2 sample_0, sample_A;
+
+        sample_0.x = samples[0][time][stat_0]; // sample0_X_r
+        sample_0.y = samples[1][time][stat_0]; // sample0_X_i
+        sample_0.z = samples[2][time][stat_0]; // sample0_Y_r
+        sample_0.w = samples[3][time][stat_0]; // sample0_Y_i
         sample_A.x = samples[0][time][stat_A]; // sampleA_X_r
         sample_A.y = samples[1][time][stat_A]; // sampleA_X_i
         sample_A.z = samples[2][time][stat_A]; // sampleA_Y_r
@@ -185,10 +203,10 @@ __global__ void correlate(void *visibilitiesPtr, const void *correctedDataPtr)
 
         // Interleave calculation of the two parts of the real and imaginary
         // visibilities to improve performance.
-        visR += SWIZZLE(sample_1,x,x,z,z) * SWIZZLE(sample_A,x,z,x,z); 
-        visI += SWIZZLE(sample_1,y,y,w,w) * SWIZZLE(sample_A,x,z,x,z);
-        visR += SWIZZLE(sample_1,y,y,w,w) * SWIZZLE(sample_A,y,w,y,w);
-        visI -= SWIZZLE(sample_1,x,x,z,z) * SWIZZLE(sample_A,y,w,y,w);
+        visR += SWIZZLE(sample_0,x,x,z,z) * SWIZZLE(sample_A,x,z,x,z); 
+        visI += SWIZZLE(sample_0,y,y,w,w) * SWIZZLE(sample_A,x,z,x,z);
+        visR += SWIZZLE(sample_0,y,y,w,w) * SWIZZLE(sample_A,y,w,y,w);
+        visI -= SWIZZLE(sample_0,x,x,z,z) * SWIZZLE(sample_A,y,w,y,w);
       }
     }
 
@@ -229,12 +247,14 @@ __global__ void correlate_2x2(void *visibilitiesPtr, const void *correctedDataPt
 #endif
 
   /* uint x = convert_uint_rtz(sqrt(convert_float(8 * block + 1)) - 0.99999f) / 2; */
-  uint x = __float2uint_rz(sqrtf(float(8 * block + 1)) - 0.99999f) / 2;
-  uint y = block - x * (x + 1) / 2;
+  int x = __float2uint_rz(sqrtf(float(8 * block + 1)) - 0.99999f) / 2;
+  int y = block - x * (x + 1) / 2;
 
-  uint stat_A = 2 * x;
+  // NOTE: stat_0 >= stat_A holds
+  int stat_0 = 2 * x;
+  int stat_A = 2 * y;
 
-  bool compute_correlations = stat_A < NR_STATIONS;
+  bool compute_correlations = stat_0 < NR_STATIONS;
 
   /* float4 vis_0A_r = (float4) 0, vis_0A_i = (float4) 0; */
   /* float4 vis_0B_r = (float4) 0, vis_0B_i = (float4) 0; */
@@ -307,16 +327,15 @@ __global__ void correlate_2x2(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   // write visibilities
-  uint stat_0 = 2 * y;
-  uint stat_1 = stat_0 + 1;
-  uint stat_B = stat_A + 1;
-  bool do_baseline_0A = stat_A < NR_STATIONS;
-  bool do_baseline_0B = stat_B < NR_STATIONS;
-  bool do_baseline_1A = do_baseline_0A && stat_1 <= stat_A;
-  bool do_baseline_1B = do_baseline_0B;
+  int stat_1 = stat_0 + 1;
+  int stat_B = stat_A + 1;
+  bool do_baseline_0A = stat_0 < NR_STATIONS;// stat_0 >= stat_A holds
+  bool do_baseline_0B = stat_0 < NR_STATIONS && stat_0 >= stat_B;
+  bool do_baseline_1A = stat_1 < NR_STATIONS;// stat_1 > stat_0 >= stat_A holds
+  bool do_baseline_1B = stat_1 < NR_STATIONS;// stat_1 = stat_0 + 1 >= stat_A + 1 = stat_B holds
 
   if (do_baseline_0A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0A_r.x, vis_0A_i.x, vis_0A_r.y, vis_0A_i.y, vis_0A_r.z, vis_0A_i.z, vis_0A_r.w, vis_0A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0A_r.x, vis_0A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0A_r.y, vis_0A_i.y);
@@ -325,7 +344,7 @@ __global__ void correlate_2x2(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0B_r.x, vis_0B_i.x, vis_0B_r.y, vis_0B_i.y, vis_0B_r.z, vis_0B_i.z, vis_0B_r.w, vis_0B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0B_r.x, vis_0B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0B_r.y, vis_0B_i.y);
@@ -334,7 +353,7 @@ __global__ void correlate_2x2(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1A_r.x, vis_1A_i.x, vis_1A_r.y, vis_1A_i.y, vis_1A_r.z, vis_1A_i.z, vis_1A_r.w, vis_1A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1A_r.x, vis_1A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1A_r.y, vis_1A_i.y);
@@ -343,7 +362,7 @@ __global__ void correlate_2x2(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1B_r.x, vis_1B_i.x, vis_1B_r.y, vis_1B_i.y, vis_1B_r.z, vis_1B_i.z, vis_1B_r.w, vis_1B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1B_r.x, vis_1B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1B_r.y, vis_1B_i.y);
@@ -379,9 +398,11 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   uint x = __float2uint_rz(sqrtf(float(8 * block + 1)) - 0.99999f) / 2;
   uint y = block - x * (x + 1) / 2;
 
-  uint stat_A = 3 * x;
+  // NOTE: stat_0 >= stat_A holds
+  int stat_0 = 3 * x;
+  int stat_A = 3 * y;
 
-  bool compute_correlations = stat_A < NR_STATIONS;
+  bool compute_correlations = stat_0 < NR_STATIONS;
 
   float4 vis_0A_r = {0, 0, 0, 0}, vis_0A_i = {0, 0, 0, 0};
   float4 vis_0B_r = {0, 0, 0, 0}, vis_0B_i = {0, 0, 0, 0};
@@ -497,24 +518,23 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   // write visibilities
-  uint stat_0 = 3 * y;
-  uint stat_1 = stat_0 + 1;
-  uint stat_2 = stat_0 + 2;
-  uint stat_B = stat_A + 1;
-  uint stat_C = stat_A + 2;
-
-  bool do_baseline_0A = stat_0 < NR_STATIONS && stat_A < NR_STATIONS && stat_0 <= stat_A;
-  bool do_baseline_0B = stat_0 < NR_STATIONS && stat_B < NR_STATIONS && stat_0 <= stat_B;
-  bool do_baseline_0C = stat_0 < NR_STATIONS && stat_C < NR_STATIONS && stat_0 <= stat_C;
-  bool do_baseline_1A = stat_1 < NR_STATIONS && stat_A < NR_STATIONS && stat_1 <= stat_A;
-  bool do_baseline_1B = stat_1 < NR_STATIONS && stat_B < NR_STATIONS && stat_1 <= stat_B;
-  bool do_baseline_1C = stat_1 < NR_STATIONS && stat_C < NR_STATIONS && stat_1 <= stat_C;
-  bool do_baseline_2A = stat_2 < NR_STATIONS && stat_A < NR_STATIONS && stat_2 <= stat_A;
-  bool do_baseline_2B = stat_2 < NR_STATIONS && stat_B < NR_STATIONS && stat_2 <= stat_B;
-  bool do_baseline_2C = stat_2 < NR_STATIONS && stat_C < NR_STATIONS && stat_2 <= stat_C;
+  int stat_1 = stat_0 + 1;
+  int stat_2 = stat_0 + 2;
+  int stat_B = stat_A + 1;
+  int stat_C = stat_A + 2;
+
+  bool do_baseline_0A = stat_0 < NR_STATIONS && stat_A < NR_STATIONS;// stat_0 >= stat_A holds
+  bool do_baseline_0B = stat_0 < NR_STATIONS && stat_B < NR_STATIONS && stat_0 >= stat_B;
+  bool do_baseline_0C = stat_0 < NR_STATIONS && stat_C < NR_STATIONS && stat_0 >= stat_C;
+  bool do_baseline_1A = stat_1 < NR_STATIONS && stat_A < NR_STATIONS;// stat_1 >= stat_A holds
+  bool do_baseline_1B = stat_1 < NR_STATIONS && stat_B < NR_STATIONS;// stat_1 >= stat_B holds
+  bool do_baseline_1C = stat_1 < NR_STATIONS && stat_C < NR_STATIONS && stat_1 >= stat_C;
+  bool do_baseline_2A = stat_2 < NR_STATIONS && stat_A < NR_STATIONS;// stat_2 >= stat_A holds
+  bool do_baseline_2B = stat_2 < NR_STATIONS && stat_B < NR_STATIONS;// stat_2 >= stat_B holds
+  bool do_baseline_2C = stat_2 < NR_STATIONS && stat_C < NR_STATIONS;// stat_2 >= stat_C holds
 
   if (do_baseline_0A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0A_r.x, vis_0A_i.x, vis_0A_r.y, vis_0A_i.y, vis_0A_r.z, vis_0A_i.z, vis_0A_r.w, vis_0A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0A_r.x, vis_0A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0A_r.y, vis_0A_i.y);
@@ -523,7 +543,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0B_r.x, vis_0B_i.x, vis_0B_r.y, vis_0B_i.y, vis_0B_r.z, vis_0B_i.z, vis_0B_r.w, vis_0B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0B_r.x, vis_0B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0B_r.y, vis_0B_i.y);
@@ -532,7 +552,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0C_r.x, vis_0C_i.x, vis_0C_r.y, vis_0C_i.y, vis_0C_r.z, vis_0C_i.z, vis_0C_r.w, vis_0C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0C_r.x, vis_0C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0C_r.y, vis_0C_i.y);
@@ -541,7 +561,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1A_r.x, vis_1A_i.x, vis_1A_r.y, vis_1A_i.y, vis_1A_r.z, vis_1A_i.z, vis_1A_r.w, vis_1A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1A_r.x, vis_1A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1A_r.y, vis_1A_i.y);
@@ -550,7 +570,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1B_r.x, vis_1B_i.x, vis_1B_r.y, vis_1B_i.y, vis_1B_r.z, vis_1B_i.z, vis_1B_r.w, vis_1B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1B_r.x, vis_1B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1B_r.y, vis_1B_i.y);
@@ -559,7 +579,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1C_r.x, vis_1C_i.x, vis_1C_r.y, vis_1C_i.y, vis_1C_r.z, vis_1C_i.z, vis_1C_r.w, vis_1C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1C_r.x, vis_1C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1C_r.y, vis_1C_i.y);
@@ -568,7 +588,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2A_r.x, vis_2A_i.x, vis_2A_r.y, vis_2A_i.y, vis_2A_r.z, vis_2A_i.z, vis_2A_r.w, vis_2A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2A_r.x, vis_2A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2A_r.y, vis_2A_i.y);
@@ -577,7 +597,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2B_r.x, vis_2B_i.x, vis_2B_r.y, vis_2B_i.y, vis_2B_r.z, vis_2B_i.z, vis_2B_r.w, vis_2B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2B_r.x, vis_2B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2B_r.y, vis_2B_i.y);
@@ -586,7 +606,7 @@ __global__ void correlate_3x3(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2C_r.x, vis_2C_i.x, vis_2C_r.y, vis_2C_i.y, vis_2C_r.z, vis_2C_i.z, vis_2C_r.w, vis_2C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2C_r.x, vis_2C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2C_r.y, vis_2C_i.y);
@@ -619,12 +639,14 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
 #endif
 
   /* uint x = convert_uint_rtz(sqrt(convert_float(8 * block + 1)) - 0.99999f) / 2; */
-  uint x = __float2uint_rz(sqrtf(float(8 * block + 1)) - 0.99999f) / 2;
-  uint y = block - x * (x + 1) / 2;
+  int x = __float2uint_rz(sqrtf(float(8 * block + 1)) - 0.99999f) / 2;
+  int y = block - x * (x + 1) / 2;
 
-  uint stat_A = 4 * x;
+  // NOTE: stat_0 >= stat_A holds
+  int stat_0 = 4 * y;
+  int stat_A = 4 * x;
 
-  bool compute_correlations = stat_A < NR_STATIONS;
+  bool compute_correlations = stat_0 < NR_STATIONS;
 
   /* float4 vis_0A_r = (float4) 0, vis_0A_i = (float4) 0; */
   /* float4 vis_0B_r = (float4) 0, vis_0B_i = (float4) 0; */
@@ -821,33 +843,32 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   // write visibilities
-  uint stat_0 = 4 * y;
-  uint stat_1 = stat_0 + 1;
-  uint stat_2 = stat_0 + 2;
-  uint stat_3 = stat_0 + 3;
-  uint stat_B = stat_A + 1;
-  uint stat_C = stat_A + 2;
-  uint stat_D = stat_A + 3;
-
-  bool do_baseline_0A = stat_0 < NR_STATIONS && stat_A < NR_STATIONS && stat_0 <= stat_A;
-  bool do_baseline_0B = stat_0 < NR_STATIONS && stat_B < NR_STATIONS && stat_0 <= stat_B;
-  bool do_baseline_0C = stat_0 < NR_STATIONS && stat_C < NR_STATIONS && stat_0 <= stat_C;
-  bool do_baseline_0D = stat_0 < NR_STATIONS && stat_D < NR_STATIONS && stat_0 <= stat_D;
-  bool do_baseline_1A = stat_1 < NR_STATIONS && stat_A < NR_STATIONS && stat_1 <= stat_A;
-  bool do_baseline_1B = stat_1 < NR_STATIONS && stat_B < NR_STATIONS && stat_1 <= stat_B;
-  bool do_baseline_1C = stat_1 < NR_STATIONS && stat_C < NR_STATIONS && stat_1 <= stat_C;
-  bool do_baseline_1D = stat_1 < NR_STATIONS && stat_D < NR_STATIONS && stat_1 <= stat_D;
-  bool do_baseline_2A = stat_2 < NR_STATIONS && stat_A < NR_STATIONS && stat_2 <= stat_A;
-  bool do_baseline_2B = stat_2 < NR_STATIONS && stat_B < NR_STATIONS && stat_2 <= stat_B;
-  bool do_baseline_2C = stat_2 < NR_STATIONS && stat_C < NR_STATIONS && stat_2 <= stat_C;
-  bool do_baseline_2D = stat_2 < NR_STATIONS && stat_D < NR_STATIONS && stat_2 <= stat_D;
-  bool do_baseline_3A = stat_3 < NR_STATIONS && stat_A < NR_STATIONS && stat_3 <= stat_A;
-  bool do_baseline_3B = stat_3 < NR_STATIONS && stat_B < NR_STATIONS && stat_3 <= stat_B;
-  bool do_baseline_3C = stat_3 < NR_STATIONS && stat_C < NR_STATIONS && stat_3 <= stat_C;
-  bool do_baseline_3D = stat_3 < NR_STATIONS && stat_D < NR_STATIONS && stat_3 <= stat_D;
+  int stat_1 = stat_0 + 1;
+  int stat_2 = stat_0 + 2;
+  int stat_3 = stat_0 + 3;
+  int stat_B = stat_A + 1;
+  int stat_C = stat_A + 2;
+  int stat_D = stat_A + 3;
+
+  bool do_baseline_0A = stat_0 < NR_STATIONS && stat_A < NR_STATIONS;// stat_0 >= stat_A holds
+  bool do_baseline_0B = stat_0 < NR_STATIONS && stat_B < NR_STATIONS && stat_0 >= stat_B;
+  bool do_baseline_0C = stat_0 < NR_STATIONS && stat_C < NR_STATIONS && stat_0 >= stat_C;
+  bool do_baseline_0D = stat_0 < NR_STATIONS && stat_D < NR_STATIONS && stat_0 >= stat_D;
+  bool do_baseline_1A = stat_1 < NR_STATIONS && stat_A < NR_STATIONS;// stat_1 >= stat_A holds
+  bool do_baseline_1B = stat_1 < NR_STATIONS && stat_B < NR_STATIONS;// stat_1 >= stat_B holds
+  bool do_baseline_1C = stat_1 < NR_STATIONS && stat_C < NR_STATIONS && stat_1 >= stat_C;
+  bool do_baseline_1D = stat_1 < NR_STATIONS && stat_D < NR_STATIONS && stat_1 >= stat_D;
+  bool do_baseline_2A = stat_2 < NR_STATIONS && stat_A < NR_STATIONS;// stat_2 >= stat_A holds
+  bool do_baseline_2B = stat_2 < NR_STATIONS && stat_B < NR_STATIONS;// stat_2 >= stat_B holds
+  bool do_baseline_2C = stat_2 < NR_STATIONS && stat_C < NR_STATIONS;// stat_2 >= stat_C holds
+  bool do_baseline_2D = stat_2 < NR_STATIONS && stat_D < NR_STATIONS && stat_2 >= stat_D;
+  bool do_baseline_3A = stat_3 < NR_STATIONS && stat_A < NR_STATIONS;// stat_3 >= stat_A holds
+  bool do_baseline_3B = stat_3 < NR_STATIONS && stat_B < NR_STATIONS;// stat_3 >= stat_B holds
+  bool do_baseline_3C = stat_3 < NR_STATIONS && stat_C < NR_STATIONS;// stat_3 >= stat_C holds
+  bool do_baseline_3D = stat_3 < NR_STATIONS && stat_D < NR_STATIONS;// stat_3 >= stat_D holds
 
   if (do_baseline_0A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0A_r.x, vis_0A_i.x, vis_0A_r.y, vis_0A_i.y, vis_0A_r.z, vis_0A_i.z, vis_0A_r.w, vis_0A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0A_r.x, vis_0A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0A_r.y, vis_0A_i.y);
@@ -856,7 +877,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0B_r.x, vis_0B_i.x, vis_0B_r.y, vis_0B_i.y, vis_0B_r.z, vis_0B_i.z, vis_0B_r.w, vis_0B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0B_r.x, vis_0B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0B_r.y, vis_0B_i.y);
@@ -865,7 +886,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0C_r.x, vis_0C_i.x, vis_0C_r.y, vis_0C_i.y, vis_0C_r.z, vis_0C_i.z, vis_0C_r.w, vis_0C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0C_r.x, vis_0C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0C_r.y, vis_0C_i.y);
@@ -874,7 +895,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_0D) {
-    uint baseline = (stat_D * (stat_D + 1) / 2) + stat_0;
+    int baseline = ::baseline(stat_0, stat_D);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_0D_r.x, vis_0D_i.x, vis_0D_r.y, vis_0D_i.y, vis_0D_r.z, vis_0D_i.z, vis_0D_r.w, vis_0D_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_0D_r.x, vis_0D_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_0D_r.y, vis_0D_i.y);
@@ -883,7 +904,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1A_r.x, vis_1A_i.x, vis_1A_r.y, vis_1A_i.y, vis_1A_r.z, vis_1A_i.z, vis_1A_r.w, vis_1A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1A_r.x, vis_1A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1A_r.y, vis_1A_i.y);
@@ -892,7 +913,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1B_r.x, vis_1B_i.x, vis_1B_r.y, vis_1B_i.y, vis_1B_r.z, vis_1B_i.z, vis_1B_r.w, vis_1B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1B_r.x, vis_1B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1B_r.y, vis_1B_i.y);
@@ -901,7 +922,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1C_r.x, vis_1C_i.x, vis_1C_r.y, vis_1C_i.y, vis_1C_r.z, vis_1C_i.z, vis_1C_r.w, vis_1C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1C_r.x, vis_1C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1C_r.y, vis_1C_i.y);
@@ -910,7 +931,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_1D) {
-    uint baseline = (stat_D * (stat_D + 1) / 2) + stat_1;
+    int baseline = ::baseline(stat_1, stat_D);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_1D_r.x, vis_1D_i.x, vis_1D_r.y, vis_1D_i.y, vis_1D_r.z, vis_1D_i.z, vis_1D_r.w, vis_1D_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_1D_r.x, vis_1D_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_1D_r.y, vis_1D_i.y);
@@ -919,7 +940,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2A_r.x, vis_2A_i.x, vis_2A_r.y, vis_2A_i.y, vis_2A_r.z, vis_2A_i.z, vis_2A_r.w, vis_2A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2A_r.x, vis_2A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2A_r.y, vis_2A_i.y);
@@ -928,7 +949,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2B_r.x, vis_2B_i.x, vis_2B_r.y, vis_2B_i.y, vis_2B_r.z, vis_2B_i.z, vis_2B_r.w, vis_2B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2B_r.x, vis_2B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2B_r.y, vis_2B_i.y);
@@ -937,7 +958,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2C_r.x, vis_2C_i.x, vis_2C_r.y, vis_2C_i.y, vis_2C_r.z, vis_2C_i.z, vis_2C_r.w, vis_2C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2C_r.x, vis_2C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2C_r.y, vis_2C_i.y);
@@ -946,7 +967,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_2D) {
-    uint baseline = (stat_D * (stat_D + 1) / 2) + stat_2;
+    int baseline = ::baseline(stat_2, stat_D);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_2D_r.x, vis_2D_i.x, vis_2D_r.y, vis_2D_i.y, vis_2D_r.z, vis_2D_i.z, vis_2D_r.w, vis_2D_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_2D_r.x, vis_2D_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_2D_r.y, vis_2D_i.y);
@@ -955,7 +976,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_3A) {
-    uint baseline = (stat_A * (stat_A + 1) / 2) + stat_3;
+    int baseline = ::baseline(stat_3, stat_A);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_3A_r.x, vis_3A_i.x, vis_3A_r.y, vis_3A_i.y, vis_3A_r.z, vis_3A_i.z, vis_3A_r.w, vis_3A_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_3A_r.x, vis_3A_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_3A_r.y, vis_3A_i.y);
@@ -964,7 +985,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_3B) {
-    uint baseline = (stat_B * (stat_B + 1) / 2) + stat_3;
+    int baseline = ::baseline(stat_3, stat_B);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_3B_r.x, vis_3B_i.x, vis_3B_r.y, vis_3B_i.y, vis_3B_r.z, vis_3B_i.z, vis_3B_r.w, vis_3B_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_3B_r.x, vis_3B_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_3B_r.y, vis_3B_i.y);
@@ -973,7 +994,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_3C) {
-    uint baseline = (stat_C * (stat_C + 1) / 2) + stat_3;
+    int baseline = ::baseline(stat_3, stat_C);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_3C_r.x, vis_3C_i.x, vis_3C_r.y, vis_3C_i.y, vis_3C_r.z, vis_3C_i.z, vis_3C_r.w, vis_3C_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_3C_r.x, vis_3C_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_3C_r.y, vis_3C_i.y);
@@ -982,7 +1003,7 @@ __global__ void correlate_4x4(void *visibilitiesPtr, const void *correctedDataPt
   }
 
   if (do_baseline_3D) {
-    uint baseline = (stat_D * (stat_D + 1) / 2) + stat_3;
+    int baseline = ::baseline(stat_3, stat_D);
     /* (*visibilities)[baseline][channel] = (fcomplex4) { vis_3D_r.x, vis_3D_i.x, vis_3D_r.y, vis_3D_i.y, vis_3D_r.z, vis_3D_i.z, vis_3D_r.w, vis_3D_i.w }; */
     (*visibilities)[baseline][channel][0][0] = make_float2(vis_3D_r.x, vis_3D_i.x);
     (*visibilities)[baseline][channel][0][1] = make_float2(vis_3D_r.y, vis_3D_i.y);
diff --git a/RTCP/Cobalt/GPUProc/share/gpu/kernels/DelayAndBandPass.cu b/RTCP/Cobalt/GPUProc/share/gpu/kernels/DelayAndBandPass.cu
index 9a93592ead3f2dae29c3451010bd3b0b5491bd49..1c66682509f056ac3e99558e51fa984f914111bc 100644
--- a/RTCP/Cobalt/GPUProc/share/gpu/kernels/DelayAndBandPass.cu
+++ b/RTCP/Cobalt/GPUProc/share/gpu/kernels/DelayAndBandPass.cu
@@ -82,9 +82,24 @@ typedef  char_complex  (* InputDataType)[NR_STATIONS][NR_SAMPLES_PER_SUBBAND][NR
 typedef  fcomplex (* InputDataType)[NR_STATIONS][NR_POLARIZATIONS][NR_SAMPLES_PER_CHANNEL][NR_CHANNELS];
 #endif
 typedef  const double (* DelaysType)[NR_SAPS][NR_STATIONS][NR_POLARIZATIONS]; // 2 Polarizations; in seconds
-typedef  const double (* PhaseOffsetsType)[NR_STATIONS][NR_POLARIZATIONS]; // 2 Polarizations; in radians
+typedef  const double2 (* Phase0sType)[NR_STATIONS]; // 2 Polarizations; in radians
 typedef  const float (* BandPassFactorsType)[NR_CHANNELS];
 
+inline __device__ fcomplex sincos_f2f(float phi)
+{
+  float2 r;
+
+  sincosf(phi, &r.y, &r.x);
+  return r;
+}
+
+inline __device__ fcomplex sincos_d2f(double phi)
+{
+  double s, c;
+
+  sincos(phi, &s, &c);
+  return make_float2(c, s);
+}
 
 /**
  * This kernel performs (up to) three operations on the input data:
@@ -113,8 +128,8 @@ typedef  const float (* BandPassFactorsType)[NR_CHANNELS];
  *                                 a 2D array [beam][station] of float2 (real:
  *                                 2 polarizations), containing delays in
  *                                 seconds after end of integration period
- * @param[in]  phaseOffsetsPtr     pointer to phase offset data of
- *                                 ::PhaseOffsetsType, a 1D array [station] of
+ * @param[in]  phase0sPt     r     pointer to phase offset data of
+ *                                 ::Phase0sType, a 1D array [station] of
  *                                 float2 (real: 2 polarizations), containing
  *                                 phase offsets in radians
  * @param[in]  bandPassFactorsPtr  pointer to bandpass correction data of
@@ -129,116 +144,112 @@ extern "C" {
                                                 unsigned beam,
                                                 const double * delaysAtBeginPtr,
                                                 const double * delaysAfterEndPtr,
-                                                const double * phaseOffsetsPtr,
+                                                const double * phase0sPtr,
                                                 const float * bandPassFactorsPtr)
 {
   OutputDataType outputData = (OutputDataType) correctedDataPtr;
   InputDataType inputData   = (InputDataType)  filteredDataPtr;
-#if defined DELAY_COMPENSATION
-  DelaysType delaysAtBegin  = (DelaysType) delaysAtBeginPtr;
-  DelaysType delaysAfterEnd = (DelaysType) delaysAfterEndPtr;
-  PhaseOffsetsType phaseOffsets = (PhaseOffsetsType) phaseOffsetsPtr;
-#endif
 
-#if defined BANDPASS_CORRECTION
-  BandPassFactorsType bandPassFactors = (BandPassFactorsType) bandPassFactorsPtr;
-#endif
+  /* The x dimension is 256 wide. */
+  const unsigned major   = (blockIdx.x * blockDim.x + threadIdx.x) / 16;
+  const unsigned minor   = (blockIdx.x * blockDim.x + threadIdx.x) % 16;
 
-#if NR_CHANNELS > 1
-  unsigned major       = (blockIdx.x * blockDim.x + threadIdx.x) / 16;
-  unsigned minor       = (blockIdx.x * blockDim.x + threadIdx.x) % 16;
-  unsigned channelBase = (blockIdx.y * blockDim.y + threadIdx.y) * 16;
+  /* The y dimension is NR_CHANNELS/16 wide (or 1 if NR_CHANNELS == 1) */
+  const unsigned channel = NR_CHANNELS == 1 ? 0 : (blockIdx.y * blockDim.y + threadIdx.y) * 16 + minor;
 
-  unsigned channel = channelBase + minor;
-#endif
-  unsigned station =  blockIdx.z * blockDim.z + threadIdx.z;
-
-#if defined DELAY_COMPENSATION
-#if NR_CHANNELS == 1
-  double frequency = subbandFrequency;
-#else
-  double frequency = subbandFrequency - 0.5 * SUBBAND_BANDWIDTH + channel * (SUBBAND_BANDWIDTH / NR_CHANNELS);
-#endif
-  double2 delayAtBegin  = make_double2((*delaysAtBegin) [beam][station][0], (*delaysAtBegin) [beam][station][1]);
-  double2 delayAfterEnd = make_double2((*delaysAfterEnd)[beam][station][0], (*delaysAfterEnd)[beam][station][1]);
+  /* The z dimension is NR_STATIONS wide. */
+  const unsigned station =  blockIdx.z * blockDim.z + threadIdx.z;
 
+  const unsigned timeStart = NR_CHANNELS == 1 ? threadIdx.x : major;
+  const unsigned timeInc   = NR_CHANNELS == 1 ? blockDim.x  : 16;
 
-  // Convert the fraction of sample duration (delayAtBegin/delayAfterEnd) to fractions of a circle.
-  // Because we `undo' the delay, we need to rotate BACK.
-  const double pi2 = -6.28318530717958647688; // -2.0 * M_PI
-  double2 phiBegin = make_double2(pi2 * delayAtBegin.x,  pi2 * delayAtBegin.y);
-  double2 phiEnd   = make_double2(pi2 * delayAfterEnd.x, pi2 * delayAfterEnd.y);
+#if defined BANDPASS_CORRECTION
+  BandPassFactorsType bandPassFactors = (BandPassFactorsType) bandPassFactorsPtr;
 
-  double2 deltaPhi = make_double2((phiEnd.x - phiBegin.x) / NR_SAMPLES_PER_CHANNEL,
-                                  (phiEnd.y - phiBegin.y) / NR_SAMPLES_PER_CHANNEL);   
-  
-#if NR_CHANNELS == 1
-  double2 myPhiBegin = make_double2(
-                        (phiBegin.x + double(threadIdx.x) * deltaPhi.x) * frequency + (*phaseOffsets)[station][0],
-                        (phiBegin.y + double(threadIdx.x) * deltaPhi.y) * frequency + (*phaseOffsets)[station][1]);
-  double2 myPhiDelta = make_double2(
-                         double(blockDim.x) * deltaPhi.x * frequency,
-                         double(blockDim.x) * deltaPhi.y * frequency);
-#else
-  double2 myPhiBegin = make_double2(
-                          (phiBegin.x + double(major) * deltaPhi.x) * frequency + (*phaseOffsets)[station][0],
-                          (phiBegin.y + double(major) * deltaPhi.y) * frequency + (*phaseOffsets)[station][1]);
-  // Magic constant 16 is the time step we take in the samples
-  double2 myPhiDelta = make_double2(16.0 * deltaPhi.x * frequency,
-                                    16.0 * deltaPhi.y * frequency);
+  float weight((*bandPassFactors)[channel]);
 #endif
 
-  dcomplex vX, vY, dvX, dvY; // store (cos(), sin())
-  sincos(myPhiBegin.x, &vX.y,  &vX.x);
-  sincos(myPhiBegin.y, &vY.y,  &vY.x);
-  sincos(myPhiDelta.x, &dvX.y, &dvX.x);
-  sincos(myPhiDelta.y, &dvY.y, &dvY.x);
-#endif
+#if defined DELAY_COMPENSATION
+  DelaysType delaysAtBegin  = (DelaysType) delaysAtBeginPtr;
+  DelaysType delaysAfterEnd = (DelaysType) delaysAfterEndPtr;
+  Phase0sType phase0s = (Phase0sType) phase0sPtr;
 
-#if defined BANDPASS_CORRECTION
-  float weight((*bandPassFactors)[channel]);
-#endif
+  /*
+   * Delay compensation means rotating the phase of each sample BACK.
+   *
+   * n     = channel number (f.e. 0 .. 255)
+   * f_n   = channel frequency of channel n
+   * f_ref = base frequency of subband (f.e. 200 MHz)
+   * df    = delta frequency of 1 channel (f.e. 768 Hz)
+   *
+   * f_n := f_ref + n * df
+   *
+   * m      = sample number (f.e. 0 .. 3071)
+   * tau_m  = delay at sample m
+   * tau_0  = delayAtBegin (f.e. -2.56us .. +2.56us)
+   * dtau   = delta delay for 1 sample (f.e. <= 1.6ns)
+   *
+   * tau_m := tau_0 + m * dtau
+   *
+   * Then, the required phase shift is:
+   *
+   *   phi_mn = -2 * pi * f_n * tau_m
+   *          = -2 * pi * (f_ref + n * df) * (tau_0 + m * dtau)
+   *          = -2 * pi * (f_ref * tau_0 + f_ref * m * dtau + tau_0 * n * df + m * n * df * dtau)
+   *                       -------------   ----------------   --------------   -----------------
+   *                           O(100)           O(0.1)            O(0.01)          O(0.001)
+   *
+   * Finally, we also want to correct for fixed phase offsets per station,
+   * as given by the phase0 array.
+   */
 
-#if defined DELAY_COMPENSATION && defined BANDPASS_CORRECTION
-  vX.x *= weight;
-  vX.y *= weight;
-  vY.x *= weight;
-  vY.y *= weight;
-#endif
+  const double frequency = NR_CHANNELS == 1
+    ? subbandFrequency
+    : subbandFrequency - 0.5 * SUBBAND_BANDWIDTH + channel * (SUBBAND_BANDWIDTH / NR_CHANNELS);
 
-#if defined DELAY_COMPENSATION
-  fcomplex fvX, fvY, fdvX, fdvY;
-  fvX = make_float2(vX.x, vX.y);
-  fvY = make_float2(vY.x, vY.y);
-  fdvX = make_float2(dvX.x, dvX.y);
-  fdvY = make_float2(dvY.x, dvY.y);
+  const double2 delayAtBegin  = make_double2((*delaysAtBegin) [beam][station][0], (*delaysAtBegin) [beam][station][1]);
+  const double2 delayAfterEnd = make_double2((*delaysAfterEnd)[beam][station][0], (*delaysAfterEnd)[beam][station][1]);
+
+  // Calculate the angles to rotate for for the first and (beyond the) last sample.
+  //
+  // We need to undo the delay, so we rotate BACK, resulting in a negative constant factor.
+  const double2 phiAtBegin  = -2.0 * M_PI * frequency * delayAtBegin  - (*phase0s)[station];
+  const double2 phiAfterEnd = -2.0 * M_PI * frequency * delayAfterEnd - (*phase0s)[station];
 #endif
 
-#if NR_CHANNELS == 1
-  for (unsigned time = threadIdx.x; time < NR_SAMPLES_PER_SUBBAND; time += blockDim.x)
+  for (unsigned time = timeStart; time < NR_SAMPLES_PER_CHANNEL; time += timeInc)
   {
-    rawSampleType sampleXraw = (*inputData)[station][time][0];
+#if NR_CHANNELS == 1
+    const rawSampleType sampleXraw = (*inputData)[station][time][0];
     fcomplex sampleX = make_float2(convertIntToFloat(sampleXraw.x),
                                    convertIntToFloat(sampleXraw.y));
-    rawSampleType sampleYraw = (*inputData)[station][time][1];
+    const rawSampleType sampleYraw = (*inputData)[station][time][1];
     fcomplex sampleY = make_float2(convertIntToFloat(sampleYraw.x),
                                    convertIntToFloat(sampleYraw.y));
 #else
-  for (unsigned timeBase = 0; timeBase < NR_SAMPLES_PER_CHANNEL; timeBase += 16)
-  {
-    unsigned time = timeBase + major;
-
     fcomplex sampleX = (*inputData)[station][0][time][channel];
     fcomplex sampleY = (*inputData)[station][1][time][channel];
 #endif
 
 #if defined DELAY_COMPENSATION    
-    sampleX = sampleX * fvX;
-    sampleY = sampleY * fvY;
-    // The calculations are with exponentional complex for: multiplication for correct phase shift
-    fvX = fvX * fdvX;
-    fvY = fvY * fdvY;
-#elif defined BANDPASS_CORRECTION
+    // Offset of this sample between begin and end.
+    const double timeOffset = double(time) / NR_SAMPLES_PER_CHANNEL;
+
+    // Interpolate the required phase rotation for this sample.
+    //
+    // Single precision angle + sincos is measured to be good enough (2013-11-20).
+    // Note that we do the interpolation in double precision still.
+    // We can afford to if we keep this kernel memory bound.
+    const float2 phi  = make_float2( phiAtBegin.x  * (1.0 - timeOffset)
+                                   + phiAfterEnd.x *        timeOffset,
+                                     phiAtBegin.y  * (1.0 - timeOffset)
+                                   + phiAfterEnd.y *        timeOffset );
+
+    sampleX = sampleX * sincos_f2f(phi.x);
+    sampleY = sampleY * sincos_f2f(phi.y);
+#endif
+
+#if defined BANDPASS_CORRECTION
     sampleX.x *= weight;
     sampleX.y *= weight;
     sampleY.x *= weight;
@@ -253,8 +264,8 @@ extern "C" {
     tmp[major][minor][0] = sampleX;
     tmp[major][minor][1] = sampleY;
     __syncthreads();
-    (*outputData)[station][channelBase + major][timeBase + minor][0] = tmp[minor][major][0];
-    (*outputData)[station][channelBase + major][timeBase + minor][1] = tmp[minor][major][1];
+    (*outputData)[station][channel - minor + major][time - major + minor][0] = tmp[minor][major][0];
+    (*outputData)[station][channel - minor + major][time - major + minor][1] = tmp[minor][major][1];
     __syncthreads();
 #elif NR_CHANNELS == 1 && defined DO_TRANSPOSE
     (*outputData)[station][0][time][0] = sampleX;
diff --git a/RTCP/Cobalt/GPUProc/share/gpu/kernels/gpu_math.cuh b/RTCP/Cobalt/GPUProc/share/gpu/kernels/gpu_math.cuh
index 2cf502d23c0a7996b66edfb564f2069bc8477545..3331dac3eda901a536c5a768ee882b39a69b9433 100644
--- a/RTCP/Cobalt/GPUProc/share/gpu/kernels/gpu_math.cuh
+++ b/RTCP/Cobalt/GPUProc/share/gpu/kernels/gpu_math.cuh
@@ -97,22 +97,52 @@ inline __device__ fcomplex operator+(fcomplex a, fcomplex b)
   return make_float2(a.x + b.x, a.y + b.y);
 }
 
+inline __device__ dcomplex operator+(dcomplex a, dcomplex b)
+{
+  return make_double2(a.x + b.x, a.y + b.y);
+}
+
+inline __device__ fcomplex operator-(fcomplex a, fcomplex b)
+{
+  return make_float2(a.x - b.x, a.y - b.y);
+}
+
+inline __device__ dcomplex operator-(dcomplex a, dcomplex b)
+{
+  return make_double2(a.x - b.x, a.y - b.y);
+}
+
 inline __device__ fcomplex operator*(fcomplex a, fcomplex b)
 {
   return make_float2(a.x * b.x - a.y * b.y,
                      a.x * b.y + a.y * b.x);
 }
 
+inline __device__ dcomplex operator*(dcomplex a, dcomplex b)
+{
+  return make_double2(a.x * b.x - a.y * b.y,
+                      a.x * b.y + a.y * b.x);
+}
+
 inline __device__ fcomplex operator*(fcomplex a, float b)
 {
   return make_float2(a.x * b, a.y * b);
 }
 
+inline __device__ dcomplex operator*(dcomplex a, double b)
+{
+  return make_double2(a.x * b, a.y * b);
+}
+
 inline __device__ fcomplex operator*(float a, fcomplex b)
 {
   return make_float2(a * b.x, a * b.y);
 }
 
+inline __device__ dcomplex operator*(double a, dcomplex b)
+{
+  return make_double2(a * b.x, a * b.y);
+}
 
 inline __device__ dcomplex dphaseShift(double frequency, double delay)
 {
diff --git a/RTCP/Cobalt/GPUProc/src/CMakeLists.txt b/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
index d722402fec901b5dd1fa7c574588bf7b0ea44054..d235101b3ad8f5a2df74ccebb28bd23a7af00322 100644
--- a/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
+++ b/RTCP/Cobalt/GPUProc/src/CMakeLists.txt
@@ -14,6 +14,8 @@ set(_gpuproc_sources
   FilterBank.cc
   global_defines.cc
   RunningStatistics.cc
+  Package__Version.cc
+  SysInfoLogger.cc
   Station/StationNodeAllocation.cc
   Station/StationInput.cc
   Storage/SSH.cc
@@ -111,6 +113,7 @@ if(USE_OPENCL)
 endif()
 
 lofar_add_bin_program(mpi_node_list Station/mpi_node_list.cc)
+lofar_add_bin_program(station_stream Station/station_stream.cc)
 
 # install the scripts for MAC and for auto-updating casacore measures tables
 install(PROGRAMS
@@ -125,4 +128,5 @@ install(PROGRAMS
 install(FILES
   rtcp.log_prop
   Station/mpi_node_list.log_prop
+  Station/station_stream.log_prop
   DESTINATION etc)
diff --git a/RTCP/Cobalt/GPUProc/src/FilterBank.cc b/RTCP/Cobalt/GPUProc/src/FilterBank.cc
index d45cbc2635c2d0e4fa0a018268f4a8bf1372df2f..2919304793e45887f9bfacfde75a79ef8e6734e2 100644
--- a/RTCP/Cobalt/GPUProc/src/FilterBank.cc
+++ b/RTCP/Cobalt/GPUProc/src/FilterBank.cc
@@ -37,6 +37,13 @@
 #include <CoInterface/Align.h>
 #include <CoInterface/Exceptions.h>
 
+// Don't enable yet, because it's untested
+#undef HAVE_ALGLIB
+
+#ifdef HAVE_ALGLIB
+#include <bessel.h>
+#endif
+
 namespace LOFAR
 {
   namespace Cobalt
@@ -114,6 +121,9 @@ namespace LOFAR
     // It was released under the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1
     double FilterBank::besselI0(double x)
     {
+#ifdef HAVE_ALGLIB
+      return ::besseli0(x);
+#else
       // Parameters of the polynomial approximation
       const double p1 = 1.0, p2 = 3.5156229, p3 = 3.0899424, p4 = 1.2067492, p5 = 0.2659732, p6 = 3.60768e-2, p7 = 4.5813e-3;
 
@@ -135,6 +145,7 @@ namespace LOFAR
       }
 
       return result;
+#endif
     }
 
 
@@ -374,7 +385,18 @@ namespace LOFAR
         // Use a n-point Kaiser window.
         // The beta parameter is found in matlab / octave with
         // [n,Wn,bta,filtype]=kaiserord([fsin/channels 1.4*fsin/channels],[1 0],[10^(0.5/20) 10^(-91/20)],fsin);
-        // where fsin is the sample freq
+        // where fsin is the sample freq, and channels the number of channels.
+        //
+        // The beta is independent of fsin and channels, and in our case is
+        // equal to
+        //   alpha = 91 dB (= -20*log10(10^(-91/20)))
+        //
+        //   beta = 0.1102 * (alpha - 8.7)
+        // as derived emperically by Kaiser.
+        //
+        // see also
+        //   http://octave.sourceforge.net/signal/function/kaiserord.html
+        //   http://www.mathworks.nl/help/signal/ref/kaiser.html
         double beta = 9.0695;
         if (itsVerbose) {
           logStr << "Kaiser window with beta = " << beta;
diff --git a/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc b/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
index 06fea3b4fae5c68152219a883ecbccbb5ea78461..35327e1fc70cdac4b28c4654b69ad97f99f6955e 100644
--- a/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
+++ b/RTCP/Cobalt/GPUProc/src/Station/StationInput.cc
@@ -65,6 +65,8 @@ namespace LOFAR {
 
 void receiveStation(const Parset &ps, const struct StationID &stationID, Semaphore &bufferReady, Semaphore &stopSignal)
 {
+  const std::string logPrefix = str(format("[station %s] ") % stationID.name());
+
   // settings for the circular buffer
   struct BufferSettings settings(stationID, false);
   settings.nrSamples_16bit = 5 * ps.nrSamplesPerSubband(); // Align with our block increment
@@ -90,7 +92,7 @@ void receiveStation(const Parset &ps, const struct StationID &stationID, Semapho
   GenericSampleBuffer buffer(settings, SharedMemoryArena::CREATE);
 
   // Set up the data transports
-  MultiPacketsToBuffer station(settings, inputStreams);
+  MultiPacketsToBuffer station(settings, inputStreams, ps.settings.startTime, ps.settings.stopTime);
 
   // Signal the creation of the SHM buffer
   bufferReady.up();
@@ -100,7 +102,7 @@ void receiveStation(const Parset &ps, const struct StationID &stationID, Semapho
     // Start a circular buffer
     #pragma omp section
     {
-      LOG_INFO_STR("Starting circular buffer");
+      LOG_DEBUG_STR(logPrefix << "Starting circular buffer and reading input streams");
       station.process();
     }
 
@@ -129,6 +131,7 @@ template<typename SampleT> void sendInputToPipeline(const Parset &ps, size_t sta
   const string fieldName   = fullFieldName.substr(5);   // HBA0
 
   const struct StationID stationID(stationName, fieldName);
+  const std::string logPrefix = str(format("[station %s] ") % stationID.name());
 
   StationNodeAllocation allocation(stationID, ps);
 
@@ -137,7 +140,7 @@ template<typename SampleT> void sendInputToPipeline(const Parset &ps, size_t sta
     return;
   }
 
-  LOG_INFO_STR("Processing data from station " << stationID);
+  LOG_INFO_STR(logPrefix << "Processing station data");
 
   const TimeStamp from(ps.startTime() * ps.subbandBandwidth(), ps.clockSpeed());
   const TimeStamp to(ps.stopTime() * ps.subbandBandwidth(), ps.clockSpeed());
@@ -174,7 +177,7 @@ template<typename SampleT> void sendInputToPipeline(const Parset &ps, size_t sta
         const struct BufferSettings settings(stationID, true);
         const struct BoardMode mode(ps.settings.nrBitsPerSample, ps.settings.clockMHz);
 
-        LOG_INFO_STR("Detected " << settings);
+        LOG_DEBUG_STR(logPrefix << "Detected " << settings);
 
         const TimeStamp from(ps.startTime() * ps.subbandBandwidth(), ps.clockSpeed());
         const TimeStamp to(ps.stopTime() * ps.subbandBandwidth(), ps.clockSpeed());
@@ -264,7 +267,7 @@ template<typename SampleT> void sendInputToPipeline(const Parset &ps, size_t sta
           size_t blockSize = ps.nrSamplesPerSubband();
 
           for (TimeStamp current = from + block * blockSize; current + blockSize < to; current += blockSize, ++block) {
-            LOG_DEBUG_STR(str(format("[rank %i block %d] Sending data from %s") % rank % block % stationID));
+            LOG_DEBUG_STR(logPrefix << str(format("[rank %i block %d] Sending data") % rank % block));
 
             // Fetch end delays (start delays are set by the previous block, or
             // before the loop).
diff --git a/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.cc b/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.cc
index 8cefe7a2fde3e12870f1a80faac1906f8f9a2568..2f0afd34c2d9bdefb50c7914e9428341935cbd58 100644
--- a/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.cc
+++ b/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.cc
@@ -25,8 +25,10 @@ namespace LOFAR
 StationNodeAllocation::StationNodeAllocation( const StationID &stationID, const Parset &parset )
 :
   stationID(stationID),
-  parset(parset)
+  parset(parset),
+  stationIdx(parset.settings.stationIndex(stationID.name()))
 {
+  ASSERTSTR(stationIdx >= 0, "Station not found in observation: " << stationID.name());
 }
 
 bool StationNodeAllocation::receivedHere() const
@@ -63,15 +65,10 @@ int StationNodeAllocation::receiverRank() const
    * by the specified MPI rank.
    */
 
-  ssize_t stationIdx = parset.settings.stationIndex(stationID.name());
+  const string receiver = parset.settings.stations[stationIdx].receiver;
 
-  if (stationIdx < 0)
-    return -1;
-
-  for (unsigned rank = 0; rank < parset.settings.nodes.size(); ++rank) {
-    const vector<size_t> &stations = parset.settings.nodes[rank].stations;
-
-    if (find(stations.begin(), stations.end(), stationIdx) != stations.end())
+  for (size_t rank = 0; rank < parset.settings.nodes.size(); ++rank) {
+    if (parset.settings.nodes[rank].name == receiver)
       return rank;
   }
 
@@ -80,12 +77,7 @@ int StationNodeAllocation::receiverRank() const
 
 std::vector< SmartPtr<Stream> > StationNodeAllocation::inputStreams() const
 {
-  const string key = str(format("PIC.Core.Station.%s.RSP.ports") % stationID.name());
-
-  // default to one board, reading from /dev/null (so no data will ever arive).
-  vector<string> inputStreamDescs = parset.isDefined(key)
-                                    ? parset.getStringVector(key, true)
-                                    : vector<string>(1, "file:/dev/null");
+  vector<string> inputStreamDescs = parset.settings.stations[stationIdx].inputStreams;
 
   vector< SmartPtr<Stream> > inputStreams(inputStreamDescs.size());
 
diff --git a/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.h b/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.h
index 4ad737394d79c89f42fab6e54a749cd2f8acc1f5..cb5dd9078d519b4b6123b1a57e75b02a908880bd 100644
--- a/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.h
+++ b/RTCP/Cobalt/GPUProc/src/Station/StationNodeAllocation.h
@@ -50,6 +50,9 @@ namespace LOFAR
       const StationID stationID;
       const Parset &parset;
 
+      // Index of the station in parset.settings.stations
+      const ssize_t stationIdx;
+
       // Returns the rank of the MPI node that should receive this station
       int receiverRank() const;
     };
diff --git a/RTCP/Cobalt/GPUProc/src/Station/mpi_node_list.log_prop b/RTCP/Cobalt/GPUProc/src/Station/mpi_node_list.log_prop
index 9e8c597894c3291cf016a2bf6d7665e25d790e04..957e05a413dcd5bc88987faa13870f838d158a43 100644
--- a/RTCP/Cobalt/GPUProc/src/Station/mpi_node_list.log_prop
+++ b/RTCP/Cobalt/GPUProc/src/Station/mpi_node_list.log_prop
@@ -14,11 +14,11 @@ log4cplus.additivity.LCS.MSLofar=false
 # Define the appenders
 log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
 log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
-log4cplus.appender.STDOUT.layout.ConversionPattern=rtcp:${MPIRANK}@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+log4cplus.appender.STDOUT.layout.ConversionPattern=mpi_node_list@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
 
 log4cplus.appender.STDERR=log4cplus::ConsoleAppender
 log4cplus.appender.STDERR.layout=log4cplus::PatternLayout
-log4cplus.appender.STDERR.layout.ConversionPattern=rtcp:${MPIRANK}@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+log4cplus.appender.STDERR.layout.ConversionPattern=mpi_node_list@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
 log4cplus.appender.STDERR.logToStdErr=true
 
 #log4cplus.appender.FILE=log4cplus::RollingFileAppender
diff --git a/RTCP/Cobalt/GPUProc/src/Station/station_stream.cc b/RTCP/Cobalt/GPUProc/src/Station/station_stream.cc
new file mode 100644
index 0000000000000000000000000000000000000000..36f0803533702a03cd6e06c460d7763328db9552
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/src/Station/station_stream.cc
@@ -0,0 +1,177 @@
+//# station_stream.cc: Generate station input stream information from a parset
+//# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id: mpi_node_list.cc 25888 2013-08-01 09:05:27Z mol $
+
+#include <lofar_config.h>
+
+#include <unistd.h>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <boost/format.hpp>
+
+#include <Common/StreamUtil.h>
+#include <CoInterface/Parset.h>
+
+using namespace LOFAR;
+using namespace LOFAR::Cobalt;
+using namespace std;
+using boost::format;
+
+void usage(char **argv)
+{
+  cerr << "usage: " << argv[0] << " -S station            -h parset" << endl;
+  cerr << "usage: " << argv[0] << " -S station [-B board] -s parset" << endl;
+  cerr << "usage: " << argv[0] << " -S station            -c parset" << endl;
+  cerr << endl;
+  cerr << "-h        : print the host name    on which this station is received" << endl;
+  cerr << "-s        : print the stream       on which this station is received" << endl;
+  cerr << "-s        : print the cpu (socket) on which this station is received" << endl;
+  cerr << endl;
+  cerr << "-S station: select station (CS001LBA, etc)" << endl;
+  cerr << "-B board  : select board (0, 1, 2, 3)" << endl;
+  cerr << endl;
+}
+
+void print_node_list(Parset &ps)
+{
+  // Collect all host names
+  vector<string> nodes;
+  for (size_t node = 0; node < ps.settings.nodes.size(); ++node)
+    nodes.push_back(ps.settings.nodes[node].hostName);
+
+  // Output all host names
+  writeVector(cout, nodes, ",", "", "");
+  cout << endl;
+}
+
+int main(int argc, char **argv)
+{
+  INIT_LOGGER("station_stream");
+
+  string station = "";
+  unsigned board = 0;
+  bool print_host = false;
+  bool print_stream = false;
+  bool print_cpu = false;
+
+  // parse all command-line option
+  int opt;
+  while ((opt = getopt(argc, argv, "B:S:hsc")) != -1) {
+    switch (opt) {
+    case 'B':
+      board = atoi(optarg);
+      break;
+
+    case 'S':
+      station = optarg;
+      break;
+
+    case 'h':
+      print_host = true;
+      break;
+
+    case 's':
+      print_stream = true;
+      break;
+
+    case 'c':
+      print_cpu = true;
+      break;
+
+    default: /* '?' */
+      usage(argv);
+      exit(1);
+    }
+  }
+
+  
+  if ( optind >= argc   // we expect a parset filename as an additional parameter
+    || station.empty()  // we expect a station to be selected
+    || (print_host + print_stream + print_cpu != 1) // print either host or stream
+     ) {
+    usage(argv);
+    exit(1);
+  }
+
+  // Create a parameters set object based on the inputs
+  Parset ps(argv[optind]);
+
+
+  // Find the selected station
+  ssize_t stationIdx = ps.settings.stationIndex(station);
+
+  if (stationIdx < 0) {
+    LOG_WARN_STR("Station not found in parset, adding: " << station);
+
+    // Add our station explicitly
+    ps.add("Observation.VirtualInstrument.stationList", str(format("[%s]") % station));
+    ps.updateSettings();
+
+    // Update index
+    stationIdx = ps.settings.stationIndex(station);
+
+    ASSERT(stationIdx >= 0);
+  }
+
+  if (print_stream) {
+    if (board >= ps.settings.stations[stationIdx].inputStreams.size()) {
+      LOG_ERROR_STR("Input for board " << board << " not found for station " << station);
+      cout << "file:/dev/null" << endl;
+      return 1;
+    }
+
+    // Print the input stream for the given station and board
+    cout << ps.settings.stations[stationIdx].inputStreams[board] << endl;
+  } else if (print_host || print_cpu) {
+    // Print the hostName of the given station, or localhost if
+    // unknown.
+
+    const string receiver = ps.settings.stations[stationIdx].receiver;
+    bool found = false;
+
+    for (size_t i = 0; i < ps.settings.nodes.size(); ++i) {
+      struct ObservationSettings::Node &node = ps.settings.nodes[i];
+      
+      if (node.name == receiver) {
+        if (print_host) {
+          cout << node.hostName << endl;
+        } else {
+          // print_cpu
+          cout << node.cpu << endl;
+        }
+
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      if (print_host) {
+        // Default to localhost
+        cout << "localhost" << endl;
+      } else {
+        // Default to cpu 0
+        cout << "0" << endl;
+      }
+    }
+  }
+  return 0;
+}
+
diff --git a/RTCP/Cobalt/GPUProc/src/Station/station_stream.log_prop b/RTCP/Cobalt/GPUProc/src/Station/station_stream.log_prop
new file mode 100644
index 0000000000000000000000000000000000000000..8eb198d00d78d6ac7e131b65cd36bc107447848b
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/src/Station/station_stream.log_prop
@@ -0,0 +1,31 @@
+# Note: mpi_node_list needs to log to stderr, to prevent clobbering its regular
+# output on stdout.
+
+# Configure the loggers
+log4cplus.rootLogger=INFO, STDERR
+log4cplus.logger.TRC=INFO
+
+# prevent debug messages: accept >=WARN only, and don't forward messages to the rootLogger
+log4cplus.logger.LCS.ApplCommon=WARN, STDERR
+log4cplus.additivity.LCS.ApplCommon=false
+log4cplus.logger.LCS.MSLofar=WARN, STDERR
+log4cplus.additivity.LCS.MSLofar=false
+
+# Define the appenders
+log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
+log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
+log4cplus.appender.STDOUT.layout.ConversionPattern=station_stream@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+
+log4cplus.appender.STDERR=log4cplus::ConsoleAppender
+log4cplus.appender.STDERR.layout=log4cplus::PatternLayout
+log4cplus.appender.STDERR.layout.ConversionPattern=station_stream@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+log4cplus.appender.STDERR.logToStdErr=true
+
+#log4cplus.appender.FILE=log4cplus::RollingFileAppender
+#log4cplus.appender.FILE.File=${LOG4CPLUS_LOGFILENAME}.log
+#log4cplus.appender.FILE.MaxFileSize=10MB
+#log4cplus.appender.FILE.MaxBackupIndex=2
+#log4cplus.appender.FILE.layout=log4cplus::PatternLayout
+#log4cplus.appender.FILE.layout.ConversionPattern=rtcp:${MPIRANK}@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+
+log4cplus.appender.DUMP=log4cplus::NullAppender
diff --git a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
index cb19c1838e189c2117718ce631611e6d03498bad..d2b559fa08b9e76958658acc79a9649aa45ec866 100644
--- a/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
+++ b/RTCP/Cobalt/GPUProc/src/Storage/StorageProcesses.cc
@@ -110,6 +110,10 @@ namespace LOFAR
       Thread thread(this, &StorageProcesses::finalMetaDataThread, itsLogPrefix + "[FinalMetaDataThread] ", 65536);
 
       thread.cancel(deadline_ts);
+      thread.wait();
+
+      // Notify clients
+      itsFinalMetaDataAvailable.trigger();
     }
 
 
@@ -165,9 +169,6 @@ namespace LOFAR
       itsFinalMetaData.read(stream);
       LOG_DEBUG_STR(itsLogPrefix << "[FinalMetaData] [ControlThread] obtained final meta data");
 
-      // Notify clients
-      itsFinalMetaDataAvailable.trigger();
-
       // Wait for or end the remote process
       sshconn.wait();
     }
diff --git a/RTCP/Cobalt/GPUProc/src/SysInfoLogger.cc b/RTCP/Cobalt/GPUProc/src/SysInfoLogger.cc
new file mode 100644
index 0000000000000000000000000000000000000000..df39190e74a06f05c4bc92d5b8c9453d3d04543a
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/src/SysInfoLogger.cc
@@ -0,0 +1,113 @@
+//# SysInfoLogger.cc
+//# Copyright (C) 2013  ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id$
+
+#include <lofar_config.h>
+#include "SysInfoLogger.h"
+
+#include <fstream>
+#include <cstdio>
+#include <unistd.h>
+#include <sys/time.h>
+
+using namespace std;
+
+namespace LOFAR
+{
+  namespace Cobalt
+  {
+
+    SysInfoLogger::SysInfoLogger(double from, double to)
+    :
+      from(from),
+      to(to),
+      thread(this, &SysInfoLogger::mainLoop)
+    {
+    }
+
+    SysInfoLogger::~SysInfoLogger()
+    {
+      thread.cancel();
+    }
+
+    void SysInfoLogger::mainLoop()
+    {
+      /*
+       * We fetch system statistics, calculate the changes over time,
+       * and log warnings if suspicious behaviour is detected.
+       */
+
+      struct stats {
+        // nr of UDP packets received but discared because nobody was listening
+        int noport;
+
+        // nr of UDP packets received but triggered an error (likely, we failed
+        // to fetch it from the kernel in time)
+        int inerror;
+      };
+
+      struct stats old_stats;
+      bool first = true;
+
+      for(;;) {
+        time_t now = time(0);
+
+        if (from && now < from) {
+          // wait for `from'
+          sleep(from - now);
+          continue;
+        }
+
+        if (to && now > to) {
+          // we're done
+          break;
+        }
+
+        // Default to previous statistics
+        struct stats new_stats = old_stats;
+
+#ifdef __linux__
+        // Fetch UDP receive errors
+        ifstream snmp("/proc/net/snmp");
+        string line;
+
+        while(std::getline(snmp, line))
+          if (sscanf(line.c_str(), "Udp: %*d %d %d %*d %*d %*d", &new_stats.noport, &new_stats.inerror) == 2)
+            break;
+#endif
+
+        if (!first) {
+          // Parse differences with previous statistics
+          int inerror = new_stats.inerror - old_stats.inerror;
+
+          if (inerror > 0)
+            LOG_WARN_STR("Kernel dropped " << inerror << " UDP packets");
+        }
+
+        old_stats = new_stats;
+        first = false;
+
+        // Don't spam the logs..
+        sleep(10);
+      }
+    }
+
+  }
+}
+
diff --git a/RTCP/Cobalt/GPUProc/src/SysInfoLogger.h b/RTCP/Cobalt/GPUProc/src/SysInfoLogger.h
new file mode 100644
index 0000000000000000000000000000000000000000..6df3baf8830fbbd7d32eeb787ca6e001cddf3423
--- /dev/null
+++ b/RTCP/Cobalt/GPUProc/src/SysInfoLogger.h
@@ -0,0 +1,57 @@
+//# SysInfoLogger.h: Periodically analyses system information.
+//# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id: cpu_utils.h 25651 2013-07-12 12:19:11Z mol $
+
+// \file
+// Include for processor optimalizetion functionality
+
+#ifndef LOFAR_GPUPROC_SYSINFOLOGGER_H
+#define LOFAR_GPUPROC_SYSINFOLOGGER_H
+
+#include <Common/Thread/Thread.h>
+
+namespace LOFAR
+{
+  namespace Cobalt
+  {
+    /*
+     * The SysInfoLogger will periodically analyse
+     * the system's performance, and log warnings
+     * in case of suspicious behaviour.
+     *
+     * Logging will stop when the destructor is called.
+     */
+    class SysInfoLogger {
+    public:
+      // Start logging in the background, in the
+      // interval [from, to). Both timestamps are
+      // in seconds since 1970.]
+      SysInfoLogger(double from = 0, double to = 0);
+      ~SysInfoLogger();
+
+    private:
+      const double from;
+      const double to;
+      Thread thread;
+
+      void mainLoop();
+    };
+  }
+}
+#endif
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.cc b/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.cc
index b419476869311631f36644a477c13d8cf9061e35..e6669d2c97d9546c541aeeb44aecb897d1d5268b 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.cc
@@ -84,7 +84,7 @@ namespace LOFAR
       setArg(1, buffers.input);
       setArg(4, buffers.delaysAtBegin);
       setArg(5, buffers.delaysAfterEnd);
-      setArg(6, buffers.phaseOffsets);
+      setArg(6, buffers.phase0s);
       setArg(7, buffers.bandPassCorrectionWeights);
 
       setEnqueueWorkSizes( gpu::Grid(256, params.nrChannelsPerSubband == 1 ? 1 : params.nrChannelsPerSubband / 16, params.nrStations),
@@ -137,7 +137,7 @@ namespace LOFAR
         return 
           (size_t) itsParameters.nrSAPs * itsParameters.nrStations * 
             NR_POLARIZATIONS * sizeof(double);
-      case DelayAndBandPassKernel::PHASE_OFFSETS:
+      case DelayAndBandPassKernel::PHASE_ZEROS:
         return
           (size_t) itsParameters.nrStations * NR_POLARIZATIONS * sizeof(double);
       case DelayAndBandPassKernel::BAND_PASS_CORRECTION_WEIGHTS:
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.h b/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.h
index 564b5d80d59af1adad23bf0ebe2c7a62f8471584..04644abf90df79a11d069a90879e6f34bfe5413f 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.h
+++ b/RTCP/Cobalt/GPUProc/src/cuda/Kernels/DelayAndBandPassKernel.h
@@ -58,7 +58,7 @@ namespace LOFAR
         INPUT_DATA,
         OUTPUT_DATA,
         DELAYS,
-        PHASE_OFFSETS,
+        PHASE_ZEROS,
         BAND_PASS_CORRECTION_WEIGHTS
       };
 
@@ -70,14 +70,14 @@ namespace LOFAR
                 const gpu::DeviceMemory& out,
                 const gpu::DeviceMemory& delaysAtBegin,
                 const gpu::DeviceMemory& delaysAfterEnd,
-                const gpu::DeviceMemory& phaseOffsets,
+                const gpu::DeviceMemory& phase0s,
                 const gpu::DeviceMemory& bandPassCorrectionWeights) :
-          Kernel::Buffers(in, out), delaysAtBegin(delaysAtBegin), delaysAfterEnd(delaysAfterEnd), phaseOffsets(phaseOffsets), bandPassCorrectionWeights(bandPassCorrectionWeights)
+          Kernel::Buffers(in, out), delaysAtBegin(delaysAtBegin), delaysAfterEnd(delaysAfterEnd), phase0s(phase0s), bandPassCorrectionWeights(bandPassCorrectionWeights)
         {}
 
         gpu::DeviceMemory delaysAtBegin;
         gpu::DeviceMemory delaysAfterEnd;
-        gpu::DeviceMemory phaseOffsets;
+        gpu::DeviceMemory phase0s;
         gpu::DeviceMemory bandPassCorrectionWeights;
       };
 
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.cc b/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.cc
index 0ec636c79fe69df672d8d070f77b41b8398e67af..49310f7c0df13bfb0796a7e18a336e7188ccda24 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.cc
@@ -56,6 +56,7 @@ namespace LOFAR
       ps(ps),
       devices(devices),
       subbandIndices(subbandIndices),
+      processingSubband0(std::find(subbandIndices.begin(), subbandIndices.end(), 0U) != subbandIndices.end()),
       workQueues((profiling ? 1 : NR_WORKQUEUES_PER_DEVICE) * devices.size()),
       nrSubbandsPerSubbandProc(
         (subbandIndices.size() + workQueues.size() - 1) / workQueues.size()),
@@ -101,7 +102,7 @@ namespace LOFAR
         // Receive the samples of all subbands from the stations for this
         // block.
 
-        LOG_INFO_STR("[block " << block << "] Collecting input buffers");
+        LOG_DEBUG_STR("[block " << block << "] Collecting input buffers");
 
         // The set of InputData objects we're using for this block.
         vector< SmartPtr<SubbandProcInputData> > inputDatas(subbandIndices.size());
@@ -132,11 +133,16 @@ namespace LOFAR
         }
 
         // Receive all subbands from all stations
-        LOG_INFO_STR("[block " << block << "] Receive input");
+        LOG_DEBUG_STR("[block " << block << "] Receive input");
+
         if (block > 2) receiveTimer.start();
         receiver.receiveBlock<SampleT>(blocks);
         if (block > 2) receiveTimer.stop();
-        LOG_INFO_STR("[block " << block << "] Input received");
+
+        if (processingSubband0)
+          LOG_INFO_STR("[block " << block << "] Input received");
+        else
+          LOG_DEBUG_STR("[block " << block << "] Input received");
 
         vector<size_t> nrFlaggedSamples(ps.nrStations(), 0);
 
@@ -170,8 +176,11 @@ namespace LOFAR
             flagStr << str(boost::format("%s: %.1f%%, ") % ps.settings.stations[stat].name % flagPerc);
         }
 
-        LOG_INFO_STR("[block " << block << "] No flagging: " << cleanStr.str());
-        LOG_INFO_STR("[block " << block << "] Flagging:    " << flagStr.str());
+        LOG_DEBUG_STR("[block " << block << "] No flagging: " << cleanStr.str());
+
+        if (!flagStr.str().empty()) {
+          LOG_WARN_STR("[block " << block << "] Flagging:    " << flagStr.str());
+        }
 
         LOG_DEBUG_STR("[block " << block << "] Forwarded input to pre processing");
       }
@@ -425,7 +434,8 @@ namespace LOFAR
 
         LOG_DEBUG_STR("[" << id << "] Forwarded output to writer");
 
-        if (time(0) != lastLogTime) {
+        // Log every 5 seconds
+        if (time(0) > lastLogTime + 5) {
           lastLogTime = time(0);
 
           LOG_INFO_STR("Forwarded " << nrBlocksForwarded << " blocks, dropped " << nrBlocksDropped << " blocks");
@@ -459,10 +469,7 @@ namespace LOFAR
 
         ASSERT(!outputData);
 
-        if (id.localSubbandIdx == 0 || id.localSubbandIdx == subbandIndices.size() - 1)
-          LOG_INFO_STR("[" << id << "] Done"); 
-        else
-          LOG_DEBUG_STR("[" << id << "] Done"); 
+        LOG_DEBUG_STR("[" << id << "] Done"); 
       }
     }
 
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.h b/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.h
index 1f67e30580c5091a71aa9cbe18eac26c5323b14d..c8f894dcfbc82b883b30a4f2a72cb84666840560 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.h
+++ b/RTCP/Cobalt/GPUProc/src/cuda/Pipelines/Pipeline.h
@@ -58,6 +58,11 @@ namespace LOFAR
       const std::vector<gpu::Device> devices;
 
       const std::vector<size_t> subbandIndices; // [localSubbandIdx]
+
+      // Whether we're the pipeline that processes the first subband.
+      // If true, we log our progress at INFO. Otherwise, at DEBUG.
+      const bool processingSubband0;
+
       std::vector< SmartPtr<SubbandProc> > workQueues;
 
       const size_t nrSubbandsPerSubbandProc;
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/BeamFormerSubbandProc.cc b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/BeamFormerSubbandProc.cc
index d9f0baaab2a05890d3c63990afe86b0e1b4f7b7b..358c65a5e4ef3c7ab5a25f19ddf8411fde400d7b 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/BeamFormerSubbandProc.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/BeamFormerSubbandProc.cc
@@ -76,7 +76,7 @@ namespace LOFAR
         factories.delayCompensation.bufferSize(
           DelayAndBandPassKernel::DELAYS),
         factories.delayCompensation.bufferSize(
-          DelayAndBandPassKernel::PHASE_OFFSETS),
+          DelayAndBandPassKernel::PHASE_ZEROS),
         context),
       // coherent stokes buffers
       devA(devInput.inputSamples),
@@ -102,7 +102,7 @@ namespace LOFAR
       // delayComp: B -> A
       delayCompensationBuffers(devB, devA, devInput.delaysAtBegin,
                                devInput.delaysAfterEnd,
-                               devInput.phaseOffsets, devNull),
+                               devInput.phase0s, devNull),
       delayCompensationKernel(
         factories.delayCompensation.create(queue, delayCompensationBuffers)),
 
@@ -390,8 +390,8 @@ namespace LOFAR
                             input.delaysAtBegin, false);
           queue.writeBuffer(devInput.delaysAfterEnd,
                             input.delaysAfterEnd, false);
-          queue.writeBuffer(devInput.phaseOffsets,
-                            input.phaseOffsets, false);
+          queue.writeBuffer(devInput.phase0s,
+                            input.phase0s, false);
           queue.writeBuffer(devBeamFormerDelays,
                             input.tabDelays, false);
 
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/CorrelatorSubbandProc.cc b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/CorrelatorSubbandProc.cc
index 6d7bd513460859b49794cdc9be83f56f6004536b..593cb89bcd898de0db4f01f4dea162bafcaa11b6 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/CorrelatorSubbandProc.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/CorrelatorSubbandProc.cc
@@ -62,7 +62,7 @@ namespace LOFAR
       devInput(std::max(ps.nrChannelsPerSubband() == 1 ? 0UL : factories.firFilter.bufferSize(FIR_FilterKernel::INPUT_DATA),
                         factories.correlator.bufferSize(CorrelatorKernel::INPUT_DATA)),
                factories.delayAndBandPass.bufferSize(DelayAndBandPassKernel::DELAYS),
-               factories.delayAndBandPass.bufferSize(DelayAndBandPassKernel::PHASE_OFFSETS),
+               factories.delayAndBandPass.bufferSize(DelayAndBandPassKernel::PHASE_ZEROS),
                context),
       devFilteredData(context,
                       std::max(factories.delayAndBandPass.bufferSize(DelayAndBandPassKernel::INPUT_DATA),
@@ -82,7 +82,7 @@ namespace LOFAR
       delayAndBandPassBuffers(devFilteredData,
                               devInput.inputSamples,
                               devInput.delaysAtBegin, devInput.delaysAfterEnd,
-                              devInput.phaseOffsets,
+                              devInput.phase0s,
                               devBandPassCorrectionWeights),
       delayAndBandPassKernel(factories.delayAndBandPass.create(queue, delayAndBandPassBuffers)),
 
@@ -299,7 +299,7 @@ namespace LOFAR
         {
           queue.writeBuffer(devInput.delaysAtBegin,  input.delaysAtBegin,  false);
           queue.writeBuffer(devInput.delaysAfterEnd, input.delaysAfterEnd, false);
-          queue.writeBuffer(devInput.phaseOffsets,   input.phaseOffsets,   false);
+          queue.writeBuffer(devInput.phase0s,        input.phase0s,   false);
 
           prevSAP = SAP;
           prevBlock = block;
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.cc b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.cc
index aaccb284ce30605a3d621805afb1f2b151cd771c..130e971d4a5ac1b79a74e2641ba3ee2e760d8a56 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.cc
@@ -88,14 +88,14 @@ namespace LOFAR
       // extract and assign the delays for the station beams
 
       // X polarisation
-      delaysAtBegin[SAP][station][0]  = ps.settings.stations[station].delayCorrection.x + metaData.stationBeam.delayAtBegin;
-      delaysAfterEnd[SAP][station][0] = ps.settings.stations[station].delayCorrection.x + metaData.stationBeam.delayAfterEnd;
-      phaseOffsets[station][0]        = ps.settings.stations[station].phaseCorrection.x;
+      delaysAtBegin[SAP][station][0]  = ps.settings.stations[station].delay.x + metaData.stationBeam.delayAtBegin;
+      delaysAfterEnd[SAP][station][0] = ps.settings.stations[station].delay.x + metaData.stationBeam.delayAfterEnd;
+      phase0s[station][0]             = ps.settings.stations[station].phase0.x;
 
       // Y polarisation
-      delaysAtBegin[SAP][station][1]  = ps.settings.stations[station].delayCorrection.y + metaData.stationBeam.delayAtBegin;
-      delaysAfterEnd[SAP][station][1] = ps.settings.stations[station].delayCorrection.y + metaData.stationBeam.delayAfterEnd;
-      phaseOffsets[station][1]        = ps.settings.stations[station].phaseCorrection.y;
+      delaysAtBegin[SAP][station][1]  = ps.settings.stations[station].delay.y + metaData.stationBeam.delayAtBegin;
+      delaysAfterEnd[SAP][station][1] = ps.settings.stations[station].delay.y + metaData.stationBeam.delayAfterEnd;
+      phase0s[station][1]             = ps.settings.stations[station].phase0.y;
 
 
       if (ps.settings.beamFormer.enabled)
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.h b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.h
index 7f1b5ab0c6b8b198f2f638b4eb5aeaab9a9b78b9..c7d513b009a55d3eedbadc3d9ee6967322699f6a 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.h
+++ b/RTCP/Cobalt/GPUProc/src/cuda/SubbandProcs/SubbandProc.h
@@ -57,17 +57,17 @@ namespace LOFAR
       {
         gpu::DeviceMemory delaysAtBegin;
         gpu::DeviceMemory delaysAfterEnd;
-        gpu::DeviceMemory phaseOffsets;
+        gpu::DeviceMemory phase0s;
         // We don't have tabDelays here, as it is only for bf.
         // It is transferred to devBeamFormerDelays declared in the bf SubbandProc,
         // similar to the bandpass correction and FIR filter weights (also not here).
         gpu::DeviceMemory inputSamples;
 
         DeviceBuffers(size_t inputSamplesSize, size_t delaysSize, 
-                      size_t phaseOffsetsSize, gpu::Context &context) :
+                      size_t phase0sSize, gpu::Context &context) :
           delaysAtBegin(context, delaysSize),
           delaysAfterEnd(context, delaysSize),
-          phaseOffsets(context, phaseOffsetsSize),
+          phase0s(context, phase0sSize),
           inputSamples(context, inputSamplesSize)
         {
         }
@@ -86,7 +86,7 @@ namespace LOFAR
       MultiDimArrayHostBuffer<double, 3> delaysAfterEnd;
 
       //!< Remainder of delays
-      MultiDimArrayHostBuffer<double, 2> phaseOffsets;
+      MultiDimArrayHostBuffer<double, 2> phase0s;
 
       //!< Delays for TABs (aka pencil beams) after station beam correction
       MultiDimArrayHostBuffer<double, 3> tabDelays;
@@ -109,7 +109,7 @@ namespace LOFAR
                        context, hostBufferFlags),
         delaysAfterEnd(boost::extents[n_beams][n_stations][n_polarizations],
                        context, hostBufferFlags),
-        phaseOffsets(boost::extents[n_stations][n_polarizations],
+        phase0s(boost::extents[n_stations][n_polarizations],
                        context, hostBufferFlags),
         tabDelays(boost::extents[n_beams][n_stations][n_tabs],
                        context, hostBufferFlags),
diff --git a/RTCP/Cobalt/GPUProc/src/cuda/gpu_utils.cc b/RTCP/Cobalt/GPUProc/src/cuda/gpu_utils.cc
index 18e61d80a9cd6d9404f57ec0cba0a01d8d5e2b19..73221e90a25774f5f730fb506ad3348cf2220875 100644
--- a/RTCP/Cobalt/GPUProc/src/cuda/gpu_utils.cc
+++ b/RTCP/Cobalt/GPUProc/src/cuda/gpu_utils.cc
@@ -274,7 +274,6 @@ namespace LOFAR
 
       // For now, keep optimisations the same to detect changes in
       // output with reference.
-      flags.insert("-use_fast_math");
       flags.insert("--restrict");
       flags.insert("-O3");
 
diff --git a/RTCP/Cobalt/GPUProc/src/rtcp.cc b/RTCP/Cobalt/GPUProc/src/rtcp.cc
index e58bfe5d1d84b4f57ad36c27e8130c267546c74b..ce13179554b7a6bb91b23db9b2f6b37555ba9408 100644
--- a/RTCP/Cobalt/GPUProc/src/rtcp.cc
+++ b/RTCP/Cobalt/GPUProc/src/rtcp.cc
@@ -19,6 +19,7 @@
 //# $Id$
 
 #include <lofar_config.h>
+#include <GPUProc/Package__Version.h>
 
 #include <cstdlib>
 #include <cstdio>
@@ -69,6 +70,7 @@
 #include "Storage/SSH.h"
 
 #include <GPUProc/cpu_utils.h>
+#include <GPUProc/SysInfoLogger.h>
 
 using namespace LOFAR;
 using namespace LOFAR::Cobalt;
@@ -170,6 +172,8 @@ int main(int argc, char **argv)
   LOG_WARN("Running without MPI!");
 #endif
 
+  LOG_INFO_STR("GPUProc version " << GPUProcVersion::getVersion() << " r" << GPUProcVersion::getRevision());
+
   /*
    * Initialise the system environment
    */
@@ -401,6 +405,9 @@ int main(int argc, char **argv)
   DirectInput::instance(&ps);
 #endif
 
+  // Periodically log system information
+  SysInfoLogger siLogger(ps.startTime(), ps.stopTime());
+
   /*
    * RUN stage
    */
@@ -429,6 +436,8 @@ int main(int argc, char **argv)
     }
   }
 
+  pipeline = 0;
+
   /*
    * COMPLETING stage
    */
@@ -440,13 +449,12 @@ int main(int argc, char **argv)
     LOG_INFO("----- Processing final metadata (broken antenna information)");
 
     // retrieve and forward final meta data
-    // TODO: Increase timeouts when FinalMetaDataGatherer starts working again
-    storageProcesses->forwardFinalMetaData(completing_start + 2);
+    storageProcesses->forwardFinalMetaData(completing_start + 300);
 
     LOG_INFO("Stopping Storage processes");
 
     // graceful exit
-    storageProcesses->stop(completing_start + 10);
+    storageProcesses->stop(completing_start + 600);
 
     LOG_INFO("Writing LTA feedback to disk");
 
@@ -455,6 +463,7 @@ int main(int argc, char **argv)
     feedbackLTA.adoptCollection(storageProcesses->feedbackLTA());
 
     // augment LTA feedback with global information
+    feedbackLTA.add("_isCobalt", "T"); // for MoM, to discriminate between Cobalt and BG/P observations
     feedbackLTA.add("LOFAR.ObsSW.Observation.DataProducts.nrOfOutput_Beamformed_", str(format("%u") % ps.nrStreams(BEAM_FORMED_DATA)));
     feedbackLTA.add("LOFAR.ObsSW.Observation.DataProducts.nrOfOutput_Correlated_", str(format("%u") % ps.nrStreams(CORRELATED_DATA)));
 
@@ -471,6 +480,9 @@ int main(int argc, char **argv)
     } else {
       LOG_WARN("Could not write feedback file: $LOFARROOT not set.");
     }
+
+    // final cleanup
+    storageProcesses = 0;
   }
   LOG_INFO("===== SUCCESS =====");
 
diff --git a/RTCP/Cobalt/GPUProc/src/rtcp.log_prop b/RTCP/Cobalt/GPUProc/src/rtcp.log_prop
index e990ec6123dbbf0833da193e082e2ee3df89084b..dd0f337853dcde185d7ed75edd21ca14d7ad60fc 100644
--- a/RTCP/Cobalt/GPUProc/src/rtcp.log_prop
+++ b/RTCP/Cobalt/GPUProc/src/rtcp.log_prop
@@ -21,10 +21,13 @@ log4cplus.appender.STDOUT.layout.ConversionPattern=rtcp:${MPIRANK}@%h %D{%d-%m-%
 # HERE BE DRAGONS: Do NOT set the logging threshold for the MACCLP appender
 # above INFO in the log_prop file, or identification with the MAC Log Processor
 # will fail!
-log4cplus.appender.MACCLP=log4cplus::SocketAppender
-log4cplus.appender.MACCLP.port=23999
-log4cplus.appender.MACCLP.host=ccu001
-log4cplus.appender.MACCLP.Threshold=INFO
+#
+# JD: Disabled for now, as log4cplus uses extra threads for this, which in turn
+# cause crashes in OpenMPI.
+#log4cplus.appender.MACCLP=log4cplus::SocketAppender
+#log4cplus.appender.MACCLP.port=23999
+#log4cplus.appender.MACCLP.host=ccu001
+#log4cplus.appender.MACCLP.Threshold=INFO
 
 #log4cplus.appender.STDERR=log4cplus::ConsoleAppender
 #log4cplus.appender.STDERR.layout=log4cplus::PatternLayout
diff --git a/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh b/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
index fc1fedf7fb11e400e9e653f81223118bb0d740c0..32ea0ca874a3771cecaa813afd370172e737df1a 100755
--- a/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
+++ b/RTCP/Cobalt/GPUProc/src/scripts/runObservation.sh
@@ -13,6 +13,9 @@ ONLINECONTROL_FEEDBACK=1
 # Augment the parset with etc/parset-additions.d/* ?
 AUGMENT_PARSET=1
 
+# File to write PID to
+PIDFILE=""
+
 # Force running on localhost instead of the hosts specified
 # in the parset?
 FORCE_LOCALHOST=0
@@ -24,6 +27,9 @@ MPIRUN_PARAMS=""
 # Parameters to pass to rtcp
 RTCP_PARAMS=""
 
+# Avoid passing on "*" if it matches nothing
+shopt -s nullglob
+
 echo "Called as $@"
 
 if test "$LOFARROOT" == ""; then
@@ -33,12 +39,14 @@ fi
 echo "LOFARROOT is set to $LOFARROOT"
 
 # Parse command-line options
-while getopts ":AFl:p" opt; do
+while getopts ":AFP:l:p" opt; do
   case $opt in
       A)  AUGMENT_PARSET=0
           ;;
       F)  ONLINECONTROL_FEEDBACK=0
           ;;
+      P)  PIDFILE="$OPTARG"
+          ;;
       l)  FORCE_LOCALHOST=1
           MPIRUN_PARAMS="$MPIRUN_PARAMS -np $OPTARG"
           ;;
@@ -62,12 +70,13 @@ PARSET="$1"
 # Show usage if no parset was provided
 if [ -z "$PARSET" ]
 then
-  echo "Usage: $0 [-A] [-F] [-l nprocs] [-p] PARSET"
+  echo "Usage: $0 [-A] [-F] [-P pidfile] [-l nprocs] [-p] PARSET"
   echo " "
   echo "Runs the observation specified by PARSET"
   echo " "
   echo "-A: do NOT augment parset"
   echo "-F: do NOT send feedback to OnlineControl"
+  echo "-P: create PID file"
   echo "-l: run on localhost using 'nprocs' processes"
   echo "-p: enable profiling"
   exit 1
@@ -80,11 +89,34 @@ function error {
 
 function getkey {
   KEY=$1
+  DEFAULT=$2
 
   # grab the last key matching "^$KEY=", ignoring spaces.
-  <$PARSET perl -ne '/^'$KEY'\s*=\s*"?(.*?)"?\s*$/ || next; print "$1\n";' | tail -n 1
+  VALUE=`<$PARSET perl -ne '/^'$KEY'\s*=\s*"?(.*?)"?\s*$/ || next; print "$1\n";' | tail -n 1`
+
+  if [ "$VALUE" == "" ]
+  then
+    echo "$DEFAULT"
+  else
+    echo "$VALUE"
+  fi
 }
 
+# ******************************
+# Preprocess: initialise
+# ******************************
+
+# Write PID if requested
+if [ "$PIDFILE" != "" ]
+then
+  echo $$ > "$PIDFILE"
+
+  # We created the PIDFILE, so we
+  # clean it up.
+  trap "rm -f $PIDFILE" EXIT
+fi
+
+# Read parset
 [ -f "$PARSET" -a -r "$PARSET" ] || error "Cannot read parset: $PARSET"
 
 OBSID=`getkey Observation.ObsID`
@@ -98,13 +130,18 @@ if [ "$AUGMENT_PARSET" -eq "1" ]
 then
   AUGMENTED_PARSET=$LOFARROOT/var/run/rtcp-$OBSID.parset
 
-  # Add static keys ($PARSET is last, to allow any key to be overridden in tests)
-  cat $LOFARROOT/etc/parset-additions.d/*.parset $PARSET > $AUGMENTED_PARSET || error "Could not create parset $AUGMENTED_PARSET"
+  # Add static keys
+  cat $LOFARROOT/etc/parset-additions.d/default/*.parset \
+      $HOME/.cobalt/default/*.parset \
+      $PARSET \
+      $LOFARROOT/etc/parset-additions.d/override/*.parset \
+      $HOME/.cobalt/override/*.parset \
+      > $AUGMENTED_PARSET || error "Could not create parset $AUGMENTED_PARSET"
 
   # If we force localhost, we need to remove the node list, or the first one will be used
   if [ "$FORCE_LOCALHOST" -eq "1" ]
   then
-    echo "Cobalt.Hardware.nrNodes = 0" >> $AUGMENTED_PARSET
+    echo "Cobalt.Nodes = []" >> $AUGMENTED_PARSET
   fi
 
   # Use the new one from now on
@@ -183,12 +220,14 @@ then
   ONLINECONTROL_HOST=`getkey Cobalt.Feedback.host`
   ONLINECONTROL_RESULT_PORT=$((21000 + $OBSID % 1000))
 
+  ONLINECONTROL_USER=`getkey Cobalt.Feedback.userName $USER`
+
   if [ $OBSRESULT -eq 0 ]
   then
     # ***** Observation ran successfully
 
     # 1. Copy LTA feedback file to ccu001
-    FEEDBACK_DEST=$ONLINECONTROL_HOST:`getkey Cobalt.Feedback.remotePath`
+    FEEDBACK_DEST=$ONLINECONTROL_USER@$ONLINECONTROL_HOST:`getkey Cobalt.Feedback.remotePath`
     echo "Copying feedback to $FEEDBACK_DEST"
     timeout 30s scp $LOFARROOT/var/run/Observation${OBSID}_feedback $FEEDBACK_DEST
 
diff --git a/RTCP/Cobalt/GPUProc/src/scripts/startBGL.sh b/RTCP/Cobalt/GPUProc/src/scripts/startBGL.sh
index 6627983ce9b8c283f4d78aa78929ac9d197af816..85192aeeadaee3301fd5e4d0fd62884d5bffba14 100755
--- a/RTCP/Cobalt/GPUProc/src/scripts/startBGL.sh
+++ b/RTCP/Cobalt/GPUProc/src/scripts/startBGL.sh
@@ -44,14 +44,11 @@ function error {
 [ -f "$PARSET" -a -r "$PARSET" ] || error "Cannot read parset: $PARSET"
 
 # Start observation in the background
-runObservation.sh "$PARSET" > $LOGFILE 2>&1 </dev/null &
+echo "Starting runObservation.sh -P $PIDFILE $PARSET"
+runObservation.sh -P "$PIDFILE" "$PARSET" > $LOGFILE 2>&1 </dev/null &
 PID=$!
 echo "PID: $PID"
 
-# Keep track of PID for stop script
-echo "PID file: $PIDFILE"
-echo $PID > $PIDFILE || error "Could not write PID file: $PIDFILE"
-
 # Done
 echo "Done"
 
diff --git a/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel.cc b/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel.cc
index 9f553026a215f7b64910e8e038a0721c0bf85eff..9b4244d2977b858a448757fffe86291275ec0808 100644
--- a/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel.cc
+++ b/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel.cc
@@ -57,10 +57,10 @@ int main() {
     filteredData(ctx, factory.bufferSize(DelayAndBandPassKernel::OUTPUT_DATA)),
     delaysAtBegin(ctx, factory.bufferSize(DelayAndBandPassKernel::DELAYS)),
     delaysAfterEnd(ctx, factory.bufferSize(DelayAndBandPassKernel::DELAYS)),
-    phaseOffsets(ctx, factory.bufferSize(DelayAndBandPassKernel::PHASE_OFFSETS)),
+    phase0s(ctx, factory.bufferSize(DelayAndBandPassKernel::PHASE_ZEROS)),
     bandPassCorrectionWeights(ctx, factory.bufferSize(DelayAndBandPassKernel::BAND_PASS_CORRECTION_WEIGHTS));
 
-  DelayAndBandPassKernel::Buffers buffers(inputData, filteredData, delaysAtBegin, delaysAfterEnd, phaseOffsets, bandPassCorrectionWeights);
+  DelayAndBandPassKernel::Buffers buffers(inputData, filteredData, delaysAtBegin, delaysAfterEnd, phase0s, bandPassCorrectionWeights);
 
   auto_ptr<DelayAndBandPassKernel> kernel(factory.create(stream, buffers));
 
diff --git a/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel2.cc b/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel2.cc
index 08544891fbcf2c46e8e9ec05dd98473389544f5e..4a0c745e2efff7fabc0399189453caa9fd897182 100644
--- a/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel2.cc
+++ b/RTCP/Cobalt/GPUProc/test/Kernels/tDelayAndBandPassKernel2.cc
@@ -58,11 +58,11 @@ TEST_FIXTURE(TestFixture, Delays)
                 DelayAndBandPassKernel::DELAYS));
 }
 
-TEST_FIXTURE(TestFixture, PhaseOffsets)
+TEST_FIXTURE(TestFixture, Phase0s)
 {
   CHECK_EQUAL(size_t(16),
               factory.bufferSize(
-                DelayAndBandPassKernel::PHASE_OFFSETS));
+                DelayAndBandPassKernel::PHASE_ZEROS));
 }
 
 TEST_FIXTURE(TestFixture, BandPassCorrectionWeights)
diff --git a/RTCP/Cobalt/GPUProc/test/MockOnlineControl.sh b/RTCP/Cobalt/GPUProc/test/MockOnlineControl.sh
index af329f003917e492f19ba536d1fe5755ba093405..dd707fb2188466d7dc98cf2d362973519b135e38 100755
--- a/RTCP/Cobalt/GPUProc/test/MockOnlineControl.sh
+++ b/RTCP/Cobalt/GPUProc/test/MockOnlineControl.sh
@@ -13,7 +13,7 @@ function error {
 
 function getkey {
   KEY=$1
-  <$PARSET perl -ne '/^'$KEY'\s*=\s*"?(.*?)"?\s*$/ || next; print "$1";'
+  <$PARSET perl -ne '/^'$KEY'\s*=\s*"?(.*?)"?\s*$/ || next; print "$1";' | tail -n 1
 }
 
 [ -n "$PARSET" ] || error "No parset specified"
diff --git a/RTCP/Cobalt/GPUProc/test/SubbandProcs/tBeamFormerSubbandProcProcessSb.cc b/RTCP/Cobalt/GPUProc/test/SubbandProcs/tBeamFormerSubbandProcProcessSb.cc
index 316660401c922fce92913dc402183d2e82bc5370..899b1204d73750e51b7d9b213d355923d840c5dd 100644
--- a/RTCP/Cobalt/GPUProc/test/SubbandProcs/tBeamFormerSubbandProcProcessSb.cc
+++ b/RTCP/Cobalt/GPUProc/test/SubbandProcs/tBeamFormerSubbandProcProcessSb.cc
@@ -165,8 +165,8 @@ int main() {
     in.delaysAtBegin.get<float>()[i] = 0.0f;
   for (size_t i = 0; i < in.delaysAfterEnd.num_elements(); i++)
     in.delaysAfterEnd.get<float>()[i] = 0.0f;
-  for (size_t i = 0; i < in.phaseOffsets.num_elements(); i++)
-    in.phaseOffsets.get<float>()[i] = 0.0f;
+  for (size_t i = 0; i < in.phase0s.num_elements(); i++)
+    in.phase0s.get<float>()[i] = 0.0f;
   for (size_t i = 0; i < in.tabDelays.num_elements(); i++)
     in.tabDelays.get<float>()[i] = 0.0f;
 
@@ -196,21 +196,9 @@ int main() {
   // - for 16-bit input: (2 * 32767 * 1 * 64 * 64)^2 = 72053196058525696
   // - for 8-bit input: (2 * 127 * 16 * 64 * 64)^2 = 1082398867456
 
-  float outVal;
-  switch(nrBitsPerSample) {
-  case 8:
-    outVal = 
-      nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2 *
-      nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2; 
-    break;
-  case 16:
-    outVal = 
-      nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2 *
-      nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2; 
-    break;
-  default:
-    break;
-  }
+  float outVal = 
+    nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2 *
+    nrStations * amplitude * scaleFactor * nrChannel1 * nrChannel2; 
   cout << "outVal = " << outVal << endl;
 
   for (size_t s = 0; s < nrStokes; s++)
diff --git a/RTCP/Cobalt/GPUProc/test/SubbandProcs/tCorrelatorSubbandProcProcessSb.cc b/RTCP/Cobalt/GPUProc/test/SubbandProcs/tCorrelatorSubbandProcProcessSb.cc
index 97b67588930c6480c00aafeb0304fd7004f484a7..177907f28f756fd852c0395ea43b2d1315d91451 100644
--- a/RTCP/Cobalt/GPUProc/test/SubbandProcs/tCorrelatorSubbandProcProcessSb.cc
+++ b/RTCP/Cobalt/GPUProc/test/SubbandProcs/tCorrelatorSubbandProcProcessSb.cc
@@ -101,8 +101,8 @@ int main() {
     in.delaysAtBegin.get<float>()[i] = 0.0f;
   for (size_t i = 0; i < in.delaysAfterEnd.size(); i++)
     in.delaysAfterEnd.get<float>()[i] = 0.0f;
-  for (size_t i = 0; i < in.phaseOffsets.size(); i++)
-    in.phaseOffsets.get<float>()[i] = 0.0f;
+  for (size_t i = 0; i < in.phase0s.size(); i++)
+    in.phase0s.get<float>()[i] = 0.0f;
 
   CorrelatedDataHostBuffer out(ps.nrStations(), ps.nrChannelsPerSubband(),
                                ps.integrationSteps(), ctx);
diff --git a/RTCP/Cobalt/GPUProc/test/cuda/tCorrelator.cc b/RTCP/Cobalt/GPUProc/test/cuda/tCorrelator.cc
index 179daf8867661402fb209a7d46a21deece1c4edb..7f0ae12dfaf6e90c99c2746a0d604100c90c4350 100644
--- a/RTCP/Cobalt/GPUProc/test/cuda/tCorrelator.cc
+++ b/RTCP/Cobalt/GPUProc/test/cuda/tCorrelator.cc
@@ -53,7 +53,8 @@ unsigned NR_BASELINES = (NR_STATIONS * (NR_STATIONS + 1) / 2);
 HostMemory runTest(gpu::Context ctx,
                    Stream cuStream,
                    float * inputData,
-                   string function)
+                   string function,
+                   unsigned nrStationsPerFunction)
 {
   string kernelFile = "Correlator.cu";
 
@@ -101,8 +102,9 @@ HostMemory runTest(gpu::Context ctx,
   hKernel.setArg(0, devVisibilitiesMemory);
   hKernel.setArg(1, devCorrectedMemory);
 
-  // Calculate the number of threads in total and per blovk
-  unsigned nrBlocks = NR_BASELINES;
+  // Calculate the number of threads in total and per block
+  unsigned nrFuncStations = (NR_STATIONS + nrStationsPerFunction - 1)/nrStationsPerFunction;
+  unsigned nrBlocks = nrFuncStations * (nrFuncStations + 1) / 2;
   unsigned nrPasses = (nrBlocks + 1024 - 1) / 1024;
   unsigned nrThreads = (nrBlocks + nrPasses - 1) / nrPasses;
   unsigned nrUsableChannels = 15;
@@ -148,6 +150,10 @@ int main()
   const char * kernel_functions[] = {
     "correlate", "correlate_2x2", "correlate_3x3", "correlate_4x4"
   };
+  unsigned kernel_nrstations[] = {
+    1, 2, 3, 4
+  };
+
   unsigned nr_kernel_functions =
     sizeof(kernel_functions) / sizeof(kernel_functions[0]);
 
@@ -162,7 +168,7 @@ int main()
     for (unsigned idx = 0; idx < inputData.num_elements(); ++idx)
       inputData.origin()[idx] = 0;
 
-    HostMemory outputOnHost = runTest(ctx, cuStream, inputData.origin(), function);
+    HostMemory outputOnHost = runTest(ctx, cuStream, inputData.origin(), function, kernel_nrstations[func_idx]);
 
     // Copy the output data to a local array
     outputOnHostPtr = outputOnHost.get<float>();
@@ -241,7 +247,7 @@ int main()
     }
 
     // Run the kernel
-    outputOnHost = runTest(ctx, cuStream, inputData.origin(), function);
+    outputOnHost = runTest(ctx, cuStream, inputData.origin(), function, kernel_nrstations[func_idx]);
 
     // Copy the output data to a local array
     outputOnHostPtr = outputOnHost.get<float>();
@@ -291,16 +297,28 @@ int main()
 
     // insert some values at specific locations in the input matrix
     unsigned timestep = NR_POLARIZATIONS*COMPLEX;
+    // station 0, channel 5:
+    //   X = 2+3i
     // [0][5][7][0][0] = 2
     // [0][5][7][0][1] = 3
     inputData[0][5][timestep * 7] = 2;
     inputData[0][5][timestep * 7 + 1] = 3;
+    // station 1, channel 5:
+    //   Y = 4+5i
     // [1][5][7][1][0] = 4
     // [1][5][7][1][1] = 5
     inputData[1][5][timestep * 7 + NR_POLARIZATIONS] = 4;
     inputData[1][5][timestep * 7 + NR_POLARIZATIONS + 1] = 5;
 
-    outputOnHost = runTest(ctx, cuStream, inputData.origin(), function);
+    // base line order is:
+    //
+    // 0-0, 1-0, 1-1, 2-0, 2-1, 2-2, ...
+
+    const unsigned baseline00 = 0;
+    const unsigned baseline10 = 1;
+    const unsigned baseline11 = 2;
+
+    outputOnHost = runTest(ctx, cuStream, inputData.origin(), function, kernel_nrstations[func_idx]);
 
     // Copy the output data to a local array
     outputOnHostPtr = outputOnHost.get<float>();
@@ -325,22 +343,21 @@ int main()
 
           // We need to find 4 specific indexes with values:
           // THe output location of the values does not change with differing input size
-          if (idx_baseline == 0 &&  idx_channels == 5 && idx == 0)
-            expected = 13.0f;
+          if (idx_baseline == baseline00 &&  idx_channels == 5 && idx == 0)
+            expected = 13.0f; // XX, real((2+3i)(2-3i))
           
-          if (idx_baseline == 1 &&  idx_channels == 5 && idx == 2)
-            expected = 23.0f;
+          if (idx_baseline == baseline10 &&  idx_channels == 5 && idx == 4)
+            expected = 23.0f; // YX, real((4+5i)(2-3i))
 
-          if (idx_baseline == 1 &&  idx_channels == 5 && idx == 3)
-            expected = 2.0f;
+          if (idx_baseline == baseline10 &&  idx_channels == 5 && idx == 5)
+            expected = -2.0f; // YX, imag((4+5i)(2-3i))
           
-          if (idx_baseline == 2 &&  idx_channels == 5 && idx == 6)
-            expected = 41.0f;
+          if (idx_baseline == baseline11 &&  idx_channels == 5 && idx == 6)
+            expected = 41.0f; // YY, real((4+5i)(4-5i))
 
           if (sample != expected)
           {
             cerr << "Unexpected number encountered: got " << sample << " but expected " << expected << endl;
-            return 1;
           }
         }
         cerr << endl;
diff --git a/RTCP/Cobalt/GPUProc/test/cuda/tDelayAndBandPass.cc b/RTCP/Cobalt/GPUProc/test/cuda/tDelayAndBandPass.cc
index e627a69a13b6c91675c042604ee357d34b7b39b6..1d9bd377b5a869f053103526deb42bb4e7c66739 100644
--- a/RTCP/Cobalt/GPUProc/test/cuda/tDelayAndBandPass.cc
+++ b/RTCP/Cobalt/GPUProc/test/cuda/tDelayAndBandPass.cc
@@ -72,7 +72,7 @@ void runKernel(gpu::Function kfunc,
                MultiDimArrayHostBuffer<T,        4> &inputData,
                MultiDimArrayHostBuffer<double,   3> &delaysAtBegin,
                MultiDimArrayHostBuffer<double,   3> &delaysAfterEnd,
-               MultiDimArrayHostBuffer<double,   2> &phaseOffsets,
+               MultiDimArrayHostBuffer<double,   2> &phase0s,
                MultiDimArrayHostBuffer<float,    1> &bandPassFactors,
                double subbandFrequency,
                unsigned beam)
@@ -83,7 +83,7 @@ void runKernel(gpu::Function kfunc,
   gpu::DeviceMemory devInput          (ctx, inputData.size());
   gpu::DeviceMemory devDelaysAtBegin  (ctx, delaysAtBegin.size());
   gpu::DeviceMemory devDelaysAfterEnd (ctx, delaysAfterEnd.size());
-  gpu::DeviceMemory devPhaseOffsets   (ctx, phaseOffsets.size());
+  gpu::DeviceMemory devPhase0s   (ctx, phase0s.size());
   gpu::DeviceMemory devBandPassFactors(ctx, bandPassFactors.size());
 
   kfunc.setArg(0, devOutput);
@@ -92,7 +92,7 @@ void runKernel(gpu::Function kfunc,
   kfunc.setArg(3, beam);
   kfunc.setArg(4, devDelaysAtBegin);
   kfunc.setArg(5, devDelaysAfterEnd);
-  kfunc.setArg(6, devPhaseOffsets);
+  kfunc.setArg(6, devPhase0s);
   kfunc.setArg(7, devBandPassFactors);
 
   gpu::Grid globalWorkSize(1,
@@ -105,7 +105,7 @@ void runKernel(gpu::Function kfunc,
   stream->writeBuffer(devInput,           inputData);
   stream->writeBuffer(devDelaysAtBegin,   delaysAtBegin);
   stream->writeBuffer(devDelaysAfterEnd,  delaysAfterEnd);
-  stream->writeBuffer(devPhaseOffsets,    phaseOffsets);
+  stream->writeBuffer(devPhase0s,    phase0s);
   stream->writeBuffer(devBandPassFactors, bandPassFactors);
 
   stream->launchKernel(kfunc, globalWorkSize, localWorkSize);
@@ -166,7 +166,7 @@ vector<fcomplex> runTest(const CompileDefinitions& compileDefs,
                          unsigned beam,
                          double delayBegin,
                          double delayEnd,
-                         double phaseOffset,
+                         double phase0,
                          float bandPassFactor)
 {
   gpu::Context ctx(stream->getContext());
@@ -222,7 +222,7 @@ vector<fcomplex> runTest(const CompileDefinitions& compileDefs,
                                                     [NR_STATIONS]
                                                     [NR_POLARIZATIONS],
                                                     ctx);
-  MultiDimArrayHostBuffer<double, 2> phaseOffsets(boost::extents
+  MultiDimArrayHostBuffer<double, 2> phase0s(boost::extents
                                                   [NR_STATIONS]
                                                   [NR_POLARIZATIONS],
                                                   ctx);
@@ -241,8 +241,8 @@ vector<fcomplex> runTest(const CompileDefinitions& compileDefs,
   for (size_t i = 0; i < delaysAfterEnd.num_elements(); i++) {
     delaysAfterEnd.origin()[i] = delayEnd;
   }
-  for (size_t i = 0; i < phaseOffsets.num_elements(); i++) {
-    phaseOffsets.origin()[i] = phaseOffset;
+  for (size_t i = 0; i < phase0s.num_elements(); i++) {
+    phase0s.origin()[i] = phase0;
   }
   for (size_t i = 0; i < bandPassFactors.num_elements(); i++) {
     bandPassFactors.origin()[i] = bandPassFactor;
@@ -257,7 +257,7 @@ vector<fcomplex> runTest(const CompileDefinitions& compileDefs,
   gpu::Function kfunc(initKernel(ctx, compileDefs));
 
   runKernel(kfunc, *outputData, *inputData,
-            delaysAtBegin, delaysAfterEnd, phaseOffsets, bandPassFactors,
+            delaysAtBegin, delaysAfterEnd, phase0s, bandPassFactors,
             subbandFrequency, beam);
 
   // Tests that use this function only check the first and last 2 output floats.
@@ -297,7 +297,7 @@ TEST(BandPass)
   CHECK_CLOSE(2.0, results[1].imag(), 0.000001);
 }
 
-TEST(PhaseOffsets)
+TEST(Phase0s)
 {
   //**********************************************************************
   // Delaycompensation but only for the phase ofsets:
@@ -313,7 +313,7 @@ TEST(PhaseOffsets)
                              0U,     // beam
                              0.0,    // delays begin
                              0.0,    // delays end
-                             M_PI,   // phase offsets
+                             -M_PI,  // phase offsets
                              1.0f)); // bandpass factor
 
   CHECK_CLOSE(-1.0, results[0].real(), 0.000001);
@@ -345,31 +345,63 @@ SUITE(DelayCompensation)
                                0.0,    // phase offsets
                                1.0f)); // bandpass factor
 
+    // For verification: for the following vals, the kernel computes for
+    // channel 0:
+    //
+    // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+    //             = 1.0              - 0.5 * 1.0              + 0        * (1.0 / 16)
+    //             = 0.5
+    // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+    //             = -2.0 * 3.1415926536 * 0.5       * 1.0          - 0.0
+    //             = -M_PI
+    // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+    //             = -2.0 * 3.1415926536 * 0.5       * 1.0           - 0.0
+    //             = -M_PI
+    //
+    // For all time steps t = [0..1):
+    //   phi = phiAtBegin * (1.0 - t) + phiAfterEnd * t
+    //        = -M_PI
+    //    
+    //   cos(phi) = -1.0
+    //   sin(phi) = -0.0
+    //
+    // In:
+    //   sampleX = sampleY = 1.0 + 1.0i
+    // Out:
+    //   sampleX *= cos(phi) + i*sin(phi)
+    //            = -1.0 + -1.0i
+
     CHECK_CLOSE(-1.0, results[0].real(), 0.000001);
     CHECK_CLOSE(-1.0, results[0].imag(), 0.000001);
 
-    // For verification: for the following vals, the kernel computes:
-    // major: offset within block of 16 samples
-    // frequency = 1.0 - 0.5*1.0 + (0 + 15) * (1.0 / 16) = 0.5 + 15/16 = 1.4375
-    // phiBegin = -2.0 * 3.141593 * delayAtBegin = -6.283185 * 1.0 = -6.283185
-    // deltaPhi = (phiEnd - phiBegin) / 64 = 0
-    // myPhiBegin = (-6.283185 + major * deltaPhi) * frequency + phaseOffset
-    //            = (-6.283185 + 0.0) * 1.4375 + 0.0 = -9.032079
-    // myPhiDelta = 16 (= time step) * deltaPhi * frequency = 0
-    // vX = ( cos(myPhiBegin.x), sin(myPhiBegin.x) ) = (-0.923880, -0.382683)
-    // vY = idem (as delays begin == delays end)
-    // dvX = ( cos(myPhiDelta.x), sin(myPhiDelta.x) ) = (1, 0)
-    // dvY = idem
-    // (vX, vY) *= weight (*1.0)
-    // sampleX = sampleY = (1.0, 1.0)
-    // After 64/16 rounds, (vX, vY) have been updated 64/16 times with
-    // (dvX, dvY).
-    // In this case, (dvX, dvY) stays (1, 0), so for the last sample, we get:
-    // sampleY = cmul(sampleY, vY) = -0.923880 - -0.382683 = -0.541196 (real)
-    //                             = -0.923880 + -0.382683 = -1.306563 (imag)
-
-    CHECK_CLOSE(-0.541196, results[1].real(), 0.000001);
-    CHECK_CLOSE(-1.306563, results[1].imag(), 0.000001);
+    // For verification: for the following vals, the kernel computes for
+    // channel 15:
+    //
+    // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+    //             = 1.0              - 0.5 * 1.0              + (0 + 15) * (1.0 / 16)
+    //             = 0.5 + 15/16 = 1.4375
+    // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+    //             = -2.0 * 3.1415926536 * 1.4375    * 1.0          - 0.0
+    //             = -9.0320788791
+    // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+    //             = -2.0 * 3.1415926536 * 1.4375    * 1.0           - 0.0
+    //             = -9.0320788791
+    //
+    // For all time steps t = [0..1):
+    //   phi = phiAtBegin * (1.0 - t) + phiAfterEnd * t
+    //        = -9.0320788791
+    //    
+    //   cos(phi) = -0.9238795325
+    //   sin(phi) = -0.3826834324
+    //
+    // In:
+    //   sampleX = sampleY = 1.0 + 1.0i
+    // Out:
+    //   sampleY *= cos(phi) + i*sin(phi)
+    //            = -0.5411961001 + -1.3065629649i
+
+    CHECK_CLOSE(-0.5411961001, results[1].real(), 0.000001);
+    CHECK_CLOSE(-1.3065629649, results[1].imag(), 0.000001);
   }
 
   TEST(SlopedDelay)
@@ -378,34 +410,12 @@ SUITE(DelayCompensation)
     // delays: begin 1, end 0; no phase offset; frequency 1; subband width 1;
     // all (complex) input samples are set to (1.0, 1.0) in runTest().
     //
-    // timeStep  = 16 (hard-coded)
-    // channel   = 0
-    // frequency = subbandFrequency - .5 * SUBBAND_BANDWIDTH
-    //             + channel * (SUBBAND_BANDWIDTH / NR_CHANNELS)
-    // phiBegin  = -2.0 * PI * delayAtBegin  = -6.283185 * 1.0 = -6.283185
-    // phiEnd    = -2.0 * PI * delayAfterEnd = -6.283185 * 0.0 =  0.0
-    // deltaPhi  = (phiEnd - phiBegin) / (NR_SAMPLES_PER_CHANNEL)
-    //           = (0.0 - -6.283135) / 64 = 0.0981748
-    //
-    // For result[0]:
-    // major = 0
-    // frequency  = 1.0 - 0.5 * 1.0 + (0 + 0) * (1.0 / 16) = 1 - 0.5 + 0 = 0.5
-    // myPhiBegin = (phiBegin + major * deltaPhi) * frequency + phaseOffset
-    //            = (-6.283185 + 0.0 * 0.0981748) * 0.5 + 0.0 = -3.141593
-    // myPhiDelta = timeStep * deltaPhi * frequency
-    //            = 16 * 0.0981748 * 0.5 = 0.785398
-    // vX =  vY   = (cos(myPhiBegin) + sin(myPhiBegin)j)
-    //            = (cos(-3.141593) + sin(-3.141593)j) = (-1 + 0j)
-    // dvX = dvY  = (cos(myPhiDelta) + sin(myPhiDelta)j)
-    //            = (cos(0.785398) + sin(0.785398)j) = (0.707107 + 0.707107j)
-    // sample     = sample * (cos(myPhiBegin) + sin(myPhiBegin)j)
-    //            = (1 + j) * (-1, 0j) = (-1, -j)
     //
     // For result[1]:
     // major = 15
     // frequency  = 1.0 - 0.5 * 1.0 + (0 + 15) * (1.0 / 16)
     //            = 0.5 + 15/16 = 1.4375
-    // myPhiBegin = (phiBegin + major * deltaPhi) * frequency + phaseOffset
+    // myPhiBegin = (phiBegin + major * deltaPhi) * frequency + phase0
     //            = (-6.283185 + 15 * 0.0981748) * 1.4375 + 0.0 = -6.915185
     // myPhiDelta = timeStep * deltaPhi * frequency
     //            = 16 * 0.0981748 * 1.4375 = 2.258020
@@ -432,59 +442,73 @@ SUITE(DelayCompensation)
                                0.0,    // phase offsets
                                1.0f)); // bandpass factor
 
+    // For verification: for the following vals, the kernel computes for
+    // channel 0:
+    //
+    // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+    //             = 1.0              - 0.5 * 1.0              + 0        * (1.0 / 16)
+    //             = 0.5
+    // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+    //             = -2.0 * 3.1415926536 * 0.5       * 1.0          - 0.0
+    //             = -M_PI
+    // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+    //             = -2.0 * 3.1415926536 * 0.5       * 0.0           - 0.0
+    //             = 0.0
+    //
+    // For time step t = 0:
+    //   phi = phiAtBegin * (1.0 - t) + phiAfterEnd * t
+    //        = -M_PI
+    //    
+    //   cos(phi) = -1.0
+    //   sin(phi) = -0.0
+    //
+    // In:
+    //   sampleX = sampleY = 1.0 + 1.0i
+    // Out:
+    //   sampleX *= cos(phi) + i*sin(phi)
+    //            = -1.0 + -1.0i
+
     CHECK_CLOSE(-1.0,     results[0].real(), 0.000001);
     CHECK_CLOSE(-1.0,     results[0].imag(), 0.000001);
-    CHECK_CLOSE(1.130716, results[1].real(), 0.000001);
-    CHECK_CLOSE(0.849400, results[1].imag(), 0.000001);
+
+    // For verification: for the following vals, the kernel computes for
+    // channel 15:
+    //
+    // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+    //             = 1.0              - 0.5 * 1.0              + (0 + 15) * (1.0 / 16)
+    //             = 0.5 + 15/16 = 1.4375
+    // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+    //             = -2.0 * 3.1415926536 * 1.4375    * 1.0          - 0.0
+    //             = -9.0320788791
+    // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+    //             = -2.0 * 3.1415926536 * 1.4375    * 0.0           - 0.0
+    //             = 0.0
+    //
+    // For time step t = (NR_SAMPLES_PER_CHANNEL-1) / NR_SAMPLES_PER_CHANNEL
+    //                 = 63/64
+    //   phi = phiAtBegin * (1.0 - t) + phiAfterEnd * t
+    //       = -9.0320788791 * 1/64   + 0.0
+    //       = -0.1411262325
+    //
+    //   cos(phi) = -0.9900582103
+    //   sin(phi) = -0.1406582393
+    //
+    // In:
+    //   sampleX = sampleY = 1.0 + 1.0i
+    // Out:
+    //   sampleY *= cos(phi) + i*sin(phi)
+    //            = 1.1307164496 + 0.8493999709i
+
+    CHECK_CLOSE(1.1307164496, results[1].real(), 0.000001);
+    CHECK_CLOSE(0.8493999709, results[1].imag(), 0.000001);
   }
 }
 
 TEST(AllAtOnce)
 {
   //**************************************************************************
-  // delays: begin 1, end 0; phase offset 1 rad.; frequency: 1;
+  // delays: begin 1, end 0; phase offset -1 rad.; frequency: 1;
   // subband width: 1; band-pass factor: 2
-  //
-  // timeStep  = 16 (hard-coded)
-  // channel   = 0
-  // frequency = subbandFrequency - .5 * SUBBAND_BANDWIDTH
-  //             + channel * (SUBBAND_BANDWIDTH / NR_CHANNELS)
-  // phiBegin  = -2.0 * PI * delayAtBegin  = -6.283185 * 1.0 = -6.283185
-  // phiEnd    = -2.0 * PI * delayAfterEnd = -6.283185 * 0.0 =  0.0
-  // deltaPhi  = (phiEnd - phiBegin) / (NR_SAMPLES_PER_CHANNEL)
-  //           = (0.0 - -6.283135) / 64 = 0.0981748
-  //
-  // For result[0]:
-  // major = 0
-  // frequency  = 1.0 - 0.5 * 1.0 + (0 + 0) * (1.0 / 16) = 1 - 0.5 + 0 = 0.5
-  // myPhiBegin = (phiBegin + major * deltaPhi) * frequency + phaseOffset
-  //            = (-6.283185 + 0.0 * 0.0981748) * 0.5 + 1.0 = -2.141593
-  // myPhiDelta = timeStep * deltaPhi * frequency
-  //            = 16 * 0.0981748 * 0.5 = 0.785398
-  // vX =  vY   = (cos(myPhiBegin) + sin(myPhiBegin))
-  //            = (cos(-2.141593) + sin(-2.141593)j) = (-0.540302 + -0.841471j)
-  // dvX = dvY  = (cos(myPhiDelta) + sin(myPhiDelta))
-  //            = (cos(0.785398) + sin(0.785398)j) = (0.707107 + 0.707107j)
-  // sample     = sample * weight * (cos(myPhiBegin) + sin(myPhiBegin)j)
-  //            = (1, j) * 2 * (-0.540302 + -0.841471j) =
-  //
-  // For result[1]:
-  // major = 15
-  // frequency  = 1.0 - 0.5 * 1.0 + (0 + 15) * (1.0 / 16)
-  //            = 0.5 + 15/16 = 1.4375
-  // myPhiBegin = (phiBegin + major * deltaPhi) * frequency + phaseOffset
-  //            = (-6.283185 + 15 * 0.0981748) * 1.4375 + 1.0 = -5.915185
-  // myPhiDelta = timeStep * deltaPhi * frequency
-  //            = 16 * 0.0981748 * 1.4375 = 2.258020
-  // vX  = vY   = (cos(myPhiBegin) + sin(myPhiBegin)j) =
-  //            = (cos(-5.915185), sin(-5.915185)j) = (0.933049 + 0.359750j)
-  // dvX = dvY  = (cos(myPhiDelta + sin(myPhiDelta)j)
-  //            = (cos(2.258020) + sin(2.258020)j) = (-0.634393 + 0.773010j)
-  //   After ((NR_SAMPLES_PER_CHANNEL - 1) / timeStep) rounds, we have
-  //   applied 63 / 16 = 3 times a phase rotation
-  // myPhiEnd   = myPhiBegin + 3 * myPhiDelta = 0.858874
-  // sample     = sample * weight * (cos(myPhiEnd) + sin(myPhiEnd)j)
-  //            = (1 + j) * 2 * (0.653291 + 0.757107j) = (-0.207633 + 2.820796j)
 
   CompileDefinitions defs(getDefaultCompileDefinitions());
   defs["DELAY_COMPENSATION"] = "1";
@@ -496,13 +520,72 @@ TEST(AllAtOnce)
                              0U,     // beam
                              1.0,    // delays begin
                              0.0,    // delays end
-                             1.0,    // phase offsets (1 rad)
+                             -1.0,   // phase offsets (-1 rad)
                              2.0f)); // bandpass factor (weights == 2)
 
-  CHECK_CLOSE( 0.602337, results[0].real(), 0.000001);
-  CHECK_CLOSE(-2.763547, results[0].imag(), 0.000001);
-  CHECK_CLOSE(-0.207633, results[1].real(), 0.000001);
-  CHECK_CLOSE( 2.820796, results[1].imag(), 0.000001);
+  // For verification: for the following vals, the kernel computes for
+  // channel 0:
+  //
+  // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+  //             = 1.0              - 0.5 * 1.0              + 0        * (1.0 / 16)
+  //             = 0.5
+  // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+  //             = -2.0 * 3.1415926536 * 0.5       * 1.0          + 1.0
+  //             = -2.1415926536
+  // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+  //             = -2.0 * 3.1415926536 * 0.5       * 0.0           + 1.0
+  //             = 1.0
+  //
+  // For time step t = 0:
+  //   phi = phiAtBegin * (1.0 - t) + phiAfterEnd * t
+  //        = -2.1415926536
+  //    
+  //   cos(phi) = -0.5403023059
+  //   sin(phi) = -0.8414709845
+  //
+  //   weight = 2.0
+  //
+  // In:
+  //   sampleX = sampleY = 1.0 + 1.0i
+  // Out:
+  //   sampleX *= weight * (cos(phi) + i*sin(phi))
+  //           = 0.60233735788 + -2.7635465814i
+
+  CHECK_CLOSE(0.60233735788, results[0].real(), 0.000001);
+  CHECK_CLOSE(-2.7635465814, results[0].imag(), 0.000001);
+
+  // For verification: for the following vals, the kernel computes for
+  // channel 15:
+  //
+  // frequency   = subbandFrequency - 0.5 * subbandBandwidth + channel  * channelBandwidth
+  //             = 1.0              - 0.5 * 1.0              + (0 + 15) * (1.0 / 16)
+  //             = 0.5 + 15/16 = 1.4375
+  // phiAtBegin  = -2.0 * M_PI         * frequency * delayAtBegin - phase0
+  //             = -2.0 * 3.1415926536 * 1.4375    * 1.0          + 1.0
+  //             = -8.0320788791
+  // phiAfterEnd = -2.0 * M_PI         * frequency * delayAfterEnd - phase0
+  //             = -2.0 * 3.1415926536 * 1.4375    * 0.0           + 1.0
+  //             = 1.0
+  //
+  // For time step t = (NR_SAMPLES_PER_CHANNEL-1) / NR_SAMPLES_PER_CHANNEL
+  //                 = 63/64
+  //   phi = phiAtBegin    * (1.0 - t) + phiAfterEnd * t
+  //       = -8.0320788791 * 1/64      + 1.0         * 63/64
+  //       = 0.8588737675
+  //
+  //   cos(phi) = 0.6532905611
+  //   sin(phi) = 0.7571072862
+  //
+  //   weight = 2.0
+  //
+  // In:
+  //   sampleX = sampleY = 1.0 + 1.0i
+  // Out:
+  //   sampleX *= weight * (cos(phi) + i*sin(phi))
+  //            = -0.2076334501 + 2.8207956946i
+
+  CHECK_CLOSE(-0.2076334501, results[1].real(), 0.000001);
+  CHECK_CLOSE(2.8207956946 , results[1].imag(), 0.000001);
 }
 
 
@@ -533,7 +616,6 @@ int main()
   gpu::Stream strm(initDevice());
   stream = &strm;
 
-  int exitStatus = UnitTest::RunAllTests();
-  return exitStatus > 0 ? 1 : 0;
+  return UnitTest::RunAllTests() > 0;
 }
 
diff --git a/RTCP/Cobalt/GPUProc/test/tBeamform_1sec_1st_5sb_noflagging.parset b/RTCP/Cobalt/GPUProc/test/tBeamform_1sec_1st_5sb_noflagging.parset
index eda6581d0673921a0eb6b1135479d7aee13bb381..3e91e73b2fb3f33650f808f8089df84e6febc7ff 100644
--- a/RTCP/Cobalt/GPUProc/test/tBeamform_1sec_1st_5sb_noflagging.parset
+++ b/RTCP/Cobalt/GPUProc/test/tBeamform_1sec_1st_5sb_noflagging.parset
@@ -199,7 +199,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tBeamform_incoherent_2sec_1st_5sb_noflagging.parset b/RTCP/Cobalt/GPUProc/test/tBeamform_incoherent_2sec_1st_5sb_noflagging.parset
index cc516bfaf9b34f0cb615f4a4db3b8f718a463241..740cb31d6b573eda789c554a5ab0e7b56c44dd96 100644
--- a/RTCP/Cobalt/GPUProc/test/tBeamform_incoherent_2sec_1st_5sb_noflagging.parset
+++ b/RTCP/Cobalt/GPUProc/test/tBeamform_incoherent_2sec_1st_5sb_noflagging.parset
@@ -199,7 +199,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB0.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB0.MS
index 69ea12d133d0dcb42871ce3791dba1e19c9e9e20..562bf16f82ea027c9e1054324a9fc90b0cc030ac 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB0.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB0.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB1.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB1.MS
index acb52546d9a7ad14af02629ddade2391cd835cf8..b58cd03dbf193d45d31ce5d5b031b17b8c8a2ca9 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB1.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB1.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB2.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB2.MS
index 85af9128e3b18aa7881cd63e65433c003c97c09e..8033bae246f5f5a66001441568ec54fe1be63f8e 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB2.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB2.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB3.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB3.MS
index f93f2871f8b7a227bb051567246c728ee74d5d41..5366f606202a7718384856f73c40ca772813efa5 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB3.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB3.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB4.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB4.MS
index e931298b672d0c4f6cc6a8eeafe8b7127e67f18d..38d49f09afa12885d1dc164caf7c3e1efe1ac782 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB4.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.output/SB4.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.parset b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.parset
index f451e53d6795ecba1875e6049dbdfd4204cf9d15..6ce0e3a17f65e6aa5a2139889a3dd92afd8506aa 100644
--- a/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.parset
+++ b/RTCP/Cobalt/GPUProc/test/tCorrelate_1sec_1st_5sb_noflagging.parset
@@ -200,7 +200,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB0.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB0.MS
index a3d21c556b595a1825cf79634671980de3230481..e851d3a89316671f690200482c172c4b10b7306e 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB0.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB0.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB1.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB1.MS
index 6eaf212d92d0fc0caabde0a571b6349a72205869..a274072c328f9cf1069cdcb9c3a09a2b54108585 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB1.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB1.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB2.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB2.MS
index 91d90a7608999d6574e21b1969133a7e38c7d68c..548e670d40e63267045d3761597a1e666944348e 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB2.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB2.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB3.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB3.MS
index 82d14a40b620dff29035717d1a2b0defde496e35..012ae12dfdd1e85fc19eca932c1e5d4eb0f3da82 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB3.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB3.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB4.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB4.MS
index 6554de89e259f7a62464462aced2a2913b3d122e..2c37624c781153706dbebc099a3743dfc8b623fc 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB4.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.output/SB4.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.parset b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.parset
index df85001d504261b138da4f004f4e7972f589b686..08e38d32112f8fa82ab2ff816f6154765319f71d 100644
--- a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.parset
+++ b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_1st_5sb.parset
@@ -200,7 +200,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0,RS106HBA/RSP1,RS106HBA/RSP2,RS10
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB0.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB0.MS
index e34754f6038e50995e9fde9e04effc18b2e0c631..337740722037dfe56a33c78b28ba13ec8236e4b4 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB0.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB0.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB1.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB1.MS
index 0c60431cb19801e554b76a0b6c2e3197938deac1..2aa88dafb012f88c07488465ebc5376efb238f07 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB1.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB1.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB2.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB2.MS
index ffe92443f1ccc11e9e719c61865b36d87d986fb9..9041fd20430d58bb2ee012c5a8c49b63695a8ac3 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB2.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB2.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB3.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB3.MS
index 986733c6088f6e93c400ac238e5470cfa8e6a200..f6bee8d9518005c30861bb00d3c7d9384ca21f49 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB3.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB3.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB4.MS b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB4.MS
index 76abe34e9267a03ded523a8c4ee618e8f9e3e5b2..f8704bf7a6c8dbc5504c3b6d152cbe731dcebd9e 100644
Binary files a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB4.MS and b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.output/SB4.MS differ
diff --git a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.parset b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.parset
index e44cea72cca792c996bf29539f4b7dc35e116b95..6a4f6b617546c0ec5c67a8ac7273fa4d0006fe13 100644
--- a/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.parset
+++ b/RTCP/Cobalt/GPUProc/test/tCorrelate_3sec_2st_5sb.parset
@@ -195,7 +195,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
@@ -210,7 +210,7 @@ PIC.Core.IONProc.R00[1].inputs = [RS205HBA/RSP0]
 PIC.Core.RS205HBA.clockCorrectionTime = 0
 PIC.Core.RS205HBA.phaseCenter = [3831479.670,463487.529,5060989.903]
 PIC.Core.RS205HBA.position = [3831479.670,463487.529,5060989.903]
-PIC.Core.Station.RS205HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs205.udp]
+PIC.Core.RS205HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs205.udp]
 Cobalt.Kernels.BeamFormerKernel.dumpOutput = false
 Cobalt.Kernels.BeamFormerTransposeKernel.dumpOutput = false
 Cobalt.Kernels.CoherentStokesKernel.dumpOutput = false
diff --git a/RTCP/Cobalt/GPUProc/test/tGPUPerformance.parset b/RTCP/Cobalt/GPUProc/test/tGPUPerformance.parset
index 7233779785d9b9f7ab6ae4eccb540a6b43e6572f..3ba4008282ad8c3c31e3c3cc470f17df35031a96 100644
--- a/RTCP/Cobalt/GPUProc/test/tGPUPerformance.parset
+++ b/RTCP/Cobalt/GPUProc/test/tGPUPerformance.parset
@@ -198,7 +198,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [factory:]
+PIC.Core.RS106HBA.RSP.ports = [factory:]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
@@ -213,5 +213,5 @@ PIC.Core.IONProc.R00[1].inputs = [RS205HBA/RSP0]
 PIC.Core.RS205HBA.clockCorrectionTime = 0
 PIC.Core.RS205HBA.phaseCenter = [3831479.670,463487.529,5060989.903]
 PIC.Core.RS205HBA.position = [3831479.670,463487.529,5060989.903]
-PIC.Core.Station.RS205HBA.RSP.ports = [factory:]
+PIC.Core.RS205HBA.RSP.ports = [factory:]
 
diff --git a/RTCP/Cobalt/GPUProc/test/tMACfeedback.in_parset b/RTCP/Cobalt/GPUProc/test/tMACfeedback.in_parset
index e7a9603691de6f59659b01f0e0937a86a2afd464..c1a8e0158095fbe91290f78200b1e69d167a6197 100644
--- a/RTCP/Cobalt/GPUProc/test/tMACfeedback.in_parset
+++ b/RTCP/Cobalt/GPUProc/test/tMACfeedback.in_parset
@@ -200,7 +200,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/t_cpu_utils.in_parset b/RTCP/Cobalt/GPUProc/test/t_cpu_utils.in_parset
index 34ffce32680e5b6e4dbd73843134b6c2c1962a15..d43aed7f35af3379bddaf14dfa7bfa3b8ce1bbd0 100644
--- a/RTCP/Cobalt/GPUProc/test/t_cpu_utils.in_parset
+++ b/RTCP/Cobalt/GPUProc/test/t_cpu_utils.in_parset
@@ -200,7 +200,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tstartBGL.in_parset b/RTCP/Cobalt/GPUProc/test/tstartBGL.in_parset
index e7a9603691de6f59659b01f0e0937a86a2afd464..c1a8e0158095fbe91290f78200b1e69d167a6197 100644
--- a/RTCP/Cobalt/GPUProc/test/tstartBGL.in_parset
+++ b/RTCP/Cobalt/GPUProc/test/tstartBGL.in_parset
@@ -200,7 +200,7 @@ PIC.Core.IONProc.R00[0].inputs = [RS106HBA/RSP0]
 PIC.Core.RS106HBA.clockCorrectionTime = 0
 PIC.Core.RS106HBA.phaseCenter = [3829205.598,469142.533,5062181.002]
 PIC.Core.RS106HBA.position = [3829205.598,469142.533,5062181.002]
-PIC.Core.Station.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
+PIC.Core.RS106HBA.RSP.ports = [file:/var/scratch/mol/test_sets/3sec/rs106.udp]
 _DPname = LOFAR_ObsSW_TempObs0024
 _parsetPrefix = CorrAppl.CorrProc.
 _processName = CorrProc
diff --git a/RTCP/Cobalt/GPUProc/test/tstartBGL.run b/RTCP/Cobalt/GPUProc/test/tstartBGL.run
index 01fa98e0976684a777ed9a46f27b8a74e5549f8b..d4acd73a6463889cd87b689b4caa74d0820f987c 100755
--- a/RTCP/Cobalt/GPUProc/test/tstartBGL.run
+++ b/RTCP/Cobalt/GPUProc/test/tstartBGL.run
@@ -63,8 +63,8 @@ echo "        (expects success)"
 echo "***************************"
 startBGL.sh 1 2 3 $testdir/tstartBGL.in_parset 1000 || error "startBGL.sh failed"
 
-# PID file must be present
-[ -r $LOFARROOT/var/run/rtcp-1000.pid ] || error "Cannot read $LOFARROOT/var/run/rtcp-1000.pid"
+# PID file must be gone
+[ ! -e $LOFARROOT/var/run/rtcp-1000.pid ] || error "Found lingering $LOFARROOT/var/run/rtcp-1000.pid"
 
 # Log file must be present
 [ -r $LOFARROOT/var/log/rtcp-1000.log ] || error "Cannot read $LOFARROOT/var/log/rtcp-1000.log"
diff --git a/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.h b/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.h
index 2614b4bddc73b00e8cb2488379eb721e64050610..fb2ecc1349c09d25637ea1ffc387269cdc8577d4 100644
--- a/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.h
+++ b/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.h
@@ -79,6 +79,9 @@ namespace LOFAR
 
         struct Block<T>::Beamlet getBeamlet( size_t beamletIdx, ssize_t offset );
 
+        const TimeStamp minFrom; // the earliest timestamp that we read, when adjusted for beamletOffsets
+        const TimeStamp maxTo;   // the latest timestamp that we read, when adjusted for beamletOffsets
+
         friend class BlockReader<T>;
       };
 
diff --git a/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.tcc b/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.tcc
index b63b1e514ab09c6b498aed636b8cdeb875d1f752..50ff9124a4f7601944c2699ddcc767e99e881a84 100644
--- a/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.tcc
+++ b/RTCP/Cobalt/InputProc/src/Buffer/BlockReader.tcc
@@ -21,6 +21,8 @@
 
 #include <Common/LofarLogger.h>
 
+#include <algorithm>
+
 namespace LOFAR {
 
   namespace Cobalt {
@@ -98,7 +100,13 @@ namespace LOFAR {
     template<typename T>
     BlockReader<T>::LockedBlock::LockedBlock( BlockReader<T> &reader, const TimeStamp &from, const TimeStamp &to, const std::vector<ssize_t> &beamletOffsets )
     :
-      reader(reader)
+      reader(reader),
+
+      // We only need minFrom/maxTo in non-real-time mode, to lock the proper
+      // part of the circular buffer. However, a block is read only once
+      // a second or so so the overhead is negligable even in real-time mode.
+      minFrom(from + *std::min_element(beamletOffsets.begin(), beamletOffsets.end())),
+      maxTo(to + *std::max_element(beamletOffsets.begin(), beamletOffsets.end()))
     {
       this->from = from;
       this->to   = to;
@@ -113,12 +121,12 @@ namespace LOFAR {
 
       // clear path for writer
       for (std::vector<size_t>::const_iterator b = reader.beamlets.begin(); b != reader.beamlets.end(); ++b) {
-        reader.buffer.noReadBefore(*b, this->from);
+        reader.buffer.noReadBefore(*b, minFrom);
       }
 
       // signal read intent on all buffers
       for (std::vector<size_t>::const_iterator b = reader.beamlets.begin(); b != reader.beamlets.end(); ++b) {
-        reader.buffer.startRead(*b, this->from, this->to);
+        reader.buffer.startRead(*b, minFrom, maxTo);
       }
 
       //LOG_DEBUG_STR("Locked block " << this->from << " to " << this->to);
@@ -187,7 +195,17 @@ namespace LOFAR {
       // Signal end of read intent on all buffers
       for (std::vector<size_t>::const_iterator b = reader.beamlets.begin(); b != reader.beamlets.end(); ++b) {
         // Unlock data
-        reader.buffer.stopRead(*b, this->to);
+        //
+        // Note that we should not unlock data that might be needed by the next
+        // block. A complicating factor is that the next block might start
+        // earlier than our `minTo', because delay compensation might cross
+        // a sample boundary, requiring one sample more.
+        //
+        // We stay very conservative, and merely assume that the next block
+        // won't start before this one. Given that the buffer is large enough
+        // to contain several blocks, freeing up to `minFrom' should provide
+        // enough space and progress.
+        reader.buffer.stopRead(*b, minFrom);
       }
     }
 
@@ -204,8 +222,15 @@ namespace LOFAR {
 
       // wait for block start (but only in real-time mode)
       if (!buffer.sync) {
-        LOG_DEBUG_STR("Waiting until " << (to + maxDelay) << " for " << from << " to " << to);
-        waiter.waitUntil(to + maxDelay);
+        const TimeStamp deadline = to + maxDelay;
+
+        LOG_DEBUG_STR("Waiting until " << deadline << " for " << from << " to " << to);
+        if (deadline < TimeStamp::now(deadline.getClock())) {
+          // We're too late!
+          LOG_ERROR_STR("Not running at real time! Deadline was " << deadline << " for " << from << " to " << to);
+        }
+
+        waiter.waitUntil(deadline);
       }
 
       return new LockedBlock(*this, from, to, beamletOffsets);
diff --git a/RTCP/Cobalt/InputProc/src/Buffer/SampleBuffer.tcc b/RTCP/Cobalt/InputProc/src/Buffer/SampleBuffer.tcc
index 1fcd081fc882e645f971881b086b249d07db87c5..ef84d93aebdc20100ca7aae9e0b31643c8873b04 100644
--- a/RTCP/Cobalt/InputProc/src/Buffer/SampleBuffer.tcc
+++ b/RTCP/Cobalt/InputProc/src/Buffer/SampleBuffer.tcc
@@ -76,12 +76,12 @@ namespace LOFAR
 
       if (create) {
         // register settings
-        LOG_INFO_STR( logPrefix << "Registering " << localSettings.station );
+        LOG_DEBUG_STR( logPrefix << "Registering " << localSettings.station );
         *sharedSettings = localSettings;
       } else {
         // verify settings
         ASSERT( *sharedSettings == localSettings );
-        LOG_INFO_STR( logPrefix << "Connected to " << localSettings.station );
+        LOG_DEBUG_STR( logPrefix << "Connected to " << localSettings.station );
       }
 
       return sharedSettings;
diff --git a/RTCP/Cobalt/InputProc/src/CMakeLists.txt b/RTCP/Cobalt/InputProc/src/CMakeLists.txt
index 0e20928847e535f2a696fc32e9ebac3013d89534..7fbae7f03fd05621fae5f6f010657bc7351df8c2 100644
--- a/RTCP/Cobalt/InputProc/src/CMakeLists.txt
+++ b/RTCP/Cobalt/InputProc/src/CMakeLists.txt
@@ -40,6 +40,12 @@ lofar_add_bin_program(printRSP Station/printRSP.cc)
 lofar_add_bin_program(generateRSP Station/generateRSP.cc)
 lofar_add_bin_program(generate Station/generate.cc)
 lofar_add_bin_program(capture Station/capture.cc)
+lofar_add_bin_program(printDelays Delays/printDelays.cc)
+
+# install the logprop file
+install(FILES
+  Delays/printDelays.log_prop
+  DESTINATION etc)
 
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/mpirun.sh.in
diff --git a/RTCP/Cobalt/InputProc/src/Delays/Delays.cc b/RTCP/Cobalt/InputProc/src/Delays/Delays.cc
index 14cf5383d18036ca926906d32c11a9e236910df1..e497e121f9208b98ccbe79312879bc5deb268915 100644
--- a/RTCP/Cobalt/InputProc/src/Delays/Delays.cc
+++ b/RTCP/Cobalt/InputProc/src/Delays/Delays.cc
@@ -78,32 +78,6 @@ namespace LOFAR
     }
 
 
-    void Delays::BeamDelays::read( Stream *str ) {
-      size_t nrTABs;
-
-      str->read(&SAP, sizeof SAP);
-
-      str->read(&nrTABs, sizeof nrTABs);
-      ASSERT(nrTABs == TABs.size());
-
-      if (nrTABs > 0) {
-        str->read(&TABs[0], TABs.size() * sizeof TABs[0]);
-      }
-    }
-
-
-    void Delays::BeamDelays::write( Stream *str ) const {
-      size_t nrTABs = TABs.size();
-
-      str->write(&SAP, sizeof SAP);
-
-      str->write(&nrTABs, sizeof nrTABs);
-      if (nrTABs > 0) {
-        str->write(&TABs[0], TABs.size() * sizeof TABs[0]);
-      }
-    }
-
-
     Delays::AllDelays::AllDelays( const Parset &parset ) {
         SAPs.resize(parset.settings.SAPs.size());
 
@@ -117,29 +91,6 @@ namespace LOFAR
     }
 
 
-    void Delays::AllDelays::read( Stream *str ) {
-      size_t nrSAPs;
-
-      str->read(&nrSAPs, sizeof nrSAPs);
-      ASSERT(nrSAPs == SAPs.size());
-
-      for (size_t n = 0; n < SAPs.size(); ++n) {
-        SAPs[n].read(str);
-      }
-    }
-
-
-    void Delays::AllDelays::write( Stream *str ) const {
-      size_t nrSAPs = SAPs.size();
-
-      str->write(&nrSAPs, sizeof nrSAPs);
-
-      for (size_t n = 0; n < SAPs.size(); ++n) {
-        SAPs[n].write(str);
-      }
-    }
-
-
 #ifdef HAVE_CASACORE
     using namespace casa;
 
@@ -248,8 +199,7 @@ namespace LOFAR
         d.direction[2] = 0.0;
       }
 
-      // Add non-geometric delays
-      d.delay += baseDelay();
+      d.clockCorrection = clockCorrection();
 
       return d;
     }
@@ -300,11 +250,13 @@ namespace LOFAR
       (void)timestamp;
 
       for (size_t sap = 0; sap < result.SAPs.size(); ++sap) {
-        result.SAPs[sap].SAP.delay = baseDelay();
+        result.SAPs[sap].SAP.delay = 0.0;
+        result.SAPs[sap].SAP.clockCorrection = clockCorrection();
 
         if (parset.settings.beamFormer.enabled) {
           for (size_t tab = 0; tab < result.SAPs[sap].TABs.size(); tab++) {
-            result.SAPs[sap].TABs[tab].delay = baseDelay();
+            result.SAPs[sap].TABs[tab].delay = 0.0;
+            result.SAPs[sap].TABs[tab].clockCorrection = clockCorrection();
           }
         }
       }
@@ -312,11 +264,11 @@ namespace LOFAR
 #endif
 
 
-    double Delays::baseDelay() const
+    double Delays::clockCorrection() const
     {
-      double clockCorrection = parset.settings.corrections.clock ? parset.settings.stations[stationIdx].clockCorrection : 0.0;
+      double corr = parset.settings.corrections.clock ? parset.settings.stations[stationIdx].clockCorrection : 0.0;
 
-      return clockCorrection;
+      return corr;
     }
 
 
@@ -408,12 +360,12 @@ namespace LOFAR
       vector<ssize_t> coarseDelaysSamples(parset.settings.SAPs.size()); // [sap], in samples
       vector<double>  coarseDelaysSeconds(parset.settings.SAPs.size()); // [sap], in seconds
       for (size_t sap = 0; sap < parset.nrBeams(); ++sap) {
-        double delayAtBegin  = delaysAtBegin.SAPs[sap].SAP.delay;
-        double delayAfterEnd = delaysAfterEnd.SAPs[sap].SAP.delay;
+        double delayAtBegin  = delaysAtBegin.SAPs[sap].SAP.totalDelay();
+        double delayAfterEnd = delaysAfterEnd.SAPs[sap].SAP.totalDelay();
 
         // The coarse delay compensation is based on the average delay
         // between begin and end.
-        coarseDelaysSamples[sap] = static_cast<ssize_t>(floor(0.5 * (delayAtBegin + delayAfterEnd) * parset.subbandBandwidth() + 0.5));
+        coarseDelaysSamples[sap] = static_cast<ssize_t>(round(0.5 * (delayAtBegin + delayAfterEnd) * parset.subbandBandwidth()));
         coarseDelaysSeconds[sap] = coarseDelaysSamples[sap] / parset.subbandBandwidth();
       }
 
@@ -434,12 +386,12 @@ namespace LOFAR
         unsigned sap = parset.settings.subbands[subband].SAP;
         double coarseDelay = coarseDelaysSeconds[sap];
 
-        metaDatas[i].stationBeam.delayAtBegin  = delaysAtBegin.SAPs[sap].SAP.delay - coarseDelay;
-        metaDatas[i].stationBeam.delayAfterEnd = delaysAfterEnd.SAPs[sap].SAP.delay - coarseDelay;
+        metaDatas[i].stationBeam.delayAtBegin  = delaysAtBegin.SAPs[sap].SAP.totalDelay() - coarseDelay;
+        metaDatas[i].stationBeam.delayAfterEnd = delaysAfterEnd.SAPs[sap].SAP.totalDelay() - coarseDelay;
 
         for (size_t tab = 0; tab < metaDatas[i].TABs.size(); ++tab) {
-          metaDatas[i].TABs[tab].delayAtBegin  = delaysAtBegin.SAPs[sap].TABs[tab].delay - coarseDelay;
-          metaDatas[i].TABs[tab].delayAfterEnd = delaysAfterEnd.SAPs[sap].TABs[tab].delay - coarseDelay;
+          metaDatas[i].TABs[tab].delayAtBegin  = delaysAtBegin.SAPs[sap].TABs[tab].totalDelay() - coarseDelay;
+          metaDatas[i].TABs[tab].delayAfterEnd = delaysAfterEnd.SAPs[sap].TABs[tab].totalDelay() - coarseDelay;
         }
       }
     }
diff --git a/RTCP/Cobalt/InputProc/src/Delays/Delays.h b/RTCP/Cobalt/InputProc/src/Delays/Delays.h
index 3447a3abc4c2c7f96302a717fe9ba35332f0d5f3..f81e491da0345edee5154bf7f1dd9ac877dfe965 100644
--- a/RTCP/Cobalt/InputProc/src/Delays/Delays.h
+++ b/RTCP/Cobalt/InputProc/src/Delays/Delays.h
@@ -97,12 +97,18 @@ namespace LOFAR
       struct Delay {
         double  direction[3];
         double  delay;
+        double  clockCorrection;
+
+        double  totalDelay() const {
+          return delay + clockCorrection;
+        }
 
         bool operator==(const Delay &other) const {
           return direction[0] == other.direction[0] &&
                  direction[1] == other.direction[1] &&
                  direction[2] == other.direction[2] &&
-                 delay == other.delay;
+                 delay == other.delay &&
+                 clockCorrection == other.clockCorrection;
         }
       };
 
@@ -110,9 +116,6 @@ namespace LOFAR
         struct Delay              SAP;
         std::vector<struct Delay> TABs;
 
-        void read( Stream *str );
-        void write( Stream *str ) const;
-
         bool operator==(const BeamDelays &other) const {
           return SAP == other.SAP && TABs == other.TABs;
         }
@@ -125,9 +128,6 @@ namespace LOFAR
         // All delays for all SAPs (and their TABs)
         std::vector<struct BeamDelays> SAPs;
 
-        void read( Stream *str );
-        void write( Stream *str ) const;
-
         bool operator==(const AllDelays &other) const {
           return SAPs == other.SAPs;
         }
@@ -192,8 +192,8 @@ namespace LOFAR
       // in `result'.
       void calcDelays( const TimeStamp &timestamp, AllDelays &result );
 
-      // Returns the non-geometric delay to add for this station
-      double baseDelay() const;
+      // Returns the clock correction delay to add for this station
+      double clockCorrection() const;
 
 #ifdef HAVE_CASACORE
       casa::MVEpoch                       toUTC( const TimeStamp &timestamp ) const;
diff --git a/RTCP/Cobalt/InputProc/src/Delays/printDelays.cc b/RTCP/Cobalt/InputProc/src/Delays/printDelays.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1c8bec1cf2eae8ff9080fd230944203c515f80ce
--- /dev/null
+++ b/RTCP/Cobalt/InputProc/src/Delays/printDelays.cc
@@ -0,0 +1,108 @@
+//# printDelays.cc: Print all delays generated for an observation
+//# Copyright (C) 2012-2013  ASTRON (Netherlands Institute for Radio Astronomy)
+//# P.O. Box 2, 7990 AA Dwingeloo, The Netherlands
+//#
+//# This file is part of the LOFAR software suite.
+//# The LOFAR software suite is free software: you can redistribute it and/or
+//# modify it under the terms of the GNU General Public License as published
+//# by the Free Software Foundation, either version 3 of the License, or
+//# (at your option) any later version.
+//#
+//# The LOFAR software suite 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 the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>.
+//#
+//# $Id: capture.cc 25540 2013-07-02 13:20:36Z mol $
+
+#include <lofar_config.h>
+
+#include <iostream>
+#include <boost/format.hpp>
+
+#include <Common/LofarLogger.h>
+
+#include <CoInterface/Parset.h>
+#include <InputProc/Delays/Delays.h>
+
+using namespace LOFAR;
+using namespace Cobalt;
+using namespace std;
+using boost::format;
+
+string printDouble3Vector( const vector<double> &vec )
+{
+  ASSERT(vec.size() == 3);
+
+  return str(format("[%.3f, %.3f, %.3f]") % vec[0] % vec[1] % vec[2]);
+}
+
+int main( int argc, char **argv )
+{
+  INIT_LOGGER( "printDelays" );
+
+  if (argc < 3) {
+    cerr << "Syntax: printDelays parset stationname" << endl;
+    exit(1);
+  }
+
+  Parset ps(argv[1]);
+  const string stationName = argv[2];
+
+  const ssize_t stationIdx = ps.settings.stationIndex(stationName);
+
+  if (stationIdx < 0) {
+    LOG_ERROR_STR("Could not find station in parset: " << stationName);
+    exit(1);
+  }
+
+  /* Determine start/stop/blocksize parameters */
+  const TimeStamp from(ps.startTime() * ps.subbandBandwidth(), ps.clockSpeed());
+  const TimeStamp to(ps.stopTime() * ps.subbandBandwidth(), ps.clockSpeed());
+  ssize_t block = -1;
+  size_t blockSize = ps.nrSamplesPerSubband();
+
+  /* Print header */
+  cout << "# Parset:           " << argv[1] << endl;
+  cout << "# Delay comp?:      " << ps.settings.delayCompensation.enabled << endl;
+  cout << "# Clock corr?:      " << ps.settings.corrections.clock << endl;
+  cout << "# Ref Phase center: " << printDouble3Vector(ps.settings.delayCompensation.referencePhaseCenter) << endl;
+  cout << "#" << endl;
+  cout << "# Station:          " << stationName << endl;
+  cout << "# Phase center:     " << printDouble3Vector(ps.settings.stations[stationIdx].phaseCenter) << endl;
+  cout << "# Clock correction: " << str(format("%.15f") % ps.settings.stations[stationIdx].clockCorrection) << endl;
+  cout << "# Start:            " << from << endl;
+  cout << "# Stop:             " << to << endl;
+  cout << "# BlockSize:        " << blockSize << " samples" << endl;
+  cout << "#" << endl;
+  cout << "# Applied delay := delay + clockCorrection" << endl;
+  cout << "# block timestamp dir.x dir.y dir.z delay" << endl;
+  cout.flush();
+
+  /* Start delay compensation thread */
+  Delays delays(ps, stationIdx, from, blockSize);
+  delays.start();
+
+  /* Produce and print delays for the whole observation */
+  for (TimeStamp current = from + block * blockSize; current + blockSize < to; current += blockSize, ++block) 
+  {
+    Delays::AllDelays delaySet(ps);
+
+    delays.getNextDelays(delaySet);
+
+
+    Delays::Delay d = delaySet.SAPs[0].SAP;
+    cout << str(format("%u %.15f %.15f %.15f %.15f %.15f")
+          % block
+          % current.getSeconds()
+          % d.direction[0] % d.direction[1] % d.direction[2]
+          % d.delay) << endl;
+  }
+
+  return 0;
+}
+
+
diff --git a/RTCP/Cobalt/InputProc/src/Delays/printDelays.log_prop b/RTCP/Cobalt/InputProc/src/Delays/printDelays.log_prop
new file mode 100644
index 0000000000000000000000000000000000000000..55e07e5aa9e3f2a6d0dc22675039a5dea461bce6
--- /dev/null
+++ b/RTCP/Cobalt/InputProc/src/Delays/printDelays.log_prop
@@ -0,0 +1,31 @@
+# Note: printDelays needs to log to stderr, to prevent clobbering its regular
+# output on stdout.
+
+# Configure the loggers
+log4cplus.rootLogger=INFO, STDERR
+log4cplus.logger.TRC=INFO
+
+# prevent debug messages: accept >=WARN only, and don't forward messages to the rootLogger
+log4cplus.logger.LCS.ApplCommon=WARN, STDERR
+log4cplus.additivity.LCS.ApplCommon=false
+log4cplus.logger.LCS.MSLofar=WARN, STDERR
+log4cplus.additivity.LCS.MSLofar=false
+
+# Define the appenders
+log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
+log4cplus.appender.STDOUT.layout=log4cplus::PatternLayout
+log4cplus.appender.STDOUT.layout.ConversionPattern=printDelays@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+
+log4cplus.appender.STDERR=log4cplus::ConsoleAppender
+log4cplus.appender.STDERR.layout=log4cplus::PatternLayout
+log4cplus.appender.STDERR.layout.ConversionPattern=printDelays@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+log4cplus.appender.STDERR.logToStdErr=true
+
+#log4cplus.appender.FILE=log4cplus::RollingFileAppender
+#log4cplus.appender.FILE.File=${LOG4CPLUS_LOGFILENAME}.log
+#log4cplus.appender.FILE.MaxFileSize=10MB
+#log4cplus.appender.FILE.MaxBackupIndex=2
+#log4cplus.appender.FILE.layout=log4cplus::PatternLayout
+#log4cplus.appender.FILE.layout.ConversionPattern=rtcp:${MPIRANK}@%h %D{%d-%m-%y %H:%M:%S.%q} %-5p %c{3} - %m [%b:%L]%n
+
+log4cplus.appender.DUMP=log4cplus::NullAppender
diff --git a/RTCP/Cobalt/InputProc/src/RSPBoards.cc b/RTCP/Cobalt/InputProc/src/RSPBoards.cc
index 0caad7c6782db2ad1fe544a4ccd1b5f5b68f46fb..f33879e6d8526eac1e4148f23f6b8e9b9841d26f 100644
--- a/RTCP/Cobalt/InputProc/src/RSPBoards.cc
+++ b/RTCP/Cobalt/InputProc/src/RSPBoards.cc
@@ -57,7 +57,7 @@ namespace LOFAR
 #   pragma omp section
         {
           // start all boards
-          LOG_INFO_STR( logPrefix << "Starting all boards" );
+          LOG_DEBUG_STR( logPrefix << "Starting all boards" );
 #     pragma omp parallel for num_threads(nrBoards)
           for (size_t i = 0; i < nrBoards; ++i) {
             OMPThread::ScopedRun sr(threads[i]);
@@ -102,7 +102,7 @@ namespace LOFAR
           waiter.waitForever();
 
           // kill all boards
-          LOG_INFO_STR( logPrefix << "Stopping all boards" );
+          LOG_DEBUG_STR( logPrefix << "Stopping all boards" );
 #     pragma omp parallel for num_threads(threads.size())
           for (size_t i = 0; i < threads.size(); ++i)
             try {
diff --git a/RTCP/Cobalt/InputProc/src/RSPTimeStamp.cc b/RTCP/Cobalt/InputProc/src/RSPTimeStamp.cc
index f140da608041bce5f1e1ecb97aa6d6417c9ef852..5bf5fa1deea88d5d7117e0c7a03cc418a8ff8ec8 100644
--- a/RTCP/Cobalt/InputProc/src/RSPTimeStamp.cc
+++ b/RTCP/Cobalt/InputProc/src/RSPTimeStamp.cc
@@ -25,6 +25,7 @@
 #include <Common/lofar_iostream.h>
 #include <Common/lofar_iomanip.h>
 
+#include <sys/time.h>
 #include <time.h>
 
 namespace LOFAR
@@ -32,6 +33,22 @@ namespace LOFAR
   namespace Cobalt
   {
 
+    TimeStamp TimeStamp::now( unsigned clockSpeed )
+    {
+      struct timeval tv;
+
+      gettimeofday(&tv, NULL);
+
+      unsigned long usec = tv.tv_sec * 1000000 + tv.tv_usec;
+      return TimeStamp(usec * clockSpeed / 1024 / 1000000, clockSpeed);
+    }
+
+
+    TimeStamp TimeStamp::convert( double seconds, unsigned clockSpeed )
+    {
+      return TimeStamp(seconds * clockSpeed / 1024, clockSpeed);
+    }
+
     ostream &operator << (ostream &os, const TimeStamp &ts)
     {
       double time_d = ts.getSeconds();
diff --git a/RTCP/Cobalt/InputProc/src/RSPTimeStamp.h b/RTCP/Cobalt/InputProc/src/RSPTimeStamp.h
index a592fe341defdf2726079898c29bcc84393240e3..d5320e23477cbf06ca1c2fec2fd35cb1ca711b18 100644
--- a/RTCP/Cobalt/InputProc/src/RSPTimeStamp.h
+++ b/RTCP/Cobalt/InputProc/src/RSPTimeStamp.h
@@ -75,6 +75,14 @@ namespace LOFAR
       operator uint64 () const;
       operator struct timespec () const;
 
+      // Give the current time, for the given clock speed.
+      static TimeStamp now(unsigned clockSpeed);
+
+      // Convert from seconds since 1970. This is a separate static
+      // function to avoid confusion with the TimeStamp(uint64, unsigned)
+      // constructor.
+      static TimeStamp convert(double seconds, unsigned clockSpeed);
+
       friend ostream &operator << (ostream &os, const TimeStamp &ss);
 
     protected:
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketReader.cc b/RTCP/Cobalt/InputProc/src/Station/PacketReader.cc
index 795bceb21f69e8801adef7f97bbddcac03ce2c9a..c5a848c1506e4c055837a1681ff86eb2be4207a1 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketReader.cc
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketReader.cc
@@ -56,25 +56,51 @@ namespace LOFAR
         SocketStream &asSocket = dynamic_cast<SocketStream &>(inputStream);
         const bool isUDP = asSocket.protocol == SocketStream::UDP;
 
-        supportPartialReads = !isUDP;
+        inputIsUDP = isUDP;
       } catch (std::bad_cast&) {
         // inputStream is not a SocketStream
-        supportPartialReads = true;
+        inputIsUDP = false;
       }
     }
 
 
-    bool PacketReader::readPacket( struct RSP &packet )
+    void PacketReader::readPackets( std::vector<struct RSP> &packets, std::vector<bool> &valid )
     {
-      if (supportPartialReads) {
-        // read header first
-        inputStream.read(&packet.header, sizeof packet.header);
+      ASSERT(valid.size() == packets.size());
 
-        // read rest of packet
-        inputStream.read(&packet.payload.data, packet.packetSize() - sizeof packet.header);
+      if (inputIsUDP) {
+        SocketStream &sstream = dynamic_cast<SocketStream&>(inputStream);
 
-        ++nrReceived;
+        size_t numRead = sstream.recvmmsg( packets, false );
+
+        nrReceived += numRead;
+
+        // validate received packets
+        for (size_t i = 0; i < numRead; ++i) {
+          valid[i] = validatePacket(packets[i]);
+        }
+
+        // mark not-received packets as invalid
+        for (size_t i = numRead; i < packets.size(); ++i) {
+          valid[i] = false;
+        }
       } else {
+        // fall-back for non-UDP streams, emit packets
+        // one at a time to avoid data loss on EndOfStream.
+        valid[0] = readPacket(packets[0]);
+
+        nrReceived++;
+
+        for (size_t i = 1; i < packets.size(); ++i) {
+          valid[i] = false;
+        }
+      }
+    }
+
+
+    bool PacketReader::readPacket( struct RSP &packet )
+    {
+      if (inputIsUDP) {
         // read full packet at once -- numbytes will tell us how much we've actually read
         size_t numbytes = inputStream.tryRead(&packet, sizeof packet);
 
@@ -91,8 +117,21 @@ namespace LOFAR
           ++nrBadSize;
           return false;
         }
+      } else {
+        // read header first
+        inputStream.read(&packet.header, sizeof packet.header);
+
+        // read rest of packet
+        inputStream.read(&packet.payload.data, packet.packetSize() - sizeof packet.header);
+
+        ++nrReceived;
       }
 
+      return validatePacket(packet);
+    }
+
+    bool PacketReader::validatePacket( const struct RSP &packet )
+    {
       // illegal version means illegal packet
       if (packet.header.version < 2) {
         // This mainly catches packets that are all zero (f.e. /dev/zero or
@@ -110,7 +149,8 @@ namespace LOFAR
       // discard packets with errors
       if (packet.payloadError()) {
         ++nrBadData;
-        return false;
+        // only count for now, emulate BGP and let the packets through
+        //return false;
       }
 
       // everything is ok
@@ -138,6 +178,8 @@ namespace LOFAR
       nrBadOther = 0;
 
       hadSizeError = false;
+
+      lastLogTime = now;
     }
 
 
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketReader.h b/RTCP/Cobalt/InputProc/src/Station/PacketReader.h
index 27b955dbd1591e417393ae4c1c6e4d042e63c9c3..14256da2d50f108e7d29136e2e4dfed73b258bfd 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketReader.h
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketReader.h
@@ -43,6 +43,10 @@ namespace LOFAR
     public:
       PacketReader( const std::string &logPrefix, Stream &inputStream );
 
+      // Reads a set of packets from the input stream. Sets valid[i] to
+      // true for each valid packet i.
+      void readPackets( std::vector<struct RSP> &packets, std::vector<bool> &valid );
+
       // Reads a packet from the input stream. Returns true if a packet was
       // succesfully read.
       bool readPacket( struct RSP &packet );
@@ -56,12 +60,13 @@ namespace LOFAR
       // The stream from which packets are read.
       Stream &inputStream;
 
-      // Whether inputStream can do a small read() without data loss.
-      bool supportPartialReads;
+      // Whether inputStream is an UDP stream
+      // (UDP streams allow partial reads, and recvmmsg).
+      bool inputIsUDP;
 
       // Statistics covering the packets read so far
       size_t nrReceived; // nr. of packets received
-      size_t nrBadSize; // nr. of packets with wrong size (only if supportPartialReads == false)
+      size_t nrBadSize; // nr. of packets with wrong size (only if inputIsUDP == false)
       size_t nrBadTime; // nr. of packets with an illegal time stamp
       size_t nrBadData; // nr. of packets with payload errors
       size_t nrBadOther; // nr. of packets that are bad in another fashion (illegal header, etc)
@@ -69,6 +74,8 @@ namespace LOFAR
       bool hadSizeError; // already reported about wrongly sized packets since last logStatistics()
 
       double lastLogTime; // time since last log print, to monitor data rates
+
+      bool validatePacket(const struct RSP &packet);
     };
 
 
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketWriter.h b/RTCP/Cobalt/InputProc/src/Station/PacketWriter.h
index c7483e2b5155eb2c642abbd4da07670f326d5fa6..5f5fddadd850ae5c2da285e6073481fee43e08d0 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketWriter.h
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketWriter.h
@@ -34,7 +34,25 @@ namespace LOFAR
 {
   namespace Cobalt
   {
-    EXCEPTION_CLASS(BadModeException, LOFAR::Exception);
+    class BadModeException : public Exception
+    {
+    public:
+      BadModeException(const std::string& text, const BoardMode &mode, const std::string& file="",
+           int line=0, const std::string& function="",
+           Backtrace* bt=0)
+      :
+        Exception(text, file, line, function, bt),
+        mode(mode)
+      {
+      }
+
+      virtual const std::string& type() const {
+        static const std::string itsType("BadModeException");
+        return itsType;
+      }
+
+      const BoardMode mode;
+    };
 
     /*
      * Writes RSP packets to a SampleBuffer
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketWriter.tcc b/RTCP/Cobalt/InputProc/src/Station/PacketWriter.tcc
index 2122ade655694938a3c10912649d31086a19f548..8460f2cc4cf3ec3d8dbf16e966dfd3ed031f9298 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketWriter.tcc
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketWriter.tcc
@@ -44,7 +44,7 @@ template<typename T> PacketWriter<T>::PacketWriter( const std::string &logPrefix
 {
   // Set mode for this board if necessary
   if (mode != *board.mode) {
-    LOG_INFO_STR(logPrefix << "Switching buffer to mode " << mode.bitMode << " bit, " << mode.clockMHz << " MHz");
+    LOG_DEBUG_STR(logPrefix << "Switching buffer to mode " << mode.bitMode << " bit, " << mode.clockMHz << " MHz");
 
     board.changeMode(mode);
   }
@@ -66,7 +66,9 @@ void PacketWriter<T>::noMoreWriting()
 template<typename T> void PacketWriter<T>::writePacket( const struct RSP &packet )
 {
   if (packet.bitMode() != mode.bitMode || packet.clockMHz() != mode.clockMHz) {
-    THROW(BadModeException, "Mode switch to " << packet.bitMode() << " bit, " << packet.clockMHz() << " MHz");
+    throw BadModeException("Mode switch",
+                           BoardMode(packet.bitMode(), packet.clockMHz()),
+                           THROW_ARGS);
   }
 
   const uint8 &nrBeamlets  = packet.header.nrBeamlets;
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.cc b/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.cc
index 956fc04af194d57a25951a18127bc1ef06d45645..41796453aaa203cfc5aabbf4b02c9e15dbe0e252 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.cc
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.cc
@@ -25,6 +25,7 @@
 #include <boost/format.hpp>
 
 #include <Common/LofarLogger.h>
+#include <Common/Thread/Thread.h>
 
 #include <InputProc/SampleType.h>
 #include <InputProc/Buffer/SampleBuffer.h>
@@ -51,17 +52,14 @@ namespace LOFAR
 
     void PacketsToBuffer::process()
     {
-      // Holder for packet
-      struct RSP packet;
-
       // Create the buffer, regardless of mode
       GenericSampleBuffer buffer(settings, SharedMemoryArena::CREATE);
 
       // Keep track of the desired mode
       struct BoardMode mode;
 
-      // Whether packet has been read already
-      bool packetValid = false;
+      std::vector<struct RSP> packets(16);
+      std::vector<bool>       write(packets.size(), false);
 
       // Keep reading if mode changes
       for(;; ) {
@@ -69,15 +67,15 @@ namespace LOFAR
           // Process packets based on (expected) bit mode
           switch(mode.bitMode) {
           case 16:
-            process< SampleType<i16complex> >(packet, mode, packetValid);
+            process< SampleType<i16complex> >(mode, packets, write);
             break;
 
           case 8:
-            process< SampleType<i8complex> >(packet, mode, packetValid);
+            process< SampleType<i8complex> >(mode, packets, write);
             break;
 
           case 4:
-            process< SampleType<i4complex> >(packet, mode, packetValid);
+            process< SampleType<i4complex> >(mode, packets, write);
             break;
           }
 
@@ -85,14 +83,10 @@ namespace LOFAR
           break;
         } catch (BadModeException &ex) {
           // Mode switch detected
-          LOG_INFO_STR(logPrefix << "Mode switch detected to " << packet.clockMHz() << " MHz, " << packet.bitMode() << " bit");
+          LOG_INFO_STR(logPrefix << "Mode switch detected to " << ex.mode.clockMHz << " MHz, " << ex.mode.bitMode << " bit");
 
           // change mode
-          mode.bitMode = packet.bitMode();
-          mode.clockMHz = packet.clockMHz();
-
-          // Process packet again
-          packetValid = true;
+          mode = ex.mode;
         }
       }
     }
@@ -109,8 +103,10 @@ namespace LOFAR
 
 
     template<typename T>
-    void PacketsToBuffer::process( struct RSP &packet, const struct BoardMode &mode, bool writeGivenPacket )
+    void PacketsToBuffer::process( const struct BoardMode &mode, std::vector<struct RSP> &packets, std::vector<bool> &write )
     {
+      Thread::ScopedPriority sp(SCHED_FIFO, 10);
+
       // Create input structures
       PacketReader reader(logPrefix, inputStream);
 
@@ -121,18 +117,21 @@ namespace LOFAR
       LOG_DEBUG_STR( logPrefix << "Processing packets" );
 
       try {
-        // Process lingering packet from previous run, if any
-        if (writeGivenPacket) {
-          writer.writePacket(packet);
-          logStatistics(reader, packet);
-        }
-
         // Transport packets from reader to writer
-        for(;; ) {
-          if (reader.readPacket(packet)) {
-            writer.writePacket(packet);
-            logStatistics(reader, packet);
+        for(;;) {
+          // Write first, in case we're given packets to write
+          for (size_t i = 0; i < packets.size(); ++i) {
+            if (!write[i])
+              continue;
+
+            writer.writePacket(packets[i]);
+            logStatistics(reader, packets[i]);
+
+            // mark packet as written
+            write[i] = false;
           }
+
+          reader.readPackets(packets, write);
         }
 
       } catch (BadModeException &ex) {
@@ -144,7 +143,7 @@ namespace LOFAR
         LOG_INFO_STR( logPrefix << "End of stream");
 
       } catch (SystemCallException &ex) {
-        if (ex.error == EINTR)
+        if (ex.error == EINTR || ex.error == 512 /* ERESTARTSYS, should not be propagated to user space?! */)
           LOG_INFO_STR( logPrefix << "Aborted: " << ex.what());
         else
           LOG_ERROR_STR( logPrefix << "Caught Exception: " << ex);
@@ -160,12 +159,12 @@ namespace LOFAR
 
 
     // Explcitly create the instances we use
-    template void PacketsToBuffer::process< SampleType<i16complex> >( struct RSP &packet, const struct BoardMode &mode, bool writeGivenPacket );
-    template void PacketsToBuffer::process< SampleType<i8complex> >( struct RSP &packet, const struct BoardMode &mode, bool writeGivenPacket );
-    template void PacketsToBuffer::process< SampleType<i4complex> >( struct RSP &packet, const struct BoardMode &mode, bool writeGivenPacket );
+    template void PacketsToBuffer::process< SampleType<i16complex> >( const struct BoardMode &mode, std::vector<struct RSP> &packets, std::vector<bool> &write );
+    template void PacketsToBuffer::process< SampleType<i8complex> >( const struct BoardMode &mode, std::vector<struct RSP> &packets, std::vector<bool> &write );
+    template void PacketsToBuffer::process< SampleType<i4complex> >( const struct BoardMode &mode, std::vector<struct RSP> &packets, std::vector<bool> &write );
 
 
-    MultiPacketsToBuffer::MultiPacketsToBuffer( const BufferSettings &settings, const std::vector< SmartPtr<Stream> > &inputStreams_ )
+    MultiPacketsToBuffer::MultiPacketsToBuffer( const BufferSettings &settings, const std::vector< SmartPtr<Stream> > &inputStreams_, double logFrom, double logTo )
     :
       RSPBoards("", inputStreams_.size()),
 
@@ -174,6 +173,8 @@ namespace LOFAR
       inputStreams(inputStreams_.size()),
 
       lastlog_time(now()),
+      logFrom(logFrom),
+      logTo(logTo),
       sum_flags(buffer.nrBoards, 0.0),
       num_flags(0.0)
     {
@@ -186,21 +187,23 @@ namespace LOFAR
 
     MultiPacketsToBuffer::~MultiPacketsToBuffer()
     {
-      // collect the log line
-      std::stringstream logstr;
+      if (!settings.sync) {
+        // collect the log line
+        std::stringstream logstr;
 
-      // compute average loss per board
-      for (size_t b = 0; b < buffer.nrBoards; ++b) {
-        const double avgloss = num_flags == 0.0 ? 0.0 : sum_flags[b] / num_flags;
+        // compute average loss per board
+        for (size_t b = 0; b < buffer.nrBoards; ++b) {
+          const double avgloss = num_flags == 0.0 ? 0.0 : sum_flags[b] / num_flags;
 
-        if (b > 0)
-          logstr << ", ";
+          if (b > 0)
+            logstr << ", ";
 
-        logstr << avgloss << "%";
-      }
+          logstr << avgloss << "%";
+        }
 
-      // report average loss
-      LOG_INFO_STR(str(boost::format("[station %s] ") % settings.station.name()) << "Average data loss per board: " << logstr.str());
+        // report average loss
+        LOG_INFO_STR(str(boost::format("[station %s] ") % settings.station.name()) << "Average data loss per board: " << logstr.str());
+      }
     }
 
 
@@ -219,8 +222,14 @@ namespace LOFAR
       if (settings.sync)
         return;
 
-      const double from_ts  = lastlog_time;
-      const double to_ts    = now();
+      // Constrain time frame to specified logging period
+      const double from_ts  = std::max(lastlog_time, logFrom);
+      const double to_ts    = std::min(now(), logTo);
+
+      // Don't do anything if there is nothing to log
+      if (from_ts >= to_ts)
+        return;
+
       const double maxdelay = 0.5; // wait this many seconds for data to arrive
 
       std::vector<double> flags(buffer.nrBoards);
@@ -233,10 +242,9 @@ namespace LOFAR
         const struct BoardMode mode = *(buffer.boards[b].mode);
         const size_t Hz = mode.clockHz();
 
-        // timestamp = (seconds since 1970) * clock / 1024
         flags[b] = buffer.boards[b].flagPercentage(
-          TimeStamp((from_ts - maxdelay) * Hz / 1024, Hz),
-          TimeStamp((to_ts   - maxdelay) * Hz / 1024, Hz));
+          TimeStamp::convert(from_ts - maxdelay, Hz),
+          TimeStamp::convert(to_ts   - maxdelay, Hz));
 
         do_log = do_log || flags[b] > 0.0;
 
diff --git a/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.h b/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.h
index 05d3a84d26a496cb42f2dd865531e1297bf83592..70e2f6c4085c5d336f30a5b6930384145dd1bbe8 100644
--- a/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.h
+++ b/RTCP/Cobalt/InputProc/src/Station/PacketsToBuffer.h
@@ -23,7 +23,9 @@
 
 #include <string>
 #include <sstream>
+#include <vector>
 #include <ios>
+#include <cfloat> // for DBL_MAX
 #include <sys/time.h>
 #include <boost/format.hpp>
 
@@ -80,15 +82,15 @@ namespace LOFAR
       static const uint32 LOG_INTERVAL = 10;
 
       // Process data for this board until interrupted or end of data.
-      // `packet' is the receive buffer for packets. If a new mode is detected,
-      // `packet' is filled with the last read packet, and a PacketWriter::BadModeException
+      // `packets' is the receive buffer for packets. If a new mode is detected,
+      // `packets' is filled with the last read packets, and a PacketWriter::BadModeException
       // is thrown.
       //
       // `mode' indicates the expected mode.
       //
-      // If `writeGivenPacket' is true, the provided `packet' is written as well.
+      // If `write[i]' is true, the provided `packets[i]' is written as well.
       template<typename T>
-      void process( struct RSP &packet, const struct BoardMode &mode, bool writeGivenPacket );
+      void process( const struct BoardMode &mode, std::vector<struct RSP> &packets, std::vector<bool> &write );
 
       // Triggers statistics logging every LOG_INTERVAL seconds
       virtual void logStatistics( PacketReader &reader, const struct RSP &packet );
@@ -101,7 +103,8 @@ namespace LOFAR
     class MultiPacketsToBuffer : public RSPBoards
     {
     public:
-      MultiPacketsToBuffer( const BufferSettings &settings, const std::vector< SmartPtr<Stream> > &inputStreams_ );
+      MultiPacketsToBuffer( const BufferSettings &settings, const std::vector< SmartPtr<Stream> > &inputStreams_,
+                            double logFrom = DBL_MAX, double logTo = 0.0);
 
       virtual ~MultiPacketsToBuffer();
 
@@ -117,6 +120,8 @@ namespace LOFAR
 
       // log statistics
       double lastlog_time;           // last time we logged
+      const double logFrom;          // start logging at this time
+      const double logTo;            // stop logging at this time
       std::vector<double> sum_flags; // sum of flags/second
       double num_flags;              // number of seconds measured
 
diff --git a/RTCP/Cobalt/InputProc/src/Station/filterRSP.cc b/RTCP/Cobalt/InputProc/src/Station/filterRSP.cc
index 4578f6e20c49674d25b823a2c58dd639527a7cdb..d1dd02184885255d0ffec0578b6a8249e5ce8166 100644
--- a/RTCP/Cobalt/InputProc/src/Station/filterRSP.cc
+++ b/RTCP/Cobalt/InputProc/src/Station/filterRSP.cc
@@ -24,8 +24,11 @@
 #include <cstdio>
 #include <ctime>
 #include <unistd.h>
+#include <omp.h>
 #include <boost/date_time/posix_time/posix_time.hpp>
 
+#include <Common/Thread/Queue.h>
+#include <Common/Thread/Thread.h>
 #include <Common/LofarLogger.h>
 #include <ApplCommon/PosixTime.h>
 #include <CoInterface/Stream.h>
@@ -47,6 +50,7 @@ void usage()
   puts("");
   puts("-f from       Discard packets before `from' (format: '2012-01-01 11:12:00')");
   puts("-t to         Discard packets at or after `to' (format: '2012-01-01 11:12:00')");
+  puts("-q            Quit if packets are received after `to'");
   puts("-s nrbeamlets Reduce or expand the number of beamlets per packet");
   puts("-b bitmode    Discard packets with bitmode other than `bitmode' (16, 8, or 4)");
   puts("-c clock      Discard packets with a clock other than `clock' (200 or 160)");
@@ -56,6 +60,11 @@ void usage()
   puts("Note: invalid packets are always discarded.");
 }
 
+struct packetSet {
+  vector<struct RSP> packets;
+  vector<bool>       valid;
+};
+
 int main(int argc, char **argv)
 {
   INIT_LOGGER("filterRSP");
@@ -67,12 +76,13 @@ int main(int argc, char **argv)
   unsigned nrbeamlets = 0;
   unsigned bitmode = 0;
   unsigned clock = 0;
+  bool quit_after_to = false;
 
   string inputStreamDesc  = "file:/dev/stdin";
   string outputStreamDesc = "file:/dev/stdout";
 
   // parse all command-line options
-  while ((opt = getopt(argc, argv, "f:t:s:b:c:i:o:")) != -1) {
+  while ((opt = getopt(argc, argv, "f:t:s:b:c:i:o:q")) != -1) {
     switch (opt) {
     case 'f':
       from = parseTime(optarg);
@@ -102,6 +112,10 @@ int main(int argc, char **argv)
       outputStreamDesc = optarg;
       break;
 
+    case 'q':
+      quit_after_to = true;
+      break;
+
     default: /* '?' */
       usage();
       exit(1);
@@ -114,44 +128,112 @@ int main(int argc, char **argv)
     exit(1);
   }
 
+  // create in- and output streams
   SmartPtr<Stream> inputStream = createStream(inputStreamDesc, true);
   SmartPtr<Stream> outputStream = createStream(outputStreamDesc, false);
   PacketReader reader("", *inputStream);
-  struct RSP packet;
-
-  try {
-    for(;; ) {
-      if( reader.readPacket(packet) ) {
-        // **** Apply FROM filter ****
-        if (from > 0 && packet.header.timestamp < from)
-          continue;
-
-        // **** Apply TO filter ****
-        if (to > 0 && packet.header.timestamp >= to)
-          continue;
-
-        // **** Apply BITMODE filter ****
-        if (bitmode > 0 && packet.bitMode() != bitmode)
-          continue;
-
-        // **** Apply CLOCK filter ****
-        if (clock > 0 && packet.clockMHz() != clock)
-          continue;
-
-        // **** Apply NRBEAMLETS filter ****
-        if (nrbeamlets > 0) {
-          // the new number of beamlets has to be valid
-          ASSERT(nrbeamlets <= 62 * (16 / packet.bitMode()));
-
-          // convert
-          packet.header.nrBeamlets = nrbeamlets;
+
+  // create packet queues between reader and writer
+  Queue< SmartPtr<packetSet> > readQueue;
+  Queue< SmartPtr<packetSet> > writeQueue;
+
+  for (size_t i = 0; i < 256; ++i) {
+    SmartPtr<packetSet> p = new packetSet;
+    p->packets.resize(256);
+    p->valid.resize(p->packets.size());
+
+    readQueue.append(p);
+  }
+
+  /*
+   * We need to read and write in separate threads
+   * for the best performance.
+   *
+   * A dedicated read thread allows us to always
+   * listen to the input, which is especially
+   * important if we're listening to UDP.
+   */
+
+  volatile bool writerDone = false;
+
+# pragma omp parallel sections num_threads(2)
+  {
+#   pragma omp section
+    {
+      try {
+        Thread::ScopedPriority sp(SCHED_FIFO, 10);
+
+        SmartPtr<packetSet> p;
+
+        while (!writerDone && (p = readQueue.remove()) != NULL) {
+          // Read packets and queue them
+          reader.readPackets(p->packets, p->valid);
+          writeQueue.append(p);
         }
+      } catch(Stream::EndOfStreamException&) {
+      }
+
+      writeQueue.append(NULL);
+    }
+
+#   pragma omp section
+    {
+      SmartPtr<packetSet> p;
+
+      // Keep reading until NULL
+      while ((p = writeQueue.remove()) != NULL) {
+        for (size_t i = 0; i < p->packets.size(); ++i) {
+          if (!p->valid[i])
+            continue;
 
-        // Write packet
-        outputStream->write(&packet, packet.packetSize());
+          struct RSP &packet = p->packets[i];
+
+          // **** Apply FROM filter ****
+          if (from > 0 && packet.header.timestamp < from)
+            continue;
+
+          // **** Apply TO filter ****
+          if (to > 0 && packet.header.timestamp >= to) {
+            if (quit_after_to) {
+              writerDone = true;
+              break;
+            }
+
+            continue;
+          }
+
+          // **** Apply BITMODE filter ****
+          if (bitmode > 0 && packet.bitMode() != bitmode)
+            continue;
+
+          // **** Apply CLOCK filter ****
+          if (clock > 0 && packet.clockMHz() != clock)
+            continue;
+
+          // **** Apply NRBEAMLETS filter ****
+          if (nrbeamlets > 0) {
+            // the new number of beamlets has to be valid
+            ASSERT(nrbeamlets <= 62 * (16 / packet.bitMode()));
+
+            // convert
+            packet.header.nrBeamlets = nrbeamlets;
+          }
+
+          // Write packet
+          outputStream->write(&packet, packet.packetSize());
+        }
+
+        // Give back packets holder
+        readQueue.append(p);
+
+        // Add a NULL if we're done to free up
+        // readQueue.remove(), to prevent race conditions.
+        if (writerDone) {
+          readQueue.append(NULL);
+          break;
+        }
       }
     }
-  } catch(Stream::EndOfStreamException&) {
   }
 }
 
diff --git a/RTCP/Cobalt/InputProc/test/tDelays.cc b/RTCP/Cobalt/InputProc/test/tDelays.cc
index 853dc2632df38402210d8cd930fadb1e084c5a68..b99044f4626d38714b1261d8ee2dd99dd368f1e0 100644
--- a/RTCP/Cobalt/InputProc/test/tDelays.cc
+++ b/RTCP/Cobalt/InputProc/test/tDelays.cc
@@ -121,44 +121,6 @@ TEST(TiedArrayBeam) {
 }
 
 
-TEST(AllDelayIO) {
-  Parset ps;
-
-  ps.add( "Observation.DataProducts.Output_Beamformed.enabled", "true" );
-  ps.add( "Observation.DataProducts.Output_Beamformed.filenames", "[beam0.raw]" );
-  ps.add( "Observation.DataProducts.Output_Beamformed.locations", "[localhost:.]" );
-  ps.add( "Observation.nrBeams", "2" );
-  ps.add( "Observation.Beam[0].directionType", "J2000" );
-  ps.add( "Observation.Beam[0].angle1", "1" );
-  ps.add( "Observation.Beam[0].angle2", "1" );
-  ps.add( "Observation.Beam[0].nrTiedArrayBeams", "0" );
-  ps.add( "Observation.Beam[1].directionType", "J2000" );
-  ps.add( "Observation.Beam[1].angle1", "1" );
-  ps.add( "Observation.Beam[1].angle2", "0" );
-  ps.add( "Observation.Beam[1].nrTiedArrayBeams", "1" );
-  ps.add( "Observation.Beam[1].TiedArrayBeam[0].directionType", "J2000" );
-  ps.add( "Observation.Beam[1].TiedArrayBeam[0].angle1", "0" );
-  ps.add( "Observation.Beam[1].TiedArrayBeam[0].angle2", "1" );
-  ps.updateSettings();
-
-  Delays::AllDelays delaySet_in(ps), delaySet_out(ps);
-
-  delaySet_in.SAPs[0].SAP.delay = 1.0;
-  delaySet_in.SAPs[1].SAP.delay = 0.5;
-  delaySet_in.SAPs[1].TABs[0].delay = 1.0;
-
-  vector<char> buffer(1024);
-
-  FixedBufferStream str_in(&buffer[0], buffer.size());
-  FixedBufferStream str_out(&buffer[0], buffer.size());
- 
-  delaySet_in.write(&str_in);
-  delaySet_out.read(&str_out);
-
-  CHECK( delaySet_in == delaySet_out );
-}
-
-
 int main()
 {
   INIT_LOGGER( "tDelays" );
diff --git a/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc b/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
index 7a6dfbf9470d77af669d8fb00cbf2b32ba8fd347..e9dd782ab6bbfc4a988e826d67d54461a76ea0ad 100644
--- a/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
+++ b/RTCP/Cobalt/OutputProc/src/MSWriterCorrelated.cc
@@ -111,7 +111,7 @@ namespace LOFAR
 
       myFormat.addSubband(msName, subbandIndex, isBigEndian);
 
-      LOG_INFO_STR(logPrefix << "MeasurementSet created");
+      LOG_DEBUG_STR(logPrefix << "MeasurementSet created");
 #endif // defined HAVE_AIPSPP
     }
 
@@ -173,14 +173,14 @@ namespace LOFAR
         brokenDuring[rcu.station].push_back(FailedTileInfo(rcu.station, rcu.time, datetime2epoch(rcu.time), rcu.type, rcu.seqnr));
       }
 
-      LOG_INFO_STR(itsLogPrefix << "Reopening MeasurementSet");
+      LOG_DEBUG_STR(itsLogPrefix << "Reopening MeasurementSet");
 
       Table ms(itsMSname, Table::Update);
 
       vector<FailedTileInfo::VectorFailed> before(FailedTileInfo::antennaConvert(ms, brokenBefore));
       vector<FailedTileInfo::VectorFailed> during(FailedTileInfo::antennaConvert(ms, brokenDuring));
 
-      LOG_INFO_STR(itsLogPrefix << "Writing broken hardware information to MeasurementSet");
+      LOG_DEBUG_STR(itsLogPrefix << "Writing broken hardware information to MeasurementSet");
 
       try {
         FailedTileInfo::writeFailed(ms, before, during);
diff --git a/RTCP/Cobalt/OutputProc/src/outputProc.cc b/RTCP/Cobalt/OutputProc/src/outputProc.cc
index 7a06712943ef3294af4a4b94b12aa89950a03754..4722eb98a9c06090f03fabce4641098301f75929 100644
--- a/RTCP/Cobalt/OutputProc/src/outputProc.cc
+++ b/RTCP/Cobalt/OutputProc/src/outputProc.cc
@@ -103,11 +103,13 @@ int main(int argc, char *argv[])
     Parset parset(&controlStream);
 
     // Send identification string to the MAC Log Processor
+    /*
     LOG_INFO_STR("MACProcessScope: " << 
                  str(format(createPropertySetName(
                               PSN_COBALT_OUTPUT_PROC, "", 
                               parset.getString("_DPname")))
                      % myRank));
+    */
 
     Observation obs(&parset, false, 64); // FIXME: assume 64 psets, because Observation still deals with BG/P
 
diff --git a/RTCP/Cobalt/OutputProc/src/plotMS.cc b/RTCP/Cobalt/OutputProc/src/plotMS.cc
index 498c892fcea66772559b5224ce44c2eca296c5ef..349363ae79aaaa0421f234fed747ad83fd93932f 100644
--- a/RTCP/Cobalt/OutputProc/src/plotMS.cc
+++ b/RTCP/Cobalt/OutputProc/src/plotMS.cc
@@ -53,6 +53,10 @@ Exception::TerminateHandler t(Exception::terminate);
 
 bool shouldSwap = false;
 
+// true: print power
+// false: print real / imag
+bool realimag = false;
+
 float power( fcomplex s )
 {
   float r = real(s);
@@ -68,9 +72,11 @@ float power( fcomplex s )
 
 static void usage(char *progname, int exitcode)
 {
-  printf("Usage: %s -p parset [-b baseline | -B station1-station2] [-c channel]\n", progname);
+  printf("Usage: %s -p parset [-b baseline | -B station1-station2] [-c channel] [-i]\n", progname);
+  printf("\n");
+  printf("-i: print real & imaginary values instead of power\n");
   printf("\n");
-  printf("Run within the MS directory of the subband to plot.\n");
+  printf("Run within the MS directory of the subband to plot. Outputs blocknr followed by XX XY YX YY.\n");
   exit(exitcode);
 }
 
@@ -95,7 +101,7 @@ int main(int argc, char *argv[])
     unsigned baseline = 0;
     int channel = -1;
 
-    while ((opt = getopt(argc, argv, "p:b:B:c:")) != -1) {
+    while ((opt = getopt(argc, argv, "p:b:B:c:i")) != -1) {
       switch (opt) {
       case 'p':
         parset_filename = strdup(optarg);
@@ -113,6 +119,10 @@ int main(int argc, char *argv[])
         channel = atoi(optarg);
         break;
 
+      case 'i':
+        realimag = true;
+        break;
+
       default:   /* '?' */
         usage(argv[0], 1);
       }
@@ -176,6 +186,10 @@ int main(int argc, char *argv[])
 
     printf( "# baseline %s - %s channel %d\n", firstStation.c_str(), secondStation.c_str(), channel);
     printf( "# observation %u\n", parset.observationID());
+    if (realimag)
+      printf( "# blocknr real(XX) imag(XX) real(XY) imag(XY) real(YX) imag(YX) real(YY) imag(YY)\n");
+    else
+      printf( "# blocknr power(XX) power(XY) power(YX) power(YY)\n");
 
     for(;; ) {
       try {
@@ -188,7 +202,19 @@ int main(int argc, char *argv[])
 
       printf( "# valid samples: %u\n", data->getNrValidSamples(baseline,channel));
 
-      printf( "%6d %10g %10g %10g %10g\n",
+      if (realimag)
+        printf( "%6d %10g %10g %10g %10g %10g %10g %10g %10g\n",
+              data->sequenceNumber(),
+              real( data->visibilities[baseline][channel][0][0] ),
+              imag( data->visibilities[baseline][channel][0][0] ),
+              real( data->visibilities[baseline][channel][0][1] ),
+              imag( data->visibilities[baseline][channel][0][1] ),
+              real( data->visibilities[baseline][channel][1][0] ),
+              imag( data->visibilities[baseline][channel][1][0] ),
+              real( data->visibilities[baseline][channel][1][1] ),
+              imag( data->visibilities[baseline][channel][1][1] ) );
+      else
+        printf( "%6d %10g %10g %10g %10g\n",
               data->sequenceNumber(),
               power( data->visibilities[baseline][channel][0][0] ),
               power( data->visibilities[baseline][channel][0][1] ),
diff --git a/RTCP/MetaDataGatherer/src/FinalMetaDataGatherer.cc b/RTCP/MetaDataGatherer/src/FinalMetaDataGatherer.cc
index cfaf246c7d34030d4847740e20e5234901d87126..96360b3917a3a3f6604ecbfa3fa3cdb78ca8a4f8 100644
--- a/RTCP/MetaDataGatherer/src/FinalMetaDataGatherer.cc
+++ b/RTCP/MetaDataGatherer/src/FinalMetaDataGatherer.cc
@@ -23,7 +23,6 @@
 #include <Interface/Stream.h>
 #include <Interface/FinalMetaData.h>
 #include <Stream/PortBroker.h>
-#include <Storage/ExitOnClosedStdin.h>
 
 // SAS
 #include <OTDB/OTDBconstants.h>
@@ -181,19 +180,7 @@ char stdoutbuf[1024], stderrbuf[1024];
 
 int main(int argc, char *argv[])
 {
-#if defined HAVE_LOG4CPLUS
-  char *dirc = strdup(argv[0]);
-
-  INIT_LOGGER(string(getenv("LOFARROOT") ? : dirname(dirc)) + "/../etc/FinalMetaDataGatherer.log_prop");
-
-  free(dirc);
-#elif defined HAVE_LOG4CXX
-  #error LOG4CXX support is broken (nonsensical?) -- please fix this code if you want to use it
-  Context::initialize();
-  setLevel("Global",8);
-#else
-  INIT_LOGGER_WITH_SYSINFO(str(boost::format("FinalMetaDataGatherer@%02d") % (argc > 2 ? atoi(argv[2]) : -1)));
-#endif
+  INIT_LOGGER("FinalMetaDataGatherer");
 
   CasaLogSink::attach();
 
@@ -201,7 +188,6 @@ int main(int argc, char *argv[])
     if (argc != 2)
       throw StorageException(str(boost::format("usage: %s obsid") % argv[0]), THROW_ARGS);
 
-    ExitOnClosedStdin			  stdinWatcher;
     setvbuf(stdout, stdoutbuf, _IOLBF, sizeof stdoutbuf);
     setvbuf(stderr, stderrbuf, _IOLBF, sizeof stderrbuf);