diff --git a/.gitattributes b/.gitattributes
index dfcc9272ed8b37317825ec6b7e328a76b932ac69..fbac7896145a5735313a27756fbe5f518d8c169c 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -22,6 +22,7 @@ CEP/Calibration/BBSControl/src/calibrate-part -text
 CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h -text
 CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_HBA.coeff -text
 CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_LBA.coeff -text
@@ -32,6 +33,7 @@ CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_theta.c -text
 CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc -text
 CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc -text
 CEP/Calibration/BBSKernel/src/Expr/Scope.cc -text
+CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc -text
 CEP/Calibration/BBSKernel/src/IonosphereExpr.cc -text
 CEP/Calibration/BBSKernel/test/tJonesCMul3.cc -text
 CEP/Calibration/BBSKernel/test/tJonesCMul3.sh -text
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
index 0f4eb490bb51b01573d943acadde8c26bfb1af54..c47d4d37a1e8b853764d1bf42fcf958ba745160d 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
@@ -34,6 +34,7 @@ install(FILES
   Expr/BasicExpr.h
   Expr/Cache.h
   Expr/ConditionNumber.h
+  Expr/EquatorialCentroid.h
   Expr/Expr.h
   Expr/ExprId.h
   Expr/ExprAdaptors.h
@@ -74,9 +75,9 @@ install(FILES
   Expr/Scope.h
   Expr/Source.h
   Expr/SpectralIndex.h
-  Expr/EquatorialCentroid.h
   Expr/StationShift.h
   Expr/StationUVW.h
+  Expr/TileArrayFactor.h
   Expr/ValueSet.h
   Expr/YatawattaDipole.h
   DESTINATION include/${PACKAGE_NAME}/Expr)
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h
index c5587d6276363fe1d862fd09d2cc60539bf1c2dd..0c96970a0a770f864e156e4c01811a9eeeefcbc0 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h
@@ -43,7 +43,7 @@ class ArrayFactor: public BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>
 public:
     ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction,
         const Expr<Vector<2> >::ConstPtr &reference,
-        const AntennaConfig &config, double referenceFreq);
+        const AntennaSelection &selection, double referenceFreq);
 
 protected:
     virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
@@ -51,8 +51,8 @@ protected:
         const;
 
 private:
-    AntennaConfig   itsConfig;
-    double          itsReferenceFreq;
+    AntennaSelection    itsSelection;
+    double              itsReferenceFreq;
 };
 
 // @}
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h
new file mode 100644
index 0000000000000000000000000000000000000000..73374903138fd8e72f5b000f20bb46f97461f352
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h
@@ -0,0 +1,61 @@
+//# TileArrayFactor.h: Compute the array factor of a LOFAR HBA tile.
+//#
+//# 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$
+
+#ifndef LOFAR_BBSKERNEL_EXPR_TILEARRAYFACTOR_H
+#define LOFAR_BBSKERNEL_EXPR_TILEARRAYFACTOR_H
+
+// \file
+// Compute the array factor of a LOFAR HBA tile.
+
+#include <BBSKernel/Expr/BasicExpr.h>
+#include <BBSKernel/Instrument.h>
+#include <measures/Measures/MDirection.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class TileArrayFactor: public BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>
+{
+public:
+    TileArrayFactor(const Expr<Vector<2> >::ConstPtr &direction,
+        const Expr<Vector<2> >::ConstPtr &reference, const TileLayout &layout);
+
+protected:
+    virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
+        const Vector<2>::View &direction, const Vector<2>::View &reference)
+        const;
+
+private:
+    TileLayout  itsLayout;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
index b82ce08e5fa8384d9f855ca5aca4a40ad005dceb..b5d38cb3cadc0004b253bc50f529c67128b6ae5b 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
@@ -41,40 +41,58 @@ namespace BBS
 // \addtogroup BBSKernel
 // @{
 
-class AntennaConfig
+class AntennaSelection
 {
 public:
+    AntennaSelection();
+    AntennaSelection(unsigned int size);
+
     const string &name() const;
-    size_t size() const;
-    double operator()(unsigned int i, unsigned int j) const;
+    unsigned int size() const;
+    const double &operator()(unsigned int i0, unsigned int i1) const;
+    double &operator()(unsigned int i0, unsigned int i1);
 
 private:
-    friend istream &operator>>(istream &in, AntennaConfig &obj);
+    friend istream &operator>>(istream &in, AntennaSelection &obj);
 
     string                  itsName;
     casa::Matrix<double>    itsPositions;
 };
 
-istream &operator>>(istream &in, AntennaConfig &obj);
+istream &operator>>(istream &in, AntennaSelection &obj);
+
+class TileLayout
+{
+public:
+    TileLayout();
+    TileLayout(unsigned int size);
+
+    unsigned int size() const;
+    const double &operator()(unsigned int i0, unsigned int i1) const;
+    double &operator()(unsigned int i0, unsigned int i1);
+
+private:
+    casa::Matrix<double>    itsPositions;
+};
 
 class Station
 {
 public:
-//    Station();
     Station(const string &name, const casa::MPosition &position);
-    Station(const string &name, const casa::MPosition &position,
-        const casa::Path &config);
 
     const string &name() const;
     const casa::MPosition &position() const;
-    const AntennaConfig &config(const string &name) const;
+    const AntennaSelection &selection(const string &name) const;
+    const TileLayout &tile(unsigned int i) const;
 
-    void readAntennaConfigurations(const casa::Path &file);
+    void readAntennaSelection(const casa::Path &file);
+    void readTileLayout(const casa::Path &file);
 
 private:
-    string                      itsName;
-    casa::MPosition             itsPosition;
-    map<string, AntennaConfig>  itsConfig;
+    string                          itsName;
+    casa::MPosition                 itsPosition;
+    map<string, AntennaSelection>   itsAntennaSelection;
+    vector<TileLayout>              itsTileLayout;
 };
 
 class Instrument
@@ -91,7 +109,7 @@ public:
     const Station &operator[](unsigned int i) const;
     const Station &operator[](const string &name) const;
 
-    void readAntennaConfigurations(const casa::Path &path);
+    void readLOFARAntennaConfig(const casa::Path &path);
 
 private:
     string                      itsName;
@@ -103,14 +121,37 @@ private:
 // @}
 
 // -------------------------------------------------------------------------- //
-// - AntennaConfig implementation                                           - //
+// - AntennaSelection implementation                                        - //
+// -------------------------------------------------------------------------- //
+
+inline const double &AntennaSelection::operator()(unsigned int i0,
+    unsigned int i1) const
+{
+    //# Swap axes to hide the Fortran index convention used by casa::Array.
+    return itsPositions(i1, i0);
+}
+
+inline double &AntennaSelection::operator()(unsigned int i0, unsigned int i1)
+{
+    //# Swap axes to hide the Fortran index convention used by casa::Array.
+    return itsPositions(i1, i0);
+}
+
+// -------------------------------------------------------------------------- //
+// - TileLayout implementation                                              - //
 // -------------------------------------------------------------------------- //
 
-inline double AntennaConfig::operator()(unsigned int i, unsigned int j)
+inline const double &TileLayout::operator()(unsigned int i0, unsigned int i1)
     const
 {
     //# Swap axes to hide the Fortran index convention used by casa::Array.
-    return itsPositions(j, i);
+    return itsPositions(i1, i0);
+}
+
+inline double &TileLayout::operator()(unsigned int i0, unsigned int i1)
+{
+    //# Swap axes to hide the Fortran index convention used by casa::Array.
+    return itsPositions(i1, i0);
 }
 
 } // namespace BBS
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am b/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am
index 52aa5d15309505d5b3f0e69740428ea57acf68bc..9743a204ab4c0273c5d6784ef556e50de79bba51 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am
@@ -28,6 +28,7 @@ pkginclude_Expr_HEADERS	= 	\
 	Expr/BasicExpr.h \
 	Expr/Cache.h \
 	Expr/ConditionNumber.h \
+	Expr/EquatorialCentroid.h \
 	Expr/Expr.h \
 	Expr/ExprId.h \
 	Expr/ExprAdaptors.h \
@@ -68,9 +69,9 @@ pkginclude_Expr_HEADERS	= 	\
 	Expr/Scope.h \
 	Expr/Source.h \
 	Expr/SpectralIndex.h \
-	Expr/EquatorialCentroid.h \
 	Expr/StationShift.h \
 	Expr/StationUVW.h \
+	Expr/TileArrayFactor.h \
 	Expr/ValueSet.h \
 	Expr/YatawattaDipole.h
 
diff --git a/CEP/Calibration/BBSKernel/src/CMakeLists.txt b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
index b51150a6162c16b65f4458388f86273642df1735..066e0df9517424e88109deb03e674925ddc9d534 100644
--- a/CEP/Calibration/BBSKernel/src/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
@@ -26,6 +26,7 @@ lofar_add_library(bbskernel
   Expr/AzEl.cc
   Expr/Cache.cc
   Expr/ConditionNumber.cc
+  Expr/EquatorialCentroid.cc
   Expr/Expr.cc
   Expr/ExprAdaptors.cc
   Expr/ExprParm.cc
@@ -62,9 +63,9 @@ lofar_add_library(bbskernel
   Expr/Scope.cc
   Expr/Source.cc
   Expr/SpectralIndex.cc
-  Expr/EquatorialCentroid.cc
   Expr/StationShift.cc
   Expr/StationUVW.cc
+  Expr/TileArrayFactor.cc
   Expr/ValueSet.cc
   Expr/YatawattaDipole.cc)
 
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc b/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc
index 3ddb7edc6e49d53d8d37cf27b7eadf7c9142062b..8b1f46ae37b647308cf91f1975436d2e885f8f07 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc
@@ -33,11 +33,11 @@ namespace BBS
 {
 
 ArrayFactor::ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction,
-    const Expr<Vector<2> >::ConstPtr &reference, const AntennaConfig &config,
-    double referenceFreq)
+    const Expr<Vector<2> >::ConstPtr &reference,
+    const AntennaSelection &selection, double referenceFreq)
     :   BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>(direction,
             reference),
-        itsConfig(config),
+        itsSelection(selection),
         itsReferenceFreq(referenceFreq)
 {
 }
@@ -45,7 +45,7 @@ ArrayFactor::ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction,
 const JonesMatrix::View ArrayFactor::evaluateImpl(const Grid &grid,
     const Vector<2>::View &direction, const Vector<2>::View &reference) const
 {
-    const size_t nElement = itsConfig.size();
+    const size_t nElement = itsSelection.size();
     const size_t nFreq = grid[FREQ]->size();
     const size_t nTime = grid[TIME]->size();
 
@@ -95,16 +95,17 @@ const JonesMatrix::View ArrayFactor::evaluateImpl(const Grid &grid,
     {
         // Compute the delay for a plane wave approaching from the direction of
         // interest with respect to the phase center of element i.
-        Matrix delay = (k[0] * itsConfig(i, 0) + k[1] * itsConfig(i, 1)
-            + k[2] * itsConfig(i, 2)) / C::c;
+        Matrix delay = (k[0] * itsSelection(i, 0) + k[1] * itsSelection(i, 1)
+            + k[2] * itsSelection(i, 2)) / C::c;
 
         // Compute the delay for a plane wave approaching from the phase
         // reference direction with respect to the phase center of element i.
-        Matrix delay0 = (k0[0] * itsConfig(i, 0) + k0[1] * itsConfig(i, 1)
-            + k0[2] * itsConfig(i, 2)) / C::c;
+        Matrix delay0 = (k0[0] * itsSelection(i, 0) + k0[1] * itsSelection(i, 1)
+            + k0[2] * itsSelection(i, 2)) / C::c;
 
-        DBGASSERT(delay.nx() == 1 && delay.ny() == nTime);
-        DBGASSERT(delay0.nx() == 1 && delay0.ny() == nTime);
+        DBGASSERT(delay.nx() == 1 && static_cast<size_t>(delay.ny()) == nTime);
+        DBGASSERT(delay0.nx() == 1
+            && static_cast<size_t>(delay0.ny()) == nTime);
 
         double *p_delay = delay.doubleStorage();
         double *p_delay0 = delay0.doubleStorage();
diff --git a/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc b/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc
new file mode 100644
index 0000000000000000000000000000000000000000..67493028c9d37e9a843636e961589206346fd112
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc
@@ -0,0 +1,137 @@
+//# TileArrayFactor.cc: Compute the array factor of a LOFAR HBA tile.
+//#
+//# 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$
+
+#include <lofar_config.h>
+#include <BBSKernel/Expr/TileArrayFactor.h>
+
+#include <casa/BasicSL/Constants.h>
+
+using namespace casa;
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+TileArrayFactor::TileArrayFactor(const Expr<Vector<2> >::ConstPtr &direction,
+    const Expr<Vector<2> >::ConstPtr &reference, const TileLayout &layout)
+    :   BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>(direction,
+            reference),
+        itsLayout(layout)
+{
+}
+
+const JonesMatrix::View TileArrayFactor::evaluateImpl(const Grid &grid,
+    const Vector<2>::View &direction, const Vector<2>::View &reference) const
+{
+    const size_t nElement = itsLayout.size();
+    const size_t nFreq = grid[FREQ]->size();
+    const size_t nTime = grid[TIME]->size();
+
+    // Check preconditions.
+    ASSERT(!direction(0).isComplex() && !direction(1).isComplex());
+    ASSERT(direction(0).nx() == 1
+        && static_cast<size_t>(direction(0).ny()) == nTime);
+    ASSERT(direction(1).nx() == 1
+        && static_cast<size_t>(direction(1).ny()) == nTime);
+    ASSERT(!reference(0).isComplex() && !reference(1).isComplex());
+    ASSERT(reference(0).nx() == 1
+        && static_cast<size_t>(reference(0).ny()) == nTime);
+    ASSERT(reference(1).nx() == 1
+        && static_cast<size_t>(reference(1).ny()) == nTime);
+
+    // Compute propagation vectors.
+    Matrix sin_phi = sin(direction(0));
+    Matrix cos_phi = cos(direction(0));
+    // Convert from elevation to zenith angle.
+    Matrix theta = Matrix(C::pi_2) - direction(1);
+    Matrix sin_theta = sin(theta);
+//    Matrix cos_theta = cos(theta);
+
+    Matrix k[2];
+    k[0] = -sin_theta * cos_phi;
+    k[1] = -sin_theta * sin_phi;
+//    k[2] = -cos_theta;
+
+    Matrix sin_phi0 = sin(reference(0));
+    Matrix cos_phi0 = cos(reference(0));
+    // Convert from elevation to zenith angle.
+    Matrix theta0 = Matrix(C::pi_2) - reference(1);
+    Matrix sin_theta0 = sin(theta0);
+//    Matrix cos_theta0 = cos(theta0);
+
+    Matrix k0[2];
+    k0[0] = -sin_theta0 * cos_phi0;
+    k0[1] = -sin_theta0 * sin_phi0;
+//    k0[2] = -cos_theta0;
+
+    // Compute difference vector.
+    k[0] = k0[0] - k[0];
+    k[1] = k0[1] - k[1];
+//    k[2] = k0[2] - k[2];
+
+    // Allocate result (initialized at 0+0i).
+    Matrix arrayFactor(makedcomplex(0.0, 0.0), nFreq, nTime);
+    for(size_t i = 0; i < nElement; ++i)
+    {
+        // Compute the effective delay for a plane wave approaching from the
+        // direction of interest with respect to the phase center of element i
+        // when beamforming in the reference direction using time delays.
+        Matrix delay = (k[0] * itsLayout(i, 0) + k[1] * itsLayout(i, 1)) / C::c;
+//        LOG_DEBUG_STR("el: " << i << " x: " << itsLayout(i, 0) << " y: "
+//            << itsLayout(i, 1));
+
+        DBGASSERT(delay.nx() == 1 && static_cast<size_t>(delay.ny()) == nTime);
+
+        double *p_re, *p_im;
+        arrayFactor.dcomplexStorage(p_re, p_im);
+        double *p_delay = delay.doubleStorage();
+
+        for(size_t t = 0; t < nTime; ++t)
+        {
+            const double delay_t = *p_delay;
+
+            for(size_t f = 0; f < nFreq; ++f)
+            {
+                const double shift = C::_2pi * grid[FREQ]->center(f) * delay_t;
+
+                (*p_re) += std::cos(shift) / nElement;
+                (*p_im) += std::sin(shift) / nElement;
+
+                ++p_re;
+                ++p_im;
+            }
+
+            ++p_delay;
+        }
+    }
+
+    JonesMatrix::View result;
+    result.assign(0, 0, arrayFactor);
+    result.assign(0, 1, Matrix(makedcomplex(0.0, 0.0)));
+    result.assign(1, 0, Matrix(makedcomplex(0.0, 0.0)));
+    result.assign(1, 1, arrayFactor);
+    return result;
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Instrument.cc b/CEP/Calibration/BBSKernel/src/Instrument.cc
index e3c04ec0caaa56b7d9a1c926cd6efebfacaa1d4a..8123b6f0c3e9772aac32fcfed44ab1d3dd166f91 100644
--- a/CEP/Calibration/BBSKernel/src/Instrument.cc
+++ b/CEP/Calibration/BBSKernel/src/Instrument.cc
@@ -31,22 +31,30 @@ namespace LOFAR
 namespace BBS
 {
 
-const string &AntennaConfig::name() const
+AntennaSelection::AntennaSelection()
+{
+}
+
+AntennaSelection::AntennaSelection(unsigned int size)
+    :   itsPositions(3, size, 0.0)
+{
+}
+
+const string &AntennaSelection::name() const
 {
     return itsName;
 }
 
-size_t AntennaConfig::size() const
+unsigned int AntennaSelection::size() const
 {
     return itsPositions.shape()[1];
 }
 
-istream &operator>>(istream &in, AntennaConfig &obj)
+istream &operator>>(istream &in, AntennaSelection &obj)
 {
     string line;
 
     // Parse configuration name.
-//    in >> ws;
     getline(in, line);
     size_t start = line.find_first_not_of(" \t\n");
     size_t end = line.find_first_of(" \t\n", start);
@@ -60,7 +68,6 @@ istream &operator>>(istream &in, AntennaConfig &obj)
     obj.itsName = line.substr(start, end);
 
     // Skip line containing phase center.
-//    in >> ws;
     getline(in, line);
 
     // Parse array shape.
@@ -99,18 +106,24 @@ istream &operator>>(istream &in, AntennaConfig &obj)
     return in;
 }
 
-Station::Station(const string &name, const casa::MPosition &position)
-    :   itsName(name),
-        itsPosition(position)
+TileLayout::TileLayout()
+{
+}
+
+TileLayout::TileLayout(unsigned int size)
+    :   itsPositions(2, size, 0.0)
 {
 }
 
-Station::Station(const string &name, const casa::MPosition &position,
-    const casa::Path &config)
+unsigned int TileLayout::size() const
+{
+    return itsPositions.shape()[1];
+}
+
+Station::Station(const string &name, const casa::MPosition &position)
     :   itsName(name),
         itsPosition(position)
 {
-    readAntennaConfigurations(config);
 }
 
 const string &Station::name() const
@@ -123,26 +136,38 @@ const casa::MPosition &Station::position() const
     return itsPosition;
 }
 
-const AntennaConfig &Station::config(const string &name) const
+const AntennaSelection &Station::selection(const string &name) const
 {
-    map<string, AntennaConfig>::const_iterator it = itsConfig.find(name);
-    if(it == itsConfig.end())
+    map<string, AntennaSelection>::const_iterator it =
+        itsAntennaSelection.find(name);
+    if(it == itsAntennaSelection.end())
     {
-        THROW(BBSKernelException, "Unknown antenna configuration for station "
-            << this->name() << ": " << name);
+        THROW(BBSKernelException, "Unknown antenna selection: " << name
+            << " for station: " << this->name());
     }
 
     return it->second;
 }
 
-void Station::readAntennaConfigurations(const casa::Path &file)
+const TileLayout &Station::tile(unsigned int i) const
+{
+    if(i >= itsTileLayout.size())
+    {
+        THROW(BBSKernelException, "Unknown tile: " << i << " for station: "
+            << this->name());
+    }
+
+    return itsTileLayout[i];
+}
+
+void Station::readAntennaSelection(const casa::Path &file)
 {
     casa::String path(file.expandedName());
 
     ifstream ifs;
     ifs.exceptions(ifstream::failbit | ifstream::badbit);
 
-    map<string, AntennaConfig> result;
+    map<string, AntennaSelection> result;
     try
     {
         ifs.open(path.c_str());
@@ -163,7 +188,7 @@ void Station::readAntennaConfigurations(const casa::Path &file)
                 continue;
             }
 
-            AntennaConfig config;
+            AntennaSelection config;
             ifs >> config;
             result[config.name()] = config;
         }
@@ -171,10 +196,74 @@ void Station::readAntennaConfigurations(const casa::Path &file)
     catch(ifstream::failure &e)
     {
         THROW(BBSKernelException, "Error opening/reading antenna configuration"
-          " file: " << path);
+            " file: " << path);
     }
 
-    itsConfig = result;
+    itsAntennaSelection = result;
+    LOG_DEBUG_STR("" << name() << ": read " << result.size() << " antenna"
+        " selection(s) from: " << path);
+}
+
+void Station::readTileLayout(const casa::Path &file)
+{
+    casa::String path(file.expandedName());
+
+    ifstream ifs;
+    ifs.exceptions(ifstream::failbit | ifstream::badbit);
+
+    string line;
+    vector<TileLayout> result;
+    try
+    {
+        ifs.open(path.c_str());
+
+        // Skip to line after header.
+        size_t pos = string::npos;
+        while(pos == string::npos)
+        {
+            getline(ifs, line);
+            pos = line.find("HBAdeltas");
+        }
+
+        // Parse array shape.
+        char sep;
+        unsigned int shape[2];
+        ifs >> shape[0] >> sep >> shape[1] >> sep;
+
+        const unsigned int tileSize = 16;
+        if(!ifs.good() || sep != '[' || shape[0] == 0 || shape[1] != 2
+            || (shape[0] % tileSize != 0))
+        {
+            ifs.setstate(istream::failbit);
+        }
+
+        // Parse array.
+        for(unsigned int j = 0; j < shape[0] / tileSize; ++j)
+        {
+            TileLayout tile(tileSize);
+            for(unsigned int i = 0; i < tileSize; ++i)
+            {
+                ifs >> tile(i, 0) >> tile(i, 1);
+            }
+
+            result.push_back(tile);
+        }
+
+        ifs >> sep;
+        if(!ifs.good() || sep != ']')
+        {
+            ifs.setstate(istream::failbit);
+        }
+    }
+    catch(ifstream::failure &e)
+    {
+        THROW(BBSKernelException, "Error opening/reading tile layout file: "
+            << path);
+    }
+
+    itsTileLayout = result;
+    LOG_DEBUG_STR("" << name() << ": read " << result.size() << " HBA tile"
+        " layout(s) from: " << path);
 }
 
 Instrument::Instrument()
@@ -225,13 +314,24 @@ const Station &Instrument::operator[](const string &name) const
     return itsStations[it->second];
 }
 
-void Instrument::readAntennaConfigurations(const casa::Path &path)
+void Instrument::readLOFARAntennaConfig(const casa::Path &path)
 {
     for(unsigned int i = 0; i < itsStations.size(); ++i)
     {
+        ASSERT(itsStations[i].name().size() >= 5);
+        string name = itsStations[i].name().substr(0, 5);
+
+        // Read station selections.
         casa::Path file(path);
-        file.append(itsStations[i].name() + "-AntennaArrays.conf");
-        itsStations[i].readAntennaConfigurations(file);
+        file.append("AntennaArrays");
+        file.append(name + "-AntennaArrays.conf");
+        itsStations[i].readAntennaSelection(file);
+
+        // Read layout of HBA tiles.
+        file = casa::Path(path);
+        file.append("HBADeltas");
+        file.append(name + "-HBADeltas.conf");
+        itsStations[i].readTileLayout(file);
     }
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/Makefile.am b/CEP/Calibration/BBSKernel/src/Makefile.am
index 11ef97399a50cd9346b2639e147d5a17c5935d9b..84e5a32c3e7a50b55b4f871548c1ae47aa7be02c 100644
--- a/CEP/Calibration/BBSKernel/src/Makefile.am
+++ b/CEP/Calibration/BBSKernel/src/Makefile.am
@@ -35,6 +35,7 @@ libbbskernel_la_SOURCES = Package__Version.cc \
 	VisDimensions.cc \
 	VisExpr.cc \
 	VisSelection.cc \
+	Expr/EquatorialCentroid.cc \
 	Expr/ArrayFactor.cc \
 	Expr/AzEl.cc \
 	Expr/Cache.cc \
@@ -75,9 +76,9 @@ libbbskernel_la_SOURCES = Package__Version.cc \
 	Expr/Scope.cc \
 	Expr/Source.cc \
 	Expr/SpectralIndex.cc \
-	Expr/EquatorialCentroid.cc \
 	Expr/StationShift.cc \
 	Expr/StationUVW.cc \
+	Expr/TileArrayFactor.cc \
 	Expr/ValueSet.cc \
 	Expr/YatawattaDipole.cc
 
diff --git a/CEP/Calibration/BBSKernel/src/Model.cc b/CEP/Calibration/BBSKernel/src/Model.cc
index 571713aa94b2e8737bcfe8ec7cdf1bc04fa3411e..d27f24fcd60235521b59ba68b4c0b5979b7b9653 100644
--- a/CEP/Calibration/BBSKernel/src/Model.cc
+++ b/CEP/Calibration/BBSKernel/src/Model.cc
@@ -30,6 +30,7 @@
 #include <BBSKernel/Expr/ArrayFactor.h>
 #include <BBSKernel/Expr/AzEl.h>
 #include <BBSKernel/Expr/ConditionNumber.h>
+#include <BBSKernel/Expr/EquatorialCentroid.h>
 #include <BBSKernel/Expr/ExprAdaptors.h>
 #include <BBSKernel/Expr/ExprVisData.h>
 #include <BBSKernel/Expr/FlagIf.h>
@@ -49,7 +50,7 @@
 #include <BBSKernel/Expr/Request.h>
 #include <BBSKernel/Expr/ScalarMatrixMul.h>
 #include <BBSKernel/Expr/SpectralIndex.h>
-#include <BBSKernel/Expr/EquatorialCentroid.h>
+#include <BBSKernel/Expr/TileArrayFactor.h>
 #include <BBSKernel/Expr/StationShift.h>
 #include <BBSKernel/Expr/StationUVW.h>
 
@@ -140,7 +141,7 @@ void Model::makeForwardExpr(const ModelConfig &config, const VisData::Ptr&,
         const BeamConfig &beamConfig = config.getBeamConfig();
 
         // Read antenna configurations.
-        itsInstrument.readAntennaConfigurations(beamConfig.getConfigPath());
+        itsInstrument.readLOFARAntennaConfig(beamConfig.getConfigPath());
 
         // Create a functor to generate element beam expression nodes.
         exprElementBeam = ElementBeamExpr::create(beamConfig, itsScope);
@@ -317,7 +318,7 @@ void Model::makeInverseExpr(const ModelConfig &config,
         const BeamConfig &beamConfig = config.getBeamConfig();
 
         // Read antenna configurations.
-        itsInstrument.readAntennaConfigurations(beamConfig.getConfigPath());
+        itsInstrument.readLOFARAntennaConfig(beamConfig.getConfigPath());
 
         // Create a functor to generate element beam expression nodes.
         exprElementBeam = ElementBeamExpr::create(beamConfig, itsScope);
@@ -863,23 +864,76 @@ void Model::makeBeamExpr(const BeamConfig &config,
 {
     for(unsigned int i = 0; i < stations.size(); ++i)
     {
-        const unsigned int station = stations[i];
-
-        // Get station element configuration.
-        const AntennaConfig &antennaConfig =
-            itsInstrument[station].config(config.getConfigName());
+        const Station &station = itsInstrument[stations[i]];
 
         // Get element orientation.
         Expr<Scalar>::Ptr orientation = itsScope(INSTRUMENT,
-            "AntennaOrientation:" + itsInstrument[station].name());
+            "AntennaOrientation:" + station.name());
+
+        AntennaSelection selection;
+        Expr<JonesMatrix>::Ptr exprBeam(exprElement->construct(exprAzEl(i),
+            orientation));
+
+        // Get LOFAR station name suffix.
+        // NB. THIS IS A TEMPORARY SOLUTION THAT CAN BE REMOVED AS SOON AS THE
+        // DIPOLE INFORMATION IS STORED AS META-DATA INSIDE THE MS.
+        const string suffix = station.name().substr(5);
+        if(suffix == "LBA")
+        {
+            try
+            {
+                selection = station.selection(config.getConfigName());
+            }
+            catch(BBSKernelException &ex)
+            {
+                selection = station.selection("LBA");
+            }
+        }
+        else if(suffix == "HBA0")
+        {
+            selection = station.selection("HBA_0");
+
+            Expr<JonesMatrix>::Ptr exprTileFactor =
+                Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i),
+                    exprRefAzEl(i), station.tile(0)));
+
+            exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor,
+                exprBeam));
+        }
+        else if(suffix == "HBA1")
+        {
+            selection = station.selection("HBA_1");
+
+            Expr<JonesMatrix>::Ptr exprTileFactor =
+                Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i),
+                    exprRefAzEl(i), station.tile(1)));
+
+            exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor,
+                exprBeam));
+        }
+        else if(suffix == "HBA")
+        {
+            selection = station.selection("HBA");
+
+            Expr<JonesMatrix>::Ptr exprTileFactor =
+                Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i),
+                    exprRefAzEl(i), station.tile(0)));
+
+            exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor,
+                exprBeam));
+        }
+        else
+        {
+            THROW(BBSKernelException, "Illegal LOFAR station name encoutered: "
+                << station.name());
+        }
 
         // Create ArrayFactor expression.
         Expr<JonesMatrix>::Ptr exprArrayFactor(new ArrayFactor(exprAzEl(i),
-            exprRefAzEl(i), antennaConfig, itsReferenceFreq));
+            exprRefAzEl(i), selection, itsReferenceFreq));
 
         accumulator(i) = compose(accumulator(i),
-            Expr<JonesMatrix>::Ptr(new MatrixMul2(exprArrayFactor,
-                exprElement->construct(exprAzEl(i), orientation))));
+            Expr<JonesMatrix>::Ptr(new MatrixMul2(exprArrayFactor, exprBeam)));
     }
 }