diff --git a/.gitattributes b/.gitattributes
index 81463bd741d889806c6a3819feabbd8261153372..e4c88e8c515f4275fb67980fe4d6d003fcaaf071 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -36,10 +36,11 @@ CEP/Calibration/BBSKernel/include/BBSKernel/Apply.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/BaselineMask.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Correlation.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/CorrelationMask.h -text
-CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Estimate.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/EstimateUtil.h -text
-CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldAzEl.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementHBA.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementLBA.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldThetaPhi.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/CachePolicy.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Delay.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ElevationCut.h -text
@@ -48,6 +49,7 @@ CEP/Calibration/BBSKernel/include/BBSKernel/Expr/FaradayRotation.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ITRFDirection.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/IonPhaseShift.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/LinearToCircularRL.h -text
+CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ParallacticRotation.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ShapeletCoherence.h -text
 CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ShapeletSource.h -text
@@ -75,10 +77,11 @@ CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_phi.c -text
 CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_theta.c -text
 CEP/Calibration/BBSKernel/src/Correlation.cc -text
 CEP/Calibration/BBSKernel/src/CorrelationMask.cc -text
-CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc -text
 CEP/Calibration/BBSKernel/src/Estimate.cc -text
 CEP/Calibration/BBSKernel/src/EstimateUtil.cc -text
-CEP/Calibration/BBSKernel/src/Expr/AntennaFieldAzEl.cc -text
+CEP/Calibration/BBSKernel/src/Expr/AntennaElementHBA.cc -text
+CEP/Calibration/BBSKernel/src/Expr/AntennaElementLBA.cc -text
+CEP/Calibration/BBSKernel/src/Expr/AntennaFieldThetaPhi.cc -text
 CEP/Calibration/BBSKernel/src/Expr/CachePolicy.cc -text
 CEP/Calibration/BBSKernel/src/Expr/Delay.cc -text
 CEP/Calibration/BBSKernel/src/Expr/ElevationCut.cc -text
@@ -87,6 +90,7 @@ CEP/Calibration/BBSKernel/src/Expr/FaradayRotation.cc -text
 CEP/Calibration/BBSKernel/src/Expr/ITRFDirection.cc -text
 CEP/Calibration/BBSKernel/src/Expr/IonPhaseShift.cc -text
 CEP/Calibration/BBSKernel/src/Expr/LinearToCircularRL.cc -text
+CEP/Calibration/BBSKernel/src/Expr/ParallacticRotation.cc -text
 CEP/Calibration/BBSKernel/src/Expr/Scope.cc -text
 CEP/Calibration/BBSKernel/src/Expr/ShapeletCoherence.cc -text
 CEP/Calibration/BBSKernel/src/Expr/ShapeletSource.cc -text
diff --git a/CEP/Calibration/BBSControl/src/Step.cc b/CEP/Calibration/BBSControl/src/Step.cc
index 61e40ce06e204894f0000ff1a700afa72c47664a..fa07affa90e7d3e9d1367b5a6da85b5130b11de8 100644
--- a/CEP/Calibration/BBSControl/src/Step.cc
+++ b/CEP/Calibration/BBSControl/src/Step.cc
@@ -157,8 +157,6 @@ namespace LOFAR
         ps.add(prefix + "Model.Beam.Mode", BeamConfig::asString(config.mode()));
         ps.add(prefix + "Model.Beam.ConjugateAF",
           toString(config.conjugateAF()));
-        ps.add(prefix + "Model.Beam.Element.Path",
-          config.getElementPath().originalName());
       }
 
       ps.add(prefix + "Model.DirectionalTEC.Enable",
@@ -243,18 +241,7 @@ namespace LOFAR
         bool conjugateAF = ps.getBool("Model.Beam.ConjugateAF",
             parentConfig.conjugateAF());
 
-        string defaultPath;
-        if(itsModelConfig.useBeam()) {
-          defaultPath = parentConfig.getElementPath().originalName();
-        } else {
-          defaultPath = "$LOFARROOT/share";
-        }
-
-        string elementPath = ps.getString("Model.Beam.Element.Path",
-          defaultPath);
-
-        itsModelConfig.setBeamConfig(BeamConfig(mode, conjugateAF,
-          casa::Path(elementPath)));
+        itsModelConfig.setBeamConfig(BeamConfig(mode, conjugateAF));
       } else {
         itsModelConfig.clearBeamConfig();
       }
diff --git a/CEP/Calibration/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/CMakeLists.txt
index 2cc46bb4c2fb0307248344b4f5d4c5145c5f9ef8..7abae3e6495d9754c3e35032827e9aa93bc60376 100644
--- a/CEP/Calibration/BBSKernel/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/CMakeLists.txt
@@ -1,6 +1,6 @@
 # $Id$
 
-lofar_package(BBSKernel 1.0 DEPENDS Blob Common ParmDB)
+lofar_package(BBSKernel 1.0 DEPENDS Blob Common ParmDB ElementResponse)
 
 include(LofarFindPackage)
 lofar_find_package(Boost REQUIRED)
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
index 9a181070de34869725e4a02b500db569ff635e24..45cc134da39cc2e1e8584425e8b3a1a4d6585b00 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt
@@ -39,7 +39,9 @@ install(FILES
   VisSelection.h
   DESTINATION include/${PACKAGE_NAME})
 install(FILES
-  Expr/AntennaFieldAzEl.h
+  Expr/AntennaElementLBA.h
+  Expr/AntennaElementHBA.h
+  Expr/AntennaFieldThetaPhi.h
   Expr/AzEl.h
   Expr/BasicExpr.h
   Expr/Cache.h
@@ -63,7 +65,6 @@ install(FILES
   Expr/FlagIf.h
   Expr/GaussianCoherence.h
   Expr/GaussianSource.h
-  Expr/HamakerDipole.h
   Expr/IonPhaseShift.h
   Expr/ITRFDirection.h
   Expr/LinearToCircularRL.h
@@ -81,6 +82,7 @@ install(FILES
   Expr/MatrixSum.h
   Expr/MatrixTmp.h
   Expr/MergeFlags.h
+  Expr/ParallacticRotation.h
   Expr/PhaseShift.h
   Expr/PiercePoint.h
   Expr/PointCoherence.h
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h b/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h
deleted file mode 100644
index a25f2cc9e2cef8eca1af84fc473814d1f35dd6dd..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//# ElementBeamExpr.h: Wrapper class that constructs the correct beam expr based
-//# on the BeamConfig instance provided in the constructor. It also caches any
-//# shared auxilliary data.
-//#
-//# 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_ELEMENTBEAMEXPR_H
-#define LOFAR_BBSKERNEL_ELEMENTBEAMEXPR_H
-
-// \file
-// Wrapper class that constructs the correct beam expr based on the BeamConfig
-// instance provided in the constructor. It also caches any shared auxilliary
-// data.
-
-#include <BBSKernel/Expr/Expr.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
-
-#include <Common/lofar_smartptr.h>
-
-#include <casa/OS/Path.h>
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-class BeamConfig;
-class Scope;
-
-// \addtogroup BBSKernel
-// @{
-
-class ElementBeamExpr
-{
-public:
-    typedef shared_ptr<ElementBeamExpr>         Ptr;
-    typedef shared_ptr<const ElementBeamExpr>   ConstPtr;
-
-    static ElementBeamExpr::Ptr create(const BeamConfig &config, Scope &scope);
-
-    virtual ~ElementBeamExpr();
-
-    virtual Expr<JonesMatrix>::Ptr
-        construct(const Expr<Vector<2> >::ConstPtr &direction,
-            const Expr<Scalar>::ConstPtr &orientation) const = 0;
-};
-
-class HamakerBeamExpr: public ElementBeamExpr
-{
-public:
-    typedef shared_ptr<HamakerBeamExpr>         Ptr;
-    typedef shared_ptr<const HamakerBeamExpr>   ConstPtr;
-
-    HamakerBeamExpr(const BeamConfig &config, Scope &scope);
-
-    virtual Expr<JonesMatrix>::Ptr
-        construct(const Expr<Vector<2> >::ConstPtr &direction,
-            const Expr<Scalar>::ConstPtr &orientation) const;
-
-private:
-    HamakerBeamCoeff    itsCoeff;
-};
-
-class YatawattaBeamExpr: public ElementBeamExpr
-{
-public:
-    typedef shared_ptr<YatawattaBeamExpr>       Ptr;
-    typedef shared_ptr<const YatawattaBeamExpr> ConstPtr;
-
-    YatawattaBeamExpr(const BeamConfig &config, Scope &scope);
-
-    virtual Expr<JonesMatrix>::Ptr
-        construct(const Expr<Vector<2> >::ConstPtr &direction,
-            const Expr<Scalar>::ConstPtr &orientation) const;
-
-private:
-    casa::Path  itsModulePath[2];
-};
-
-// @}
-
-} //# namespace BBS
-} //# namespace LOFAR
-
-#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/YatawattaDipole.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementHBA.h
similarity index 62%
rename from CEP/Calibration/BBSKernel/include/BBSKernel/Expr/YatawattaDipole.h
rename to CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementHBA.h
index 404baf3ce39ebb552463e49ce4c88d4982b0356a..4e46bae67ae78e0a273b407ebe00d5cb557775f7 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/YatawattaDipole.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementHBA.h
@@ -1,7 +1,7 @@
-//# YatawattaDipole.h: Dipole voltage beam using Sarod Yatawatta's analytical
-//# model.
+//# AntennaElementHBA.h: Model of an idealized LOFAR HBA dual dipole antenna
+//# element.
 //#
-//# Copyright (C) 2008
+//# Copyright (C) 2011
 //# ASTRON (Netherlands Institute for Radio Astronomy)
 //# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
 //#
@@ -21,16 +21,13 @@
 //#
 //# $Id$
 
-#ifndef LOFAR_BBSKERNEL_EXPR_YATAWATTADIPOLE_H
-#define LOFAR_BBSKERNEL_EXPR_YATAWATTADIPOLE_H
+#ifndef LOFAR_BBSKERNEL_EXPR_ANTENNAELEMENTHBA_H
+#define LOFAR_BBSKERNEL_EXPR_ANTENNAELEMENTHBA_H
 
-#include <BBSKernel/Expr/BasicExpr.h>
-#include <BBSKernel/Expr/ExternalFunction.h>
+// \file
+// Model of an idealized LOFAR HBA dual dipole antenna element.
 
-namespace casa
-{
-    class Path;
-}
+#include <BBSKernel/Expr/BasicExpr.h>
 
 namespace LOFAR
 {
@@ -40,19 +37,17 @@ namespace BBS
 // \addtogroup Expr
 // @{
 
-class YatawattaDipole: public BasicBinaryExpr<Vector<2>, Scalar, JonesMatrix>
+class AntennaElementHBA: public BasicUnaryExpr<Vector<2>, JonesMatrix>
 {
 public:
-    YatawattaDipole(const casa::Path &moduleTheta, const casa::Path &modulePhi,
-        const Expr<Vector<2> >::ConstPtr &azel,
-        const Expr<Scalar>::ConstPtr &orientation);
+    typedef shared_ptr<AntennaElementHBA>       Ptr;
+    typedef shared_ptr<const AntennaElementHBA> ConstPtr;
+
+    AntennaElementHBA(const Expr<Vector<2> >::ConstPtr &target);
 
 protected:
     virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
-        const Vector<2>::View &azel, const Scalar::View &orientation) const;
-
-private:
-    ExternalFunction    itsThetaFunction, itsPhiFunction;
+        const Vector<2>::View &target) const;
 };
 
 // @}
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementLBA.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementLBA.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce9fbefda8a97870dcc72739210e5b0f5a6d7696
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaElementLBA.h
@@ -0,0 +1,58 @@
+//# AntennaElementLBA.h: Model of an idealized LOFAR LBA dual dipole antenna
+//# element.
+//#
+//# Copyright (C) 2011
+//# 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_ANTENNAELEMENTLBA_H
+#define LOFAR_BBSKERNEL_EXPR_ANTENNAELEMENTLBA_H
+
+// \file
+// Model of an idealized LOFAR LBA dual dipole antenna element.
+
+#include <BBSKernel/Expr/BasicExpr.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class AntennaElementLBA: public BasicUnaryExpr<Vector<2>, JonesMatrix>
+{
+public:
+    typedef shared_ptr<AntennaElementLBA>       Ptr;
+    typedef shared_ptr<const AntennaElementLBA> ConstPtr;
+
+    AntennaElementLBA(const Expr<Vector<2> >::ConstPtr &target);
+
+protected:
+    virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
+        const Vector<2>::View &target) const;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldAzEl.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldAzEl.h
deleted file mode 100644
index 7c00e7ad35c3293f23e6a06e02110c946f62e4bd..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldAzEl.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//# AntennaFieldAzEl.h: Compute azimuth and elevation in radians relevative to
-//# the antenna field coordinate system (P, Q, R). The input direction as well
-//# as the positive coordinate axes are assumed to be unit vectors expressed in
-//# ITRF. Zero azimuth corresponds to the positive Q axis and positive azimuth
-//# runs from the positive Q axis to the positive P axis. Elevation is the angle
-//# the direction makes with the (P, Q) plane.
-//#
-//# Copyright (C) 2011
-//# 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_ANTENNAFIELDAZEL_H
-#define LOFAR_BBSKERNEL_EXPR_ANTENNAFIELDAZEL_H
-
-// \file
-// Compute azimuth and elevation in radians relevative to the antenna field
-// coordinate system (P, Q, R). The input direction as well as the positive
-// coordinate axes are assumed to be unit vectors expressed in ITRF. Zero
-// azimuth corresponds to the positive Q axis and positive azimuth runs from the
-// positive Q axis to the positive P axis. Elevation is the angle the direction
-// makes with the (P, Q) plane.
-
-#include <BBSKernel/Expr/BasicExpr.h>
-#include <BBSKernel/Instrument.h>
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-// \addtogroup Expr
-// @{
-
-class AntennaFieldAzEl: public BasicUnaryExpr<Vector<3>, Vector<2> >
-{
-public:
-    typedef shared_ptr<AntennaFieldAzEl>        Ptr;
-    typedef shared_ptr<const AntennaFieldAzEl>  ConstPtr;
-
-    AntennaFieldAzEl(const Expr<Vector<3> >::ConstPtr &direction,
-        const AntennaField::ConstPtr &field);
-
-protected:
-    virtual const Vector<2>::View evaluateImpl(const Grid &grid,
-        const Vector<3>::View &direction) const;
-
-private:
-    AntennaField::ConstPtr  itsField;
-};
-
-// @}
-
-} //# namespace BBS
-} //# namespace LOFAR
-
-#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldThetaPhi.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldThetaPhi.h
new file mode 100644
index 0000000000000000000000000000000000000000..bee80c9b4eda48993df0afb1962e033c409a6a40
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/AntennaFieldThetaPhi.h
@@ -0,0 +1,76 @@
+//# AntennaFieldThetaPhi.h: Compute topocentric (local) theta and phi spherical
+//# coordinates (in radians) relative to the Cartesian antenna field coordinate
+//# system (PQR), for a given target direction. The target direction is assumed
+//# to be an ITRF unit vector in the direction of arrival. The positive
+//# coordinate axes are assumed to be ITRF unit vectors. Zero phi corresponds to
+//# the positive P axis, and positive phi runs from the positive P axis towards
+//# the positive Q axis (roughly East over North). Theta or zenith angle is the
+//# angle the target direction makes with the positive R axis.
+//#
+//# Copyright (C) 2011
+//# 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_ANTENNAFIELDTHETAPHI_H
+#define LOFAR_BBSKERNEL_EXPR_ANTENNAFIELDTHETAPHI_H
+
+// \file
+// Compute topocentric (local) theta and phi spherical coordinates (in radians)
+// relative to the Cartesian antenna field coordinate system (PQR), for a given
+// target direction. The target direction is assumed to be an ITRF unit vector
+// in the direction of arrival. The positive coordinate axes are assumed to be
+// ITRF unit vectors. Zero phi corresponds to the positive P axis, and positive
+// phi runs from the positive P axis towards the positive Q axis (roughly East
+// over North). Theta or zenith angle is the angle the target direction makes
+// with the positive R axis.
+
+#include <BBSKernel/Expr/BasicExpr.h>
+#include <BBSKernel/Instrument.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class AntennaFieldThetaPhi: public BasicUnaryExpr<Vector<3>, Vector<2> >
+{
+public:
+    typedef shared_ptr<AntennaFieldThetaPhi>        Ptr;
+    typedef shared_ptr<const AntennaFieldThetaPhi>  ConstPtr;
+
+    AntennaFieldThetaPhi(const Expr<Vector<3> >::ConstPtr &direction,
+        const AntennaField::ConstPtr &field);
+
+protected:
+    virtual const Vector<2>::View evaluateImpl(const Grid &grid,
+        const Vector<3>::View &direction) const;
+
+private:
+    AntennaField::ConstPtr  itsField;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/HamakerDipole.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/HamakerDipole.h
deleted file mode 100644
index 1471e126210786004cd157d60eed4571c47aa8c7..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/HamakerDipole.h
+++ /dev/null
@@ -1,122 +0,0 @@
-//# HamakerDipole.h: Implementation of J.P. Hamaker's memo
-//# "Mathematical-physical analysis of the generic dual-dipole antenna".
-//#
-//# Copyright (C) 2008
-//# 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_HAMAKERDIPOLE_H
-#define LOFAR_BBSKERNEL_EXPR_HAMAKERDIPOLE_H
-
-// \file
-// Implementation of J.P. Hamaker's memo "Mathematical-physical analysis of the
-// generic dual-dipole antenna".
-
-#include <BBSKernel/Expr/BasicExpr.h>
-#include <Common/lofar_complex.h>
-
-#include <casa/Arrays.h>
-
-namespace casa
-{
-    class Path;
-}
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-// \addtogroup Expr
-// @{
-
-class HamakerBeamCoeff
-{
-public:
-    HamakerBeamCoeff();
-
-    void init(const casa::Path &coeffFile);
-
-    // Center frequency used to scale frequency to range [-1.0, 1.0].
-    double center() const;
-    // Width used to scale frequency to range [-1.0, 1.0].
-    double width() const;
-
-    unsigned int shape(unsigned int i) const;
-
-    dcomplex operator()(unsigned int element, unsigned int harmonic,
-        unsigned int powTheta, unsigned int powFreq) const;
-
-private:
-    double                  itsCenter, itsWidth;
-    casa::Array<dcomplex>   itsCoeff;
-};
-
-class HamakerDipole: public BasicBinaryExpr<Vector<2>, Scalar, JonesMatrix>
-{
-public:
-    typedef shared_ptr<HamakerDipole>       Ptr;
-    typedef shared_ptr<const HamakerDipole> ConstPtr;
-
-    HamakerDipole(const HamakerBeamCoeff &coeff,
-        const Expr<Vector<2> >::ConstPtr &azel,
-        const Expr<Scalar>::ConstPtr &orientation);
-
-protected:
-    virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
-        const Vector<2>::View &azel, const Scalar::View &orientation) const;
-
-private:
-    HamakerBeamCoeff    itsCoeff;
-};
-
-// @}
-
-// -------------------------------------------------------------------------- //
-// - Implementation: HamakerBeamCoeff                                       - //
-// -------------------------------------------------------------------------- //
-
-inline double HamakerBeamCoeff::center() const
-{
-    return itsCenter;
-}
-
-inline double HamakerBeamCoeff::width() const
-{
-    return itsWidth;
-}
-
-inline unsigned int HamakerBeamCoeff::shape(unsigned int i) const
-{
-    // Reverse axes because casa::Array<> uses fortran order.
-    DBGASSERT(i < 4);
-    return itsCoeff.shape()(3 - i);
-}
-
-inline dcomplex HamakerBeamCoeff::operator()(unsigned int element,
-    unsigned int harmonic, unsigned int powTheta, unsigned int powFreq) const
-{
-    // Reverse axes because casa::Array<> uses fortran order.
-    return itsCoeff(casa::IPosition(4, powFreq, powTheta, harmonic, element));
-}
-
-} //# namespace BBS
-} //# namespace LOFAR
-
-#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ParallacticRotation.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ParallacticRotation.h
new file mode 100644
index 0000000000000000000000000000000000000000..32642f5ddab4f468991ce9ea585142e17c5e7399
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ParallacticRotation.h
@@ -0,0 +1,71 @@
+//# ParallacticRotation.h: Jones matrix that relates the (X,Y)-frame used to
+//# express polarization on the sky (according to the IAU definition) to the
+//# topocentric (theta,phi)-frame. Both are Cartesian frames defined on the
+//# tangent plane, with +X towards the North, +Y towards the East, +theta away
+//# from the (pseudo) zenith, and +phi East over North around the (pseudo)
+//# zenith.
+//#
+//# Copyright (C) 2011
+//# 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_PARALLACTICROTATION_H
+#define LOFAR_BBSKERNEL_EXPR_PARALLACTICROTATION_H
+
+// \file
+// Jones matrix that relates the (X,Y)-frame used to express polarization on the
+// sky (according to the IAU definition) to the topocentric (theta,phi)-frame.
+// Both are Cartesian frames defined on the tangent plane, with +X towards the
+// North, +Y towards the East, +theta away from the (pseudo) zenith, and +phi
+// East over North around the (pseudo) zenith.
+
+#include <BBSKernel/Expr/BasicExpr.h>
+#include <BBSKernel/Instrument.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+// \addtogroup Expr
+// @{
+
+class ParallacticRotation: public BasicUnaryExpr<Vector<3>, JonesMatrix>
+{
+public:
+    typedef shared_ptr<ParallacticRotation>         Ptr;
+    typedef shared_ptr<const ParallacticRotation>   ConstPtr;
+
+    ParallacticRotation(const Expr<Vector<3> >::ConstPtr &target,
+        const AntennaField::ConstPtr &field);
+
+protected:
+    virtual const JonesMatrix::View evaluateImpl(const Grid &grid,
+        const Vector<3>::View &target) const;
+
+private:
+    AntennaField::ConstPtr  itsField;
+};
+
+// @}
+
+} //# namespace BBS
+} //# namespace LOFAR
+
+#endif
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
index a90cf6839318c6259dea27d0f0ba2b1022b8a5ee..d442b93df93be7034b58cd7b39b817b0d4eb3389 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h
@@ -50,8 +50,8 @@ namespace BBS
 class AntennaField
 {
 public:
-    typedef shared_ptr<AntennaField>    Ptr;
-    typedef shared_ptr<AntennaField>    ConstPtr;
+    typedef shared_ptr<AntennaField>        Ptr;
+    typedef shared_ptr<const AntennaField>  ConstPtr;
 
     enum Axis
     {
@@ -72,7 +72,7 @@ public:
 
     const string &name() const;
     const Vector3 &position() const;
-    const Vector3 &axis(Axis axis);
+    const Vector3 &axis(Axis axis) const;
 
     bool isHBA() const;
 
@@ -82,11 +82,13 @@ public:
 
     void appendElement(const Element &element);
     inline size_t nElement() const;
+    inline size_t nActiveElement() const;
     inline const Element &element(size_t i) const;
 
 private:
     string                  itsName;
     Vector3                 itsPosition;
+    size_t                  itsActiveElementCount;
     Vector3                 itsAxes[N_Axis];
     vector<Vector3>         itsTileElements;
     vector<Element>         itsElements;
@@ -95,8 +97,8 @@ private:
 class Station
 {
 public:
-    typedef shared_ptr<Station> Ptr;
-    typedef shared_ptr<Station> ConstPtr;
+    typedef shared_ptr<Station>       Ptr;
+    typedef shared_ptr<const Station> ConstPtr;
 
     Station(const string &name, const casa::MPosition &position);
     Station(const string &name, const casa::MPosition &position,
@@ -109,6 +111,9 @@ public:
 
     bool isPhasedArray() const;
     unsigned int nField() const;
+    size_t nElement() const;
+    size_t nActiveElement() const;
+
     AntennaField::ConstPtr field(unsigned int i) const;
 
 private:
@@ -120,8 +125,8 @@ private:
 class Instrument
 {
 public:
-    typedef shared_ptr<Instrument>  Ptr;
-    typedef shared_ptr<Instrument>  ConstPtr;
+    typedef shared_ptr<Instrument>        Ptr;
+    typedef shared_ptr<const Instrument>  ConstPtr;
 
     Instrument(const string &name, const casa::MPosition &position);
 
@@ -166,6 +171,11 @@ inline size_t AntennaField::nElement() const
     return itsElements.size();
 }
 
+inline size_t AntennaField::nActiveElement() const
+{
+    return itsActiveElementCount;
+}
+
 inline const AntennaField::Element &AntennaField::element(size_t i) const
 {
     return itsElements[i];
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementAIPS.h b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementAIPS.h
index ad8d4809256d34fd9825216a8b0fd9bfdeb1be15..bdba8e923cbde5f2491d4a10de06f9ed85f2a90a 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementAIPS.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementAIPS.h
@@ -72,24 +72,15 @@ public:
     virtual void writeHistory(const ParameterSet &parset) const;
 
     virtual BaselineMask asMask(const string &filter) const;
-
     // @}
 
 private:
-    void initInstrument();
-    Station::Ptr initStation(unsigned int id, const string &name,
-        const casa::MPosition &position) const;
     void initReferenceDirections();
     void initDimensions();
 
-    bool hasColumn(const string &column) const;
-    bool hasColumn(const casa::Table &table, const string &column) const;
     void createVisibilityColumn(const string &name);
     void createCovarianceColumn(const string &name);
 
-    bool hasSubTable(const string &table) const;
-    casa::Table getSubTable(const string &table) const;
-
     casa::MDirection getColumnPhaseReference(const string &column) const;
 
     casa::Table getVisSelection(casa::Table table,
@@ -126,6 +117,16 @@ private:
     unsigned int            itsIdDataDescription;
 };
 
+Instrument::Ptr readInstrument(const casa::MeasurementSet &ms,
+    unsigned int idObservation = 0);
+casa::MDirection readPhaseReference(const casa::MeasurementSet &ms,
+    unsigned int idField = 0);
+casa::MDirection readDelayReference(const casa::MeasurementSet &ms,
+    unsigned int idField = 0);
+casa::MDirection readTileReference(const casa::MeasurementSet &ms,
+    unsigned int idField = 0);
+double readFreqReference(const casa::MeasurementSet &ms,
+    unsigned int idDataDescription = 0);
 // @}
 
 } //# namespace BBS
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFAR.h b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFAR.h
index d9e4ad4d7ef0561424c9286c45e4f6dc742ec5fc..e6f0a273780563468ea7035ea105a27c1fb8cf2b 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFAR.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFAR.h
@@ -38,7 +38,6 @@
 #include <BBSKernel/VisBuffer.h>
 #include <BBSKernel/Expr/CachePolicy.h>
 #include <BBSKernel/Expr/Expr.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
 #include <BBSKernel/Expr/Scope.h>
 #include <BBSKernel/Expr/Source.h>
 #include <ParmDB/ParmDB.h>
@@ -64,7 +63,7 @@ public:
     MeasurementExprLOFAR(SourceDB &sourceDB,
         const BufferMap &buffers,
         const ModelConfig &config,
-        const Instrument::Ptr &instrument,
+        const Instrument::ConstPtr &instrument,
         const BaselineSeq &baselines,
         double refFreq,
         const casa::MDirection &refPhase,
@@ -105,7 +104,7 @@ private:
     void makeForwardExpr(SourceDB &sourceDB,
         const BufferMap &buffers,
         const ModelConfig &config,
-        const Instrument::Ptr &instrument,
+        const Instrument::ConstPtr &instrument,
         double refFreq,
         const casa::MDirection &refPhase,
         const casa::MDirection &refDelay,
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFARUtil.h b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFARUtil.h
index f7bcc096fcf0e4572879518e00839961693014c0..a95ed4e5afb3bd8f3aec9e462b39a5ba62da0637 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFARUtil.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/MeasurementExprLOFARUtil.h
@@ -43,8 +43,6 @@ namespace LOFAR
 {
 namespace BBS
 {
-class HamakerBeamCoeff;
-
 // \addtogroup BBSKernel
 // @{
 
@@ -108,9 +106,7 @@ makeBeamExpr(Scope &scope,
     const Expr<Vector<3> >::Ptr &exprITRF,
     const Expr<Vector<3> >::Ptr &exprRefDelayITRF,
     const Expr<Vector<3> >::Ptr &exprRefTileITRF,
-    const BeamConfig &config,
-    const HamakerBeamCoeff &coeffLBA,
-    const HamakerBeamCoeff &coeffHBA);
+    const BeamConfig &config);
 
 Expr<JonesMatrix>::Ptr
 makeDirectionalTECExpr(Scope &scope,
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/ModelConfig.h b/CEP/Calibration/BBSKernel/include/BBSKernel/ModelConfig.h
index 82d922dc16f86f936dcc7df4e0e422075bca6ec0..ef63b0b05bdaa84ddcde72a416d16a9537562959 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/ModelConfig.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/ModelConfig.h
@@ -31,8 +31,6 @@
 #include <Common/lofar_vector.h>
 #include <Common/lofar_iosfwd.h>
 
-#include <casa/OS/Path.h>
-
 namespace LOFAR
 {
 namespace BBS
@@ -54,11 +52,10 @@ public:
     };
 
     BeamConfig();
-    BeamConfig(Mode mode, bool conjugateAF, const casa::Path &elementPath);
+    BeamConfig(Mode mode, bool conjugateAF);
 
     Mode mode() const;
     bool conjugateAF() const;
-    const casa::Path &getElementPath() const;
 
     static bool isDefined(Mode in);
     static Mode asMode(const string &in);
@@ -67,7 +64,6 @@ public:
 private:
     Mode            itsMode;
     bool            itsConjugateAF;
-    casa::Path      itsElementPath;
 };
 
 // Configuration options specific to the ionospheric model.
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/StationExprLOFAR.h b/CEP/Calibration/BBSKernel/include/BBSKernel/StationExprLOFAR.h
index e62521134e70881651f4fb69d4eee2ccc8bef5c9..ab8556c6b3056db594b3825efc3cfd8e9fa9c94d 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/StationExprLOFAR.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/StationExprLOFAR.h
@@ -36,7 +36,6 @@
 #include <BBSKernel/Expr/CachePolicy.h>
 #include <BBSKernel/Expr/Expr.h>
 #include <BBSKernel/Expr/ExprValue.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
 #include <BBSKernel/Expr/Scope.h>
 #include <ParmDB/SourceDB.h>
 #include <measures/Measures/MDirection.h>
@@ -87,7 +86,7 @@ private:
     void initialize(SourceDB &sourceDB,
         const BufferMap &buffers,
         const ModelConfig &config,
-        const Instrument::Ptr &instrument,
+        const Instrument::ConstPtr &instrument,
         double refFreq,
         const casa::MDirection &refPhase,
         const casa::MDirection &refDelay,
diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/StationResponse.h b/CEP/Calibration/BBSKernel/include/BBSKernel/StationResponse.h
index 38336154120064855b4ff0813b997c99d5b7472c..5541def25a4d392c1cfa8d80ec2d3dae266f0a18 100644
--- a/CEP/Calibration/BBSKernel/include/BBSKernel/StationResponse.h
+++ b/CEP/Calibration/BBSKernel/include/BBSKernel/StationResponse.h
@@ -38,7 +38,6 @@
 
 #include <ms/MeasurementSets/MeasurementSet.h>
 #include <measures/Measures/MDirection.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
 
 namespace LOFAR
 {
@@ -108,9 +107,6 @@ public:
     // Set the tile delay reference direction (used by the tile beamformer).
     void setRefTile(const casa::MDirection &reference);
 
-    // Set the reference orientation of the +X dipole.
-    void setRefOrientation(double orientation);
-
     // Set the direction of interest.
     void setDirection(const casa::MDirection &direction);
 
@@ -125,11 +121,6 @@ public:
     const JonesMatrix::View evaluate(unsigned int i);
 
 private:
-    Instrument::Ptr initInstrument(const casa::MeasurementSet &ms) const;
-    Station::Ptr initStation(const casa::MeasurementSet &ms, unsigned int id,
-        const string &name, const casa::MPosition &position) const;
-    double getReferenceFreq(const casa::MeasurementSet &ms) const;
-
     // Right multiply \p lhs by \p rhs. Return \p rhs if \p lhs is
     // uninitialized.
     Expr<JonesMatrix>::Ptr compose(const Expr<JonesMatrix>::Ptr &lhs,
@@ -137,7 +128,6 @@ private:
 
     Dummy<Vector<2> >::Ptr          itsRefDelay;
     Dummy<Vector<2> >::Ptr          itsRefTile;
-    Dummy<Scalar>::Ptr              itsRefOrientation;
     Dummy<Vector<2> >::Ptr          itsDirection;
     vector<Expr<JonesMatrix>::Ptr>  itsExpr;
     Request                         itsRequest;
diff --git a/CEP/Calibration/BBSKernel/src/CMakeLists.txt b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
index 7608e00f472ce181e3d709defe7680c2cfbe7fe8..153c6abe659478855401920d2d520bcfdc01ad0a 100644
--- a/CEP/Calibration/BBSKernel/src/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/src/CMakeLists.txt
@@ -2,7 +2,7 @@
 
 include(LofarPackageVersion)
 
-add_subdirectory(Contrib)
+#add_subdirectory(Contrib)
 
 lofar_add_library(bbskernel
   Package__Version.cc
@@ -31,7 +31,9 @@ lofar_add_library(bbskernel
   VisDimensions.cc
   VisEquator.cc
   VisSelection.cc
-  Expr/AntennaFieldAzEl.cc
+  Expr/AntennaElementLBA.cc
+  Expr/AntennaElementHBA.cc
+  Expr/AntennaFieldThetaPhi.cc
   Expr/AzEl.cc
   Expr/CachePolicy.cc
   Expr/Cache.cc
@@ -52,7 +54,6 @@ lofar_add_library(bbskernel
   Expr/FlagArray.cc
   Expr/GaussianCoherence.cc
   Expr/GaussianSource.cc
-  Expr/HamakerDipole.cc
   Expr/IonPhaseShift.cc
   Expr/ITRFDirection.cc
   Expr/LinearToCircularRL.cc
@@ -69,6 +70,7 @@ lofar_add_library(bbskernel
   Expr/MatrixRep.cc
   Expr/MatrixSum.cc
   Expr/MatrixTmp.cc
+  Expr/ParallacticRotation.cc
   Expr/PhaseShift.cc
   Expr/PiercePoint.cc
   Expr/PointCoherence.cc
@@ -91,4 +93,4 @@ lofar_add_library(bbskernel
   Expr/Timer.cc)
 
 # Because we're using dlopen()
-target_link_libraries(bbskernel ${CMAKE_DL_LIBS})
+#target_link_libraries(bbskernel ${CMAKE_DL_LIBS})
diff --git a/CEP/Calibration/BBSKernel/src/Contrib/CMakeLists.txt b/CEP/Calibration/BBSKernel/src/Contrib/CMakeLists.txt
index 36a016d81e5ef8c4e341085fe9573e0a9142ce62..c633d91530b9ee6bb67194c89698cc894929d421 100644
--- a/CEP/Calibration/BBSKernel/src/Contrib/CMakeLists.txt
+++ b/CEP/Calibration/BBSKernel/src/Contrib/CMakeLists.txt
@@ -1,4 +1,4 @@
 # $Id$
 
-#add_subdirectory(SBY_DipoleBeam)
+add_subdirectory(SBY_DipoleBeam)
 add_subdirectory(JPH_DipoleBeam)
diff --git a/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc b/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc
deleted file mode 100644
index d286b894bef634ef875345fb048caafe650cef53..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-//# ElementBeamExpr.cc: Wrapper class that constructs the correct beam expr based on the BeamConfig instance provided in the constructor. It also caches any shared auxilliary data.
-//#
-//# 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/ElementBeamExpr.h>
-#include <BBSKernel/Exceptions.h>
-#include <BBSKernel/ModelConfig.h>
-#include <BBSKernel/Expr/YatawattaDipole.h>
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-ElementBeamExpr::~ElementBeamExpr()
-{
-}
-
-ElementBeamExpr::Ptr ElementBeamExpr::create(const BeamConfig &config,
-    Scope &scope)
-{
-    LOG_INFO_STR("Using element beam type: "
-        << BeamConfig::asString(config.getElementType()));
-    ASSERT(BeamConfig::isDefined(config.getElementType()));
-
-    switch(config.getElementType())
-    {
-        case BeamConfig::HAMAKER_LBA:
-        case BeamConfig::HAMAKER_HBA:
-        {
-            return ElementBeamExpr::Ptr(new HamakerBeamExpr(config, scope));
-        }
-
-        case BeamConfig::YATAWATTA_LBA:
-        case BeamConfig::YATAWATTA_HBA:
-        {
-            return ElementBeamExpr::Ptr(new YatawattaBeamExpr(config, scope));
-        }
-
-        default:
-            THROW(BBSKernelException, "Unsupported element type encountered.");
-    }
-}
-
-HamakerBeamExpr::HamakerBeamExpr(const BeamConfig &config, Scope&)
-{
-    ASSERT(config.getElementType() == BeamConfig::HAMAKER_LBA
-        || config.getElementType() == BeamConfig::HAMAKER_HBA);
-
-    casa::Path path = config.getElementPath();
-    path.append("element_beam_" + BeamConfig::asString(config.getElementType())
-        + ".coeff");
-    LOG_INFO_STR("Element beam config file: " << path.expandedName());
-
-    // Read beam coefficients from file.
-    itsCoeff.init(path);
-}
-
-Expr<JonesMatrix>::Ptr
-HamakerBeamExpr::construct(const Expr<Vector<2> >::ConstPtr &direction,
-    const Expr<Scalar>::ConstPtr &orientation) const
-{
-    return Expr<JonesMatrix>::Ptr(new HamakerDipole(itsCoeff, direction,
-        orientation));
-}
-
-YatawattaBeamExpr::YatawattaBeamExpr(const BeamConfig &config, Scope&)
-{
-    ASSERT(config.getElementType() == BeamConfig::YATAWATTA_LBA
-        || config.getElementType() == BeamConfig::YATAWATTA_HBA);
-
-    // TODO: Transparantly handle platforms that use a different extension for
-    // loadable modules.
-    itsModulePath[0] = config.getElementPath();
-    itsModulePath[0].append("element_beam_"
-        + BeamConfig::asString(config.getElementType()) + "_theta.so");
-
-    itsModulePath[1] = config.getElementPath();
-    itsModulePath[1].append("element_beam_"
-        + BeamConfig::asString(config.getElementType()) + "_phi.so");
-
-    LOG_INFO_STR("Element beam loadable modules: ["
-        << itsModulePath[0].expandedName() << ","
-        << itsModulePath[1].expandedName() << "]");
-}
-
-Expr<JonesMatrix>::Ptr
-YatawattaBeamExpr::construct(const Expr<Vector<2> >::ConstPtr &direction,
-    const Expr<Scalar>::ConstPtr &orientation) const
-{
-    return Expr<JonesMatrix>::Ptr(new YatawattaDipole(itsModulePath[0],
-        itsModulePath[1], direction, orientation));
-}
-
-} //# namespace BBS
-} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/AntennaElementHBA.cc b/CEP/Calibration/BBSKernel/src/Expr/AntennaElementHBA.cc
new file mode 100644
index 0000000000000000000000000000000000000000..90ec9c88fa4fb7635167a4835ebc12707ad2d8a8
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/AntennaElementHBA.cc
@@ -0,0 +1,100 @@
+//# AntennaElementHBA.cc: Model of an idealized LOFAR HBA dual dipole antenna
+//# element.
+//#
+//# Copyright (C) 2011
+//# 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/AntennaElementHBA.h>
+#include <ElementResponse/ElementResponse.h>
+#include <casa/BasicSL/Constants.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+AntennaElementHBA::AntennaElementHBA(const Expr<Vector<2> >::ConstPtr &target)
+    :   BasicUnaryExpr<Vector<2>, JonesMatrix>(target)
+{
+}
+
+const JonesMatrix::View AntennaElementHBA::evaluateImpl(const Grid &grid,
+    const Vector<2>::View &target) const
+{
+    const size_t nFreq = grid[FREQ]->size();
+    const size_t nTime = grid[TIME]->size();
+
+    // Check preconditions.
+    ASSERT(!target(0).isComplex() && target(0).nx() == 1
+        && static_cast<size_t>(target(0).ny()) == nTime);
+    ASSERT(!target(1).isComplex() && target(1).nx() == 1
+        && static_cast<size_t>(target(1).ny()) == nTime);
+
+    // Get pointers to input and output data.
+    const double *theta = target(0).doubleStorage();
+    const double *phi = target(1).doubleStorage();
+
+    Matrix E00, E01, E10, E11;
+    double *E00_re, *E00_im;
+    E00.setDCMat(nFreq, nTime);
+    E00.dcomplexStorage(E00_re, E00_im);
+
+    double *E01_re, *E01_im;
+    E01.setDCMat(nFreq, nTime);
+    E01.dcomplexStorage(E01_re, E01_im);
+
+    double *E10_re, *E10_im;
+    E10.setDCMat(nFreq, nTime);
+    E10.dcomplexStorage(E10_re, E10_im);
+
+    double *E11_re, *E11_im;
+    E11.setDCMat(nFreq, nTime);
+    E11.dcomplexStorage(E11_re, E11_im);
+
+    // Evaluate antenna model.
+    dcomplex J[2][2];
+    for(size_t i = 0; i < nTime; ++i)
+    {
+        for(size_t j = 0; j < nFreq; ++j)
+        {
+            // The positive X dipole direction is SW of the reference
+            // orientation, which translates to a phi coordinate of 5/4*pi in
+            // the topocentric spherical coordinate system. The phi coordinate
+            // is corrected for this offset before evaluating the antenna model.
+            element_response_hba(grid[FREQ]->center(j), theta[i],
+                phi[i] - 5.0 * casa::C::pi_4, J);
+
+            *E00_re++ = real(J[0][0]);
+            *E00_im++ = imag(J[0][0]);
+            *E01_re++ = real(J[0][1]);
+            *E01_im++ = imag(J[0][1]);
+            *E10_re++ = real(J[1][0]);
+            *E10_im++ = imag(J[1][0]);
+            *E11_re++ = real(J[1][1]);
+            *E11_im++ = imag(J[1][1]);
+        }
+    }
+
+    return JonesMatrix::View(E00, E01, E10, E11);
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/AntennaElementLBA.cc b/CEP/Calibration/BBSKernel/src/Expr/AntennaElementLBA.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d8446801832a4b44ae00f32dd0446a6b0be3c0b3
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/AntennaElementLBA.cc
@@ -0,0 +1,100 @@
+//# AntennaElementLBA.cc: Model of an idealized LOFAR LBA dual dipole antenna
+//# element.
+//#
+//# Copyright (C) 2011
+//# 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/AntennaElementLBA.h>
+#include <ElementResponse/ElementResponse.h>
+#include <casa/BasicSL/Constants.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+AntennaElementLBA::AntennaElementLBA(const Expr<Vector<2> >::ConstPtr &target)
+    :   BasicUnaryExpr<Vector<2>, JonesMatrix>(target)
+{
+}
+
+const JonesMatrix::View AntennaElementLBA::evaluateImpl(const Grid &grid,
+    const Vector<2>::View &target) const
+{
+    const size_t nFreq = grid[FREQ]->size();
+    const size_t nTime = grid[TIME]->size();
+
+    // Check preconditions.
+    ASSERT(!target(0).isComplex() && target(0).nx() == 1
+        && static_cast<size_t>(target(0).ny()) == nTime);
+    ASSERT(!target(1).isComplex() && target(1).nx() == 1
+        && static_cast<size_t>(target(1).ny()) == nTime);
+
+    // Get pointers to input and output data.
+    const double *theta = target(0).doubleStorage();
+    const double *phi = target(1).doubleStorage();
+
+    Matrix E00, E01, E10, E11;
+    double *E00_re, *E00_im;
+    E00.setDCMat(nFreq, nTime);
+    E00.dcomplexStorage(E00_re, E00_im);
+
+    double *E01_re, *E01_im;
+    E01.setDCMat(nFreq, nTime);
+    E01.dcomplexStorage(E01_re, E01_im);
+
+    double *E10_re, *E10_im;
+    E10.setDCMat(nFreq, nTime);
+    E10.dcomplexStorage(E10_re, E10_im);
+
+    double *E11_re, *E11_im;
+    E11.setDCMat(nFreq, nTime);
+    E11.dcomplexStorage(E11_re, E11_im);
+
+    // Evaluate antenna model.
+    dcomplex J[2][2];
+    for(size_t i = 0; i < nTime; ++i)
+    {
+        for(size_t j = 0; j < nFreq; ++j)
+        {
+            // The positive X dipole direction is SW of the reference
+            // orientation, which translates to a phi coordinate of 5/4*pi in
+            // the topocentric spherical coordinate system. The phi coordinate
+            // is corrected for this offset before evaluating the antenna model.
+            element_response_lba(grid[FREQ]->center(j), theta[i],
+                phi[i] - 5.0 * casa::C::pi_4, J);
+
+            *E00_re++ = real(J[0][0]);
+            *E00_im++ = imag(J[0][0]);
+            *E01_re++ = real(J[0][1]);
+            *E01_im++ = imag(J[0][1]);
+            *E10_re++ = real(J[1][0]);
+            *E10_im++ = imag(J[1][0]);
+            *E11_re++ = real(J[1][1]);
+            *E11_im++ = imag(J[1][1]);
+        }
+    }
+
+    return JonesMatrix::View(E00, E01, E10, E11);
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/AntennaFieldAzEl.cc b/CEP/Calibration/BBSKernel/src/Expr/AntennaFieldThetaPhi.cc
similarity index 53%
rename from CEP/Calibration/BBSKernel/src/Expr/AntennaFieldAzEl.cc
rename to CEP/Calibration/BBSKernel/src/Expr/AntennaFieldThetaPhi.cc
index 567ac7932f0a61491e2f9a876359c5c3d2eef116..3455e296c705d1429c8aa6c1dd691e1fff55986a 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/AntennaFieldAzEl.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/AntennaFieldThetaPhi.cc
@@ -1,9 +1,11 @@
-//# AntennaFieldAzEl.cc: Compute azimuth and elevation in radians relevative to
-//# the antenna field coordinate system (P, Q, R). The input direction as well
-//# as the positive coordinate axes are assumed to be unit vectors expressed in
-//# ITRF. Zero azimuth corresponds to the positive Q axis and positive azimuth
-//# runs from the positive Q axis to the positive P axis. Elevation is the angle
-//# the direction makes with the (P, Q) plane.
+//# AntennaFieldThetaPhi.cc: Compute topocentric (local) theta and phi spherical
+//# coordinates (in radians) relative to the Cartesian antenna field coordinate
+//# system (PQR), for a given target direction. The target direction is assumed
+//# to be an ITRF unit vector in the direction of arrival. The positive
+//# coordinate axes are assumed to be ITRF unit vectors. Zero phi corresponds to
+//# the positive P axis, and positive phi runs from the positive P axis towards
+//# the positive Q axis (roughly East over North). Theta or zenith angle is the
+//# angle the target direction makes with the positive R axis.
 //#
 //# Copyright (C) 2011
 //# ASTRON (Netherlands Institute for Radio Astronomy)
@@ -26,7 +28,7 @@
 //# $Id$
 
 #include <lofar_config.h>
-#include <BBSKernel/Expr/AntennaFieldAzEl.h>
+#include <BBSKernel/Expr/AntennaFieldThetaPhi.h>
 #include <casa/BasicSL/Constants.h>
 
 namespace LOFAR
@@ -34,14 +36,14 @@ namespace LOFAR
 namespace BBS
 {
 
-AntennaFieldAzEl::AntennaFieldAzEl(const Expr<Vector<3> >::ConstPtr &direction,
+AntennaFieldThetaPhi::AntennaFieldThetaPhi(const Expr<Vector<3> >::ConstPtr &direction,
     const AntennaField::ConstPtr &field)
     :   BasicUnaryExpr<Vector<3>, Vector<2> >(direction),
         itsField(field)
 {
 }
 
-const Vector<2>::View AntennaFieldAzEl::evaluateImpl(const Grid&,
+const Vector<2>::View AntennaFieldThetaPhi::evaluateImpl(const Grid&,
     const Vector<3>::View &direction) const
 {
     // Check preconditions.
@@ -61,19 +63,27 @@ const Vector<2>::View AntennaFieldAzEl::evaluateImpl(const Grid&,
         + direction(2) * q[2];
 
     // Compute the inner product between the antenna field normal (R) and the
-    // direction vector to get the sine of the elevation (cosine of the zenith
-    // angle).
-    Matrix sinEl = direction(0) * r[0] + direction(1) * r[1]
+    // direction vector to get the cosine of the zenith angle (sine of the
+    // elevation).
+    Matrix projectionR = direction(0) * r[0] + direction(1) * r[1]
         + direction(2) * r[2];
 
-    // Compute azimuth and elevation. Zero azimuth corresponds to the positive Q
-    // axis and positive azimuth runs from the positive Q axis to the positive P
-    // axis. Elevation is computed by taking the arcsine of the angle computed
-    // earlier.
-    Vector<2>::View azel;
-    azel.assign(0, atan2(projectionP, projectionQ));
-    azel.assign(1, asin(sinEl));
-    return azel;
+    // Compute theta and phi. Zero phi corresponds to the positive P axis and
+    // positive phi runs from the positive P axis to the positive Q axis.
+    Vector<2>::View result;
+    result.assign(0, acos(projectionR));
+    result.assign(1, atan2(projectionQ, projectionP));
+
+//    LOG_DEBUG_STR("EP: [" << p[0] << ", " << p[1] << ", " << p[2] << "]");
+//    LOG_DEBUG_STR("EQ: [" << q[0] << ", " << q[1] << ", " << q[2] << "]");
+//    LOG_DEBUG_STR("ER: [" << r[0] << ", " << r[1] << ", " << r[2] << "]");
+//    LOG_DEBUG_STR("X: " << direction(0));
+//    LOG_DEBUG_STR("Y: " << direction(1));
+//    LOG_DEBUG_STR("Z: " << direction(2));
+//    LOG_DEBUG_STR("THETA: " << result(0));
+//    LOG_DEBUG_STR("PHI: " << result(1));
+
+    return result;
 }
 
 } //# namespace BBS
diff --git a/CEP/Calibration/BBSKernel/src/Expr/HamakerDipole.cc b/CEP/Calibration/BBSKernel/src/Expr/HamakerDipole.cc
deleted file mode 100644
index c157c52a1981601cf80c8161d4e7f82968f41f7e..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/src/Expr/HamakerDipole.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-//# HamakerDipole.cc: Implementation of J.P. Hamaker's memo
-//# "Mathematical-physical analysis of the generic dual-dipole antenna".
-//#
-//# Copyright (C) 2008
-//# 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/HamakerDipole.h>
-#include <BBSKernel/Exceptions.h>
-
-#include <casa/BasicSL/Constants.h>
-#include <casa/OS/Path.h>
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-HamakerBeamCoeff::HamakerBeamCoeff()
-    :   itsCenter(0.0),
-        itsWidth(1.0)
-{
-}
-
-void HamakerBeamCoeff::init(const casa::Path &coeffFile)
-{
-    // Open file.
-    casa::String path = coeffFile.expandedName();
-    ifstream in(path.c_str());
-    if(!in)
-    {
-        THROW(BBSKernelException, "" << path << ": unable to open file");
-    }
-
-    // Read file header.
-    string header, token0, token1, token2, token3, token4, token5;
-    getline(in, header);
-
-    size_t nElements, nHarmonics, nPowerTime, nPowerFreq;
-    double freqAvg, freqRange;
-
-    istringstream iss(header);
-    iss >> token0 >> nElements >> token1 >> nHarmonics >> token2 >> nPowerTime
-        >> token3 >> nPowerFreq >> token4 >> freqAvg >> token5 >> freqRange;
-
-    if(!in || !iss || token0 != "d" || token1 != "k" || token2 != "pwrT"
-        || token3 != "pwrF" || token4 != "freqAvg" || token5 != "freqRange")
-    {
-        THROW(BBSKernelException, "" << path << ": unable to parse header");
-    }
-
-    if(nElements * nHarmonics * nPowerTime * nPowerFreq == 0)
-    {
-        THROW(BBSKernelException, "" << path << ": the number of coefficients"
-            " should be larger than zero.");
-    }
-
-    LOG_DEBUG_STR("" << path << ": nElements: " << nElements << " nHarmonics: "
-        << nHarmonics << " nPowerTime: " << nPowerTime << " nPowerFreq: "
-        << nPowerFreq);
-
-    // Allocate coefficient matrix.
-    itsCenter = freqAvg;
-    itsWidth = freqRange;
-    itsCoeff = casa::Array<dcomplex>(casa::IPosition(4, nPowerFreq, nPowerTime,
-        nHarmonics, nElements));
-
-    size_t nCoeff = 0;
-    while(in.good())
-    {
-        // Read line from file.
-        string line;
-        getline(in, line);
-
-        // Skip lines that contain only whitespace.
-        if(line.find_last_not_of(" ") == string::npos)
-        {
-            continue;
-        }
-
-        // Parse line.
-        size_t element, harmonic, powerTime, powerFreq;
-        double re, im;
-
-        iss.clear();
-        iss.str(line);
-        iss >> element >> harmonic >> powerTime >> powerFreq >> re >> im;
-
-        if(!iss || element >= nElements || harmonic >= nHarmonics
-            || powerTime >= nPowerTime || powerFreq >= nPowerFreq)
-        {
-            THROW(BBSKernelException, "" << path << ": errror reading file.");
-        }
-
-        // Store coefficient.
-        itsCoeff(casa::IPosition(4, powerFreq, powerTime, harmonic, element)) =
-            makedcomplex(re, im);
-
-        // Update coefficient counter.
-        ++nCoeff;
-    }
-
-    if(!in.eof())
-    {
-        THROW(BBSKernelException, "" << path << ": error reading file.");
-    }
-
-    if(nCoeff != nElements * nHarmonics * nPowerTime * nPowerFreq)
-    {
-        THROW(BBSKernelException, "" << path << ": the number of coefficients"
-            " specified in the header does not match the number of coefficients"
-            " in the file.");
-    }
-}
-
-HamakerDipole::HamakerDipole(const HamakerBeamCoeff &coeff,
-    const Expr<Vector<2> >::ConstPtr &azel,
-    const Expr<Scalar>::ConstPtr &orientation)
-    :   BasicBinaryExpr<Vector<2>, Scalar, JonesMatrix>(azel, orientation),
-        itsCoeff(coeff)
-{
-}
-
-const JonesMatrix::View HamakerDipole::evaluateImpl(const Grid &grid,
-    const Vector<2>::View &azel, const Scalar::View &orientation) const
-{
-    const size_t nFreq = grid[FREQ]->size();
-    const size_t nTime = grid[TIME]->size();
-
-    // Check preconditions.
-    ASSERT(static_cast<size_t>(azel(0).nelements()) == nTime);
-    ASSERT(static_cast<size_t>(azel(1).nelements()) == nTime);
-    ASSERT(static_cast<size_t>(orientation().nelements()) == 1);
-
-    // Get pointers to input and output data.
-    const double *az = azel(0).doubleStorage();
-    const double *el = azel(1).doubleStorage();
-    const double angle = orientation().getDouble(0, 0);
-
-    Matrix E00, E01, E10, E11;
-    double *E00_re, *E00_im;
-    E00.setDCMat(nFreq, nTime);
-    E00.dcomplexStorage(E00_re, E00_im);
-
-    double *E01_re, *E01_im;
-    E01.setDCMat(nFreq, nTime);
-    E01.dcomplexStorage(E01_re, E01_im);
-
-    double *E10_re, *E10_im;
-    E10.setDCMat(nFreq, nTime);
-    E10.dcomplexStorage(E10_re, E10_im);
-
-    double *E11_re, *E11_im;
-    E11.setDCMat(nFreq, nTime);
-    E11.dcomplexStorage(E11_re, E11_im);
-
-    // Evaluate beam.
-    const unsigned int nHarmonics = itsCoeff.shape(1);
-    const unsigned int nPowTheta = itsCoeff.shape(2);
-    const unsigned int nPowFreq = itsCoeff.shape(3);
-
-    for(size_t t = 0; t < nTime; ++t)
-    {
-        // Correct azimuth for dipole orientation.
-        const double phi = az[t] - angle;
-
-        // NB: The model is parameterized in terms of zenith angle. The
-        // appropriate conversion is taken care of below.
-        const double theta = casa::C::pi_2 - el[t];
-
-        for(size_t f = 0; f < nFreq; ++f)
-        {
-            // J-jones matrix (2x2 complex matrix)
-            dcomplex J[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
-
-            // Only compute the beam response for directions above the horizon.
-            if(theta < casa::C::pi_2)
-            {
-                // NB: The model is parameterized in terms of a normalized
-                // frequency in the range [-1, 1]. The appropriate conversion is
-                // taken care of below.
-                const double normFreq = (grid[FREQ]->center(f)
-                    - itsCoeff.center()) / itsCoeff.width();
-
-                for(size_t k = 0; k < nHarmonics; ++k)
-                {
-                    // Compute diagonal projection matrix P for the current
-                    // harmonic.
-                    dcomplex P[2] = {0.0, 0.0};
-
-                    dcomplex inner[2];
-                    for(long i = nPowTheta - 1; i >= 0; --i)
-                    {
-                        inner[0] = itsCoeff(0, k, i, nPowFreq - 1);
-                        inner[1] = itsCoeff(1, k, i, nPowFreq - 1);
-
-                        for(long j = nPowFreq - 2; j >= 0; --j)
-                        {
-                            inner[0] =
-                                inner[0] * normFreq + itsCoeff(0, k, i, j);
-                            inner[1] =
-                                inner[1] * normFreq + itsCoeff(1, k, i, j);
-                        }
-                        P[0] = P[0] * theta + inner[0];
-                        P[1] = P[1] * theta + inner[1];
-                    }
-
-                    // Compute Jones matrix for this harmonic by rotating P over
-                    // kappa * phi and add it to the result.
-                    const double kappa =
-                        ((k & 1) == 0 ? 1.0 : -1.0) * (2.0 * k + 1.0);
-                    const double cphi = std::cos(kappa * phi);
-                    const double sphi = std::sin(kappa * phi);
-
-                    J[0][0] += cphi * P[0];
-                    J[0][1] += -sphi * P[1];
-                    J[1][0] += sphi * P[0];
-                    J[1][1] += cphi * P[1];
-                }
-            }
-
-            *E00_re++ = real(J[0][0]);
-            *E00_im++ = imag(J[0][0]);
-            *E01_re++ = real(J[0][1]);
-            *E01_im++ = imag(J[0][1]);
-            *E10_re++ = real(J[1][0]);
-            *E10_im++ = imag(J[1][0]);
-            *E11_re++ = real(J[1][1]);
-            *E11_im++ = imag(J[1][1]);
-        }
-    }
-
-    JonesMatrix::View result;
-    result.assign(0, 0, E00);
-    result.assign(0, 1, E01);
-    result.assign(1, 0, E10);
-    result.assign(1, 1, E11);
-
-    return result;
-}
-
-} //# namespace BBS
-} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/ParallacticRotation.cc b/CEP/Calibration/BBSKernel/src/Expr/ParallacticRotation.cc
new file mode 100644
index 0000000000000000000000000000000000000000..50fe91836a62c5c9164e02766d424a72125fa86f
--- /dev/null
+++ b/CEP/Calibration/BBSKernel/src/Expr/ParallacticRotation.cc
@@ -0,0 +1,166 @@
+//# ParallacticRotation.cc: Jones matrix that relates the (X,Y)-frame used to
+//# express polarization on the sky (according to the IAU definition) to the
+//# topocentric (theta,phi)-frame. Both are Cartesian frames defined on the
+//# tangent plane, with +X towards the North, +Y towards the East, +theta away
+//# from the (pseudo) zenith, and +phi East over North around the (pseudo)
+//# zenith.
+//#
+//# Copyright (C) 2011
+//# 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/ParallacticRotation.h>
+#include <Common/LofarLogger.h>
+
+namespace LOFAR
+{
+namespace BBS
+{
+
+ParallacticRotation::ParallacticRotation(
+    const Expr<Vector<3> >::ConstPtr &target,
+    const AntennaField::ConstPtr &field)
+    :   BasicUnaryExpr<Vector<3>, JonesMatrix>(target),
+        itsField(field)
+{
+}
+
+const JonesMatrix::View ParallacticRotation::evaluateImpl(const Grid &grid,
+    const Vector<3>::View &target) const
+{
+    const size_t nFreq = grid[FREQ]->size();
+    const size_t nTime = grid[TIME]->size();
+
+    // Check preconditions.
+    ASSERT(!target(0).isComplex() && target(0).nx() == 1
+        && static_cast<size_t>(target(0).ny()) == nTime);
+    ASSERT(!target(1).isComplex() && target(1).nx() == 1
+        && static_cast<size_t>(target(1).ny()) == nTime);
+    ASSERT(!target(2).isComplex() && target(2).nx() == 1
+        && static_cast<size_t>(target(2).ny()) == nTime);
+
+    // Compute the cross product of the NCP and the target direction. This
+    // yields a vector tangent to the celestial sphere at the target direction,
+    // pointing towards the East (the direction of +Y in the IAU definition,
+    // or positive right ascension).
+    Matrix v1x = -target(1);
+    Matrix v1y = target(0);
+    Matrix v1z = Matrix(0.0);
+
+    Matrix v1norm = sqrt(sqr(v1x) + sqr(v1y) + sqr(v1z));
+    v1x = v1x / v1norm;
+    v1y = v1y / v1norm;
+    v1z = v1z / v1norm;
+
+    // Compute the cross product of the antenna field normal (R) and the target
+    // direction. This yields a vector tangent to the topocentric spherical
+    // coordinate system at the target direction, pointing towards the direction
+    // of positive phi (which runs East over North around the pseudo zenith).
+    const Vector3 &r = itsField->axis(AntennaField::R);
+    Matrix v2x = target(2) * r[1] - target(1) * r[2];
+    Matrix v2y = target(0) * r[2] - target(2) * r[0];
+    Matrix v2z = target(1) * r[0] - target(0) * r[1];
+
+    Matrix v2norm = sqrt(sqr(v2x) + sqr(v2y) + sqr(v2z));
+    v2x = v2x / v2norm;
+    v2y = v2y / v2norm;
+    v2z = v2z / v2norm;
+
+    // Compute the cosine and sine of the parallactic angle, i.e. the angle
+    // between v1 and v2, both tangent to a latitude circle of their respective
+    // spherical coordinate systems.
+    Matrix coschi = v1x * v2x + v1y * v2y + v1z * v2z;
+    Matrix sinchi = (v1y * v2z - v1z * v2y) * target(0)
+        + (v1z * v2x - v1x * v2z) * target(1)
+        + (v1x * v2y - v1y * v2x) * target(2);
+
+    // The input coordinate system is a right handed system with its third axis
+    // along the direction of propagation (IAU +Z). The output coordinate system
+    // is right handed as well, but its third axis points in the direction of
+    // arrival (i.e. exactly opposite).
+    //
+    // Because the electromagnetic field is always perpendicular to the
+    // direction of propagation, we only need to relate the (X, Y) axes of the
+    // input system to the corresponding (theta, phi) axes of the output system.
+    //
+    // To this end, we first rotate the input system around its third axis to
+    // align the Y axis with the phi axis. The X and theta axis are parallel
+    // after this rotation, but point in opposite directions. To align the X
+    // axis with the theta axis, we flip it.
+    //
+    // The Jones matrix to align the Y axis with the phi axis when these are
+    // separated by an angle phi (measured counter-clockwise around the
+    // direction of propagation, looking towards the origin), is given by:
+    //
+    // [ cos(phi)  sin(phi)]
+    // [-sin(phi)  cos(phi)]
+    //
+    // Here, cos(phi) and sin(phi) can be computed directly, without having to
+    // compute phi first (see the computation of coschi and sinchi above).
+    //
+    // Now, sinchi as computed above is opposite to sin(phi), because the
+    // direction used in the computation is the direction of arrival instead
+    // of the direction of propagation. Therefore, the sign of sinchi needs to
+    // be reversed. Furthermore, as explained above, the X axis has to be
+    // flipped to align with the theta axis. The Jones matrix returned from this
+    // function is therefore given by:
+    //
+    // [-coschi  sinchi]
+    // [ sinchi  coschi]
+    //
+    // This is an improper rotation, or rotoreflection.
+
+//    LOG_DEBUG_STR("COS: " << coschi);
+//    LOG_DEBUG_STR("SIN: " << sinchi);
+
+    ASSERT(!coschi.isComplex() && coschi.nx() == 1
+        && static_cast<size_t>(coschi.ny()) == nTime);
+    ASSERT(!sinchi.isComplex() && sinchi.nx() == 1
+        && static_cast<size_t>(sinchi.ny()) == nTime);
+
+    if(nFreq == 1)
+    {
+        return JonesMatrix::View(-coschi, sinchi, sinchi, coschi);
+    }
+
+    // Create 2D arrays because MeqMatrix does not support 1D.
+    const double *p_coschi = coschi.doubleStorage();
+    const double *p_sinchi = sinchi.doubleStorage();
+
+    Matrix coschi2, sinchi2;
+    double *p_coschi2 = coschi2.setDoubleFormat(nFreq, nTime);
+    double *p_sinchi2 = sinchi2.setDoubleFormat(nFreq, nTime);
+
+    for(unsigned int t = 0; t < nTime; ++t)
+    {
+        for(unsigned int f = 0; f < nFreq; ++f)
+        {
+            *p_coschi2++ = *p_coschi;
+            *p_sinchi2++ = *p_sinchi;
+        }
+        ++p_coschi;
+        ++p_sinchi;
+    }
+
+    return JonesMatrix::View(-coschi2, sinchi2, sinchi2, coschi2);
+}
+
+} //# namespace BBS
+} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Expr/StationBeamFormer.cc b/CEP/Calibration/BBSKernel/src/Expr/StationBeamFormer.cc
index fde5e02b52349a81390c0158651b3c0d2360dfe4..15dd68fa90e03318d4196f01b3182e52658a562f 100644
--- a/CEP/Calibration/BBSKernel/src/Expr/StationBeamFormer.cc
+++ b/CEP/Calibration/BBSKernel/src/Expr/StationBeamFormer.cc
@@ -221,7 +221,6 @@ const JonesMatrix::View StationBeamFormer::evaluateImpl(const Grid &grid,
     Matrix E[2][2];
     Matrix AF(makedcomplex(0.0, 0.0), nFreq, nTime);
 
-    size_t countX = 0, countY = 0;
     for(size_t i = 0; i < itsStation->nField(); ++i)
     {
         AntennaField::ConstPtr field = itsStation->field(i);
@@ -285,13 +284,11 @@ const JonesMatrix::View StationBeamFormer::evaluateImpl(const Grid &grid,
             if(!element.flag[0])
             {
                 AFX += AF;
-                ++countX;
             }
 
             if(!element.flag[1])
             {
                 AFY += AF;
-                ++countY;
             }
         }
 
@@ -319,16 +316,13 @@ const JonesMatrix::View StationBeamFormer::evaluateImpl(const Grid &grid,
     }
 
     // Normalize.
-    if(countX > 0)
+    const size_t nActiveElement = itsStation->nActiveElement();
+    if(nActiveElement > 0)
     {
-        E[0][0] /= countX;
-        E[0][1] /= countX;
-    }
-
-    if(countY > 0)
-    {
-        E[1][0] /= countY;
-        E[1][1] /= countY;
+        E[0][0] /= nActiveElement;
+        E[0][1] /= nActiveElement;
+        E[1][0] /= nActiveElement;
+        E[1][1] /= nActiveElement;
     }
 
     return JonesMatrix::View(E[0][0], E[0][1], E[1][0], E[1][1]);
diff --git a/CEP/Calibration/BBSKernel/src/Expr/YatawattaDipole.cc b/CEP/Calibration/BBSKernel/src/Expr/YatawattaDipole.cc
deleted file mode 100644
index 6e53ed87da5de1f8c85aa0ea38c16747c069cc37..0000000000000000000000000000000000000000
--- a/CEP/Calibration/BBSKernel/src/Expr/YatawattaDipole.cc
+++ /dev/null
@@ -1,150 +0,0 @@
-//# YatawattaDipole.cc: Dipole voltage beam based on external functions.
-//#
-//# Copyright (C) 2008
-//# 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/YatawattaDipole.h>
-
-#include <Common/lofar_complex.h>
-#include <casa/BasicSL/Constants.h>
-
-namespace LOFAR
-{
-namespace BBS
-{
-
-YatawattaDipole::YatawattaDipole(const casa::Path &moduleTheta,
-    const casa::Path &modulePhi, const Expr<Vector<2> >::ConstPtr &azel,
-    const Expr<Scalar>::ConstPtr &orientation)
-    :   BasicBinaryExpr<Vector<2>, Scalar, JonesMatrix>(azel, orientation),
-        itsThetaFunction(moduleTheta, "test"),
-        itsPhiFunction(modulePhi, "test")
-{
-    ASSERT(itsThetaFunction.nArguments() == 5);
-    ASSERT(itsPhiFunction.nArguments() == 5);
-}
-
-const JonesMatrix::View YatawattaDipole::evaluateImpl(const Grid &grid,
-    const Vector<2>::View &azel, const Scalar::View &orientation) const
-{
-    const size_t nFreq = grid[FREQ]->size();
-    const size_t nTime = grid[TIME]->size();
-
-    // Check preconditions.
-    ASSERT(static_cast<size_t>(azel(0).nelements()) == nTime);
-    ASSERT(static_cast<size_t>(azel(1).nelements()) == nTime);
-    ASSERT(static_cast<size_t>(orientation().nelements()) == 1);
-
-    // Get pointers to input and output data.
-    const double *az = azel(0).doubleStorage();
-    const double *el = azel(1).doubleStorage();
-    const double angle = orientation().getDouble(0, 0);
-
-    Matrix E00, E01, E10, E11;
-    double *E00_re, *E00_im;
-    E00.setDCMat(nFreq, nTime);
-    E00.dcomplexStorage(E00_re, E00_im);
-
-    double *E01_re, *E01_im;
-    E01.setDCMat(nFreq, nTime);
-    E01.dcomplexStorage(E01_re, E01_im);
-
-    double *E10_re, *E10_im;
-    E10.setDCMat(nFreq, nTime);
-    E10.dcomplexStorage(E10_re, E10_im);
-
-    double *E11_re, *E11_im;
-    E11.setDCMat(nFreq, nTime);
-    E11.dcomplexStorage(E11_re, E11_im);
-
-    //  Parameters for external functions:
-    //      0: time
-    //          (NOTE: ignored)
-    //      1: frequency
-    //      2: az
-    //      3: el
-    //          (NOTE: incorrectly labelled zenith angle in implementation!)
-    //      4: orientation (phi0)
-
-    // Create argument vectors for the X and Y dipole (used for calling
-    // external functions).
-    vector<dcomplex> xArgs(5, makedcomplex(0.0, 0.0));
-    vector<dcomplex> yArgs(5, makedcomplex(0.0, 0.0));
-
-    // TODO: Inside external function, these parameters are added to the
-    // azimuth. The resulting azimuth is therefore:
-    //
-    // az = az + orientation (- pi / 2.0)
-    //
-    // Whereas it seems to me that the orientation should be subtracted
-    // instead of added. It probably does not matter much, because the
-    // beam pattern is symmetric with respect to azimuth.
-    xArgs[4] = makedcomplex(angle, 0.0);
-    yArgs[4] = makedcomplex(angle - casa::C::pi_2, 0.0);
-
-    // Evaluate beam.
-    for(size_t t = 0; t < nTime; ++t)
-    {
-        // TODO: Where does the -pi/4 term in azimuth come from (see
-        // global_model.py in EJones_HBA)? Is this just the default dipole
-        // orientation? If so, the term should be removed in favor of setting
-        // a correct dipole orientation in the parameter database (such that
-        // the orientation in the parameter database corresponds 1:1 with the
-        // real orientation).
-//        xArgs[2] = yArgs[2] = makedcomplex(az[t] - casa::C::pi_4, 0.0);
-        xArgs[2] = yArgs[2] = makedcomplex(az[t], 0.0);
-        xArgs[3] = yArgs[3] = makedcomplex(el[t], 0.0);
-
-        for(size_t f = 0; f < nFreq; ++f)
-        {
-            // Update frequency.
-            xArgs[1] = yArgs[1] = makedcomplex(grid[FREQ]->center(f), 0.0);
-
-            // Compute dipole beam value.
-            const dcomplex xTheta = itsThetaFunction(xArgs);
-            const dcomplex xPhi = itsPhiFunction(xArgs);
-            *E00_re++ = real(xTheta);
-            *E00_im++ = imag(xTheta);
-            *E01_re++ = real(xPhi);
-            *E01_im++ = imag(xPhi);
-
-            const dcomplex yTheta = itsThetaFunction(yArgs);
-            const dcomplex yPhi = itsPhiFunction(yArgs);
-            *E10_re++ = real(yTheta);
-            *E10_im++ = imag(yTheta);
-            *E11_re++ = real(yPhi);
-            *E11_im++ = imag(yPhi);
-        }
-    }
-
-    JonesMatrix::View result;
-    result.assign(0, 0, E00);
-    result.assign(0, 1, E01);
-    result.assign(1, 0, E10);
-    result.assign(1, 1, E11);
-
-    return result;
-}
-
-
-} //# namespace BBS
-} //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/Instrument.cc b/CEP/Calibration/BBSKernel/src/Instrument.cc
index f151d2acee3e455d00c332ff75e092b60ea9c916..f3031d5dda5d56b5929d7de0614c35225d841601 100644
--- a/CEP/Calibration/BBSKernel/src/Instrument.cc
+++ b/CEP/Calibration/BBSKernel/src/Instrument.cc
@@ -37,7 +37,8 @@ namespace BBS
 AntennaField::AntennaField(const string &name, const Vector3 &position,
     const Vector3 &p, const Vector3 &q, const Vector3 &r)
     :   itsName(name),
-        itsPosition(position)
+        itsPosition(position),
+        itsActiveElementCount(0)
 {
     itsAxes[P] = p;
     itsAxes[Q] = q;
@@ -54,7 +55,7 @@ const Vector3 &AntennaField::position() const
     return itsPosition;
 }
 
-const Vector3 &AntennaField::axis(Axis axis)
+const Vector3 &AntennaField::axis(Axis axis) const
 {
     return itsAxes[axis];
 }
@@ -72,6 +73,11 @@ void AntennaField::appendTileElement(const Vector3 &offset)
 void AntennaField::appendElement(const Element &element)
 {
     itsElements.push_back(element);
+
+    if(!element.flag[0] || !element.flag[1])
+    {
+        ++itsActiveElementCount;
+    }
 }
 
 Station::Station(const string &name, const casa::MPosition &position)
@@ -117,6 +123,26 @@ unsigned int Station::nField() const
     return itsFields.size();
 }
 
+size_t Station::nElement() const
+{
+    size_t count = 0;
+    for(unsigned int i = 0; i < nField(); ++i)
+    {
+        count += field(i)->nElement();
+    }
+    return count;
+}
+
+size_t Station::nActiveElement() const
+{
+    size_t count = 0;
+    for(unsigned int i = 0; i < nField(); ++i)
+    {
+        count += field(i)->nActiveElement();
+    }
+    return count;
+}
+
 AntennaField::ConstPtr Station::field(unsigned int i) const
 {
     return itsFields[i];
diff --git a/CEP/Calibration/BBSKernel/src/MeasurementAIPS.cc b/CEP/Calibration/BBSKernel/src/MeasurementAIPS.cc
index 886b61e50dc30a94daa36e878b969dd998a2b945..ace130b686bac7654750f999b1d68799ba47d784 100644
--- a/CEP/Calibration/BBSKernel/src/MeasurementAIPS.cc
+++ b/CEP/Calibration/BBSKernel/src/MeasurementAIPS.cc
@@ -25,7 +25,7 @@
 #include <BBSKernel/MeasurementAIPS.h>
 #include <BBSKernel/Exceptions.h>
 
-#include <cstring>
+//#include <cstring>
 #include <Common/Timer.h>
 #include <Common/lofar_algorithm.h>
 #include <Common/LofarLogger.h>
@@ -79,6 +79,16 @@ namespace LOFAR
 namespace BBS
 {
 
+namespace
+{
+    bool hasColumn(const Table &table, const string &column);
+    bool hasSubTable(const Table &table, const string &name);
+    Table getSubTable(const Table &table, const string &name);
+
+    Station::Ptr readStation(const Table &table, unsigned int id,
+        const string &name, const MPosition &position);
+}
+
 MeasurementAIPS::MeasurementAIPS(const string &filename,
     unsigned int idObservation, unsigned int idField,
     unsigned int idDataDescription)
@@ -89,7 +99,7 @@ MeasurementAIPS::MeasurementAIPS(const string &filename,
         itsIdDataDescription(idDataDescription)
 {
     // Get information about the telescope (instrument).
-    initInstrument();
+    itsInstrument = readInstrument(itsMS, itsIdObservation);
 
     // Get the reference directions for the selected field (i.e. phase center,
     // delay center, tile delay center).
@@ -127,7 +137,7 @@ VisBuffer::Ptr MeasurementAIPS::read(const VisSelection &selection,
     // Find the column with covariance information associated with the specified
     // column.
     string columnCov = getLinkedCovarianceColumn(column,
-        hasColumn("WEIGHT_SPECTRUM") ? "WEIGHT_SPECTRUM" : "WEIGHT");
+        hasColumn(itsMS, "WEIGHT_SPECTRUM") ? "WEIGHT_SPECTRUM" : "WEIGHT");
 
     // Create cell slicers for array columns.
     Slicer slicer = getCellSlicer(selection);
@@ -309,7 +319,7 @@ void MeasurementAIPS::write(VisBuffer::Ptr buffer,
     ASSERT(itsMS.isWritable());
 
     // Add visbility column if it does not exist.
-    if(!hasColumn(column))
+    if(!hasColumn(itsMS, column))
     {
         LOG_INFO_STR("Creating visibility column: " << column);
         createVisibilityColumn(column);
@@ -327,7 +337,7 @@ void MeasurementAIPS::write(VisBuffer::Ptr buffer,
         setLinkedCovarianceColumn(column, columnCov);
 
         // Add covariance column if it does not exist.
-        if(!hasColumn(columnCov))
+        if(!hasColumn(itsMS, columnCov))
         {
             LOG_INFO_STR("Creating covariance column: " << columnCov);
             createCovarianceColumn(columnCov);
@@ -510,7 +520,7 @@ void MeasurementAIPS::write(VisBuffer::Ptr buffer,
 
 void MeasurementAIPS::writeHistory(const ParameterSet &parset) const
 {
-    Table tab_history = getSubTable("HISTORY");
+    Table tab_history = getSubTable(itsMS, "HISTORY");
     tab_history.reopenRW();
 
     ScalarColumn<double> c_time(tab_history, "TIME");
@@ -592,182 +602,14 @@ BaselineMask MeasurementAIPS::asMask(const string &filter) const
     return mask;
 }
 
-void MeasurementAIPS::initInstrument()
-{
-    // Get station names and positions in ITRF coordinates.
-    ROMSAntennaColumns antenna(itsMS.antenna());
-    ROMSObservationColumns observation(itsMS.observation());
-
-    ASSERT(observation.nrow() > itsIdObservation);
-    ASSERT(!observation.flagRow()(itsIdObservation));
-
-    // Get instrument name.
-    string name(observation.telescopeName()(itsIdObservation));
-
-    // Get station positions.
-    MVPosition centroid;
-    vector<Station::Ptr> stations(antenna.nrow());
-    for(unsigned int i = 0; i < stations.size(); ++i)
-    {
-        // Get station name and ITRF position.
-        MPosition position = MPosition::Convert(antenna.positionMeas()(i),
-            MPosition::ITRF)();
-
-        // Store station information.
-        stations[i] = initStation(i, antenna.name()(i), position);
-
-        // Update ITRF centroid.
-        centroid += position.getValue();
-    }
-
-    // Get the instrument position in ITRF coordinates, or use the centroid
-    // of the station positions if the instrument position is unknown.
-    MPosition position;
-    if(MeasTable::Observatory(position, name))
-    {
-        position = MPosition::Convert(position, MPosition::ITRF)();
-    }
-    else
-    {
-        LOG_WARN("Instrument position unknown; will use centroid of stations.");
-        ASSERT(antenna.nrow() != 0);
-        centroid *= 1.0 / static_cast<double>(antenna.nrow());
-        position = MPosition(centroid, MPosition::ITRF);
-    }
-
-    itsInstrument = Instrument::Ptr(new Instrument(name, position,
-        stations.begin(), stations.end()));
-}
-
-Station::Ptr MeasurementAIPS::initStation(unsigned int id, const string &name,
-    const MPosition &position) const
-{
-    if(!hasSubTable("LOFAR_ANTENNA_FIELD"))
-    {
-        return Station::Ptr(new Station(name, position));
-    }
-
-    Table tab_field = getSubTable("LOFAR_ANTENNA_FIELD");
-    tab_field = tab_field(tab_field.col("ANTENNA_ID") == static_cast<Int>(id));
-
-    const size_t nFields = tab_field.nrow();
-    if(nFields < 1 || nFields > 2)
-    {
-        LOG_WARN_STR("Antenna " << name << " consists of an incompatible number"
-            " of antenna fields. Beam model simulation will not work for this"
-            " antenna.");
-        return Station::Ptr(new Station(name, position));
-    }
-
-    ROScalarColumn<String> c_name(tab_field, "NAME");
-    ROArrayQuantColumn<Double> c_position(tab_field, "POSITION", "m");
-    ROArrayQuantColumn<Double> c_axes(tab_field, "COORDINATE_AXES", "m");
-    ROArrayQuantColumn<Double> c_tile_offset(tab_field, "TILE_ELEMENT_OFFSET",
-        "m");
-    ROArrayQuantColumn<Double> c_offset(tab_field, "ELEMENT_OFFSET", "m");
-    ROArrayColumn<Bool> c_flag(tab_field, "ELEMENT_FLAG");
-
-    AntennaField::Ptr field[2];
-    for(size_t i = 0; i < nFields; ++i)
-    {
-        // Read antenna field center (ITRF).
-        Vector<Quantum<Double> > aips_position = c_position(i);
-        ASSERT(aips_position.size() == 3);
-
-        Vector3 position = {{aips_position(0).getValue(),
-            aips_position(1).getValue(), aips_position(2).getValue()}};
-
-        // Read antenna field coordinate axes (ITRF).
-        Matrix<Quantum<Double> > aips_axes = c_axes(i);
-        ASSERT(aips_axes.shape().isEqual(IPosition(2, 3, 3)));
-
-        Vector3 P = {{aips_axes(0, 0).getValue(), aips_axes(1, 0).getValue(),
-            aips_axes(2, 0).getValue()}};
-        Vector3 Q = {{aips_axes(0, 1).getValue(), aips_axes(1, 1).getValue(),
-            aips_axes(2, 1).getValue()}};
-        Vector3 R = {{aips_axes(0, 2).getValue(), aips_axes(1, 2).getValue(),
-            aips_axes(2, 2).getValue()}};
-
-        // Store information as AntennaField.
-        field[i] = AntennaField::Ptr(new AntennaField(c_name(i), position, P,
-            Q, R));
-
-        // Read offsets (ITRF) of the dipoles within a tile for HBA antenna
-        // fields.
-        if(c_name(i) != "LBA")
-        {
-            // Read tile configuration for HBA antenna fields.
-            Matrix<Quantum<Double> > aips_offset = c_tile_offset(i);
-            ASSERT(aips_offset.nrow() == 3);
-
-            const size_t nElement = aips_offset.ncolumn();
-            for(size_t j = 0; j < nElement; ++j)
-            {
-                Vector3 offset = {{aips_offset(0, j).getValue(),
-                    aips_offset(1, j).getValue(),
-                    aips_offset(2, j).getValue()}};
-
-                field[i]->appendTileElement(offset);
-            }
-        }
-
-        // Read element offsets and flags.
-        Matrix<Quantum<Double> > aips_offset = c_offset(i);
-        Matrix<Bool> aips_flag = c_flag(i);
-
-        const size_t nElement = aips_offset.ncolumn();
-        ASSERT(aips_offset.shape().isEqual(IPosition(2, 3, nElement)));
-        ASSERT(aips_flag.shape().isEqual(IPosition(2, 2, nElement)));
-
-        for(size_t j = 0; j < nElement; ++j)
-        {
-            AntennaField::Element element;
-            element.offset[0] = aips_offset(0, j).getValue();
-            element.offset[1] = aips_offset(1, j).getValue();
-            element.offset[2] = aips_offset(2, j).getValue();
-            element.flag[0] = aips_flag(0, j);
-            element.flag[1] = aips_flag(1, j);
-
-            field[i]->appendElement(element);
-        }
-    }
-
-    return (nFields == 1 ? Station::Ptr(new Station(name, position, field[0]))
-        : Station::Ptr(new Station(name, position, field[0], field[1])));
-}
-
 void MeasurementAIPS::initReferenceDirections()
 {
-    // Get phase center as RA and DEC (J2000).
-    ROMSFieldColumns field(itsMS.field());
-    ASSERT(field.nrow() > itsIdField);
-    ASSERT(!field.flagRow()(itsIdField));
-
-    itsPhaseReference = MDirection::Convert(field.phaseDirMeas(itsIdField),
-        MDirection::J2000)();
-    itsDelayReference = MDirection::Convert(field.delayDirMeas(itsIdField),
-        MDirection::J2000)();
-
-    // By default, the tile beam reference direction is assumed to be equal
-    // to the station beam reference direction (for backward compatibility,
-    // and for non-HBA measurements).
-    itsTileReference = itsDelayReference;
-
-    // The MeasurementSet class does not support LOFAR specific columns, so we
-    // use ROArrayMeasColumn to read the tile beam reference direction.
-    Table tab_field = getSubTable("FIELD");
-
-    static const String columnName = "LOFAR_TILE_BEAM_DIR";
-    if(hasColumn(tab_field, columnName))
-    {
-        ROArrayMeasColumn<MDirection> c_direction(tab_field, columnName);
-        if(c_direction.isDefined(itsIdField))
-        {
-            itsTileReference =
-                MDirection::Convert(c_direction(itsIdField)(IPosition(1, 0)),
-                MDirection::J2000)();
-        }
-    }
+    itsPhaseReference = MDirection::Convert(readPhaseReference(itsMS,
+        itsIdField), MDirection::J2000)();
+    itsDelayReference = MDirection::Convert(readDelayReference(itsMS,
+        itsIdField), MDirection::J2000)();
+    itsTileReference = MDirection::Convert(readTileReference(itsMS,
+        itsIdField), MDirection::J2000)();
 }
 
 void MeasurementAIPS::initDimensions()
@@ -886,16 +728,6 @@ void MeasurementAIPS::initDimensions()
     itsDims.setCorrelations(correlations);
 }
 
-bool MeasurementAIPS::hasColumn(const string &column) const
-{
-    return hasColumn(itsMS, column);
-}
-
-bool MeasurementAIPS::hasColumn(const Table &table, const string &column) const
-{
-    return table.tableDesc().isColumn(column);
-}
-
 void MeasurementAIPS::createVisibilityColumn(const string &name)
 {
     // Added column should get the same shape as the other data columns in
@@ -948,7 +780,7 @@ void MeasurementAIPS::createCovarianceColumn(const string &name)
     itsMS.addColumn(columnDescriptor, storageManager);
 
     // Figure out which column to use as input.
-    bool hasSpectrum = hasColumn("WEIGHT_SPECTRUM");
+    bool hasSpectrum = hasColumn(itsMS, "WEIGHT_SPECTRUM");
     string weightColumn = hasSpectrum ? "WEIGHT_SPECTRUM" : "WEIGHT";
 
     // Initialize the covariance column using the weight (assumed to equal one
@@ -1052,16 +884,6 @@ void MeasurementAIPS::createCovarianceColumn(const string &name)
             == static_cast<Int>(itsIdDataDescription));
 }
 
-bool MeasurementAIPS::hasSubTable(const string &table) const
-{
-    return itsMS.keywordSet().isDefined(table);
-}
-
-Table MeasurementAIPS::getSubTable(const string &table) const
-{
-    return itsMS.keywordSet().asTable(table);
-}
-
 MDirection MeasurementAIPS::getColumnPhaseReference(const string &column) const
 {
     static const String keyword = "LOFAR_DIRECTION";
@@ -1166,7 +988,7 @@ BaselineMask MeasurementAIPS::getBaselineMask(const VisSelection &selection)
     return asMask("*&&");
 }
 
-// NOTE: OPTIMIZATION OPPORTUNITY: when reading all channels, do not use a
+// NOTE: OPTIMIZATION OPPORTUNITY: When reading all channels, do not use a
 // slicer at all.
 Interval<size_t>
 MeasurementAIPS::getChannelRange(const VisSelection &selection) const
@@ -1462,5 +1284,228 @@ VisDimensions MeasurementAIPS::getDimensionsImpl(const Table &tab_selection,
     return dims;
 }
 
+Instrument::Ptr readInstrument(const MeasurementSet &ms,
+  unsigned int idObservation)
+{
+    ROMSObservationColumns observation(ms.observation());
+    ASSERT(observation.nrow() > idObservation);
+    ASSERT(!observation.flagRow()(idObservation));
+
+    // Get station names and positions in ITRF coordinates.
+    ROMSAntennaColumns antenna(ms.antenna());
+
+    // Get station positions.
+    MVPosition centroid;
+    vector<Station::Ptr> stations(antenna.nrow());
+    for(unsigned int i = 0; i < stations.size(); ++i)
+    {
+        // Get station name and ITRF position.
+        MPosition position = MPosition::Convert(antenna.positionMeas()(i),
+            MPosition::ITRF)();
+
+        // Store station information.
+        stations[i] = readStation(ms, i, antenna.name()(i), position);
+
+        // Update ITRF centroid.
+        centroid += position.getValue();
+    }
+
+    // Get the instrument position in ITRF coordinates, or use the centroid
+    // of the station positions if the instrument position is unknown.
+    MPosition position;
+
+    // Read observatory name and try to look-up its position.
+    const string observatory = observation.telescopeName()(idObservation);
+    if(MeasTable::Observatory(position, observatory))
+    {
+        position = MPosition::Convert(position, MPosition::ITRF)();
+    }
+    else
+    {
+        LOG_WARN("Instrument position unknown; will use centroid of stations.");
+        ASSERT(antenna.nrow() != 0);
+        centroid *= 1.0 / static_cast<double>(antenna.nrow());
+        position = MPosition(centroid, MPosition::ITRF);
+    }
+
+    return Instrument::Ptr(new Instrument(observatory, position,
+      stations.begin(), stations.end()));
+}
+
+MDirection readPhaseReference(const MeasurementSet &ms, unsigned int idField)
+{
+    ROMSFieldColumns field(ms.field());
+    ASSERT(field.nrow() > idField);
+    ASSERT(!field.flagRow()(idField));
+
+    return field.phaseDirMeas(idField);
+}
+
+MDirection readDelayReference(const MeasurementSet &ms, unsigned int idField)
+{
+    ROMSFieldColumns field(ms.field());
+    ASSERT(field.nrow() > idField);
+    ASSERT(!field.flagRow()(idField));
+
+    return field.delayDirMeas(idField);
+}
+
+MDirection readTileReference(const MeasurementSet &ms, unsigned int idField)
+{
+    // The MeasurementSet class does not support LOFAR specific columns, so we
+    // use ROArrayMeasColumn to read the tile beam reference direction.
+    Table tab_field = getSubTable(ms, "FIELD");
+
+    static const String columnName = "LOFAR_TILE_BEAM_DIR";
+    if(hasColumn(tab_field, columnName))
+    {
+        ROArrayMeasColumn<MDirection> c_direction(tab_field, columnName);
+        if(c_direction.isDefined(idField))
+        {
+            return c_direction(idField)(IPosition(1, 0));
+        }
+    }
+
+    // By default, the tile beam reference direction is assumed to be equal
+    // to the station beam reference direction (for backward compatibility,
+    // and for non-HBA measurements).
+    return readDelayReference(ms, idField);
+}
+
+double readFreqReference(const MeasurementSet &ms,
+    unsigned int idDataDescription)
+{
+    // Read spectral window id.
+    ROMSDataDescColumns desc(ms.dataDescription());
+    ASSERT(desc.nrow() > idDataDescription);
+    ASSERT(!desc.flagRow()(idDataDescription));
+
+    const unsigned int idWindow = desc.spectralWindowId()(idDataDescription);
+
+    // Read reference frequency.
+    ROMSSpWindowColumns window(ms.spectralWindow());
+    ASSERT(window.nrow() > idWindow);
+    ASSERT(!window.flagRow()(idWindow));
+
+    return window.refFrequency()(idWindow);
+}
+
+namespace
+{
+
+bool hasColumn(const Table &table, const string &column)
+{
+    return table.tableDesc().isColumn(column);
+}
+
+bool hasSubTable(const Table &table, const string &name)
+{
+    return table.keywordSet().isDefined(name);
+}
+
+Table getSubTable(const Table &table, const string &name)
+{
+    return table.keywordSet().asTable(name);
+}
+
+Station::Ptr readStation(const Table &table, unsigned int id,
+    const string &name, const MPosition &position)
+{
+    if(!hasSubTable(table, "LOFAR_ANTENNA_FIELD"))
+    {
+        return Station::Ptr(new Station(name, position));
+    }
+
+    Table tab_field = getSubTable(table, "LOFAR_ANTENNA_FIELD");
+    tab_field = tab_field(tab_field.col("ANTENNA_ID") == static_cast<Int>(id));
+
+    const size_t nFields = tab_field.nrow();
+    if(nFields < 1 || nFields > 2)
+    {
+        LOG_WARN_STR("Antenna " << name << " consists of an incompatible number"
+            " of antenna fields. Beam model simulation will not work for this"
+            " antenna.");
+        return Station::Ptr(new Station(name, position));
+    }
+
+    ROScalarColumn<String> c_name(tab_field, "NAME");
+    ROArrayQuantColumn<Double> c_position(tab_field, "POSITION", "m");
+    ROArrayQuantColumn<Double> c_axes(tab_field, "COORDINATE_AXES", "m");
+    ROArrayQuantColumn<Double> c_tile_offset(tab_field, "TILE_ELEMENT_OFFSET",
+        "m");
+    ROArrayQuantColumn<Double> c_offset(tab_field, "ELEMENT_OFFSET", "m");
+    ROArrayColumn<Bool> c_flag(tab_field, "ELEMENT_FLAG");
+
+    AntennaField::Ptr field[2];
+    for(size_t i = 0; i < nFields; ++i)
+    {
+        // Read antenna field center (ITRF).
+        Vector<Quantum<Double> > aips_position = c_position(i);
+        ASSERT(aips_position.size() == 3);
+
+        Vector3 position = {{aips_position(0).getValue(),
+            aips_position(1).getValue(), aips_position(2).getValue()}};
+
+        // Read antenna field coordinate axes (ITRF).
+        Matrix<Quantum<Double> > aips_axes = c_axes(i);
+        ASSERT(aips_axes.shape().isEqual(IPosition(2, 3, 3)));
+
+        Vector3 P = {{aips_axes(0, 0).getValue(), aips_axes(1, 0).getValue(),
+            aips_axes(2, 0).getValue()}};
+        Vector3 Q = {{aips_axes(0, 1).getValue(), aips_axes(1, 1).getValue(),
+            aips_axes(2, 1).getValue()}};
+        Vector3 R = {{aips_axes(0, 2).getValue(), aips_axes(1, 2).getValue(),
+            aips_axes(2, 2).getValue()}};
+
+        // Store information as AntennaField.
+        field[i] = AntennaField::Ptr(new AntennaField(c_name(i), position, P,
+            Q, R));
+
+        // Read offsets (ITRF) of the dipoles within a tile for HBA antenna
+        // fields.
+        if(c_name(i) != "LBA")
+        {
+            // Read tile configuration for HBA antenna fields.
+            Matrix<Quantum<Double> > aips_offset = c_tile_offset(i);
+            ASSERT(aips_offset.nrow() == 3);
+
+            const size_t nElement = aips_offset.ncolumn();
+            for(size_t j = 0; j < nElement; ++j)
+            {
+                Vector3 offset = {{aips_offset(0, j).getValue(),
+                    aips_offset(1, j).getValue(),
+                    aips_offset(2, j).getValue()}};
+
+                field[i]->appendTileElement(offset);
+            }
+        }
+
+        // Read element offsets and flags.
+        Matrix<Quantum<Double> > aips_offset = c_offset(i);
+        Matrix<Bool> aips_flag = c_flag(i);
+
+        const size_t nElement = aips_offset.ncolumn();
+        ASSERT(aips_offset.shape().isEqual(IPosition(2, 3, nElement)));
+        ASSERT(aips_flag.shape().isEqual(IPosition(2, 2, nElement)));
+
+        for(size_t j = 0; j < nElement; ++j)
+        {
+            AntennaField::Element element;
+            element.offset[0] = aips_offset(0, j).getValue();
+            element.offset[1] = aips_offset(1, j).getValue();
+            element.offset[2] = aips_offset(2, j).getValue();
+            element.flag[0] = aips_flag(0, j);
+            element.flag[1] = aips_flag(1, j);
+
+            field[i]->appendElement(element);
+        }
+    }
+
+    return (nFields == 1 ? Station::Ptr(new Station(name, position, field[0]))
+        : Station::Ptr(new Station(name, position, field[0], field[1])));
+}
+
+} //# namespace unnamed
+
 } //# namespace BBS
 } //# namespace LOFAR
diff --git a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
index 84e52fb12c1754f35062746660e383ec34f40673..3ebca01db48b09dc20e506d08b97e13566c9e907 100644
--- a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
+++ b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFAR.cc
@@ -60,7 +60,7 @@ namespace BBS
 
 MeasurementExprLOFAR::MeasurementExprLOFAR(SourceDB &sourceDB,
     const BufferMap &buffers, const ModelConfig &config,
-    const Instrument::Ptr &instrument, const BaselineSeq &baselines,
+    const Instrument::ConstPtr &instrument, const BaselineSeq &baselines,
     double refFreq, const casa::MDirection &refPhase,
     const casa::MDirection &refDelay, const casa::MDirection &refTile,
     bool circular)
@@ -104,7 +104,7 @@ void MeasurementExprLOFAR::solvablesChanged()
 
 void MeasurementExprLOFAR::makeForwardExpr(SourceDB &sourceDB,
     const BufferMap &buffers, const ModelConfig &config,
-    const Instrument::Ptr &instrument, double refFreq,
+    const Instrument::ConstPtr &instrument, double refFreq,
     const casa::MDirection &refPhase, const casa::MDirection &refDelay,
     const casa::MDirection &refTile, bool circular)
 {
@@ -149,21 +149,6 @@ void MeasurementExprLOFAR::makeForwardExpr(SourceDB &sourceDB,
             instrument->station(i)->position(), refPhase);
     }
 
-    HamakerBeamCoeff coeffLBA, coeffHBA;
-    if(config.useBeam())
-    {
-        // Read LBA beam model coefficients.
-        casa::Path path;
-        path = config.getBeamConfig().getElementPath();
-        path.append("element_beam_HAMAKER_LBA.coeff");
-        coeffLBA.init(path);
-
-        // Read HBA beam model coefficients.
-        path = config.getBeamConfig().getElementPath();
-        path.append("element_beam_HAMAKER_HBA.coeff");
-        coeffHBA.init(path);
-    }
-
     IonosphereExpr::Ptr exprIonosphere;
     if(config.useIonosphere())
     {
@@ -215,7 +200,7 @@ void MeasurementExprLOFAR::makeForwardExpr(SourceDB &sourceDB,
                 exprDDE[j] = compose(exprDDE[j],
                     makeBeamExpr(itsScope, instrument->station(j), refFreq,
                     exprPatchPositionITRF, exprRefDelayITRF, exprRefTileITRF,
-                    config.getBeamConfig(), coeffLBA, coeffHBA));
+                    config.getBeamConfig()));
             }
 
             // Directional TEC.
@@ -343,7 +328,7 @@ void MeasurementExprLOFAR::makeInverseExpr(SourceDB &sourceDB,
 
     LOG_DEBUG_STR("Building expression tree...");
 
-    Instrument::Ptr instrument = buffer->instrument();
+    Instrument::ConstPtr instrument = buffer->instrument();
 
     // Allocate space for the station response expressions.
     vector<Expr<JonesMatrix>::Ptr> stationExpr(instrument->nStations());
@@ -411,21 +396,6 @@ void MeasurementExprLOFAR::makeInverseExpr(SourceDB &sourceDB,
         Expr<Vector<3> >::Ptr exprRefTileITRF =
             makeITRFExpr(instrument->position(), exprRefTile);
 
-        HamakerBeamCoeff coeffLBA, coeffHBA;
-        if(config.useBeam())
-        {
-            // Read LBA beam model coefficients.
-            casa::Path path;
-            path = config.getBeamConfig().getElementPath();
-            path.append("element_beam_HAMAKER_LBA.coeff");
-            coeffLBA.init(path);
-
-            // Read HBA beam model coefficients.
-            path = config.getBeamConfig().getElementPath();
-            path.append("element_beam_HAMAKER_HBA.coeff");
-            coeffHBA.init(path);
-        }
-
         // Functor for the creation of the ionosphere sub-expression.
         IonosphereExpr::Ptr exprIonosphere;
         if(config.useIonosphere())
@@ -462,7 +432,7 @@ void MeasurementExprLOFAR::makeInverseExpr(SourceDB &sourceDB,
                         makeBeamExpr(itsScope, instrument->station(i),
                         buffer->getReferenceFreq(), exprRefPhaseITRF,
                         exprRefDelayITRF, exprRefTileITRF,
-                        config.getBeamConfig(), coeffLBA, coeffHBA));
+                        config.getBeamConfig()));
                 }
 
                 // Ionosphere.
@@ -510,7 +480,7 @@ void MeasurementExprLOFAR::makeInverseExpr(SourceDB &sourceDB,
                         makeBeamExpr(itsScope, instrument->station(i),
                         buffer->getReferenceFreq(), exprPatchPositionITRF,
                         exprRefDelayITRF, exprRefTileITRF,
-                        config.getBeamConfig(), coeffLBA, coeffHBA));
+                        config.getBeamConfig()));
                 }
 
                 // Directional TEC.
diff --git a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFARUtil.cc b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFARUtil.cc
index 29c844690463962c398790fcb07355908b2aef5d..b99dbc038acec7f37e2cc4d7ec7b246bb93f0cee 100644
--- a/CEP/Calibration/BBSKernel/src/MeasurementExprLOFARUtil.cc
+++ b/CEP/Calibration/BBSKernel/src/MeasurementExprLOFARUtil.cc
@@ -24,20 +24,22 @@
 #include <lofar_config.h>
 #include <BBSKernel/MeasurementExprLOFARUtil.h>
 #include <BBSKernel/Exceptions.h>
-#include <BBSKernel/Expr/AntennaFieldAzEl.h>
+#include <BBSKernel/Expr/AntennaElementLBA.h>
+#include <BBSKernel/Expr/AntennaElementHBA.h>
+#include <BBSKernel/Expr/AntennaFieldThetaPhi.h>
 #include <BBSKernel/Expr/AzEl.h>
 #include <BBSKernel/Expr/Delay.h>
 #include <BBSKernel/Expr/ElevationCut.h>
 #include <BBSKernel/Expr/EquatorialCentroid.h>
 #include <BBSKernel/Expr/ExprAdaptors.h>
 #include <BBSKernel/Expr/FaradayRotation.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
 #include <BBSKernel/Expr/ITRFDirection.h>
 #include <BBSKernel/Expr/Literal.h>
 #include <BBSKernel/Expr/LMN.h>
 #include <BBSKernel/Expr/MatrixMul2.h>
 #include <BBSKernel/Expr/MatrixMul3.h>
 #include <BBSKernel/Expr/MatrixSum.h>
+#include <BBSKernel/Expr/ParallacticRotation.h>
 #include <BBSKernel/Expr/PhaseShift.h>
 #include <BBSKernel/Expr/ScalarMatrixMul.h>
 #include <BBSKernel/Expr/StationBeamFormer.h>
@@ -240,9 +242,7 @@ makeBeamExpr(Scope&,
     const Expr<Vector<3> >::Ptr &exprITRF,
     const Expr<Vector<3> >::Ptr &exprRefDelayITRF,
     const Expr<Vector<3> >::Ptr &exprRefTileITRF,
-    const BeamConfig &config,
-    const HamakerBeamCoeff &coeffLBA,
-    const HamakerBeamCoeff &coeffHBA)
+    const BeamConfig &config)
 {
     // Check if the beam model can be computed for this station.
     if(!station->isPhasedArray())
@@ -252,10 +252,6 @@ makeBeamExpr(Scope&,
             " station beam is missing.");
     }
 
-    // The positive X dipole direction is SE of the reference orientation, which
-    // translates to an azimuth of 3/4*pi.
-    Expr<Scalar>::Ptr exprOrientation(new Literal(3.0 * casa::C::pi_4));
-
     // Build expressions for the dual-dipole or tile beam of each antenna field.
     Expr<JonesMatrix>::Ptr exprElementBeam[2];
     for(size_t i = 0; i < station->nField(); ++i)
@@ -265,21 +261,28 @@ makeBeamExpr(Scope&,
         // Element (dual-dipole) beam expression.
         if(config.mode() != BeamConfig::ARRAY_FACTOR)
         {
-            Expr<Vector<2> >::Ptr exprAzEl(new AntennaFieldAzEl(exprITRF,
+            Expr<Vector<2> >::Ptr exprThetaPhi =
+                Expr<Vector<2> >::Ptr(new AntennaFieldThetaPhi(exprITRF,
                 field));
 
             if(field->isHBA())
             {
                 exprElementBeam[i] =
-                    Expr<JonesMatrix>::Ptr(new HamakerDipole(coeffHBA, exprAzEl,
-                    exprOrientation));
+                    Expr<JonesMatrix>::Ptr(new AntennaElementHBA(exprThetaPhi));
             }
             else
             {
                 exprElementBeam[i] =
-                    Expr<JonesMatrix>::Ptr(new HamakerDipole(coeffLBA, exprAzEl,
-                    exprOrientation));
+                    Expr<JonesMatrix>::Ptr(new AntennaElementLBA(exprThetaPhi));
             }
+
+            Expr<JonesMatrix>::Ptr exprRotation =
+                Expr<JonesMatrix>::Ptr(new ParallacticRotation(exprITRF,
+                field));
+
+            exprElementBeam[i] =
+                Expr<JonesMatrix>::Ptr(new MatrixMul2(exprElementBeam[i],
+                exprRotation));
         }
         else
         {
diff --git a/CEP/Calibration/BBSKernel/src/ModelConfig.cc b/CEP/Calibration/BBSKernel/src/ModelConfig.cc
index 486399574e450bf21c893ce82b356ff8d0377878..33db77ca8e20f752020767be4c4930c15f7abf28 100644
--- a/CEP/Calibration/BBSKernel/src/ModelConfig.cc
+++ b/CEP/Calibration/BBSKernel/src/ModelConfig.cc
@@ -96,11 +96,9 @@ BeamConfig::BeamConfig()
 {
 }
 
-BeamConfig::BeamConfig(Mode mode, bool conjugateAF,
-    const casa::Path &elementPath)
+BeamConfig::BeamConfig(Mode mode, bool conjugateAF)
     :   itsMode(mode),
-        itsConjugateAF(conjugateAF),
-        itsElementPath(elementPath)
+        itsConjugateAF(conjugateAF)
 {
 }
 
@@ -114,11 +112,6 @@ bool BeamConfig::conjugateAF() const
     return itsConjugateAF;
 }
 
-const casa::Path &BeamConfig::getElementPath() const
-{
-    return itsElementPath;
-}
-
 // -------------------------------------------------------------------------- //
 // - IonosphereConfig implementation                                        - //
 // -------------------------------------------------------------------------- //
@@ -421,9 +414,7 @@ ostream &operator<<(ostream &out, const BeamConfig &obj)
 {
     out << indent << "Mode: " << BeamConfig::asString(obj.mode())
         << endl << indent << "Conjugate array factor: " << boolalpha
-        << obj.conjugateAF() << noboolalpha
-        << endl << indent << "Element model path: "
-        << obj.getElementPath().originalName();
+        << obj.conjugateAF() << noboolalpha;
     return out;
 }
 
diff --git a/CEP/Calibration/BBSKernel/src/StationExprLOFAR.cc b/CEP/Calibration/BBSKernel/src/StationExprLOFAR.cc
index e0d660437c6e75c861ab10eb607db5a386e6be2f..99f882f24ee64ba45be4cfb03be738fa113ba0da 100644
--- a/CEP/Calibration/BBSKernel/src/StationExprLOFAR.cc
+++ b/CEP/Calibration/BBSKernel/src/StationExprLOFAR.cc
@@ -25,7 +25,6 @@
 #include <BBSKernel/StationExprLOFAR.h>
 #include <BBSKernel/Exceptions.h>
 #include <BBSKernel/MeasurementExprLOFARUtil.h>
-#include <BBSKernel/Expr/AntennaFieldAzEl.h>
 #include <BBSKernel/Expr/AzEl.h>
 #include <BBSKernel/Expr/CachePolicy.h>
 #include <BBSKernel/Expr/Delay.h>
@@ -64,7 +63,7 @@ StationExprLOFAR::StationExprLOFAR(SourceDB &sourceDB, const BufferMap &buffers,
 }
 
 void StationExprLOFAR::initialize(SourceDB &sourceDB, const BufferMap &buffers,
-    const ModelConfig &config, const Instrument::Ptr &instrument,
+    const ModelConfig &config, const Instrument::ConstPtr &instrument,
     double refFreq, const casa::MDirection &refPhase,
     const casa::MDirection &refDelay, const casa::MDirection &refTile,
     bool inverse)
@@ -128,21 +127,6 @@ void StationExprLOFAR::initialize(SourceDB &sourceDB, const BufferMap &buffers,
         Expr<Vector<3> >::Ptr exprRefTileITRF =
             makeITRFExpr(instrument->position(), exprRefTile);
 
-        HamakerBeamCoeff coeffLBA, coeffHBA;
-        if(config.useBeam())
-        {
-            // Read LBA beam model coefficients.
-            casa::Path path;
-            path = config.getBeamConfig().getElementPath();
-            path.append("element_beam_HAMAKER_LBA.coeff");
-            coeffLBA.init(path);
-
-            // Read HBA beam model coefficients.
-            path = config.getBeamConfig().getElementPath();
-            path.append("element_beam_HAMAKER_HBA.coeff");
-            coeffHBA.init(path);
-        }
-
         // Functor for the creation of the ionosphere sub-expression.
         IonosphereExpr::Ptr exprIonosphere;
         if(config.useIonosphere())
@@ -177,8 +161,7 @@ void StationExprLOFAR::initialize(SourceDB &sourceDB, const BufferMap &buffers,
                     itsExpr[i] = compose(itsExpr[i],
                         makeBeamExpr(itsScope, instrument->station(i),
                         refFreq, exprRefPhaseITRF, exprRefDelayITRF,
-                        exprRefTileITRF, config.getBeamConfig(), coeffLBA,
-                        coeffHBA));
+                        exprRefTileITRF, config.getBeamConfig()));
                 }
 
                 // Ionosphere.
@@ -225,8 +208,7 @@ void StationExprLOFAR::initialize(SourceDB &sourceDB, const BufferMap &buffers,
                     itsExpr[i] = compose(itsExpr[i],
                         makeBeamExpr(itsScope, instrument->station(i), refFreq,
                         exprPatchPositionITRF, exprRefDelayITRF,
-                        exprRefTileITRF, config.getBeamConfig(), coeffLBA,
-                        coeffHBA));
+                        exprRefTileITRF, config.getBeamConfig()));
                 }
 
                 // Directional TEC.
diff --git a/CEP/Calibration/BBSKernel/src/StationResponse.cc b/CEP/Calibration/BBSKernel/src/StationResponse.cc
index 04c95f73b3f1c23ad3bffd874ed7f093cbde4dda..00924ed38d03c6d8b206c30ae57287167c51b96c 100644
--- a/CEP/Calibration/BBSKernel/src/StationResponse.cc
+++ b/CEP/Calibration/BBSKernel/src/StationResponse.cc
@@ -24,36 +24,23 @@
 #include <lofar_config.h>
 #include <BBSKernel/StationResponse.h>
 #include <BBSKernel/Exceptions.h>
+#include <BBSKernel/MeasurementAIPS.h>
+#include <BBSKernel/Expr/AntennaElementLBA.h>
+#include <BBSKernel/Expr/AntennaElementHBA.h>
+#include <BBSKernel/Expr/AntennaFieldThetaPhi.h>
 #include <BBSKernel/Expr/CachePolicy.h>
-#include <BBSKernel/Expr/HamakerDipole.h>
+#include <BBSKernel/Expr/ExprAdaptors.h>
+#include <BBSKernel/Expr/ITRFDirection.h>
 #include <BBSKernel/Expr/Literal.h>
 #include <BBSKernel/Expr/MatrixInverse.h>
 #include <BBSKernel/Expr/MatrixMul2.h>
-#include <BBSKernel/Expr/ExprAdaptors.h>
-#include <BBSKernel/Expr/AntennaFieldAzEl.h>
-#include <BBSKernel/Expr/ITRFDirection.h>
+#include <BBSKernel/Expr/ParallacticRotation.h>
 #include <BBSKernel/Expr/ScalarMatrixMul.h>
 #include <BBSKernel/Expr/StationBeamFormer.h>
 #include <BBSKernel/Expr/TileArrayFactor.h>
 #include <Common/LofarLogger.h>
 #include <measures/Measures/MeasConvert.h>
 #include <measures/Measures/MCDirection.h>
-#include <measures/Measures/MCPosition.h>
-#include <ms/MeasurementSets/MSAntenna.h>
-#include <ms/MeasurementSets/MSAntennaParse.h>
-#include <ms/MeasurementSets/MSAntennaColumns.h>
-#include <ms/MeasurementSets/MSDataDescription.h>
-#include <ms/MeasurementSets/MSDataDescColumns.h>
-#include <ms/MeasurementSets/MSField.h>
-#include <ms/MeasurementSets/MSFieldColumns.h>
-#include <ms/MeasurementSets/MSObservation.h>
-#include <ms/MeasurementSets/MSObsColumns.h>
-#include <ms/MeasurementSets/MSPolarization.h>
-#include <ms/MeasurementSets/MSPolColumns.h>
-#include <ms/MeasurementSets/MSSpectralWindow.h>
-#include <ms/MeasurementSets/MSSpWindowColumns.h>
-#include <ms/MeasurementSets/MSSelection.h>
-#include <measures/Measures/MeasTable.h>
 
 namespace LOFAR
 {
@@ -64,7 +51,6 @@ StationResponse::StationResponse(const casa::MeasurementSet &ms,
     bool inverse, bool useElementBeam, bool useArrayFactor, bool conjugateAF)
     :   itsRefDelay(new Dummy<Vector<2> >()),
         itsRefTile(new Dummy<Vector<2> >()),
-        itsRefOrientation(new Dummy<Scalar>()),
         itsDirection(new Dummy<Vector<2> >())
 {
     // Set pointing and beamformer reference directions towards NCP by default.
@@ -72,13 +58,9 @@ StationResponse::StationResponse(const casa::MeasurementSet &ms,
     setRefTile(casa::MDirection());
     setDirection(casa::MDirection());
 
-    // The positive X dipole direction is SE of the reference orientation, which
-    // translates to an azimuth of 3/4*pi.
-    setRefOrientation(3.0 * casa::C::pi_4);
-
     // Load observation details.
-    Instrument::Ptr instrument = initInstrument(ms);
-    double refFreq = getReferenceFreq(ms);
+    Instrument::Ptr instrument = readInstrument(ms);
+    double refFreq = readFreqReference(ms);
 
     // The ITRF direction vectors for the direction of interest and the
     // reference direction are computed w.r.t. the center of the station
@@ -92,13 +74,6 @@ StationResponse::StationResponse(const casa::MeasurementSet &ms,
         Expr<Vector<3> >::Ptr(new ITRFDirection(instrument->position(),
         itsRefTile));
 
-    // Load beam model coefficients.
-    HamakerBeamCoeff coeffLBA, coeffHBA;
-    coeffLBA.init(casa::Path("$LOFARROOT/share/element_beam_HAMAKER_LBA"
-        ".coeff"));
-    coeffHBA.init(casa::Path("$LOFARROOT/share/element_beam_HAMAKER_HBA"
-        ".coeff"));
-
     itsExpr.reserve(instrument->nStations());
     for(size_t i = 0; i < instrument->nStations(); ++i)
     {
@@ -129,21 +104,28 @@ StationResponse::StationResponse(const casa::MeasurementSet &ms,
             // Element (dual-dipole) beam expression.
             if(useElementBeam)
             {
-                Expr<Vector<2> >::Ptr exprAzEl(new AntennaFieldAzEl(exprDirITRF,
+                Expr<Vector<2> >::Ptr exprThetaPhi =
+                    Expr<Vector<2> >::Ptr(new AntennaFieldThetaPhi(exprDirITRF,
                     field));
 
                 if(field->isHBA())
                 {
                     exprElementBeam[j] =
-                        Expr<JonesMatrix>::Ptr(new HamakerDipole(coeffHBA,
-                        exprAzEl, itsRefOrientation));
+                        Expr<JonesMatrix>::Ptr(new AntennaElementHBA(exprThetaPhi));
                 }
                 else
                 {
                     exprElementBeam[j] =
-                        Expr<JonesMatrix>::Ptr(new HamakerDipole(coeffLBA,
-                        exprAzEl, itsRefOrientation));
+                        Expr<JonesMatrix>::Ptr(new AntennaElementLBA(exprThetaPhi));
                 }
+
+                Expr<JonesMatrix>::Ptr exprRotation =
+                    Expr<JonesMatrix>::Ptr(new ParallacticRotation(exprDirITRF,
+                    field));
+
+                exprElementBeam[j] =
+                    Expr<JonesMatrix>::Ptr(new MatrixMul2(exprElementBeam[j],
+                    exprRotation));
             }
             else
             {
@@ -243,16 +225,6 @@ void StationResponse::setRefTile(const casa::MDirection &reference)
     itsCache.clearStats();
 }
 
-void StationResponse::setRefOrientation(double orientation)
-{
-    // Update dipole reference orientation.
-    itsRefOrientation->setValue(Scalar(Matrix(orientation)));
-
-    // Clear cache.
-    itsCache.clear();
-    itsCache.clearStats();
-}
-
 void StationResponse::setDirection(const casa::MDirection &direction)
 {
     // Convert to ensure the direction is specified with respect to the correct
@@ -306,171 +278,5 @@ StationResponse::compose(const Expr<JonesMatrix>::Ptr &lhs,
     return rhs;
 }
 
-Instrument::Ptr StationResponse::initInstrument(const casa::MeasurementSet &ms)
-    const
-{
-    // Get station names and positions in ITRF coordinates.
-    casa::ROMSAntennaColumns antenna(ms.antenna());
-    casa::ROMSObservationColumns observation(ms.observation());
-    ASSERT(observation.nrow() > 0);
-    ASSERT(!observation.flagRow()(0));
-
-    // Get instrument name.
-    string name = observation.telescopeName()(0);
-
-    // Get station positions.
-    casa::MVPosition centroid;
-    vector<Station::Ptr> stations(antenna.nrow());
-    for(unsigned int i = 0; i < stations.size(); ++i)
-    {
-        // Get station name and ITRF position.
-        casa::MPosition position =
-            casa::MPosition::Convert(antenna.positionMeas()(i),
-            casa::MPosition::ITRF)();
-
-        // Store station information.
-        stations[i] = initStation(ms, i, antenna.name()(i), position);
-
-        // Update ITRF centroid.
-        centroid += position.getValue();
-    }
-
-    // Get the instrument position in ITRF coordinates, or use the centroid
-    // of the station positions if the instrument position is unknown.
-    casa::MPosition position;
-    if(casa::MeasTable::Observatory(position, name))
-    {
-        position = casa::MPosition::Convert(position, casa::MPosition::ITRF)();
-    }
-    else
-    {
-        LOG_WARN("Instrument position unknown; will use centroid of stations.");
-        ASSERT(antenna.nrow() != 0);
-        centroid *= 1.0 / static_cast<double>(antenna.nrow());
-        position = casa::MPosition(centroid, casa::MPosition::ITRF);
-    }
-
-    return Instrument::Ptr(new Instrument(name, position, stations.begin(),
-        stations.end()));
-}
-
-Station::Ptr StationResponse::initStation(const casa::MeasurementSet &ms,
-    unsigned int id, const string &name, const casa::MPosition &position) const
-{
-    if(!ms.keywordSet().isDefined("LOFAR_ANTENNA_FIELD"))
-    {
-        return Station::Ptr(new Station(name, position));
-    }
-
-    casa::Table tab_field(ms.keywordSet().asTable("LOFAR_ANTENNA_FIELD"));
-    tab_field = tab_field(tab_field.col("ANTENNA_ID")
-        == static_cast<casa::Int>(id));
-
-    const size_t nFields = tab_field.nrow();
-    if(nFields < 1 || nFields > 2)
-    {
-        LOG_WARN_STR("Antenna " << name << " consists of an incompatible number"
-            " of antenna fields. Beam model simulation will not work for this"
-            " antenna.");
-        return Station::Ptr(new Station(name, position));
-    }
-
-    casa::ROScalarColumn<casa::String> c_name(tab_field, "NAME");
-    casa::ROArrayQuantColumn<casa::Double> c_position(tab_field, "POSITION",
-        "m");
-    casa::ROArrayQuantColumn<casa::Double> c_axes(tab_field, "COORDINATE_AXES",
-        "m");
-    casa::ROArrayQuantColumn<casa::Double> c_tile_offset(tab_field,
-        "TILE_ELEMENT_OFFSET", "m");
-    casa::ROArrayQuantColumn<casa::Double> c_offset(tab_field, "ELEMENT_OFFSET",
-        "m");
-    casa::ROArrayColumn<casa::Bool> c_flag(tab_field, "ELEMENT_FLAG");
-
-    AntennaField::Ptr field[2];
-    for(size_t i = 0; i < nFields; ++i)
-    {
-        // Read antenna field center.
-        casa::Vector<casa::Quantum<casa::Double> > aips_position =
-            c_position(i);
-        ASSERT(aips_position.size() == 3);
-
-        Vector3 position = {{aips_position(0).getValue(),
-            aips_position(1).getValue(), aips_position(2).getValue()}};
-
-        // Read antenna field coordinate axes.
-        casa::Matrix<casa::Quantum<casa::Double> > aips_axes = c_axes(i);
-        ASSERT(aips_axes.shape().isEqual(casa::IPosition(2, 3, 3)));
-
-        Vector3 P = {{aips_axes(0, 0).getValue(), aips_axes(1, 0).getValue(),
-            aips_axes(2, 0).getValue()}};
-        Vector3 Q = {{aips_axes(0, 1).getValue(), aips_axes(1, 1).getValue(),
-            aips_axes(2, 1).getValue()}};
-        Vector3 R = {{aips_axes(0, 2).getValue(), aips_axes(1, 2).getValue(),
-            aips_axes(2, 2).getValue()}};
-
-        // Store information as AntennaField.
-        field[i] = AntennaField::Ptr(new AntennaField(c_name(i), position, P,
-            Q, R));
-
-        if(c_name(i) != "LBA")
-        {
-            // Read tile configuration for HBA antenna fields.
-            casa::Matrix<casa::Quantum<casa::Double> > aips_offset =
-                c_tile_offset(i);
-            ASSERT(aips_offset.nrow() == 3);
-
-            const size_t nElement = aips_offset.ncolumn();
-            for(size_t j = 0; j < nElement; ++j)
-            {
-                Vector3 offset = {{aips_offset(0, j).getValue(),
-                    aips_offset(1, j).getValue(),
-                    aips_offset(2, j).getValue()}};
-
-                field[i]->appendTileElement(offset);
-            }
-        }
-
-        // Read element position offsets and flags.
-        casa::Matrix<casa::Quantum<casa::Double> > aips_offset = c_offset(i);
-        casa::Matrix<casa::Bool> aips_flag = c_flag(i);
-
-        const size_t nElement = aips_offset.ncolumn();
-        ASSERT(aips_offset.shape().isEqual(casa::IPosition(2, 3, nElement)));
-        ASSERT(aips_flag.shape().isEqual(casa::IPosition(2, 2, nElement)));
-
-        for(size_t j = 0; j < nElement; ++j)
-        {
-            AntennaField::Element element;
-            element.offset[0] = aips_offset(0, j).getValue();
-            element.offset[1] = aips_offset(1, j).getValue();
-            element.offset[2] = aips_offset(2, j).getValue();
-            element.flag[0] = aips_flag(0, j);
-            element.flag[1] = aips_flag(1, j);
-
-            field[i]->appendElement(element);
-        }
-    }
-
-    return (nFields == 1 ? Station::Ptr(new Station(name, position, field[0]))
-        : Station::Ptr(new Station(name, position, field[0], field[1])));
-}
-
-double StationResponse::getReferenceFreq(const casa::MeasurementSet &ms) const
-{
-    // Read polarization id and spectral window id.
-    casa::ROMSDataDescColumns desc(ms.dataDescription());
-    ASSERT(desc.nrow() > 0);
-    ASSERT(!desc.flagRow()(0));
-
-    const unsigned int idWindow = desc.spectralWindowId()(0);
-
-    // Get spectral information.
-    casa::ROMSSpWindowColumns window(ms.spectralWindow());
-    ASSERT(window.nrow() > idWindow);
-    ASSERT(!window.flagRow()(idWindow));
-
-    return window.refFrequency()(idWindow);
-}
-
 } //# namespace BBS
 } //# namespace LOFAR
diff --git a/CEP/Calibration/ElementResponse/include/ElementResponse/ElementResponse.h b/CEP/Calibration/ElementResponse/include/ElementResponse/ElementResponse.h
index c1cf9fb93533fee4461c3e52be877a24eb8e9509..f95ba672544e94f30f6046d752f3cf73ffa1c853 100644
--- a/CEP/Calibration/ElementResponse/include/ElementResponse/ElementResponse.h
+++ b/CEP/Calibration/ElementResponse/include/ElementResponse/ElementResponse.h
@@ -37,61 +37,59 @@ namespace LOFAR
 // @{
 
 // Compute the response of an idealized LOFAR LBA dual dipole antenna to
-// radiation at frequency freq (Hz) arriving from the direction given by
-// az, el (rad). The +X dipole is at azimuth 0.0, the +Y dipole is at azimuth
-// pi / 2.0.
+// radiation at frequency freq (Hz) arriving from the direction given by theta,
+// phi (rad). The antenna model is described in a spherical coordinate system
+// with coordinates theta (zenith angle) and phi (azimith). The +X dipole is at
+// azimuth zero, the +Y dipole is at azimuth PI / 2.0.
 //
 // Preconditions:
 // --------------
 // freq: Frequency in Hz in the range [10 MHz, 100 MHz].
-// az: Azimuth in rad in the range [0.0, 2.0 * pi].
-// el: Elevation in rad in the range [0.0, pi / 2.0].
+// theta: Zenith angle in rad in the range [0.0, PI / 2.0].
+// phi: Azimuth in rad in the range [0.0, 2.0 * PI].
 //
-// NB: Clipping directions below the horizon (el < 0.0) is the responsibility of
-// the caller.
-void element_response_lba(double freq, double az, double el,
+void element_response_lba(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2]);
 
 // Compute the response of an idealized LOFAR HBA dual dipole antenna to
-// radiation at frequency freq (Hz) arriving from the direction given by
-// az, el (rad). The +X dipole is at azimuth 0.0, the +Y dipole is at azimuth
-// pi / 2.0.
+// radiation at frequency freq (Hz) arriving from the direction given by theta,
+// phi (rad). The antenna model is described in a spherical coordinate system
+// with coordinates theta (zenith angle) and phi (azimith). The +X dipole is at
+// azimuth zero, the +Y dipole is at azimuth PI / 2.0.
 //
 // Preconditions:
 // --------------
 // freq: Frequency in Hz in the range [120 MHz, 240 MHz].
-// az: Azimuth in rad in the range [0.0, 2.0 * pi].
-// el: Elevation in rad in the range [0.0, pi / 2.0].
+// theta: Zenith angle in rad in the range [0.0, PI / 2.0].
+// phi: Azimuth in rad in the range [0.0, 2.0 * PI].
 //
-// NB: Clipping directions below the horizon (el < 0.0) is the responsibility of
-// the caller.
-void element_response_hba(double freq, double az, double el,
+void element_response_hba(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2]);
 
 // Compute the response of an idealized LOFAR dual dipole antenna to radiation
-// at frequency freq (Hz) arriving from the direction given by az, el (rad).
-// The +X dipole is at azimuth 0.0, the +Y dipole is at azimuth pi / 2.0.
+// at frequency freq (Hz) arriving from the direction given by theta, phi (rad).
+// The antenna model is described in a spherical coordinate system with
+// coordinates theta (zenith angle) and phi (azimith). The +X dipole is at
+// azimuth zero, the +Y dipole is at azimuth PI / 2.0.
 //
 // This function uses a set of user defined coefficients to evaluate the beam
 // model. The coeff_shape parameter defines the shape of the coefficient array
 // as no. of harmonics x degree in theta x degree in frequency x 2. The last
 // dimension is implicit and always equal to 2. The coeff parameter points to an
-// array of coefficients of the proper size, stored in row-major order (or "C"-
-// order). The freq_center and freq_range parameters define the frequency range
-// covered by the model described by the set of coefficients.
+// array of coefficients of the proper size, stored in row-major order
+// ("C"-order). The freq_center and freq_range parameters define the frequency
+// range covered by the model described by the set of coefficients.
 //
 // Preconditions:
 // --------------
 // freq: Frequency in Hz in the range [freq_center - freq_range,
 //     freq_center + freq_range].
-// az: Azimuth in rad in the range [0.0, 2.0 * pi].
-// el: Elevation in rad in the range [0.0, pi / 2.0].
+// theta: Zenith angle in rad in the range [0.0, PI / 2.0].
+// phi: Azimuth in rad in the range [0.0, 2.0 * PI].
 // freq_range, freq_center: Frequency center and range in Hz, should be > 0.
 // coeff_shape: Shape of the coefficient array, all dimensions should be > 0.
 //
-// NB: Clipping directions below the horizon (el < 0.0) is the responsibility of
-// the caller.
-void element_response(double freq, double az, double el,
+void element_response(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2], double freq_center,
     double freq_range, const unsigned int (&coeff_shape)[3],
     const std::complex<double> coeff[]);
diff --git a/CEP/Calibration/ElementResponse/src/CMakeLists.txt b/CEP/Calibration/ElementResponse/src/CMakeLists.txt
index ad09788de60c25444395006ef59585770ba3064a..fbbf6cf0cc590054491f91aa4ef16c2b2732ccf5 100644
--- a/CEP/Calibration/ElementResponse/src/CMakeLists.txt
+++ b/CEP/Calibration/ElementResponse/src/CMakeLists.txt
@@ -1,7 +1,7 @@
 # $Id: CMakeLists.txt 18775 2011-09-06 13:36:45Z zwieten $
 
-#include(LofarPackageVersion)
+include(LofarPackageVersion)
 
 lofar_add_library(elementresponse
-#  Package__Version.cc
+  Package__Version.cc
   ElementResponse.cc)
diff --git a/CEP/Calibration/ElementResponse/src/ElementResponse.cc b/CEP/Calibration/ElementResponse/src/ElementResponse.cc
index 6008a52ca164ba8357f9f1b0afd2803217cab639..1324bfd4be5479bbadbd685bad2362e4d4c260fc 100644
--- a/CEP/Calibration/ElementResponse/src/ElementResponse.cc
+++ b/CEP/Calibration/ElementResponse/src/ElementResponse.cc
@@ -39,43 +39,45 @@ const double pi_2 = 1.570796326794896619231322;
 namespace LOFAR
 {
 
-void element_response_lba(double freq, double az, double el,
+void element_response_lba(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2])
 {
-    element_response(freq, az, el, response, default_lba_freq_center,
+    element_response(freq, theta, phi, response, default_lba_freq_center,
         default_lba_freq_range, default_lba_coeff_shape, default_lba_coeff);
 }
 
-void element_response_hba(double freq, double az, double el,
+void element_response_hba(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2])
 {
-    element_response(freq, az, el, response, default_hba_freq_center,
+    element_response(freq, theta, phi, response, default_hba_freq_center,
         default_hba_freq_range, default_hba_coeff_shape, default_hba_coeff);
 }
 
-void element_response(double freq, double az, double el,
+void element_response(double freq, double theta, double phi,
     std::complex<double> (&response)[2][2], double freq_center,
     double freq_range, const unsigned int (&coeff_shape)[3],
     const std::complex<double> coeff[])
 {
+    // Initialize the response to zero.
+    response[0][0] = 0.0;
+    response[0][1] = 0.0;
+    response[1][0] = 0.0;
+    response[1][1] = 0.0;
+
+    // Clip directions below the horizon.
+    if(theta >= pi_2)
+    {
+        return;
+    }
+
     const unsigned int nHarmonics  = coeff_shape[0];
     const unsigned int nPowerTheta = coeff_shape[1];
     const unsigned int nPowerFreq  = coeff_shape[2];
 
-    // The model is parameterized in terms of zenith angle. The appropriate
-    // conversion is taken care of below.
-    const double theta = pi_2 - el;
-
     // The model is parameterized in terms of a normalized frequency in the
     // range [-1, 1]. The appropriate conversion is taken care of below.
     freq = (freq - freq_center) / freq_range;
 
-    // Initialize the response to zero.
-    response[0][0] = 0.0;
-    response[0][1] = 0.0;
-    response[1][0] = 0.0;
-    response[1][1] = 0.0;
-
     // The variables sign and kappa are used to compute the value of kappa
     // mentioned in the description of the beam model [kappa = (-1)^k * (2 * k
     //+ 1)] incrementally.
@@ -137,7 +139,7 @@ void element_response(double freq, double az, double el,
 
         // Compute the Jones matrix for the current harmonic, by rotating P over
         // kappa * az, and add it to the result.
-        const double angle = sign * kappa * az;
+        const double angle = sign * kappa * phi;
         const double caz = std::cos(angle);
         const double saz = std::sin(angle);
 
diff --git a/CEP/Calibration/pystationresponse/src/__init__.py b/CEP/Calibration/pystationresponse/src/__init__.py
index c04a4105506eb1ae02bd6473346a5d367592817c..d5bb434c54b1b60677064cf7701d6d41d2319a63 100755
--- a/CEP/Calibration/pystationresponse/src/__init__.py
+++ b/CEP/Calibration/pystationresponse/src/__init__.py
@@ -91,20 +91,6 @@ class stationresponse(StationResponse):
         """
         self._setRefTile(ra, dec)
 
-    def setRefOrientation (self, orientation):
-        """Set the orientation of the +X dipole (azimuth in the antenna field
-        coordinate system). Antenna field azimuth is defined with respect to the
-        positive Q axis, and positive azimuth runs from the positive Q axis to
-        the positive P axis (roughly North over East, depending on the field).
-        The orientation of the +Y dipole is assumed to be +90 degrees away from
-        orientation of the +X dipole.
-
-        `orientation`
-          Orientation of the +X dipole as azimuth North over East, in radians.
-          Defaults to SW, or an azimuth of 3/4*pi.
-        """
-        self._setRefOrientation(orientation)
-
     def setDirection (self, ra, dec):
         """Set the direction of interest (can be and often will be different
         from the pointing). By default, PHASE_DIR of field 0 is used.
diff --git a/CEP/Calibration/pystationresponse/src/pystationresponse.cc b/CEP/Calibration/pystationresponse/src/pystationresponse.cc
index fe58492ecc01a7bad4bf179b667b8b49949a149b..d57fa9a4a9539248b31df3fd5227a872cc5fe3e2 100755
--- a/CEP/Calibration/pystationresponse/src/pystationresponse.cc
+++ b/CEP/Calibration/pystationresponse/src/pystationresponse.cc
@@ -66,14 +66,6 @@ namespace LOFAR { namespace BBS  {
     // relevant only for HBA observations.
     void setRefTile(double ra, double dec);
 
-    // Set the orientation of the +X dipole (azimuth in the antenna field
-    // coordinate system). Antenna field azimuth is defined with respect to the
-    // positive Q axis, and positive azimuth runs from the positive Q axis to
-    // the positive P axis (roughly North over East, depending on the field).
-    // The orientation of the +Y dipole is assumed to be +90 degrees away from
-    // orientation of the +X dipole.
-    void setRefOrientation(double orientation);
-
     // Set the direction of interest in radians, J2000. Can and often will be
     // different than the delay and/or tile reference direction.
     void setDirection(double ra, double dec);
@@ -134,11 +126,6 @@ namespace LOFAR { namespace BBS  {
     itsResponse->setRefTile(MDirection(radec, MDirection::J2000));
   }
 
-  void PyStationResponse::setRefOrientation(double orientation)
-  {
-    itsResponse->setRefOrientation(orientation);
-  }
-
   void PyStationResponse::setDirection(double ra, double dec)
   {
     MVDirection radec(Quantity(ra,"rad"), Quantity(dec,"rad"));
@@ -277,8 +264,6 @@ namespace LOFAR { namespace BBS  {
         (boost::python::arg("ra"), boost::python::arg("dec")))
       .def ("_setRefTile", &PyStationResponse::setRefTile,
         (boost::python::arg("ra"), boost::python::arg("dec")))
-      .def ("_setRefOrientation", &PyStationResponse::setRefOrientation,
-        (boost::python::arg("orientation")))
       .def ("_setDirection", &PyStationResponse::setDirection,
         (boost::python::arg("ra"), boost::python::arg("dec")))
       .def ("_evaluate0", &PyStationResponse::evaluate0,
diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/quality/histogrampage.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/quality/histogrampage.h
index fa67fe6a6f7df3c30da296d18144995d47e82fd5..54f053b6612a64b85e7ce9bc86cd5037afa231e4 100644
--- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/quality/histogrampage.h
+++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/quality/histogrampage.h
@@ -32,6 +32,7 @@
 
 #include <AOFlagger/gui/plot/plot2d.h>
 #include <AOFlagger/gui/plot/plotwidget.h>
+#include <gtkmm/textview.h>
 
 /**
 	@author A.R. Offringa <offringa@astro.rug.nl>
@@ -63,9 +64,11 @@ class HistogramPage : public Gtk::HBox {
 		void updatePlot();
 		void plotPolarization(class HistogramCollection &histograms, unsigned p);
 		void plotFit(class LogHistogram &histogram, const std::string &title);
+		void plotSlope(class LogHistogram &histogram, const std::string &title);
 		void onPlotPropertiesClicked();
 		void onDataExportClicked();
 		void readFromFile();
+		void updateSlopeFrame();
 		void updateDataWindow();
 		
 		void onAutoRangeClicked()
@@ -98,6 +101,11 @@ class HistogramPage : public Gtk::HBox {
 		
 		Gtk::Button _plotPropertiesButton, _dataExportButton;
 		
+		Gtk::Frame _slopeFrame;
+		Gtk::VBox _slopeBox;
+		Gtk::TextView _slopeTextView;
+		Gtk::CheckButton _drawSlope;
+		
 		std::string _statFilename;
 		Plot2D _plot;
 		PlotWidget _plotWidget;
diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/quality/histogramcollection.h b/CEP/DP3/AOFlagger/include/AOFlagger/quality/histogramcollection.h
index f3a81a4152c1534cef1e140f36b4457928aa3434..40dfe35b33d589779affc6f46f5663f460920e40 100644
--- a/CEP/DP3/AOFlagger/include/AOFlagger/quality/histogramcollection.h
+++ b/CEP/DP3/AOFlagger/include/AOFlagger/quality/histogramcollection.h
@@ -34,6 +34,10 @@ class HistogramCollection
 	public:
 		typedef std::pair<unsigned, unsigned> AntennaPair;
 		
+		HistogramCollection() : _polarizationCount(0)
+		{
+		}
+		
 		HistogramCollection(unsigned polarizationCount) : _polarizationCount(polarizationCount)
 		{
 			init();
@@ -54,6 +58,13 @@ class HistogramCollection
 			destruct();
 		}
 		
+		void SetPolarizationCount(unsigned polarizationCount)
+		{
+			destruct();
+			_polarizationCount = polarizationCount;
+			init();
+		}
+		
 		void Add(const unsigned antenna1, const unsigned antenna2, const unsigned polarization, const std::complex<float> *values, const bool *isRFI, size_t sampleCount)
 		{
 			LogHistogram &totalHistogram = GetTotalHistogram(antenna1, antenna2, polarization);
@@ -120,25 +131,34 @@ class HistogramCollection
 		
 		void init()
 		{
-			_totalHistograms = new std::map<AntennaPair, LogHistogram*>[_polarizationCount];
-			_rfiHistograms = new std::map<AntennaPair, LogHistogram*>[_polarizationCount];
+			if(_polarizationCount != 0)
+			{
+				_totalHistograms = new std::map<AntennaPair, LogHistogram*>[_polarizationCount];
+				_rfiHistograms = new std::map<AntennaPair, LogHistogram*>[_polarizationCount];
+			} else {
+				_totalHistograms = 0;
+				_rfiHistograms = 0;
+			}
 		}
 		
 		void destruct()
 		{
-			for(unsigned p=0;p<_polarizationCount;++p)
+			if(_polarizationCount != 0)
 			{
-				for(std::map<AntennaPair, LogHistogram*>::iterator i=_totalHistograms[p].begin(); i!=_totalHistograms[p].end(); ++i)
-				{
-					delete i->second;
-				}
-				for(std::map<AntennaPair, LogHistogram*>::iterator i=_rfiHistograms[p].begin(); i!=_rfiHistograms[p].end(); ++i)
+				for(unsigned p=0;p<_polarizationCount;++p)
 				{
-					delete i->second;
+					for(std::map<AntennaPair, LogHistogram*>::iterator i=_totalHistograms[p].begin(); i!=_totalHistograms[p].end(); ++i)
+					{
+						delete i->second;
+					}
+					for(std::map<AntennaPair, LogHistogram*>::iterator i=_rfiHistograms[p].begin(); i!=_rfiHistograms[p].end(); ++i)
+					{
+						delete i->second;
+					}
 				}
+				delete[] _totalHistograms;
+				delete[] _rfiHistograms;
 			}
-			delete[] _totalHistograms;
-			delete[] _rfiHistograms;
 		}
 		
 		void copy(std::map<AntennaPair, LogHistogram*> &destination, const std::map<AntennaPair, LogHistogram*> &source)
diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/quality/loghistogram.h b/CEP/DP3/AOFlagger/include/AOFlagger/quality/loghistogram.h
index 8577bc29d6c1435e0e3d79216e790b7a0486edaf..0d5da46cdebb15757f4b34626d9ab2199fcca2e8 100644
--- a/CEP/DP3/AOFlagger/include/AOFlagger/quality/loghistogram.h
+++ b/CEP/DP3/AOFlagger/include/AOFlagger/quality/loghistogram.h
@@ -194,13 +194,12 @@ class LogHistogram
 		{
 			unsigned long n = 0;
 			long double sumX = 0.0, sumXY = 0.0, sumY = 0.0, sumXSquare = 0.0;
-			for(std::map<double, class AmplitudeBin>::const_iterator i=_amplitudes.begin();i!=_amplitudes.end();++i)
+			for(const_iterator i=begin();i!=end();++i)
 			{
-				if(i->first >= startAmplitude && i->first < endAmplitude)
+				if(i.value() >= startAmplitude && i.value() < endAmplitude)
 				{
-					long unsigned count = i->second.GetCount();
-					double x = log10(i->first);
-					double y = log10((double) count / i->first);
+					double x = log10(i.value());
+					double y = log10(i.normalizedCount());
 					++n;
 					sumX += x;
 					sumXSquare += x * x;
@@ -211,12 +210,38 @@ class LogHistogram
 			return (sumXY - sumX*sumY/n)/(sumXSquare - (sumX*sumX/n));
 		}
 		
-		double NormalizedSlopeInRFIRegion() const
+		double NormalizedSlopeOffset(double startAmplitude, double endAmplitude, double slope) const
+		{
+			unsigned long n = 0;
+			long double sumOffset = 0.0;
+			for(const_iterator i=begin();i!=end();++i)
+			{
+				if(i.value() >= startAmplitude && i.value() < endAmplitude)
+				{
+					double y = log10(i.normalizedCount());
+					double x = log10(i.value());
+					double ySlope = x*slope;
+					++n;
+					sumOffset += (y - ySlope);
+				}
+			}
+			return (double) (sumOffset/(long double) n);
+		}
+		
+		void GetRFIRegion(double &start, double &end) const
 		{
 			double sigmaEstimate = AmplitudeWithMaxNormalizedCount();
 			double maxAmplitude = MaxAmplitude();
 			double halfWay = exp((log(sigmaEstimate) + log(maxAmplitude)) * 0.5);
-			return NormalizedSlope(sigmaEstimate * 20.0, halfWay);
+			start = sigmaEstimate * 20.0;
+			end = halfWay;
+		}
+
+		double NormalizedSlopeInRFIRegion() const
+		{
+			double start, end;
+			GetRFIRegion(start ,end);
+			return NormalizedSlope(start, end);
 		}
 		
 		void SetData(std::vector<HistogramTablesFormatter::HistogramItem> &histogramData)
diff --git a/CEP/DP3/AOFlagger/src/aoquality.cpp b/CEP/DP3/AOFlagger/src/aoquality.cpp
index 80819992f7258348d84c0f1be4f7b54f5b3c27d2..7394773555892bdd70ae5c08bef39930a945054b 100644
--- a/CEP/DP3/AOFlagger/src/aoquality.cpp
+++ b/CEP/DP3/AOFlagger/src/aoquality.cpp
@@ -60,7 +60,7 @@ enum CollectingMode
 	CollectHistograms
 };
 
-void actionCollect(const std::string &filename, enum CollectingMode mode)
+void actionCollect(const std::string &filename, enum CollectingMode mode, StatisticsCollection &statisticsCollection, HistogramCollection &histogramCollection)
 {
 	MeasurementSet *ms = new MeasurementSet(filename);
 	const unsigned polarizationCount = ms->GetPolarizationCount();
@@ -93,19 +93,19 @@ void actionCollect(const std::string &filename, enum CollectingMode mode)
 		std::cout << "Channel zero will be included in the statistics, as it seems that channel 0 is okay.\n";
 	
 	// Initialize statisticscollection
-	StatisticsCollection collection(polarizationCount);
+	statisticsCollection.SetPolarizationCount(polarizationCount);
 	if(mode == CollectDefault)
 	{
 		for(unsigned b=0;b<bandCount;++b)
 		{
 			if(ignoreChannelZero)
-				collection.InitializeBand(b, (frequencies[b]+1), bands[b].channelCount-1);
+				statisticsCollection.InitializeBand(b, (frequencies[b]+1), bands[b].channelCount-1);
 			else
-				collection.InitializeBand(b, frequencies[b], bands[b].channelCount);
+				statisticsCollection.InitializeBand(b, frequencies[b], bands[b].channelCount);
 		}
 	}
 	// Initialize Histograms collection
-	HistogramCollection histogramCollection(polarizationCount);
+	histogramCollection.SetPolarizationCount(polarizationCount);
 
 	// get columns
 	casa::Table table(filename, casa::Table::Update);
@@ -170,7 +170,7 @@ void actionCollect(const std::string &filename, enum CollectingMode mode)
 				case CollectDefault:
 					{
 						const bool origFlags = false;
-						collection.Add(antenna1Index, antenna2Index, time, bandIndex, p, &samples[p]->real(), &samples[p]->imag(), isRFI[p], &origFlags, band.channelCount - startChannel, 2, 1, 0);
+						statisticsCollection.Add(antenna1Index, antenna2Index, time, bandIndex, p, &samples[p]->real(), &samples[p]->imag(), isRFI[p], &origFlags, band.channelCount - startChannel, 2, 1, 0);
 					}
 					break;
 				case CollectHistograms:
@@ -193,6 +193,14 @@ void actionCollect(const std::string &filename, enum CollectingMode mode)
 	delete[] frequencies;
 	delete[] bands;
 	std::cout << "100\n";
+}
+
+void actionCollect(const std::string &filename, enum CollectingMode mode)
+{
+	StatisticsCollection statisticsCollection;
+	HistogramCollection histogramCollection;
+	
+	actionCollect(filename, mode, statisticsCollection, histogramCollection);
 	
 	switch(mode)
 	{
@@ -201,7 +209,7 @@ void actionCollect(const std::string &filename, enum CollectingMode mode)
 				std::cout << "Writing quality tables..." << std::endl;
 				
 				QualityTablesFormatter qualityData(filename);
-				collection.Save(qualityData);
+				statisticsCollection.Save(qualityData);
 			}
 			break;
 		case CollectHistograms:
@@ -212,76 +220,17 @@ void actionCollect(const std::string &filename, enum CollectingMode mode)
 				histogramCollection.Save(histograms);
 			}
 			break;
-			
-		/*const std::map<HistogramCollection::AntennaPair, LogHistogram*> &map = histogramCollection.GetHistograms(0);
-		Plot plotSlopes("histogram-slopes.pdf");
-		plotSlopes.SetYRange(-10.0, 10.0);
-		Plot plotHistograms("histograms.pdf");
-		for(std::map<HistogramCollection::AntennaPair, LogHistogram*>::const_iterator i = map.begin(); i != map.end(); ++i)
-		{
-			if(i->first.first != i->first.second)
-			{
-				const LogHistogram *histogram = i->second;
-				double rangeCentre = histogram->MinPositiveAmplitude();
-				rangeCentre = exp2(floor(log2(rangeCentre)));
-				const double maxAmplitude = histogram->MaxAmplitude();
-				std::cout << "Antennae " << i->first.first << " x " << i->first.second << "\n";
-				std::stringstream s;
-				s << i->first.first << " x " << i->first.second;
-				//plotSlopes.StartLine(s.str());
-				//plotHistograms.StartLine(s.str());
-				plotSlopes.StartLine();
-				plotSlopes.SetLogScale(true, false);
-				plotHistograms.StartLine();
-				plotHistograms.SetLogScale(true, true);
-				while(rangeCentre < maxAmplitude && rangeCentre > 0.0)
-				{
-					const double rangeStart = rangeCentre * 0.75;
-					const double rangeEnd = rangeCentre * 1.5;
-					const double slope = histogram->NormalizedSlope(rangeStart, rangeEnd, LogHistogram::TotalAmplitudeHistogram);
-					std::cout << rangeStart << "-" << rangeEnd << ": " << slope << "\n";
-					rangeCentre *= 2.0;
-					plotSlopes.PushDataPoint(rangeCentre, slope);
-					const double count = histogram->NormalizedCount(rangeStart, rangeEnd, LogHistogram::TotalAmplitudeHistogram);
-					if(count > 0 && std::isfinite(count))
-						plotHistograms.PushDataPoint(rangeCentre, count);
-				}
-			}
-		}
-		Plot plotFine("histogram-fine.pdf");
-		Plot plotGlobalSlopes("histogram-gslopes.pdf");
-		plotFine.SetLogScale(true, true);
-		plotGlobalSlopes.SetLogScale(true, false);
-		plotGlobalSlopes.SetYRange(-5.0, 5.0);
-		LogHistogram intHistogram;
-		histogramCollection.GetHistogramForCrossCorrelations(0, intHistogram);
-		
-		plotFine.StartLine("Total");
-		plotGlobalSlopes.StartLine("Total");
-		for(LogHistogram::iterator i=intHistogram.begin(); i!=intHistogram.end(); ++i)
-		{
-			plotFine.PushDataPoint(i.value(), i.normalizedCount(LogHistogram::TotalAmplitudeHistogram));
-			plotGlobalSlopes.PushDataPoint(i.value(), intHistogram.NormalizedSlope(i.value()*0.5, i.value()*2.0, LogHistogram::TotalAmplitudeHistogram));
-		}
-		plotFine.StartLine("RFI");
-		plotGlobalSlopes.StartLine("RFI");
-		for(LogHistogram::iterator i=intHistogram.begin(); i!=intHistogram.end(); ++i)
-		{
-			plotFine.PushDataPoint(i.value(), i.normalizedCount(LogHistogram::RFIAmplitudeHistogram));
-			plotGlobalSlopes.PushDataPoint(i.value(), intHistogram.NormalizedSlope(i.value()*0.5, i.value()*2.0, LogHistogram::RFIAmplitudeHistogram));
-		}
-		plotFine.StartLine("Data");
-		plotGlobalSlopes.StartLine("Data");
-		for(LogHistogram::iterator i=intHistogram.begin(); i!=intHistogram.end(); ++i)
-		{
-			plotFine.PushDataPoint(i.value(), i.normalizedCount(LogHistogram::DataAmplitudeHistogram));
-			plotGlobalSlopes.PushDataPoint(i.value(), intHistogram.NormalizedSlope(i.value()*0.5, i.value()*2.0, LogHistogram::DataAmplitudeHistogram));
-		}*/
 	}
 	
 	std::cout << "Done.\n";
 }
 
+void actionCollectHistogram(const std::string &filename, HistogramCollection &histogramCollection)
+{
+	StatisticsCollection tempCollection;
+	actionCollect(filename, CollectHistograms, tempCollection, histogramCollection);
+}
+
 void printStatistics(std::complex<long double> *complexStat, unsigned count)
 {
 	if(count != 1)
@@ -481,10 +430,10 @@ void actionHistogram(const std::string &filename, const std::string &query)
 {
 	HistogramTablesFormatter histogramFormatter(filename);
 	const unsigned polarizationCount = MeasurementSet::GetPolarizationCount(filename);
-	HistogramCollection collection(polarizationCount);
-	collection.Load(histogramFormatter);
 	if(query == "rfislope")
 	{
+		HistogramCollection collection(polarizationCount);
+		collection.Load(histogramFormatter);
 		MeasurementSet set(filename);
 		std::cout << set.GetBandInfo(0).CenterFrequencyHz();
 		for(unsigned p=0;p<polarizationCount;++p)
@@ -494,6 +443,29 @@ void actionHistogram(const std::string &filename, const std::string &query)
 			std::cout <<  '\t' << histogram.NormalizedSlopeInRFIRegion();
 		}
 		std::cout << '\n';
+	} else if(query == "rfislope-per-baseline")
+	{
+		HistogramCollection collection;
+		actionCollectHistogram(filename, collection);
+		MeasurementSet set(filename);
+		size_t antennaCount = set.AntennaCount();
+		AntennaInfo antennae[antennaCount];
+		for(size_t a=0;a<antennaCount;++a)
+			antennae[a] = set.GetAntennaInfo(a);
+		
+		for(unsigned p=0;p<polarizationCount;++p)
+		{
+			const std::map<HistogramCollection::AntennaPair, LogHistogram*> &histogramMap = collection.GetRFIHistogram(p);
+			for(std::map<HistogramCollection::AntennaPair, LogHistogram*>::const_iterator i=histogramMap.begin(); i!=histogramMap.end();++i)
+			{
+				const unsigned a1 = i->first.first, a2 = i->first.second;
+				Baseline baseline(antennae[a1], antennae[a2]);
+				double length = baseline.Distance();
+				const LogHistogram &histogram = *i->second;
+				double slope = histogram.NormalizedSlopeInRFIRegion();
+				std::cout << p << '\t' << a1 << '\t' << a2 << '\t' << length << '\t' << slope << '\n';
+			}
+		}
 	}
 }
 
diff --git a/CEP/DP3/AOFlagger/src/gui/plot/plot2d.cpp b/CEP/DP3/AOFlagger/src/gui/plot/plot2d.cpp
index 2919ee7e5c463bea7afd8520287016a438d7468a..a3e567ba9dbf0886a1af210b78c5d82dafe8359a 100644
--- a/CEP/DP3/AOFlagger/src/gui/plot/plot2d.cpp
+++ b/CEP/DP3/AOFlagger/src/gui/plot/plot2d.cpp
@@ -238,7 +238,7 @@ void Plot2D::render(Cairo::RefPtr<Cairo::Context> cr, Plot2DPointSet &pointSet)
 				y2Val = (log10(pointSet.GetY(i+1)) - minYLog10) / (maxYLog10 - minYLog10);
 		} else {
 			y1Val = (pointSet.GetY(i) - yMin) / (yMax - yMin);
-			y2Val = (pointSet.GetY(i) - yMin) / (yMax - yMin);
+			y2Val = (pointSet.GetY(i+1) - yMin) / (yMax - yMin);
 		}
 		if(y1Val < 0.0) y1Val = 0.0;
 		if(y1Val > 1.0) y1Val = 1.0;
diff --git a/CEP/DP3/AOFlagger/src/gui/quality/histogrampage.cpp b/CEP/DP3/AOFlagger/src/gui/quality/histogrampage.cpp
index 1652e7921b92919c0d786dad1a1fa520c72e8ac9..147d70504b178e83e0ebe010a200ddec85975a1d 100644
--- a/CEP/DP3/AOFlagger/src/gui/quality/histogrampage.cpp
+++ b/CEP/DP3/AOFlagger/src/gui/quality/histogrampage.cpp
@@ -49,6 +49,8 @@ HistogramPage::HistogramPage() :
 	_dndsButton("dN(S)/dS"),
 	_plotPropertiesButton("Properties"),
 	_dataExportButton("Data"),
+	_slopeFrame("Slope"),
+	_drawSlope("Draw"),
 	_plotPropertiesWindow(0),
 	_histograms(0)
 	{
@@ -120,6 +122,13 @@ HistogramPage::HistogramPage() :
 	_dataExportButton.signal_clicked().connect(sigc::mem_fun(*this, &HistogramPage::onDataExportClicked));
 	_sideBox.pack_start(_dataExportButton, Gtk::PACK_SHRINK);
 	
+	_slopeBox.pack_start(_slopeTextView, Gtk::PACK_SHRINK);
+	_drawSlope.signal_clicked().connect(sigc::mem_fun(*this, &HistogramPage::updatePlot));
+	_slopeBox.pack_start(_drawSlope, Gtk::PACK_SHRINK);
+	
+	_slopeFrame.add(_slopeBox);
+	_sideBox.pack_start(_slopeFrame, Gtk::PACK_SHRINK);
+	
 	pack_start(_sideBox, Gtk::PACK_SHRINK);
 	
 	_plotWidget.SetPlot(_plot);
@@ -178,6 +187,7 @@ void HistogramPage::updatePlot()
 			plotPolarization(*_histograms, 3);
 		
 		_plotWidget.Update();
+		updateSlopeFrame();
 		updateDataWindow();
 	}
 }
@@ -208,6 +218,10 @@ void HistogramPage::plotPolarization(class HistogramCollection &histograms, unsi
 		{
 			plotFit(rfiHistogram, "Fit to RFI");
 		}
+		if(_drawSlope.get_active())
+		{
+			plotSlope(rfiHistogram, "Fitted slope");
+		}
 	}
 	
 	if(_notRFIHistogramButton.get_active())
@@ -323,6 +337,21 @@ void HistogramPage::addRayleighDifferenceToPlot(LogHistogram &histogram, double
 	}
 }
 
+void HistogramPage::plotSlope(class LogHistogram &histogram, const std::string &title)
+{
+	double start, end;
+	histogram.GetRFIRegion(start, end);
+	double slope = histogram.NormalizedSlope(start, end);
+	double offset = histogram.NormalizedSlopeOffset(start, end, slope);
+	_plot.StartLine(title, "Amplitude in arbitrary units (log)", "Frequency (log)");
+	double xStart = log10(start / 10.0);
+	double xEnd = log10(histogram.MaxAmplitude());
+	double yStart = xStart*slope + offset;
+	double yEnd = xEnd*slope + offset;
+	_plot.PushDataPoint(xStart, yStart);
+	_plot.PushDataPoint(xEnd, yEnd);
+}
+
 void HistogramPage::onPlotPropertiesClicked()
 {
 	if(_plotPropertiesWindow == 0)
@@ -342,6 +371,20 @@ void HistogramPage::onDataExportClicked()
 	updateDataWindow();
 }
 
+void HistogramPage::updateSlopeFrame()
+{
+	std::stringstream str;
+	str << "Slopes:";
+	for(size_t p=0;p<_histograms->PolarizationCount();++p)
+	{
+		LogHistogram histogram;
+		_histograms->GetRFIHistogramForCrossCorrelations(p, histogram);
+		double slope = histogram.NormalizedSlopeInRFIRegion();
+		str << '\n' << slope;
+	}
+	_slopeTextView.get_buffer()->set_text(str.str());
+}
+
 void HistogramPage::updateDataWindow()
 {
 	if(_dataWindow->is_visible())
diff --git a/CEP/DP3/DPPP/src/Demixer.cc b/CEP/DP3/DPPP/src/Demixer.cc
index 7978b8e9385b34b9bcd089246d41c50efd81238c..c7141e75fb151e936d0a691012622c9c75f44093 100644
--- a/CEP/DP3/DPPP/src/Demixer.cc
+++ b/CEP/DP3/DPPP/src/Demixer.cc
@@ -176,7 +176,7 @@ namespace LOFAR {
 //        stations.begin(), stations.end()));
 
       MeasurementAIPS ___bla(input->msName());
-      Instrument::Ptr instrument = ___bla.instrument();
+      Instrument::ConstPtr instrument = ___bla.instrument();
 
 
       // Get directions and make sure they are in J2000.
@@ -223,8 +223,7 @@ namespace LOFAR {
       ModelConfig config;
 //      config.setDirectionalGain();
       config.setGain();
-      BeamConfig beamConfig(BeamConfig::DEFAULT, false,
-        casa::Path("$LOFARROOT/share"));
+      BeamConfig beamConfig(BeamConfig::DEFAULT, false);
       config.setBeamConfig(beamConfig);
       config.setCache();
 
diff --git a/CEP/Imager/LofarFT/CMakeLists.txt b/CEP/Imager/LofarFT/CMakeLists.txt
index 8b2233b9b20b1668232d425e53bf5c920edf7aaa..16bb5a78907e2cf608ab787ab1b486d47e424f47 100644
--- a/CEP/Imager/LofarFT/CMakeLists.txt
+++ b/CEP/Imager/LofarFT/CMakeLists.txt
@@ -1,11 +1,11 @@
 # $Id$
 
-lofar_package(LofarFT 0.1 DEPENDS BBSKernel Common ParmDB)
+lofar_package(LofarFT 0.1 DEPENDS BBSKernel Common ParmDB ElementResponse)
 
 lofar_find_package(Casarest REQUIRED COMPONENTS synthesis)
 lofar_find_package(Casacore REQUIRED COMPONENTS images msfits)
 lofar_find_package(Boost REQUIRED COMPONENTS thread)
-lofar_find_package (FFTW3 REQUIRED COMPONENTS single double)
+lofar_find_package(FFTW3 REQUIRED COMPONENTS single double)
 
 # Needed for casarest
 add_definitions(-DCASA_STANDALONE)
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarATerm.h b/CEP/Imager/LofarFT/include/LofarFT/LofarATerm.h
index 87624dfdd5b815fabda1ce0b21f44c16136cee54..0eb48cf502d745831a0bf23629e80803da55dff0 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarATerm.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarATerm.h
@@ -24,271 +24,114 @@
 #define LOFAR_LOFARFT_LOFARATERM_H
 
 #include <Common/LofarTypes.h>
-#include <Common/lofar_map.h>
 #include <Common/lofar_vector.h>
+#include <BBSKernel/Instrument.h>
+#include <ParmDB/ParmFacade.h>
 
 #include <casa/Arrays/Array.h>
-#include <casa/BasicSL/String.h>
-#include <measures/Measures/MPosition.h>
+#include <casa/Containers/Record.h>
 #include <measures/Measures/MDirection.h>
+#include <measures/Measures/MEpoch.h>
 
 namespace casa
 {
   class DirectionCoordinate;
-  class MEpoch;
   class MeasurementSet;
-  class Path;
 }
 
 namespace LOFAR
 {
-  struct Vector3
-  {
-    const double &operator[](uint i) const
-    { return __data[i]; }
-
-    double &operator[](uint i)
-    { return __data[i]; }
-
-    double  __data[3];
-  };
-
-  class AntennaField
+  class LofarATerm
   {
   public:
-    enum Axis
-    {
-      P,
-      Q,
-      R,
-      N_Axis
-    };
+    LofarATerm(const casa::MeasurementSet &ms, const casa::Record& parameters);
 
-    struct Element
+    struct ITRFDirectionMap
     {
-      Vector3 offset;
-      bool    flag[2];
+      casa::MEpoch              epoch;
+      BBS::Vector3              refDelay;
+      BBS::Vector3              refTile;
+      casa::Cube<casa::Double>  directions;
     };
-
-    AntennaField()
-    {
-    }
-
-    AntennaField(const casa::String &name, const Vector3 &position,
-                 const Vector3 &p,
-                 const Vector3 &q, const Vector3 &r);
-
-    const casa::String &name() const;
-    const Vector3 &position() const;
-    const Vector3 &axis(Axis axis) const;
-
-    bool isHBA() const;
-
-    void appendTileElement(const Vector3 &offset);
-    inline uint nTileElement() const;
-    inline const Vector3 &tileElement(uint i) const;
-
-    void appendElement(const Element &element);
-    inline uint nElement() const;
-    inline const Element &element(uint i) const;
-
-  private:
-    casa::String    m_name;
-    Vector3         m_position;
-    Vector3         m_axes[N_Axis];
-    vector<Vector3> m_tileElements;
-    vector<Element> m_elements;
-  };
-
-  class Station
-  {
-  public:
-    Station()
-    {
-    }
-
-    Station(const casa::String &name, const casa::MPosition &position);
-    Station(const casa::String &name, const casa::MPosition &position,
-            const AntennaField &field0);
-    Station(const casa::String &name, const casa::MPosition &position,
-            const AntennaField &field0, const AntennaField &field1);
-
-    const casa::String &name() const;
-    const casa::MPosition &position() const;
-
-    bool isPhasedArray() const;
-    uint nField() const;
-    const AntennaField &field(uint i) const;
-
-  private:
-    casa::String            m_name;
-    casa::MPosition         m_position;
-    vector<AntennaField>    m_fields;
-  };
-
-  class Instrument
-  {
-  public:
-    Instrument()
-    {
-    }
-
-    Instrument(const casa::String &name, const casa::MPosition &position);
-
-    template <typename T>
-    Instrument(const casa::String &name, const casa::MPosition &position,
-               T first, T last);
-
-    const casa::String &name() const;
-    const casa::MPosition &position() const;
-
-    uint nStations() const;
-    const Station &station(uint i) const;
-    const Station &station(const casa::String &name) const;
-
-    void append(const Station &station);
-
-  private:
-    casa::String              m_name;
-    casa::MPosition           m_position;
-    map<casa::String, uint>   m_index;
-    vector<Station>           m_stations;
-  };
-
-  inline uint AntennaField::nTileElement() const
-  {
-    return m_tileElements.size();
-  }
-
-  const Vector3 &AntennaField::tileElement(uint i) const
-  {
-    return m_tileElements[i];
-  }
-
-  inline uint AntennaField::nElement() const
-  {
-    return m_elements.size();
-  }
-
-  inline const AntennaField::Element &AntennaField::element(uint i) const
-  {
-    return m_elements[i];
-  }
-
-  template <typename T>
-  Instrument::Instrument(const casa::String &name,
-                         const casa::MPosition &position,
-                         T first, T last)
-    :   m_name(name),
-        m_position(position),
-        m_stations(first, last)
-  {
-  }
-
-  class BeamCoeff
-  {
-  public:
-    BeamCoeff();
-
-    void load(const casa::Path &path);
-
-    // Center frequency used to scale frequency to range [-1.0, 1.0].
-    double center() const
-    {
-      return m_center;
-    }
-
-    // Width used to scale frequency to range [-1.0, 1.0].
-    double width() const
-    {
-      return m_width;
-    }
-
-    uint nElements() const
-    {
-      return m_coeff.shape()(0);
-    }
-
-    uint nPowerFreq() const
-    {
-      return m_coeff.shape()(1);
-    }
-
-    uint nPowerTheta() const
-    {
-      return m_coeff.shape()(2);
-    }
-
-    uint nHarmonics() const
-    {
-      return m_coeff.shape()(3);
-    }
-
-    casa::DComplex operator()(uint i, uint freq, uint theta, uint harmonic) const
-    {
-      return m_coeff(casa::IPosition(4, i, freq, theta, harmonic));
-    }
-
-  private:
-    double                      m_center, m_width;
-    casa::Array<casa::DComplex> m_coeff;
-  };
-
-  class LofarATerm
-  {
-  public:
-    LofarATerm(const casa::MeasurementSet &ms,
-               const casa::String &beamElementPath);
-
-    vector<casa::Cube<casa::Complex> > evaluate(const casa::IPosition &shape,
-      const casa::DirectionCoordinate &coordinates,
+    
+    void setDirection(const casa::DirectionCoordinate &coordinates, const casa::IPosition &shape);
+    
+    void setEpoch(const casa::MEpoch &epoch);
+
+    // Compute an ITRF direction vector for each pixel at the given epoch. This
+    // map can then be used to call any of the evaluate* functions.
+    ITRFDirectionMap
+    makeDirectionMap(const casa::DirectionCoordinate &coordinates,
+      const casa::IPosition &shape,
+      const casa::MEpoch &epoch) const;
+
+    // Compute the LOFAR station response for the given station. This includes
+    // the effects of paralactic rotation, the dual dipole LOFAR antenna, the
+    // tile beam former (HBA only), and the station beam former.
+    //
+    // The freq argument is a list of frequencies at which the response will be
+    // evaluated. The reference argument is a list of station beam former
+    // reference frequencies. The normalize argument, when set to true, causes
+    // the response to be multiplied by the inverse of the response at the
+    // central pixel.
+    vector<casa::Cube<casa::Complex> > evaluate(uint idStation,
+      const casa::Vector<casa::Double> &freq,
+      const casa::Vector<casa::Double> &reference, bool normalize = false)
+      const;
+
+    // Compute the array factor for the given station and polarization (0 = X,
+    // 1 = Y).
+    //
+    // The freq argument is a list of frequencies at which the array factor will
+    // be evaluated. The reference argument is a list of station beam former
+    // reference frequencies. The normalize argument, when set to true, causes
+    // the response to be multiplied by the inverse of the array factor at the
+    // central pixel.
+    vector<casa::Matrix<casa::Complex> > evaluateArrayFactor(uint idStation,
+      uint idPolarization,
+      const casa::Vector<casa::Double> &freq,
+      const casa::Vector<casa::Double> &reference, bool normalize = false)
+      const;
+
+    // Compute the LOFAR element response for the given station and antenna
+    // field. This includes the effects of paralactic rotation and the dual
+    // dipole LOFAR antenna.
+    //
+    // The freq argument is a list of frequencies at which the response will be
+    // evaluated. The normalize argument, when set to true, causes the response
+    // to be multiplied by the inverse of the response at the central pixel.
+    vector<casa::Cube<casa::Complex> > evaluateElementResponse(uint idStation,
+      uint idField,
+      const casa::Vector<casa::Double> &freq, bool normalize = false) const;
+
+    vector<casa::Cube<casa::Complex> > evaluateIonosphere(
       uint station,
-      const casa::MEpoch &epoch,
       const casa::Vector<casa::Double> &freq,
-      bool normalize = false) const;
+      bool normalize);
 
   private:
-    casa::Array<casa::DComplex>
-    normalize(const casa::Array<casa::DComplex> &response) const;
-
-    casa::Cube<casa::Double>
-    computeITRFMap(const casa::DirectionCoordinate &coordinates,
-      const casa::IPosition &shape,
-      casa::MDirection::Convert convertor) const;
-
-    casa::Array<casa::DComplex> evaluateStationBeam(const Station &station,
-      const Vector3 &refDelay,
-      const Vector3 &refTile,
-      const casa::Cube<casa::Double> &map,
-      const casa::Vector<casa::Double> &freq) const;
-
-    casa::Cube<casa::DComplex> evaluateTileArrayFactor(const AntennaField &field,
-      const Vector3 &reference,
-      const casa::Cube<casa::Double> &map,
-      const casa::Vector<casa::Double> &freq) const;
-
-    casa::Array<casa::DComplex> evaluateElementBeam(const BeamCoeff &coeff,
-      const AntennaField &field,
-      const casa::Cube<casa::Double> &map,
-      const casa::Vector<casa::Double> &freq) const;
-
-    void initInstrument(const casa::MeasurementSet &ms);
-
-    Station initStation(const casa::MeasurementSet &ms,
-      uint id,
-      const casa::String &name,
-      const casa::MPosition &position) const;
-
-    void initReferenceDirections(const casa::MeasurementSet &ms, uint idField);
-
-    void initReferenceFreq(const casa::MeasurementSet &ms,
-      uint idDataDescription);
-
-    BeamCoeff        m_coeffLBA, m_coeffHBA;
-    casa::MDirection m_refDelay, m_refTile;
-    double           m_refFreq;
-    Instrument       m_instrument;
+    
+    void initParmDB(const casa::String &parmdbname);
+    double get_parmvalue( std::string parmname );
+
+    casa::Record itsParameters;
+
+    BBS::Instrument::Ptr  itsInstrument;
+    const casa::DirectionCoordinate *itsDirectionCoordinates;
+    const casa::IPosition       *itsShape;
+    casa::MDirection      itsRefDelay, itsRefTile;
+    ITRFDirectionMap      itsITRFDirectionMap;
+    
+    // state variables for ionosphere
+    casa::Bool itsapplyIonosphere;
+    LOFAR::BBS::ParmFacade* pdb;
+    double time, r0, beta, height;
+    casa::Vector<casa::String>   cal_pp_names;
+    casa::Matrix<casa::Double> cal_pp;
+    casa::Vector<casa::Double> tec_white;
+    
   };
+
 } // namespace LOFAR
 
 #endif
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarATermOld.h b/CEP/Imager/LofarFT/include/LofarFT/LofarATermOld.h
new file mode 100644
index 0000000000000000000000000000000000000000..02d88016369279431e17636f7717d19e89fd15bc
--- /dev/null
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarATermOld.h
@@ -0,0 +1,294 @@
+//# LofarATermOld.h: Compute the LOFAR beam response on the sky.
+//#
+//# Copyright (C) 2011
+//# 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_LOFARFT_LOFARATERMOLD_H
+#define LOFAR_LOFARFT_LOFARATERMOLD_H
+
+#include <Common/LofarTypes.h>
+#include <Common/lofar_map.h>
+#include <Common/lofar_vector.h>
+
+#include <casa/Arrays/Array.h>
+#include <casa/BasicSL/String.h>
+#include <measures/Measures/MPosition.h>
+#include <measures/Measures/MDirection.h>
+
+namespace casa
+{
+  class DirectionCoordinate;
+  class MEpoch;
+  class MeasurementSet;
+  class Path;
+}
+
+namespace LOFAR
+{
+  struct Vector3
+  {
+    const double &operator[](uint i) const
+    { return __data[i]; }
+
+    double &operator[](uint i)
+    { return __data[i]; }
+
+    double  __data[3];
+  };
+
+  class AntennaField
+  {
+  public:
+    enum Axis
+    {
+      P,
+      Q,
+      R,
+      N_Axis
+    };
+
+    struct Element
+    {
+      Vector3 offset;
+      bool    flag[2];
+    };
+
+    AntennaField()
+    {
+    }
+
+    AntennaField(const casa::String &name, const Vector3 &position,
+                 const Vector3 &p,
+                 const Vector3 &q, const Vector3 &r);
+
+    const casa::String &name() const;
+    const Vector3 &position() const;
+    const Vector3 &axis(Axis axis) const;
+
+    bool isHBA() const;
+
+    void appendTileElement(const Vector3 &offset);
+    inline uint nTileElement() const;
+    inline const Vector3 &tileElement(uint i) const;
+
+    void appendElement(const Element &element);
+    inline uint nElement() const;
+    inline const Element &element(uint i) const;
+
+  private:
+    casa::String    m_name;
+    Vector3         m_position;
+    Vector3         m_axes[N_Axis];
+    vector<Vector3> m_tileElements;
+    vector<Element> m_elements;
+  };
+
+  class Station
+  {
+  public:
+    Station()
+    {
+    }
+
+    Station(const casa::String &name, const casa::MPosition &position);
+    Station(const casa::String &name, const casa::MPosition &position,
+            const AntennaField &field0);
+    Station(const casa::String &name, const casa::MPosition &position,
+            const AntennaField &field0, const AntennaField &field1);
+
+    const casa::String &name() const;
+    const casa::MPosition &position() const;
+
+    bool isPhasedArray() const;
+    uint nField() const;
+    const AntennaField &field(uint i) const;
+
+  private:
+    casa::String            m_name;
+    casa::MPosition         m_position;
+    vector<AntennaField>    m_fields;
+  };
+
+  class Instrument
+  {
+  public:
+    Instrument()
+    {
+    }
+
+    Instrument(const casa::String &name, const casa::MPosition &position);
+
+    template <typename T>
+    Instrument(const casa::String &name, const casa::MPosition &position,
+               T first, T last);
+
+    const casa::String &name() const;
+    const casa::MPosition &position() const;
+
+    uint nStations() const;
+    const Station &station(uint i) const;
+    const Station &station(const casa::String &name) const;
+
+    void append(const Station &station);
+
+  private:
+    casa::String              m_name;
+    casa::MPosition           m_position;
+    map<casa::String, uint>   m_index;
+    vector<Station>           m_stations;
+  };
+
+  inline uint AntennaField::nTileElement() const
+  {
+    return m_tileElements.size();
+  }
+
+  const Vector3 &AntennaField::tileElement(uint i) const
+  {
+    return m_tileElements[i];
+  }
+
+  inline uint AntennaField::nElement() const
+  {
+    return m_elements.size();
+  }
+
+  inline const AntennaField::Element &AntennaField::element(uint i) const
+  {
+    return m_elements[i];
+  }
+
+  template <typename T>
+  Instrument::Instrument(const casa::String &name,
+                         const casa::MPosition &position,
+                         T first, T last)
+    :   m_name(name),
+        m_position(position),
+        m_stations(first, last)
+  {
+  }
+
+  class BeamCoeff
+  {
+  public:
+    BeamCoeff();
+
+    void load(const casa::Path &path);
+
+    // Center frequency used to scale frequency to range [-1.0, 1.0].
+    double center() const
+    {
+      return m_center;
+    }
+
+    // Width used to scale frequency to range [-1.0, 1.0].
+    double width() const
+    {
+      return m_width;
+    }
+
+    uint nElements() const
+    {
+      return m_coeff.shape()(0);
+    }
+
+    uint nPowerFreq() const
+    {
+      return m_coeff.shape()(1);
+    }
+
+    uint nPowerTheta() const
+    {
+      return m_coeff.shape()(2);
+    }
+
+    uint nHarmonics() const
+    {
+      return m_coeff.shape()(3);
+    }
+
+    casa::DComplex operator()(uint i, uint freq, uint theta, uint harmonic) const
+    {
+      return m_coeff(casa::IPosition(4, i, freq, theta, harmonic));
+    }
+
+  private:
+    double                      m_center, m_width;
+    casa::Array<casa::DComplex> m_coeff;
+  };
+
+  class LofarATermOld
+  {
+  public:
+    LofarATermOld(const casa::MeasurementSet &ms,
+               const casa::String &beamElementPath);
+
+    vector<casa::Cube<casa::Complex> > evaluate(const casa::IPosition &shape,
+      const casa::DirectionCoordinate &coordinates,
+      uint station,
+      const casa::MEpoch &epoch,
+      const casa::Vector<casa::Double> &freq,
+      bool normalize = false) const;
+
+  private:
+    casa::Array<casa::DComplex>
+    normalize(const casa::Array<casa::DComplex> &response) const;
+
+    casa::Cube<casa::Double>
+    computeITRFMap(const casa::DirectionCoordinate &coordinates,
+      const casa::IPosition &shape,
+      casa::MDirection::Convert convertor) const;
+
+    casa::Array<casa::DComplex> evaluateStationBeam(const Station &station,
+      const Vector3 &refDelay,
+      const Vector3 &refTile,
+      const casa::Cube<casa::Double> &map,
+      const casa::Vector<casa::Double> &freq) const;
+
+    casa::Cube<casa::DComplex> evaluateTileArrayFactor(const AntennaField &field,
+      const Vector3 &reference,
+      const casa::Cube<casa::Double> &map,
+      const casa::Vector<casa::Double> &freq) const;
+
+    casa::Array<casa::DComplex> evaluateElementBeam(const BeamCoeff &coeff,
+      const AntennaField &field,
+      const casa::Cube<casa::Double> &map,
+      const casa::Vector<casa::Double> &freq) const;
+
+    void initInstrument(const casa::MeasurementSet &ms);
+
+    Station initStation(const casa::MeasurementSet &ms,
+      uint id,
+      const casa::String &name,
+      const casa::MPosition &position) const;
+
+    void initReferenceDirections(const casa::MeasurementSet &ms, uint idField);
+
+    void initReferenceFreq(const casa::MeasurementSet &ms,
+      uint idDataDescription);
+
+    BeamCoeff        m_coeffLBA, m_coeffHBA;
+    casa::MDirection m_refDelay, m_refTile;
+    double           m_refFreq;
+    Instrument       m_instrument;
+  };
+} // namespace LOFAR
+
+#endif
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunction.h b/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunction.h
index 4bf2c5640ffcf674b4865a73fe015b9d38e0fdf9..5058100c751815273f41c1122ef798dea5552022 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunction.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunction.h
@@ -44,6 +44,11 @@
 #include <coordinates/Coordinates/DirectionCoordinate.h>
 #include <casa/OS/PrecTimer.h>
 
+#include <lattices/Lattices/ArrayLattice.h>
+#include <lattices/Lattices/LatticeFFT.h>
+
+
+
 
 using namespace casa;
 
@@ -73,10 +78,16 @@ namespace LOFAR
                              const MeasurementSet& ms,
                              uInt nW, double Wmax,
                              uInt oversample,
-                             const String& beamElementPath,
-			     Int verbose,
-			     Int maxsupport,
-                             const String& imgName);
+                             Int verbose,
+                             Int maxsupport,
+                             const String& imgName,
+			     Bool Use_EJones,
+			     Bool Apply_Element,
+                             const casa::Record& parameters
+                            );
+    //,
+    //			     Int TaylorTerm,
+    //			     Double RefFreq);
 
 //      ~LofarConvolutionFunction ()
 //      {
@@ -118,8 +129,12 @@ namespace LOFAR
                                          bool degridding_step,
                                          double Append_average_PB_CF,
                                          Matrix<Complex>& Stack_PB_CF,
-                                         double& sum_weight_square);
+                                         double& sum_weight_square,
+					 uInt spw, Int TaylorTerm, double RefFreq);
 
+    Array<Complex>  ApplyElementBeam(Array<Complex> input_grid, Double time, uInt spw, const Matrix<bool>& Mask_Mueller_in, bool degridding_step);
+    Array<Complex>  ApplyElementBeam2(Array<Complex>& input_grid, Double time, uInt spw, const Matrix<bool>& Mask_Mueller_in, bool degridding_step, Int UsedMask=-1);
+    
     // Returns the average Primary Beam from the disk
     Matrix<float> Give_avg_pb();
 
@@ -133,20 +148,90 @@ namespace LOFAR
     // Zero padding of a Matrix
     Matrix<Complex> zero_padding(const Matrix<Complex>& Image, int Npixel_Out);
 
+
     // Get the W scale.
     const WScale& wScale() const
       { return m_wScale; }
 
+    vector< Matrix< Bool > > itsVectorMasksDegridElement;
+    void MakeMaskDegrid( const Array<Complex>& gridin, Int NumMask)
+    {
+
+      String MaskName("JAWS_masks_degrid/Mask"+String::toString(NumMask)+".boolim");
+      File MaskFile(MaskName);
+      if(!MaskFile.exists()){
+	//cout<<"... Making Masks ..."<<endl;
+	Matrix<Bool> Mask(IPosition(2,gridin.shape()[0],gridin.shape()[0]),false);
+	Matrix<Int> IntMask(IPosition(2,gridin.shape()[0],gridin.shape()[0]),false);
+	int GridSize(gridin.shape()[0]);
+	const Complex* inPtr = gridin.data();
+	Bool* outPtr = Mask.data();
+	for (uInt i=0; i<GridSize; ++i) {
+	  for (uInt j=0; j<GridSize; ++j) {
+	    if (inPtr->real() != 0  ||  inPtr->imag() != 0) {
+	      (*(outPtr)) = true;
+	    }
+	    inPtr++;
+	    outPtr++;
+	  }
+	}
+	//itsVectorMasksDegridElement.push_back(Mask);
+	
+	store(Mask,MaskName);
+	//cout<<"... Done Making Masks ..."<<endl;
+      }
+    }
+
+    Bool itsFilledVectorMasks;
+      //vector< Matrix< Bool > > itsVectorMasksDegridElement;
+      void ReadMaskDegrid()
+      {
+      	Int NumMask(0);
+      	while(true){
+      	  String MaskName("JAWS_masks_degrid/Mask"+String::toString(NumMask)+".boolim");
+      	  File MaskFile(MaskName);
+      	  if(MaskFile.exists())
+	    {
+	      //cout<<"Reading:"<<MaskName<<endl;
+	      PagedImage<Bool> pim(MaskName);
+	      Array<Bool> arr = pim.get();
+	      Matrix<Bool> Mask;
+	      Mask.reference (arr.nonDegenerate(2));
+	      itsVectorMasksDegridElement.push_back(Mask);
+	      NumMask+=1;
+	    }
+	  else
+	    {
+	      break;
+	    }
+	}
+	itsFilledVectorMasks=true;
+	
+      }
+      
+      Bool VectorMaskIsFilled(){return itsFilledVectorMasks;}
+
   private:
     void normalized_fft (Matrix<Complex>&, bool toFreq=true);
     void normalized_fft (PrecTimer& timer, Matrix<Complex>&, bool toFreq=true);
 
+    Matrix<Complex> give_normalized_fft_lapack(const Matrix<Complex> &im, bool toFreq=true)
+      {
+        Matrix<Complex> result(im.copy());
+        ArrayLattice<Complex> lattice(result);
+        LatticeFFT::cfft2d(lattice, toFreq);
+        if(toFreq){
+          result/=static_cast<Float>(result.shape()(0)*result.shape()(1));
+        }
+        else{
+          result*=static_cast<Float>(result.shape()(0)*result.shape()(1));
+        };
+        return result;
+      }
+
     MEpoch observationStartTime (const MeasurementSet &ms,
                                  uInt idObservation) const;
 
-    Double observationReferenceFreq (const MeasurementSet &ms,
-                                     uInt idDataDescription);
-
     // Estime spheroidal convolution function from the support of the fft
     // of the spheroidal in the image plane
     Double makeSpheroidCut();
@@ -158,11 +243,12 @@ namespace LOFAR
                                Double pixelSize,
                                Double w) const;
 
+
     // Return the angular resolution required for making the image of the
     // angular size determined by coordinates and shape.
     // The resolution is assumed to be the same on both direction axes.
     Double estimateAResolution(const IPosition &shape,
-                               const DirectionCoordinate &coordinates) const;
+                               const DirectionCoordinate &coordinates, double station_diam = 70.) const;
 
     // Apply a spheroidal taper to the input function.
     template <typename T>
@@ -181,7 +267,216 @@ namespace LOFAR
         }
       }
     }
+
+
+    // Linear interpolation
+    template <typename T>
+    Matrix< T > LinearInterpol(Matrix<T> ImageIn, Int  NpixOut)
+      {
+	Matrix<T> ImageOut(IPosition(2,NpixOut,NpixOut),0.);
+	float d0(1./(NpixOut-1.));
+	float d1(1./(ImageIn.shape()[0]-1.));
+	float dd(d0/d1);
+	float dx,dy,dxd,dyd,xin,yin;
+	float onef(1.);
+	uInt NpixOutm(NpixOut-1);
+	for(uInt i=0;i<(NpixOut);++i){
+	  dxd=i*dd;
+	  xin=floor(dxd);
+	  dx=dxd-xin;
+	  for(uInt j=0;j<(NpixOut);++j){
+	    dyd=j*dd;
+	    yin=floor(dyd);
+	    dy=dyd-yin;
+	    ImageOut(i,j)=(onef-dx)*(onef-dy)*ImageIn(xin,yin) + (onef-dx)*(dy)*ImageIn(xin,yin+1) + (dx)*(onef-dy)*ImageIn(xin+1,yin) + (dx)*(dy)*ImageIn(xin+1,yin+1);
+	  }
+	}
+	return ImageOut;
+      }
+
+    void Convolve(Matrix<Complex> gridin, Matrix<Complex> gridout, Matrix<Complex> ConvFunc){
+      Int Support(ConvFunc.shape()[0]);
+      Int GridSize(gridin.shape()[0]);
+      Int off(Support/2);
+      for(uInt i=Support/2;i<GridSize-Support/2;++i){
+	for(uInt j=Support/2;j<GridSize-Support/2;++j){
+	  if((gridin(i,j))!=Complex(0.,0.)){
+	    Complex val(gridin(i,j));
+	    for(uInt ii=0;ii<Support;++ii){
+	      for(uInt jj=0;jj<Support;++jj){
+		gridout(i-off+ii,j-off+jj)+=ConvFunc(ii,jj)*val;
+	      }
+	    }
+	  }
+	}
+      }
+    }
+
+    void ConvolveOpt(Matrix<Complex> gridin, Matrix<Complex> gridout, Matrix<Complex> ConvFunc){
+      Int Support(ConvFunc.shape()[0]);
+      Int GridSize(gridin.shape()[0]);
+      Int off(Support/2);
+
+      Complex* __restrict__ gridInPtr = gridin.data();
+      Complex* __restrict__ gridOutPtr = gridout.data();
+      Complex* __restrict__ ConvFuncPtr = ConvFunc.data();
+
+      for(uInt i=Support/2;i<GridSize-Support/2;++i){
+	for(uInt j=Support/2;j<GridSize-Support/2;++j){
+	  gridInPtr=gridin.data()+GridSize*i+j;
+	  if (gridInPtr->real() != 0  ||  gridInPtr->imag() != 0) {//if((*gridInPtr)!=Complex(0.,0.)){
+	    ConvFuncPtr = ConvFunc.data();
+	    for(uInt jj=0;jj<Support;++jj){
+	      for(uInt ii=0;ii<Support;++ii){
+		gridOutPtr = gridout.data()+(j-off+jj)*GridSize+i-off+ii;
+		(*gridOutPtr) += (*ConvFuncPtr)*(*gridInPtr);
+		ConvFuncPtr++;//=ConvFunc.data()+Support*ii+jj;
+	      }
+	    }
+	  }
+	  //gridInPtr++;
+	}
+      }
+      
+    }
+
+    void ConvolveGer( const Matrix<Complex>& gridin, Matrix<Complex>& gridout,
+		      const Matrix<Complex>& ConvFunc)
+    {
+      int Support(ConvFunc.shape()[0]);
+      int GridSize(gridin.shape()[0]);
+      int off(Support/2);
+      const Complex* inPtr = gridin.data() + off*GridSize + off;
+      for (uInt i=0; i<GridSize-Support; ++i) {
+	for (uInt j=0; j<GridSize-Support; ++j) {
+	  if (inPtr->real() != 0  ||  inPtr->imag() != 0) {
+	    const Complex* cfPtr = ConvFunc.data();
+	    for (uInt ii=0; ii<Support; ++ii) {
+	      Complex* outPtr = gridout.data() + (i+ii)*GridSize + j;
+	      for (uInt jj=0; jj<Support; ++jj) {
+		outPtr[jj] += *cfPtr++ * *inPtr;
+	      }
+	    }
+	  }
+	  inPtr++;
+	}
+	inPtr += Support;
+      }
+    }
+
+    void ConvolveGerArray( const Array<Complex>& gridin, Int ConvPol, Matrix<Complex>& gridout,
+			   const Matrix<Complex>& ConvFunc)
+    {
+      int Support(ConvFunc.shape()[0]);
+      int GridSize(gridin.shape()[0]);
+      int off(Support/2);
+
+      const Complex* inPtr = gridin.data() + ConvPol*GridSize*GridSize + off*GridSize + off;
+      for (uInt i=0; i<GridSize-Support; ++i) {
+	for (uInt j=0; j<GridSize-Support; ++j) {
+	  if (inPtr->real() != 0  ||  inPtr->imag() != 0) {
+	    const Complex* cfPtr = ConvFunc.data();
+	    for (uInt ii=0; ii<Support; ++ii) {
+	      Complex* outPtr = gridout.data() + (i+ii)*GridSize + j;
+	      for (uInt jj=0; jj<Support; ++jj) {
+		outPtr[jj] += *cfPtr++ * *inPtr;
+	      }
+	    }
+	  }
+	  inPtr++;
+	  }
+	inPtr += Support;
+      }
+    }
     
+    
+
+    void ConvolveGerArrayMask( const Array<Complex>& gridin, Int ConvPol, Matrix<Complex>& gridout,
+			       const Matrix<Complex>& ConvFunc, Int UsedMask)
+    {
+      int Support(ConvFunc.shape()[0]);
+      int GridSize(gridin.shape()[0]);
+      int off(Support/2);
+
+      const Complex* inPtr = gridin.data() + ConvPol*GridSize*GridSize + off*GridSize + off;
+      const Bool* MaskPtr = itsVectorMasksDegridElement[UsedMask].data() + off*GridSize + off;
+      for (uInt i=0; i<GridSize-Support; ++i) {
+	for (uInt j=0; j<GridSize-Support; ++j) {
+	  if ((*MaskPtr)==true) {
+	    const Complex* cfPtr = ConvFunc.data();
+	    for (uInt ii=0; ii<Support; ++ii) {
+	      Complex* outPtr = gridout.data() + (i+ii)*GridSize + j;
+	      for (uInt jj=0; jj<Support; ++jj) {
+		outPtr[jj] += *cfPtr++ * *inPtr;
+	      }
+	    }
+	  }
+	  MaskPtr++;
+	  inPtr++;
+	}
+	inPtr += Support;
+	MaskPtr += Support;
+      }
+    }
+    
+    
+    
+    // Linear interpolation
+    template <typename T>
+    Matrix< T > LinearInterpol2(Matrix<T> ImageIn, Int  NpixOut)
+      {
+	Matrix<T> ImageOut(IPosition(2,NpixOut,NpixOut),1e-7);
+	int nd(ImageIn.shape()[0]);
+	int ni(NpixOut);
+	float off(-.5);//-(((1.+1./(nd-1.))-1.)/2.)*(nd-1));
+	float a(nd/(ni-1.));//((1.+1./(nd-1.))/(ni-1.))*(nd-1));
+	float dx,dy,dxd,dyd,xin,yin;
+	float onef(1.);
+	uInt NpixOutm(NpixOut-1);
+	for(uInt i=0;i<(NpixOut);++i){
+	  dxd=i*a+off;
+	  xin=floor(dxd);
+	  dx=dxd-xin;
+	  for(uInt j=0;j<(NpixOut);++j){
+	    dyd=j*a+off;
+	    yin=floor(dyd);
+	    dy=dyd-yin;
+	    if((dxd<0)||((xin+1)>ImageIn.shape()[0]-1.)){continue;}
+	    if((dyd<0)||((yin+1)>ImageIn.shape()[0]-1.)){continue;}
+	    ImageOut(i,j)=(onef-dx)*(onef-dy)*ImageIn(xin,yin) + (onef-dx)*(dy)*ImageIn(xin,yin+1) + (dx)*(onef-dy)*ImageIn(xin+1,yin) + (dx)*(dy)*ImageIn(xin+1,yin+1);
+	  }
+	}
+	/* store(ImageIn,"ImageIn.img"); */
+	/* store(ImageOut,"ImageOut.img"); */
+	/* assert(false); */
+	return ImageOut;
+      }
+
+    void EstimateCoordShape(IPosition shape, DirectionCoordinate coordinate, double station_diameter=70.){
+      coordinate = m_coordinates;
+      Double aPixelAngSize = min(m_pixelSizeSpheroidal,
+				 estimateAResolution(m_shape, m_coordinates, station_diameter));
+      
+      Double pixelSize = abs(m_coordinates.increment()[0]);
+      Double imageDiameter = pixelSize * m_shape(0);
+      Int nPixelsConv = imageDiameter / aPixelAngSize;
+      if (nPixelsConv > itsMaxSupport) {
+          nPixelsConv = itsMaxSupport;
+      }
+      // Make odd and optimal.
+      nPixelsConv = FFTCMatrix::optimalOddFFTSize (nPixelsConv);
+      aPixelAngSize = imageDiameter / nPixelsConv;
+
+      shape=IPosition(2, nPixelsConv, nPixelsConv);
+      Vector<Double> increment_old(coordinate.increment());
+      Vector<Double> increment(2);
+      increment[0] = aPixelAngSize*sign(increment_old[0]);
+      increment[1] = aPixelAngSize*sign(increment_old[1]);
+      coordinate.setIncrement(increment);
+      Vector<Double> refpix(2, 0.5*(nPixelsConv-1));
+      coordinate.setReferencePixel(refpix);
+    }
+
     Double spheroidal(Double nu) const;
 
     template <typename T>
@@ -200,6 +495,7 @@ namespace LOFAR
 
 
     //# Data members.
+    casa::Record       itsParameters;
     IPosition           m_shape;
     DirectionCoordinate m_coordinates;
     WScale              m_wScale;
@@ -217,15 +513,20 @@ namespace LOFAR
     Matrix<Complex>     Spheroid_cut;
     //# Stack of the convolution functions for the average PB calculation
     Matrix<Float>       Spheroid_cut_im;
+    Matrix<Float>       Spheroid_cut_im_element;
     //# List of the ferquencies the CF have to be caluclated for
     Vector< Double >    list_freq;
     vector< Matrix<Complex> > m_WplanesStore;
     //# Aterm_store[double time][antenna][channel]=Cube[Npix,Npix,4]
     map<Double, vector< vector< Cube<Complex> > > > m_AtermStore;
+    map<Double, vector< vector< Cube<Complex> > > > m_AtermStore_element;
+    map<Double, vector< vector< Cube<Complex> > > > m_AtermStore_station;
     //# Average primary beam
     Matrix<Float>       Im_Stack_PB_CF0;
     Int                 itsVerbose;
     Int                 itsMaxSupport;
+    //    Int                 itsTaylorTerm;
+    //Double              itsRefFreq;
     String              itsImgName;
     vector<FFTCMatrix>  itsFFTMachines;
     Double              itsTimeW;
@@ -240,6 +541,17 @@ namespace LOFAR
     Double              itsTimeCFpar;
     Double              itsTimeCFfft;
     unsigned long long  itsTimeCFcnt;
+    Bool                its_Use_EJones;
+    Bool                its_Apply_Element;
+    uInt                its_MaxWSupport;
+    uInt                its_count_time;
+    mutable LogIO       m_logIO;
+    Matrix<Complex>     spheroid_cut_element_fft;
+    vector< vector< Matrix< Complex > > > GridsMueller;
+    LogIO &logIO() const
+      {
+        return m_logIO;
+      }
   };
 
 
@@ -264,7 +576,7 @@ namespace LOFAR
   void store (const DirectionCoordinate &dir, const Matrix<T> &data,
               const string &name)
   {
-    cout<<"Saving... "<<name<<endl;
+    //cout<<"Saving... "<<name<<endl;
     Vector<Int> stokes(1);
     stokes(0) = Stokes::I;
     CoordinateSystem csys;
@@ -295,7 +607,7 @@ namespace LOFAR
              const string &name)
   {
     AlwaysAssert(data.shape()(2) == 4, SynthesisError);
-    cout<<"Saving... "<<name<<endl;
+    //cout<<"Saving... "<<name<<endl;
     Vector<Int> stokes(4);
     stokes(0) = Stokes::XX;
     stokes(1) = Stokes::XY;
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunctionOld.h b/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunctionOld.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6d4a0e6499b5387651df5668a8c2a6ad24582c7
--- /dev/null
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarConvolutionFunctionOld.h
@@ -0,0 +1,234 @@
+//# LofarConvolutionFunctionOld.h: Compute LOFAR convolution functions on demand.
+//#
+//# Copyright (C) 2011
+//# 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 LOFARFT_LOFARCONVOLUTIONFUNCTIONOLD_H
+#define LOFARFT_LOFARCONVOLUTIONFUNCTIONOLD_H
+
+#include <LofarFT/LofarATermOld.h>
+#include <LofarFT/LofarWTerm.h>
+#include <LofarFT/LofarCFStore.h>
+#include <LofarFT/FFTCMatrix.h>
+#include <Common/Timer.h>
+
+#include <casa/Arrays/Cube.h>
+#include <casa/Arrays/Matrix.h>
+#include <casa/Arrays/MatrixMath.h>
+#include <casa/Arrays/ArrayIter.h>
+#include <casa/Arrays/ArrayMath.h>
+#include <images/Images/PagedImage.h>
+#include <casa/Utilities/Assert.h>
+#include <ms/MeasurementSets/MeasurementSet.h>
+#include <measures/Measures/MDirection.h>
+#include <coordinates/Coordinates/CoordinateSystem.h>
+#include <coordinates/Coordinates/SpectralCoordinate.h>
+#include <coordinates/Coordinates/StokesCoordinate.h>
+#include <coordinates/Coordinates/DirectionCoordinate.h>
+#include <casa/OS/PrecTimer.h>
+
+
+using namespace casa;
+
+namespace LOFAR
+{
+
+  class LofarConvolutionFunctionOld
+  {
+
+  public:
+    LofarConvolutionFunctionOld(const IPosition& shape,
+                             const DirectionCoordinate& coordinates,
+                             const MeasurementSet& ms,
+                             uInt nW, double Wmax,
+                             uInt oversample,
+                             const String& beamElementPath,
+			     Int verbose,
+			     Int maxsupport,
+                             const String& imgName);
+
+//      ~LofarConvolutionFunctionOld ()
+//      {
+//      }
+
+    // Show the relative timings of the various steps.
+    void showTimings (std::ostream&, double duration, double timeCF) const;
+
+    // Show percentage of value in total with 1 decimal.
+    static void showPerc1 (std::ostream& os, double value, double total);
+
+    // Compute and store W-terms and A-terms in the fourier domain
+    void store_all_W_images();
+
+    // Get the spheroidal cut.
+    const Matrix<Float>& getSpheroidCut();
+
+    // Get the spheroidal cut from the file.
+    static Matrix<Float> getSpheroidCut (const String& imgName);
+
+    // Get the average PB from the file.
+    static Matrix<Float> getAveragePB (const String& imgName);
+
+
+    // Compute the fft of the beam at the minimal resolution for all antennas,
+    // and append it to a map object with a (double time) key.
+    void computeAterm(Double time);
+
+    // Compute the convolution function for all channel, for the polarisations
+    // specified in the Mueller_mask matrix
+    // Also specify weither to compute the Mueller matrix for the forward or
+    // the backward step. A dirty way to calculate the average beam has been
+    // implemented, by specifying the beam correcting to the given baseline
+    // and timeslot.
+    // RETURNS in a LofarCFStore: result[channel][Mueller row][Mueller column]
+    LofarCFStore makeConvolutionFunction(uInt stationA, uInt stationB,
+                                         Double time, Double w,
+                                         const Matrix<bool>& Mask_Mueller,
+                                         bool degridding_step,
+                                         double Append_average_PB_CF,
+                                         Matrix<Complex>& Stack_PB_CF,
+                                         double& sum_weight_square);
+
+    // Returns the average Primary Beam from the disk
+    Matrix<float> Give_avg_pb();
+
+    // Compute the average Primary Beam from the Stack of convolution functions
+    Matrix<Float> Compute_avg_pb(Matrix<Complex> &Sum_Stack_PB_CF,
+                                 double sum_weight_square);
+
+    // Zero padding of a Cube
+    Cube<Complex> zero_padding(const Cube<Complex>& Image, int Npixel_Out);
+
+    // Zero padding of a Matrix
+    Matrix<Complex> zero_padding(const Matrix<Complex>& Image, int Npixel_Out);
+
+    // Get the W scale.
+    const WScale& wScale() const
+      { return m_wScale; }
+
+  private:
+    void normalized_fft (Matrix<Complex>&, bool toFreq=true);
+    void normalized_fft (PrecTimer& timer, Matrix<Complex>&, bool toFreq=true);
+
+    MEpoch observationStartTime (const MeasurementSet &ms,
+                                 uInt idObservation) const;
+
+    Double observationReferenceFreq (const MeasurementSet &ms,
+                                     uInt idDataDescription);
+
+    // Estime spheroidal convolution function from the support of the fft
+    // of the spheroidal in the image plane
+    Double makeSpheroidCut();
+
+    // Return the angular resolution required for making the image of the
+    // angular size determined by coordinates and shape.
+    // The resolution is assumed to be the same on both direction axes.
+    Double estimateWResolution(const IPosition &shape,
+                               Double pixelSize,
+                               Double w) const;
+
+    // Return the angular resolution required for making the image of the
+    // angular size determined by coordinates and shape.
+    // The resolution is assumed to be the same on both direction axes.
+    Double estimateAResolution(const IPosition &shape,
+                               const DirectionCoordinate &coordinates) const;
+
+    // Apply a spheroidal taper to the input function.
+    template <typename T>
+    void taper (Matrix<T> &function) const
+    {
+      AlwaysAssert(function.shape()[0] == function.shape()[1], SynthesisError);
+      uInt size = function.shape()[0];
+      Double halfSize = (size-1) / 2.0;
+      Vector<Double> x(size);
+      for (uInt i=0; i<size; ++i) {
+        x[i] = spheroidal(abs(i - halfSize) / halfSize);
+      }
+      for (uInt i=0; i<size; ++i) {
+        for (uInt j=0; j<size; ++j) {
+          function(j, i) *= x[i] * x[j];
+        }
+      }
+    }
+    
+    Double spheroidal(Double nu) const;
+
+    template <typename T>
+    uInt findSupport(Matrix<T> &function, Double threshold) const
+    {
+      ///      Double peak = abs(max(abs(function)));
+      Double peak = max(amplitude(function));
+      threshold *= peak;
+      uInt halfSize = function.shape()[0] / 2;
+      uInt x = 0;
+      while (x < halfSize && abs(function(x, halfSize)) < threshold) {
+        ++x;
+      }
+      return 2 * (halfSize - x);
+    }
+
+
+    //# Data members.
+    IPosition           m_shape;
+    DirectionCoordinate m_coordinates;
+    WScale              m_wScale;
+    LofarWTerm          m_wTerm;
+    LofarATermOld       m_aTerm;
+    Double              m_maxW;
+    Double              m_pixelSizeSpheroidal;
+    uInt                m_nWPlanes;
+    uInt                m_nStations;
+    uInt                m_oversampling;
+    uInt                m_nChannel;
+    Double              m_refFrequency;
+    uInt                m_maxCFSupport;
+    //# Stack of the convolution functions for the average PB calculation
+    Matrix<Complex>     Spheroid_cut;
+    //# Stack of the convolution functions for the average PB calculation
+    Matrix<Float>       Spheroid_cut_im;
+    //# List of the ferquencies the CF have to be caluclated for
+    Vector< Double >    list_freq;
+    vector< Matrix<Complex> > m_WplanesStore;
+    //# Aterm_store[double time][antenna][channel]=Cube[Npix,Npix,4]
+    map<Double, vector< vector< Cube<Complex> > > > m_AtermStore;
+    //# Average primary beam
+    Matrix<Float>       Im_Stack_PB_CF0;
+    Int                 itsVerbose;
+    Int                 itsMaxSupport;
+    String              itsImgName;
+    vector<FFTCMatrix>  itsFFTMachines;
+    Double              itsTimeW;
+    Double              itsTimeWpar;
+    Double              itsTimeWfft;
+    unsigned long long  itsTimeWcnt;
+    Double              itsTimeA;
+    Double              itsTimeApar;
+    Double              itsTimeAfft;
+    unsigned long long  itsTimeAcnt;
+    Double              itsTimeCF;
+    Double              itsTimeCFpar;
+    Double              itsTimeCFfft;
+    unsigned long long  itsTimeCFcnt;
+  };
+
+
+} //# end namespace casa
+
+#endif
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarCubeSkyEquation.h b/CEP/Imager/LofarFT/include/LofarFT/LofarCubeSkyEquation.h
index 1a409d92a34089ff8382ca3cd6b9fba73ad6149d..9d82a5163d03cfabdb0f3fce07ef5c5b30d7e4cc 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarCubeSkyEquation.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarCubeSkyEquation.h
@@ -46,36 +46,52 @@ class LofarCubeSkyEquation : public SkyEquation {
 
  public:
   LofarCubeSkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft, ComponentFTMachine& cft, Bool noModelCol=False);
- 
+
   //Read only iterator...hence no scratch col
   LofarCubeSkyEquation(SkyModel& sm, ROVisibilityIterator& vi, FTMachine& ft, ComponentFTMachine& cft, Bool noModelCol=False);
 
   virtual ~LofarCubeSkyEquation();
   virtual void predict(Bool incremental=False, MS::PredefinedColumns Type=MS::MODEL_DATA);
   virtual void gradientsChiSquared(Bool incremental, Bool commitModel=False);
-  
+
+//  virtual Matrix<Float> GiveAvgPB (Int taylor_order)
+//  {
+//    Matrix< Float > a((ftm_p[taylor_order]->getAveragePB()).copy());
+//    return a;
+//  };
+
+  /* virtual const Matrix<Float>& GiveAvgPB(Int taylor_order) { */
+  /*   Matrix< Float> a(IPosition(2,2,2),0.); */
+  /*   return a; */
+  /* }; */
+
   virtual void initializePutSlice(const VisBuffer& vb, Int cubeSlice=0, Int nCubeSlice=1);
-  virtual void putSlice(VisBuffer& vb, Bool dopsf, 
-			FTMachine::Type col,Int cubeSlice=0, 
+  virtual void putSlice(VisBuffer& vb, Bool dopsf,
+			FTMachine::Type col,Int cubeSlice=0,
 			Int nCubeSlice=1);
-  virtual void finalizePutSlice(const VisBuffer& vb,  
+  virtual void finalizePutSlice(const VisBuffer& vb,
 				Int cubeSlice=0, Int nCubeSlice=1);
   void initializeGetSlice(const VisBuffer& vb, Int row,
-			  Bool incremental, Int cubeSlice=0, 
-			  Int nCubeSlice=1);   
-  virtual VisBuffer& getSlice(VisBuffer& vb, 
+			  Bool incremental, Int cubeSlice=0,
+			  Int nCubeSlice=1);
+  virtual VisBuffer& getSlice(VisBuffer& vb,
 			      Bool incremental, Int cubeSlice=0,
-			      Int nCubeSlice=1); 
+			      Int nCubeSlice=1);
   void finalizeGetSlice();
   void isLargeCube(ImageInterface<Complex>& theIm, Int& nCubeSlice);
   //void makeApproxPSF(Int model, ImageInterface<Float>& psf);
-  //virtual void makeApproxPSF(Int model, ImageInterface<Float>& psf); 
+  //virtual void makeApproxPSF(Int model, ImageInterface<Float>& psf);
   void makeApproxPSF(PtrBlock<TempImage<Float> * >& psfs);
 
   //Get the flux scale that the ftmachines have if they have
   virtual void getCoverageImage(Int model, ImageInterface<Float>& im);
+
+
+
  protected:
 
+
+
   //Different versions of psf making
   void makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs);
   void makeMosaicPSF(PtrBlock<TempImage<Float> * >& psfs);
@@ -85,15 +101,16 @@ class LofarCubeSkyEquation : public SkyEquation {
   Block<Matrix<Float> >weightSlice_p;
   Slicer sl_p;
   Int nchanPerSlice_p;
-  // Type of copy 
+  // Type of copy
   // 0 => a independent image just with coordinates gotten from cImage
   // 1 => a subImage referencing cImage ...no image copy
-  void sliceCube(CountedPtr<ImageInterface<Complex> >& slice,Int model, Int cubeSlice, Int nCubeSlice, Int typeOfCopy=0); 
+  void sliceCube(CountedPtr<ImageInterface<Complex> >& slice,Int model, Int cubeSlice, Int nCubeSlice, Int typeOfCopy=0);
   void sliceCube(SubImage<Float>*& slice,ImageInterface<Float>& image, Int cubeSlice, Int nCubeSlice);
   //frequency range from image
   Bool getFreqRange(ROVisibilityIterator& vi, const CoordinateSystem& coords,
 		  Int slice, Int nslice);
 
+
  private:
   // if skyjones changed in get or put we need to tell put or get respectively
   // about it
@@ -101,6 +118,7 @@ class LofarCubeSkyEquation : public SkyEquation {
 
   Bool destroyVisibilityIterator_p;
 
+
   Bool internalChangesPut_p;
   Bool internalChangesGet_p;
   Bool firstOneChangesPut_p;
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachine.h b/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachine.h
index eac1048497a8e110de7e35af3c38f3eea650c697..ad54ac195d515c23a1b4004c81c5fe5e73b54fc5 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachine.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachine.h
@@ -48,6 +48,7 @@
 #include <lattices/Lattices/LatticeCache.h>
 #include <lattices/Lattices/ArrayLattice.h>
 
+#include <Common/OpenMP.h>
 
 using namespace casa;
 
@@ -144,13 +145,25 @@ public:
   LofarFTMachine(Long cachesize, Int tilesize,  CountedPtr<VisibilityResamplerBase>& visResampler, String convType, const MeasurementSet& ms,
                  Int nwPlanes,
                  MPosition mLocation, Float padding, Bool usezero,
-                 Bool useDoublePrec, double wmax, const String& beamPath,
+                 Bool useDoublePrec, double wmax,
                  Int verbose,
-		 Int maxsupport,
+                 Int maxsupport,
                  Int oversample,
                  const String& imageName,
                  const Matrix<Bool>& gridMuellerMask,
-                 const Matrix<Bool>& degridMuellerMask);
+                 const Matrix<Bool>& degridMuellerMask,
+		 Double RefFreq,
+		 Bool Use_Linear_Interp_Gridder,
+		 Bool Use_EJones,
+		 int StepApplyElement,
+		 Double PBCut,
+		 Bool PredictFT,
+		 String PsfOnDisk,
+		 Bool UseMasksDegrid,
+		 Bool ReallyDoPSF,
+                 const casa::Record& parameters
+                );//,
+		 //Double FillFactor);
 //  LofarFTMachine(Long cachesize, Int tilesize,  CountedPtr<VisibilityResamplerBase>& visResampler,String convType,
 //	 MDirection mTangent, Float padding=1.0, Bool usezero=True,
 //	 Bool useDoublePrec=False);
@@ -205,6 +218,8 @@ public:
   void put(const VisBuffer& vb, Int row=-1, Bool dopsf=False,
            FTMachine::Type type=FTMachine::OBSERVED);
 
+  mutable Matrix<Float> itsAvgPB;
+  Bool its_Use_Linear_Interp_Gridder;
 
   // Make the entire image
   void makeImage(FTMachine::Type type,
@@ -217,7 +232,7 @@ public:
   ImageInterface<Complex>& getImage(Matrix<Float>&, Bool normalize=True);
 
   // Get the average primary beam.
-  const Matrix<Float>& getAveragePB() const;
+  virtual const Matrix<Float>& getAveragePB() const;
 
   // Get the spheroidal cut.
   const Matrix<Float>& getSpheroidCut() const
@@ -242,7 +257,7 @@ public:
     // size is not done.  If sumWt is not provided, normalization by
     // the sum of weights is also not done.
     //
-  
+
 
 
     virtual void makeSensitivityImage(Lattice<Complex>&,
@@ -289,18 +304,33 @@ public:
   virtual void setNoPadding(Bool nopad){noPadding_p=nopad;};
 
   virtual String name();
-  virtual void setMiscInfo(const Int qualifier){(void)qualifier;};
+  //virtual void setMiscInfo(const Int qualifier){(void)qualifier;};
+
+  //Cyr: The FTMachine has got to know the order of the Taylor term
+  virtual void setMiscInfo(const Int qualifier){thisterm_p=qualifier;};
   virtual void ComputeResiduals(VisBuffer&vb, Bool useCorrected);
 
-    void makeConjPolMap(const VisBuffer& vb, const Vector<Int> cfPolMap, Vector<Int>& conjPolMap);
-    //    Vector<Int> makeConjPolMap(const VisBuffer& vb);
-    void makeCFPolMap(const VisBuffer& vb, const Vector<Int>& cfstokes, Vector<Int>& polM);
 
+  void makeConjPolMap(const VisBuffer& vb, const Vector<Int> cfPolMap, Vector<Int>& conjPolMap);
+  //    Vector<Int> makeConjPolMap(const VisBuffer& vb);
+  void makeCFPolMap(const VisBuffer& vb, const Vector<Int>& cfstokes, Vector<Int>& polM);
+
+  String itsNamePsfOnDisk;
+  void setPsfOnDisk(String NamePsf){itsNamePsfOnDisk=NamePsf;}
+  virtual String GiveNamePsfOnDisk(){return itsNamePsfOnDisk;}
+  
 
 protected:
   // Padding in FFT
   Float padding_p;
-
+  Int thisterm_p;
+  Double itsRefFreq;
+  Bool itsPredictFT;
+  Int itsTotalStepsGrid;
+  Int itsTotalStepsDeGrid;
+  Bool itsMasksAllDone;
+  Bool its_UseMasksDegrid;
+  //Float its_FillFactor;
   // Get the appropriate data pointer
   Array<Complex>* getDataPointer(const IPosition&, Bool);
 
@@ -322,6 +352,65 @@ protected:
   // Gridder
   ConvolveGridder<Double, Complex>* gridder;
 
+  //Sum Grids
+  void SumGridsOMP(Array<Complex>& grid, const Array<Complex>& GridToAdd){
+    int y,ch,pol,dChan,dPol,dx;
+    int GridSize(grid.shape()[0]);
+    int NPol(grid.shape()[2]);
+    int NChan(grid.shape()[3]);
+    Complex* gridPtr;
+    const Complex* GridToAddPtr;
+    
+#pragma omp parallel for private(y,ch,pol,gridPtr,GridToAddPtr)
+    for(int x=0 ; x<grid.shape()[0] ; ++x){
+      for(ch=0 ; ch<NChan ; ++ch){
+	for(pol=0 ; pol<NPol ; ++pol){
+	  gridPtr = grid.data() + ch*NPol*GridSize*GridSize + pol*GridSize*GridSize+x*GridSize;
+	  GridToAddPtr = GridToAdd.data() + ch*NPol*GridSize*GridSize + pol*GridSize*GridSize+x*GridSize;
+	  for(y=0 ; y<grid.shape()[1] ; ++y){
+	    (*gridPtr++) += *GridToAddPtr++;
+	    //gridPtr++;
+	    //GridToAddPtr++;
+	  }
+	}
+      }
+    }
+    
+  }
+
+  void SumGridsOMP(Array<Complex>& grid, const vector< Array<Complex> >& GridToAdd0 ){
+
+    for(uInt vv=0; vv<GridToAdd0.size();vv++){
+      Array<Complex> GridToAdd(GridToAdd0[vv]);
+      int y,ch,pol,dChan,dPol,dx;
+      int GridSize(grid.shape()[0]);
+      int NPol(grid.shape()[2]);
+      int NChan(grid.shape()[3]);
+      Complex* gridPtr;
+      const Complex* GridToAddPtr;
+      
+#pragma omp parallel for private(y,ch,pol,gridPtr,GridToAddPtr)
+      for(int x=0 ; x<grid.shape()[0] ; ++x){
+	for(ch=0 ; ch<NChan ; ++ch){
+	  for(pol=0 ; pol<NPol ; ++pol){
+	    gridPtr = grid.data() + ch*NPol*GridSize*GridSize + pol*GridSize*GridSize+x*GridSize;
+	    GridToAddPtr = GridToAdd.data() + ch*NPol*GridSize*GridSize + pol*GridSize*GridSize+x*GridSize;
+	    for(y=0 ; y<grid.shape()[1] ; ++y){
+	      (*gridPtr++) += *GridToAddPtr++;
+	      //gridPtr++;
+	      //GridToAddPtr++;
+	    }
+	  }
+	}
+      }
+    }
+
+  }
+
+  
+  
+
+
   // Is this tiled?
   Bool isTiled;
 
@@ -344,15 +433,18 @@ protected:
 
   // Arrays for non-tiled gridding (one per thread).
   vector< Array<Complex> >  itsGriddedData;
+  Array<Complex> its_stacked_GriddedData;
+
   vector< Array<DComplex> > itsGriddedData2;
   vector< Matrix<Complex> > itsSumPB;
   vector< Matrix<Double> >  itsSumWeight;
   vector< double > itsSumCFWeight;
+
+
   ///Array<Complex>  griddedData;
   ///Array<DComplex> griddedData2;
   ///Matrix<Complex> itsSumPB;
   ///double itsSumWeight;
-  mutable Matrix<Float> itsAvgPB;
 
   Int priorCacheSize;
 
@@ -385,17 +477,22 @@ protected:
 
   LofarVisResampler visResamplers_p;
 
+  casa::Record       itsParameters;
   casa::MeasurementSet itsMS;
   Int itsNWPlanes;
   double itsWMax;
+  Double its_PBCut;
   int itsNThread;
-
+  Bool its_Use_EJones;
+  Bool its_Apply_Element;
+  Bool its_Already_Initialized;
+  Bool                its_reallyDoPSF;
   CountedPtr<LofarConvolutionFunction> itsConvFunc;
   Vector<Int> ConjCFMap_p, CFMap_p;
-  String itsBeamPath;
   int itsVerbose;
   int itsMaxSupport;
   Int itsOversample;
+  Vector< Double >    itsListFreq;
   String itsImgName;
   Matrix<Bool> itsGridMuellerMask;
   Matrix<Bool> itsDegridMuellerMask;
@@ -403,12 +500,22 @@ protected:
   double itsDegriddingTime;
   double itsCFTime;
   PrecTimer itsTotalTimer;
+  PrecTimer itsCyrilTimer;
+
+  double itsNextApplyTime;
+  int itsCounterTimes;
+  int itsStepApplyElement;
+  double itsTStartObs;
+  double itsDeltaTime;
+  Array<Complex> itsTmpStackedGriddedData;
+  Array<Complex> itsGridToDegrid;
+
 
 
       template <class T>
         void store(const Cube<T> &data, const string &name)
         {
-          
+
           CoordinateSystem csys;
           Matrix<Double> xform(2, 2);
           xform = 0.0;
@@ -427,7 +534,7 @@ protected:
           stokes(3) = Stokes::YY;
           csys.addCoordinate(StokesCoordinate(stokes));
           csys.addCoordinate(SpectralCoordinate(casa::MFrequency::TOPO, 60e6, 0.0, 0.0, 60e6));
-          
+
           PagedImage<T> im(TiledShape(IPosition(4, data.shape()(0), data.shape()(1), 4, 1)), csys, name);
           im.putSlice(data, IPosition(4, 0, 0, 0, 0));
         }
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachineOld.h b/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachineOld.h
new file mode 100644
index 0000000000000000000000000000000000000000..61ad036b49a5efeae5bb7d7a46c68e4bc9e07bfc
--- /dev/null
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarFTMachineOld.h
@@ -0,0 +1,440 @@
+//# LofarFTMachineOld.h: Definition for LofarFTMachineOld
+//# Copyright (C) 1996,1997,1998,1999,2000,2002
+//# Associated Universities, Inc. Washington DC, USA.
+//#
+//# This library is free software; you can redistribute it and/or modify it
+//# under the terms of the GNU Library General Public License as published by
+//# the Free Software Foundation; either version 2 of the License, or (at your
+//# option) any later version.
+//#
+//# This library 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 Library General Public
+//# License for more details.
+//#
+//# You should have received a copy of the GNU Library General Public License
+//# along with this library; if not, write to the Free Software Foundation,
+//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
+//#
+//# Correspondence concerning AIPS++ should be adressed as follows:
+//#        Internet email: aips2-request@nrao.edu.
+//#        Postal address: AIPS++ Project Office
+//#                        National Radio Astronomy Observatory
+//#                        520 Edgemont Road
+//#                        Charlottesville, VA 22903-2475 USA
+//#
+//#
+//# $Id$
+
+#ifndef LOFARFT_LOFARFTMACHINEOLD_H
+#define LOFARFT_LOFARFTMACHINEOLD_H
+
+#include <synthesis/MeasurementComponents/FTMachine.h>
+#include <casa/OS/File.h>
+#include <casa/OS/PrecTimer.h>
+#include <LofarFT/LofarVisResamplerOld.h>
+#include <LofarFT/LofarConvolutionFunctionOld.h>
+#include <LofarFT/LofarCFStore.h>
+#include <casa/Arrays/Matrix.h>
+#include <scimath/Mathematics/FFTServer.h>
+#include <msvis/MSVis/VisBuffer.h>
+#include <images/Images/ImageInterface.h>
+#include <images/Images/ImageInterface.h>
+#include <casa/Containers/Block.h>
+#include <casa/Arrays/Array.h>
+#include <casa/Arrays/Vector.h>
+#include <casa/Arrays/Matrix.h>
+#include <scimath/Mathematics/ConvolveGridder.h>
+#include <lattices/Lattices/LatticeCache.h>
+#include <lattices/Lattices/ArrayLattice.h>
+
+
+using namespace casa;
+
+namespace LOFAR {
+
+class casa::UVWMachine;
+// <summary>  An FTMachine for Gridded Fourier transforms </summary>
+
+// <use visibility=export>
+
+// <reviewed reviewer="" date="" tests="" demos="">
+
+// <prerequisite>
+//   <li> <linkto class=FTMachine>FTMachine</linkto> module
+//   <li> <linkto class=SkyEquation>SkyEquation</linkto> module
+//   <li> <linkto class=VisBuffer>VisBuffer</linkto> module
+// </prerequisite>
+//
+// <etymology>
+// FTMachine is a Machine for Fourier Transforms. LofarFTMachine does
+// Grid-based Fourier transforms.
+// </etymology>
+//
+// <synopsis>
+// The <linkto class=SkyEquation>SkyEquation</linkto> needs to be able
+// to perform Fourier transforms on visibility data. LofarFTMachine
+// allows efficient Fourier Transform processing using a
+// <linkto class=VisBuffer>VisBuffer</linkto> which encapsulates
+// a chunk of visibility (typically all baselines for one time)
+// together with all the information needed for processing
+// (e.g. UVW coordinates).
+//
+// Gridding and degridding in LofarFTMachine are performed using a
+// novel sort-less algorithm. In this approach, the gridded plane is
+// divided into small patches, a cache of which is maintained in memory
+// using a general-purpose <linkto class=LatticeCache>LatticeCache</linkto> class. As the (time-sorted)
+// visibility data move around slowly in the Fourier plane, patches are
+// swapped in and out as necessary. Thus, optimally, one would keep at
+// least one patch per baseline.
+//
+// A grid cache is defined on construction. If the gridded uv plane is smaller
+// than this, it is kept entirely in memory and all gridding and
+// degridding is done entirely in memory. Otherwise a cache of tiles is
+// kept an paged in and out as necessary. Optimally the cache should be
+// big enough to hold all polarizations and frequencies for all
+// baselines. The paging rate will then be small. As the cache size is
+// reduced below this critical value, paging increases. The algorithm will
+// work for only one patch but it will be very slow!
+//
+// This scheme works well for arrays having a moderate number of
+// antennas since the saving in space goes as the ratio of
+// baselines to image size. For the ATCA, VLBA and WSRT, this ratio is
+// quite favorable. For the VLA, one requires images of greater than
+// about 200 pixels on a side to make it worthwhile.
+//
+// The FFT step is done plane by plane for images having less than
+// 1024 * 1024 pixels on each plane, and line by line otherwise.
+//
+// The gridding and degridding steps are implemented in Fortran
+// for speed. In gridding, the visibilities are added onto the
+// grid points in the neighborhood using a weighting function.
+// In degridding, the value is derived by a weight summ of the
+// same points, using the same weighting function.
+// </synopsis>
+//
+// <example>
+// See the example for <linkto class=SkyModel>SkyModel</linkto>.
+// </example>
+//
+// <motivation>
+// Define an interface to allow efficient processing of chunks of
+// visibility data
+// </motivation>
+//
+// <todo asof="97/10/01">
+// <ul> Deal with large VLA spectral line case
+// </todo>
+
+class LofarFTMachineOld : public casa::FTMachine {
+public:
+
+  // Constructor: cachesize is the size of the cache in words
+  // (e.g. a few million is a good number), tilesize is the
+  // size of the tile used in gridding (cannot be less than
+  // 12, 16 works in most cases), and convType is the type of
+  // gridding used (SF is prolate spheriodal wavefunction,
+  // and BOX is plain box-car summation). mLocation is
+  // the position to be used in some phase rotations. If
+  // mTangent is specified then the uvw rotation is done for
+  // that location iso the image center.
+  // <group>
+//  LofarFTMachineOld(Long cachesize, Int tilesize, CountedPtr<VisibilityResamplerBase>& visResampler,
+//	  String convType="SF", Float padding=1.0, Bool usezero=True, Bool useDoublePrec=False);
+  LofarFTMachineOld(Long cachesize, Int tilesize,  CountedPtr<VisibilityResamplerBase>& visResampler, String convType, const MeasurementSet& ms,
+                 Int nwPlanes,
+                 MPosition mLocation, Float padding, Bool usezero,
+                 Bool useDoublePrec, double wmax, const String& beamPath,
+                 Int verbose,
+		 Int maxsupport,
+                 Int oversample,
+                 const String& imageName,
+                 const Matrix<Bool>& gridMuellerMask,
+                 const Matrix<Bool>& degridMuellerMask);
+//  LofarFTMachineOld(Long cachesize, Int tilesize,  CountedPtr<VisibilityResamplerBase>& visResampler,String convType,
+//	 MDirection mTangent, Float padding=1.0, Bool usezero=True,
+//	 Bool useDoublePrec=False);
+//  LofarFTMachineOld(Long cachesize, Int tilesize,  CountedPtr<VisibilityResamplerBase>& visResampler,String convType,
+//	 MPosition mLocation, MDirection mTangent, Float passing=1.0,
+//	 Bool usezero=True, Bool useDoublePrec=False);
+  // </group>
+
+  // Construct from a Record containing the LofarFTMachineOld state
+//  LofarFTMachineOld(const RecordInterface& stateRec);
+
+  // Copy constructor
+  LofarFTMachineOld(const LofarFTMachineOld &other);
+
+  // Assignment operator
+  LofarFTMachineOld &operator=(const LofarFTMachineOld &other);
+
+  // Clone
+  LofarFTMachineOld* clone() const;
+
+
+  ~LofarFTMachineOld();
+
+  // Show the relative timings of the various steps.
+  void showTimings (std::ostream&, double duration) const;
+
+  // Initialize transform to Visibility plane using the image
+  // as a template. The image is loaded and Fourier transformed.
+  void initializeToVis(ImageInterface<Complex>& image,
+		       const VisBuffer& vb);
+
+  // Finalize transform to Visibility plane: flushes the image
+  // cache and shows statistics if it is being used.
+  void finalizeToVis();
+
+  // Initialize transform to Sky plane: initializes the image
+  void initializeToSky(ImageInterface<Complex>& image,  Matrix<Float>& weight,
+		       const VisBuffer& vb);
+
+
+  // Finalize transform to Sky plane: flushes the image
+  // cache and shows statistics if it is being used. DOES NOT
+  // DO THE FINAL TRANSFORM!
+  void finalizeToSky();
+
+
+  // Get actual coherence from grid by degridding
+  void get(VisBuffer& vb, Int row=-1);
+
+
+  // Put coherence to grid by gridding.
+  void put(const VisBuffer& vb, Int row=-1, Bool dopsf=False,
+           FTMachine::Type type=FTMachine::OBSERVED);
+
+
+  // Make the entire image
+  void makeImage(FTMachine::Type type,
+		 VisSet& vs,
+		 ImageInterface<Complex>& image,
+		 Matrix<Float>& weight);
+
+  // Get the final image: do the Fourier transform and
+  // grid-correct, then optionally normalize by the summed weights
+  ImageInterface<Complex>& getImage(Matrix<Float>&, Bool normalize=True);
+
+  // Get the average primary beam.
+  const Matrix<Float>& getAveragePB() const;
+
+  // Get the spheroidal cut.
+  const Matrix<Float>& getSpheroidCut() const
+    { return itsConvFunc->getSpheroidCut(); }
+
+
+  ///  virtual void normalizeImage(Lattice<Complex>& skyImage,
+  ///			      const Matrix<Double>& sumOfWts,
+  ///			      Lattice<Float>& sensitivityImage,
+  ///			      Bool fftNorm)
+  ///    {throw(AipsError("LofarFTMachineOld::normalizeImage() called"));}
+
+  void normalizeAvgPB();
+  void normalizeAvgPB(ImageInterface<Complex>& inImage,
+                      ImageInterface<Float>& outImage);
+    //
+    // Make a sensitivity image (sensitivityImage), given the gridded
+    // weights (wtImage).  These are related to each other by a
+    // Fourier transform and normalization by the sum-of-weights
+    // (sumWt) and normalization by the product of the 2D FFT size
+    // along each axis.  If doFFTNorm=False, normalization by the FFT
+    // size is not done.  If sumWt is not provided, normalization by
+    // the sum of weights is also not done.
+    //
+  
+
+
+    virtual void makeSensitivityImage(Lattice<Complex>&,
+				      ImageInterface<Float>&,
+				      const Matrix<Float>& =Matrix<Float>(),
+				      const Bool& =True) {}
+    virtual void makeSensitivityImage(const VisBuffer& vb, const ImageInterface<Complex>& imageTemplate,
+				      ImageInterface<Float>& sensitivityImage);
+
+    inline virtual Float pbFunc(const Float& a, const Float& limit)
+    {if (abs(a) >= limit) return (a);else return 1.0;};
+    inline virtual Complex pbFunc(const Complex& a, const Float& limit)
+    {if (abs(a)>=limit) return (a); else return Complex(1.0,0.0);};
+    //
+    // Given the sky image (Fourier transform of the visibilities),
+    // sum of weights and the sensitivity image, this method replaces
+    // the skyImage with the normalized image of the sky.
+    //
+    virtual void normalizeImage(Lattice<Complex>& skyImage,
+				const Matrix<Double>& sumOfWts,
+				Lattice<Float>& sensitivityImage,
+				Bool fftNorm=True);
+    virtual void normalizeImage(Lattice<Complex>& skyImage,
+				const Matrix<Double>& sumOfWts,
+				Lattice<Float>& sensitivityImage,
+				Lattice<Complex>& sensitivitySqImage,
+				Bool fftNorm=True);
+
+    virtual ImageInterface<Float>& getSensitivityImage() {return *avgPB_p;}
+    virtual Matrix<Double>& getSumOfWeights() {return sumWeight;};
+    virtual Matrix<Double>& getSumOfCFWeights() {return sumCFWeight;};
+
+  // Get the final weights image
+  void getWeightImage(ImageInterface<Float>&, Matrix<Float>&);
+
+  // Save and restore the LofarFTMachineOld to and from a record
+  virtual Bool toRecord(String& error, RecordInterface& outRec,
+			Bool withImage=False);
+  virtual Bool fromRecord(String& error, const RecordInterface& inRec);
+
+  // Can this FTMachine be represented by Fourier convolutions?
+  virtual Bool isFourier() {return True;}
+
+  virtual void setNoPadding(Bool nopad){noPadding_p=nopad;};
+
+  virtual String name();
+  virtual void setMiscInfo(const Int qualifier){(void)qualifier;};
+  virtual void ComputeResiduals(VisBuffer&vb, Bool useCorrected);
+
+    void makeConjPolMap(const VisBuffer& vb, const Vector<Int> cfPolMap, Vector<Int>& conjPolMap);
+    //    Vector<Int> makeConjPolMap(const VisBuffer& vb);
+    void makeCFPolMap(const VisBuffer& vb, const Vector<Int>& cfstokes, Vector<Int>& polM);
+
+
+protected:
+  // Padding in FFT
+  Float padding_p;
+
+  // Get the appropriate data pointer
+  Array<Complex>* getDataPointer(const IPosition&, Bool);
+
+  void ok();
+
+  void init();
+
+  // Is this record on Grid? check both ends. This assumes that the
+  // ends bracket the middle
+  Bool recordOnGrid(const VisBuffer& vb, Int rownr) const;
+
+  // Image cache
+  LatticeCache<Complex> * imageCache;
+
+  // Sizes
+  Long cachesize;
+  Int  tilesize;
+
+  // Gridder
+  ConvolveGridder<Double, Complex>* gridder;
+
+  // Is this tiled?
+  Bool isTiled;
+
+  // Array lattice
+  CountedPtr<Lattice<Complex> > arrayLattice;
+
+  // Lattice. For non-tiled gridding, this will point to arrayLattice,
+  //  whereas for tiled gridding, this points to the image
+  CountedPtr<Lattice<Complex> > lattice;
+
+  String convType;
+
+  Float maxAbsData;
+
+  // Useful IPositions
+  IPosition centerLoc, offsetLoc;
+
+  // Image Scaling and offset
+  Vector<Double> uvScale, uvOffset;
+
+  // Arrays for non-tiled gridding (one per thread).
+  vector< Array<Complex> >  itsGriddedData;
+  vector< Array<DComplex> > itsGriddedData2;
+  vector< Matrix<Complex> > itsSumPB;
+  vector< Matrix<Double> >  itsSumWeight;
+  vector< double > itsSumCFWeight;
+  ///Array<Complex>  griddedData;
+  ///Array<DComplex> griddedData2;
+  ///Matrix<Complex> itsSumPB;
+  ///double itsSumWeight;
+  mutable Matrix<Float> itsAvgPB;
+
+  Int priorCacheSize;
+
+  // Grid/degrid zero spacing points?
+
+  Bool usezero_p;
+
+  //force no padding
+  Bool noPadding_p;
+
+  //Check if using put that avoids non-necessary reads
+  Bool usePut2_p;
+
+  //machine name
+  String machineName_p;
+
+  // Shape of the padded image
+  IPosition padded_shape;
+
+  Int convSampling;
+    Float pbLimit_p;
+    Int sensitivityPatternQualifier_p;
+    String sensitivityPatternQualifierStr_p;
+    Vector<Float> pbPeaks;
+    Bool pbNormalized_p;
+    // The average PB for sky image normalization
+    //
+    CountedPtr<ImageInterface<Float> > avgPB_p;
+    CountedPtr<ImageInterface<Complex> > avgPBSq_p;
+
+  LofarVisResamplerOld visResamplers_p;
+
+  casa::MeasurementSet itsMS;
+  Int itsNWPlanes;
+  double itsWMax;
+  int itsNThread;
+
+  CountedPtr<LofarConvolutionFunctionOld> itsConvFunc;
+  Vector<Int> ConjCFMap_p, CFMap_p;
+  String itsBeamPath;
+  int itsVerbose;
+  int itsMaxSupport;
+  Int itsOversample;
+  String itsImgName;
+  Matrix<Bool> itsGridMuellerMask;
+  Matrix<Bool> itsDegridMuellerMask;
+  double itsGriddingTime;
+  double itsDegriddingTime;
+  double itsCFTime;
+  PrecTimer itsTotalTimer;
+
+
+      template <class T>
+        void store(const Cube<T> &data, const string &name)
+        {
+          
+          CoordinateSystem csys;
+          Matrix<Double> xform(2, 2);
+          xform = 0.0;
+          xform.diagonal() = 1.0;
+          Quantum<Double> incLon((8.0 / data.shape()(0)) * C::pi / 180.0, "rad");
+          Quantum<Double> incLat((8.0 / data.shape()(1)) * C::pi / 180.0, "rad");
+          Quantum<Double> refLatLon(45.0 * C::pi / 180.0, "rad");
+          csys.addCoordinate(DirectionCoordinate(MDirection::J2000, Projection(Projection::SIN),
+                             refLatLon, refLatLon, incLon, incLat,
+                             xform, data.shape()(0) / 2, data.shape()(1) / 2));
+
+          Vector<Int> stokes(4);
+          stokes(0) = Stokes::XX;
+          stokes(1) = Stokes::XY;
+          stokes(2) = Stokes::YX;
+          stokes(3) = Stokes::YY;
+          csys.addCoordinate(StokesCoordinate(stokes));
+          csys.addCoordinate(SpectralCoordinate(casa::MFrequency::TOPO, 60e6, 0.0, 0.0, 60e6));
+          
+          PagedImage<T> im(TiledShape(IPosition(4, data.shape()(0), data.shape()(1), 4, 1)), csys, name);
+          im.putSlice(data, IPosition(4, 0, 0, 0, 0));
+        }
+
+
+};
+
+} //# end namespace
+
+#endif
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarImager.h b/CEP/Imager/LofarFT/include/LofarFT/LofarImager.h
index 51a9da81974d9448918d112a1c9673dc537661c0..bb47a0ec822e151206aeeb962d524465af6af340 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarImager.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarImager.h
@@ -26,6 +26,7 @@
 #define LOFAR_LOFARFT_LOFARIMAGER_H
 
 #include <LofarFT/LofarFTMachine.h>
+#include <LofarFT/LofarFTMachineOld.h>
 #include <synthesis/MeasurementEquations/Imager.h>
 #include <casa/Containers/Record.h>
 
@@ -50,19 +51,20 @@ namespace LOFAR
 
     // Get the average primary beam.
     const Matrix<Float>& getAveragePB() const
-      { return itsMachine->getAveragePB(); }
+    { return itsMachine ? itsMachine->getAveragePB() : itsMachineOld->getAveragePB(); }
 
     // Get the spheroidal cut.
     const Matrix<Float>& getSpheroidCut() const
-      { return itsMachine->getSpheroidCut(); }
+    { return itsMachine ? itsMachine->getSpheroidCut() : itsMachineOld->getSpheroidCut(); }
 
     // Show the relative timings of the various steps.
     void showTimings (std::ostream&, double duration) const;
 
   private:
     //# Data members.
-    casa::Record    itsParameters;
-    LofarFTMachine* itsMachine;
+    casa::Record       itsParameters;
+    LofarFTMachine*    itsMachine;
+    LofarFTMachineOld* itsMachineOld;
   };
 
 } //# end namespace
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarVisResampler.h b/CEP/Imager/LofarFT/include/LofarFT/LofarVisResampler.h
index 49c7f0bbad33f6cf9ce0d436fe12c21e9d56ff18..9abc2078ec8ec8d4711045027691444385b52dca 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarVisResampler.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarVisResampler.h
@@ -110,6 +110,20 @@ namespace LOFAR { //# NAMESPACE CASA - BEGIN
                           const Bool& dopsf, LofarCFStore& cfs)
     {DataToGridImpl_p(griddedData, vbs, rows, rbeg, rend, sumwt,dopsf,cfs);}
 
+    void lofarDataToGrid_linear (Array<Complex>& griddedData, LofarVBStore& vbs,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+                          Matrix<Double>& sumwt,
+                          const Bool& dopsf, LofarCFStore& cfs)
+    {DataToGridImpl_linear_p(griddedData, vbs, rows, rbeg, rend, sumwt,dopsf,cfs);}
+    void lofarDataToGrid_linear (Array<DComplex>& griddedData, LofarVBStore& vbs,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+                          Matrix<Double>& sumwt,
+                          const Bool& dopsf, LofarCFStore& cfs)
+    {DataToGridImpl_linear_p(griddedData, vbs, rows, rbeg, rend, sumwt,dopsf,cfs);}
+
+
     void lofarGridToData(LofarVBStore& vbs,
                          const Array<Complex>& grid,
                          const Vector<uInt>& rows,
@@ -166,6 +180,13 @@ namespace LOFAR { //# NAMESPACE CASA - BEGIN
 			  Matrix<Double>& sumwt,const Bool& dopsf,
                           LofarCFStore& cfs);
 
+    template <class T>
+    void DataToGridImpl_linear_p(Array<T>& griddedData, LofarVBStore& vb,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+			  Matrix<Double>& sumwt,const Bool& dopsf,
+                          LofarCFStore& cfs);
+
 
     Vector<Int> cfMap_p, conjCFMap_p;
   };
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarVisResamplerOld.h b/CEP/Imager/LofarFT/include/LofarFT/LofarVisResamplerOld.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e59cf224803c0d665e21205492aca646666b677
--- /dev/null
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarVisResamplerOld.h
@@ -0,0 +1,173 @@
+//# LofarVisResamplerOld.h: Convolutional AW resampler for LOFAR data
+//# Copyright (C) 2011
+//# Associated Universities, Inc. Washington DC, USA.
+//#
+//# This library is free software; you can redistribute it and/or modify it
+//# under the terms of the GNU Library General Public License as published by
+//# the Free Software Foundation; either version 2 of the License, or (at your
+//# option) any later version.
+//#
+//# This library 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 Library General Public
+//# License for more details.
+//#
+//# You should have received a copy of the GNU Library General Public License
+//# along with this library; if not, write to the Free Software Foundation,
+//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
+//#
+//# Correspondence concerning AIPS++ should be addressed as follows:
+//#        Internet email: aips2-request@nrao.edu.
+//#        Postal address: AIPS++ Project Office
+//#                        National Radio Astronomy Observatory
+//#                        520 Edgemont Road
+//#                        Charlottesville, VA 22903-2475 USA
+//#
+//# $Id$
+
+#ifndef LOFARFT_LOFARVISRESAMPLEROLD_H
+#define LOFARFT_LOFARVISRESAMPLEROLD_H
+
+#include <synthesis/MeasurementComponents/AWVisResampler.h>
+#include <LofarFT/LofarCFStore.h>
+#include <LofarFT/LofarVBStore.h>
+//added
+#include <LofarFT/LofarCFStore.h>
+
+#include <casa/Logging/LogIO.h>
+#include <casa/Logging/LogOrigin.h>
+#include <casa/Arrays/Cube.h>
+#include <casa/Arrays/Matrix.h>
+#include <casa/Arrays/ArrayIter.h>
+#include <casa/Arrays/ArrayMath.h>
+#include <images/Images/PagedImage.h>
+#include <casa/Utilities/Assert.h>
+
+#include <coordinates/Coordinates/CoordinateSystem.h>
+#include <coordinates/Coordinates/SpectralCoordinate.h>
+#include <coordinates/Coordinates/StokesCoordinate.h>
+
+#include <ms/MeasurementSets/MeasurementSet.h>
+#include <measures/Measures/MDirection.h>
+#include <measures/Measures/MeasConvert.h>
+#include <measures/Measures/MCDirection.h>
+#include <measures/Measures/MCPosition.h>
+#include <ms/MeasurementSets/MSAntenna.h>
+#include <ms/MeasurementSets/MSAntennaParse.h>
+#include <ms/MeasurementSets/MSAntennaColumns.h>
+#include <ms/MeasurementSets/MSDataDescription.h>
+#include <ms/MeasurementSets/MSDataDescColumns.h>
+#include <ms/MeasurementSets/MSField.h>
+#include <ms/MeasurementSets/MSFieldColumns.h>
+#include <ms/MeasurementSets/MSObservation.h>
+#include <ms/MeasurementSets/MSObsColumns.h>
+#include <ms/MeasurementSets/MSPolarization.h>
+#include <ms/MeasurementSets/MSPolColumns.h>
+#include <ms/MeasurementSets/MSSpectralWindow.h>
+#include <ms/MeasurementSets/MSSpWindowColumns.h>
+#include <ms/MeasurementSets/MSSelection.h>
+#include <measures/Measures/MeasTable.h>
+
+#include <lattices/Lattices/ArrayLattice.h>
+#include <lattices/Lattices/LatticeFFT.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <casa/vector.h>
+#include <casa/OS/Directory.h>
+
+//=========
+
+using namespace casa;
+
+namespace LOFAR { //# NAMESPACE CASA - BEGIN
+
+  class LofarVisResamplerOld: public AWVisResampler
+  {
+  public:
+    LofarVisResamplerOld(): AWVisResampler()  {}
+    LofarVisResamplerOld(const CFStore& cfs): AWVisResampler(cfs)      {}
+    virtual ~LofarVisResamplerOld()                                    {}
+
+    virtual VisibilityResamplerBase* clone()
+    {return new LofarVisResamplerOld(*this);}
+
+    void copy(const LofarVisResamplerOld& other)
+    {AWVisResampler::copy(other); }
+
+    // Re-sample the griddedData on the VisBuffer (a.k.a gridding).
+    void lofarDataToGrid (Array<Complex>& griddedData, LofarVBStore& vbs,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+                          Matrix<Double>& sumwt,
+                          const Bool& dopsf, LofarCFStore& cfs)
+    {DataToGridImpl_p(griddedData, vbs, rows, rbeg, rend, sumwt,dopsf,cfs);}
+    void lofarDataToGrid (Array<DComplex>& griddedData, LofarVBStore& vbs,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+                          Matrix<Double>& sumwt,
+                          const Bool& dopsf, LofarCFStore& cfs)
+    {DataToGridImpl_p(griddedData, vbs, rows, rbeg, rend, sumwt,dopsf,cfs);}
+
+    void lofarGridToData(LofarVBStore& vbs,
+                         const Array<Complex>& grid,
+                         const Vector<uInt>& rows,
+                         Int rbeg, Int rend,
+                         LofarCFStore& cfs);
+
+
+    virtual void setCFMaps(const Vector<Int>& cfMap, const Vector<Int>& conjCFMap)
+    {cfMap_p.assign(cfMap); conjCFMap_p.assign(conjCFMap);}
+
+    void lofarComputeResiduals(LofarVBStore& vbs);
+
+  void sgrid(Vector<Double>& pos, Vector<Int>& loc,
+			     Vector<Int>& off, Complex& phasor,
+			     const Int& irow, const Matrix<Double>& uvw,
+			     const Double& dphase, const Double& freq,
+			     const Vector<Double>& scale,
+			     const Vector<Double>& offset,
+                                const Vector<Float>& sampling);
+
+    /*
+  template <class T>
+    void store2(const Matrix<T> &data, const string &name)
+    {
+      CoordinateSystem csys;
+
+      Matrix<Double> xform(2, 2);
+      xform = 0.0;
+      xform.diagonal() = 1.0;
+      Quantum<Double> incLon((8.0 / data.shape()(0)) * C::pi / 180.0, "rad");
+      Quantum<Double> incLat((8.0 / data.shape()(1)) * C::pi / 180.0, "rad");
+      Quantum<Double> refLatLon(45.0 * C::pi / 180.0, "rad");
+      csys.addCoordinate(DirectionCoordinate(MDirection::J2000, Projection(Projection::SIN),
+					     refLatLon, refLatLon, incLon, incLat,
+					     xform, data.shape()(0) / 2, data.shape()(1) / 2));
+
+      Vector<Int> stokes(1);
+      stokes(0) = Stokes::I;
+      csys.addCoordinate(StokesCoordinate(stokes));
+      csys.addCoordinate(SpectralCoordinate(casa::MFrequency::TOPO, 60e6, 0.0, 0.0, 60e6));
+
+      PagedImage<T> im(TiledShape(IPosition(4, data.shape()(0), data.shape()(1), 1, 1)), csys, name);
+      im.putSlice(data, IPosition(4, 0, 0, 0, 0));
+    };
+    */
+
+  private:
+    // Re-sample the griddedData on the VisBuffer (a.k.a de-gridding).
+    //
+    template <class T>
+    void DataToGridImpl_p(Array<T>& griddedData, LofarVBStore& vb,
+                          const Vector<uInt>& rows,
+                          Int rbeg, Int rend,
+			  Matrix<Double>& sumwt,const Bool& dopsf,
+                          LofarCFStore& cfs);
+
+
+    Vector<Int> cfMap_p, conjCFMap_p;
+  };
+
+} //# NAMESPACE CASA - END
+
+#endif //
diff --git a/CEP/Imager/LofarFT/include/LofarFT/LofarWTerm.h b/CEP/Imager/LofarFT/include/LofarFT/LofarWTerm.h
index d31aa137b983246566c7f04b893a1ed4964b6b8a..7253064ca58311360971494c0ec96f0eef5cdb0e 100644
--- a/CEP/Imager/LofarFT/include/LofarFT/LofarWTerm.h
+++ b/CEP/Imager/LofarFT/include/LofarFT/LofarWTerm.h
@@ -71,12 +71,12 @@ namespace LOFAR {
       if (m_scale == 0.0) {
         return 0;
       }
-
       w = abs(w);
       uint estimate = floor(sqrt(w / m_scale));
       return w > upper(estimate) ? estimate + 1 : estimate;
     }
 
+
   private:
     //# Data members.
     double m_scale;
diff --git a/CEP/Imager/LofarFT/src/CMakeLists.txt b/CEP/Imager/LofarFT/src/CMakeLists.txt
index cf3040123333305a73bb45640e135ecfc11d8c80..462d30cd5ddd87c01184e203637d5486abc24c00 100644
--- a/CEP/Imager/LofarFT/src/CMakeLists.txt
+++ b/CEP/Imager/LofarFT/src/CMakeLists.txt
@@ -6,13 +6,17 @@ lofar_add_library(lofarft
   Package__Version.cc
   FFTCMatrix.cc
   LofarATerm.cc
+  LofarATermOld.cc
   LofarConvolutionFunction.cc
+  LofarConvolutionFunctionOld.cc
   LofarImager.cc
   LofarCFStore.cc
   LofarFTMachine.cc
+  LofarFTMachineOld.cc
   LofarWTerm.cc
 #  LofarVisibilityResamplerBase.cc
   LofarVisResampler.cc
+  LofarVisResamplerOld.cc
   LofarCubeSkyEquation.cc
 )
 
diff --git a/CEP/Imager/LofarFT/src/LofarATerm.cc b/CEP/Imager/LofarFT/src/LofarATerm.cc
index 3c5ec0147eec390e60bfd129cae21f8981ae2d37..f6c27f4d17202527c13bf847962b06a752d1db09 100644
--- a/CEP/Imager/LofarFT/src/LofarATerm.cc
+++ b/CEP/Imager/LofarFT/src/LofarATerm.cc
@@ -22,1017 +22,855 @@
 
 #include <lofar_config.h>
 #include <LofarFT/LofarATerm.h>
+
 #include <Common/LofarLogger.h>
 #include <Common/Exception.h>
+#include <BBSKernel/MeasurementAIPS.h>
+#include <ElementResponse/ElementResponse.h>
 
-#include <casa/OS/Path.h>
 #include <casa/Arrays/ArrayIter.h>
 #include <casa/Arrays/Cube.h>
 #include <coordinates/Coordinates/DirectionCoordinate.h>
-#include <measures/Measures/MeasTable.h>
 #include <measures/Measures/MeasConvert.h>
 #include <measures/Measures/MCDirection.h>
 #include <measures/Measures/MCPosition.h>
-#include <ms/MeasurementSets/MeasurementSet.h>
-#include <ms/MeasurementSets/MSAntenna.h>
-#include <ms/MeasurementSets/MSAntennaParse.h>
-#include <ms/MeasurementSets/MSAntennaColumns.h>
-#include <ms/MeasurementSets/MSDataDescription.h>
-#include <ms/MeasurementSets/MSDataDescColumns.h>
-#include <ms/MeasurementSets/MSField.h>
-#include <ms/MeasurementSets/MSFieldColumns.h>
-#include <ms/MeasurementSets/MSObservation.h>
-#include <ms/MeasurementSets/MSObsColumns.h>
-#include <ms/MeasurementSets/MSPolarization.h>
-#include <ms/MeasurementSets/MSPolColumns.h>
-#include <ms/MeasurementSets/MSSpectralWindow.h>
-#include <ms/MeasurementSets/MSSpWindowColumns.h>
-#include <ms/MeasurementSets/MSSelection.h>
 #include <synthesis/MeasurementComponents/SynthesisError.h>
 
-// DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
-#include <iomanip>
-// DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
-
 using namespace casa;
 
 namespace LOFAR
 {
-  LofarATerm::LofarATerm(const MeasurementSet& ms,
-                         const String& beamElementPath)
-  {
-    if (beamElementPath.empty()) {
-      m_coeffLBA.load(Path("element_beam_HAMAKER_LBA.coeff"));
-      m_coeffHBA.load(Path("element_beam_HAMAKER_HBA.coeff"));
-    } else {
-      m_coeffLBA.load(Path(beamElementPath + "/element_beam_HAMAKER_LBA.coeff"));
-      m_coeffHBA.load(Path(beamElementPath + "/element_beam_HAMAKER_HBA.coeff"));
-    }
-     //    m_coeffLBA.load(Path("element_beam_LBA.coeff"));
-     //    m_coeffHBA.load(Path("element_beam_HBA.coeff"));
-
-    initInstrument(ms);
-    initReferenceFreq(ms, 0);
-    initReferenceDirections(ms, 0);
-  }
-
-  vector<Cube<Complex> > LofarATerm::evaluate(const IPosition &shape,
-    const DirectionCoordinate &coordinates,
-    uint station,
-    const MEpoch &epoch,
-    const Vector<Double> &freq,
-    bool normalize) const
-  {
-    AlwaysAssert(station < m_instrument.nStations(), SynthesisError);
-    AlwaysAssert(shape[0] > 0 && shape[1] > 0, SynthesisError);
-    AlwaysAssert(freq.size() > 0, SynthesisError);
-
-    // Create conversion engine (from J2000 -> ITRF).
-    MDirection::Convert convertor = MDirection::Convert(MDirection::J2000,
-      MDirection::Ref(MDirection::ITRF,
-      MeasFrame(epoch, m_instrument.position())));
-
-    MVDirection mvRefDelay = convertor(m_refDelay).getValue();
-    Vector3 refDelay = {{mvRefDelay(0), mvRefDelay(1), mvRefDelay(2)}};
-
-    MVDirection mvRefTile = convertor(m_refTile).getValue();
-    Vector3 refTile = {{mvRefTile(0), mvRefTile(1), mvRefTile(2)}};
-
-    // Compute ITRF map.
-    LOG_INFO("LofarATerm::evaluate(): Computing ITRF map...");
-    Cube<double> mapITRF = computeITRFMap(coordinates, shape, convertor);
-    LOG_INFO("LofarATerm::evaluate(): Computing ITRF map... done.");
 
-    // Compute element beam response.
-    LOG_INFO("LofarATerm::evaluate(): Computing station response...");
-    Array<DComplex> response =
-      evaluateStationBeam(m_instrument.station(station), refDelay, refTile,
-        mapITRF, freq);
-
-    // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
-//    MDirection world;
-//    Vector<double> refPixel = coordinates.referencePixel();
-
-//    cout << "shape: " << shape << " ref. pixel: " << refPixel << endl;
-//    coordinates.toWorld(world, refPixel);
-
-//    casa::Quantum<casa::Vector<casa::Double> > refAngles = world.getAngle();
-//    double ra = refAngles.getBaseValue()(0);
-//    double dec = refAngles.getBaseValue()(1);
-//    cout << "ref. world: " << std::setprecision(17) << ra << " " << dec << endl;
-
-//    cout << "station: " << station << endl;
-//    cout << "freq: " << std::setprecision(17) << freq << endl;
-//    cout << "time: " << std::setprecision(17) << epoch.getValue().getTime("s") << endl;
-//    IPosition st(4, refPixel(0), refPixel(1), 0, 0);
-//    IPosition en(4, refPixel(0), refPixel(1), 3, freq.size() - 1);
-//    Array<DComplex> tmpResponse = response(st, en).nonDegenerate();
-//    cout << "response shape: " << tmpResponse.shape() << endl;
-//    cout << "response: " << endl << tmpResponse << endl;
+namespace
+{
+  Array<DComplex> computeFieldArrayFactor(const BBS::Station::ConstPtr &station,
+    uint idField, const LofarATerm::ITRFDirectionMap &map,
+    const Vector<Double> &freq, const Vector<Double> &reference);
 
-//    refPixel = 0.0;
-//    coordinates.toWorld(world, refPixel);
-//    refAngles = world.getAngle();
-//    ra = refAngles.getBaseValue()(0);
-//    dec = refAngles.getBaseValue()(1);
-//    cout << "0 world: " << std::setprecision(17) << ra << " " << dec << endl;
+  Cube<DComplex>
+  computeTileArrayFactor(const BBS::AntennaField::ConstPtr &field,
+    const LofarATerm::ITRFDirectionMap &map, const Vector<Double> &freq);
 
-//    st = IPosition(4, 0, 0, 0, 0);
-//    en = IPosition(4, 0, 0, 3, freq.size() - 1);
-//    Array<DComplex> tmpResponse2 = response(st, en).nonDegenerate();
-//    cout << "response shape: " << tmpResponse2.shape() << endl;
-//    cout << "response: " << endl << tmpResponse2 << endl;
+  struct ElementLBA;
+  struct ElementHBA;
 
-//    AlwaysAssert(false, SynthesisError);
-    // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
+  template <typename T_ELEMENT>
+  Array<DComplex>
+  computeElementResponse(const BBS::AntennaField::ConstPtr &field,
+    const LofarATerm::ITRFDirectionMap &map, const Vector<Double> &freq);
 
+  void rescale(Array<DComplex> &response);
+  void rescale(Cube<DComplex> &response);
 
+  vector<Cube<Complex> > asVector(Array<DComplex> &response);
+  vector<Matrix<Complex> > asVector(Cube<DComplex> &response);
+}
 
-    //Cyril
-    if(normalize)
+  LofarATerm::LofarATerm(const MeasurementSet& ms, const casa::Record& parameters)
+  {
+    itsInstrument = BBS::readInstrument(ms);
+    itsRefDelay = MDirection::Convert(BBS::readDelayReference(ms),
+      MDirection::J2000)();
+    itsRefTile = MDirection::Convert(BBS::readTileReference(ms),
+      MDirection::J2000)();
+     itsDirectionCoordinates = 0;
+    itsParameters = parameters;
+    itsapplyIonosphere = False;
+    if (itsParameters.fieldNumber("applyIonosphere") > -1) itsapplyIonosphere = itsParameters.asBool("applyIonosphere");
+    cout << "Apply Ionosphere:" << itsapplyIonosphere << endl;
+    if (itsapplyIonosphere) 
     {
-     response = this->normalize(response);
+      String parmdbname = ms.tableName() + "/instrument";
+      cout << parmdbname << endl;
+      initParmDB(parmdbname);
+      cout << cal_pp_names << endl;
     }
-    LOG_INFO("LofarATerm::evaluate(): Computing station response... done.");
+  }
 
-    // Convert an Array<DComplex> to a vector<Cube<Complex> >.
-    vector<Cube<Complex> > tmp;
-    tmp.reserve(freq.size());
-    for (ArrayIterator<DComplex> iter(response, 3);
-         !iter.pastEnd(); iter.next())
+  void LofarATerm::initParmDB(const casa::String  &parmdbname)
+  {
+    this->pdb = new LOFAR::BBS::ParmFacade (parmdbname);
+    std::string prefix = "Piercepoint:X:";
+    std::vector<std::string> v = this->pdb->getNames(prefix + "*");
+    this->cal_pp_names = Vector<String>(v.size());
+    this->cal_pp = Matrix<Double>(3,v.size());
+    this->tec_white = Vector<Double>(v.size());
+    
+    //strip cal_pp_names from prefix
+    for (uint i=0; i<v.size(); i++) 
     {
-      Cube<Complex> planef(iter.array().shape());
-      convertArray (planef, iter.array());
-      tmp.push_back(planef);
+      this->cal_pp_names[i] = v[i].substr(prefix.length());
     }
-
-    // if(normalize)
-    //   MDirection::Convert convertor = MDirection::Convert(MDirection::J2000, MDirection::Ref(MDirection::ITRF, MeasFrame(epoch, m_instrument.position())));
-    // mapITRF = computeITRFMap(coordinates, shape, convertor);
-    // Cube<double> mapITRF_center;
-    // DirectionCoordinate coordinates_center(coordinates);
-    //   Vector<Double> Refpix(2,0.);
-    //   coordinates_center.setReferencePixel(Refpix);
-    //   mapITRF_center = computeITRFMap(coordinates_center, IPosition(2,1,1), convertor);
-    //   for(uInt i = 0; i < freq.size(); ++i){
-    // 	{
-    //   evaluateStationBeam(m_instrument.station(station), refDelay, refTile,
-    //     mapITRF, freq);
-    // 	  Cube<Complex> gain(evaluateStationBeam(mapITRF_center, convertor(m_phaseReference), m_instrument.station(station), freq[i]));
-    // 	  Matrix<Complex> central_gain(gain.xzPlane(0));
-    // 	  // central_gain.resize(2,2,true); //resize does not work:
-    // 	  // Central gain  Axis Lengths: [1, 4]  (NB: Matrix in Row/Column order)
-    // 	  //   [(-0.0235668,-0.000796029), (-0.0345345,-0.000373378), (0.030112,0.000938836), (-0.0268743,-0.000258621)]
-    // 	  // Central gain  Axis Lengths: [2, 2]  (NB: Matrix in Row/Column order)
-    // 	  //   [(-0.0235668,-0.000796029), (-0.0345345,-0.000373378)
-    // 	  //    (0,0), (0,0)]
-    // 	  Matrix<Complex> central_gain_reform(central_gain.reform(IPosition(2,2,2)));
-    // 	  Matrix<Complex> central_gain_invert(invert(central_gain_reform));
-
-    // 	  //Cube<Complex> IM=beams[i];
-    // 	  for(uInt ii=0;ii<shape[0];++ii)
-    // 	    {
-    // 	      for(uInt jj=0;jj<shape[1];++jj)
-    // 	  	{
-    // 	  	  Cube<Complex> pixel(tmp[i](IPosition(3,ii,jj,0),IPosition(3,ii,jj,3)).copy());
-    // 		  // cout<<"================="<<pixel<<endl;
-    // 		  // cout<<"pixel"<<pixel<<endl;
-    // 	  	  Matrix<Complex> pixel_reform(pixel.reform(IPosition(2,2,2)));
-    // 		  // cout<<"pixel_reform"<<pixel_reform<<endl;
-    // 	  	  Matrix<Complex> pixel_product=product(central_gain_invert,pixel_reform);
-    // 		  // cout<<"pixel_product"<<pixel_product<<endl;
-    // 		  Matrix<Complex> pixel_product_reform(pixel_product.reform(IPosition(2,1,4)));
-    // 		  // cout<<"pixel_product_reform"<<pixel_product_reform<<endl;
-
-    // 		  for(uInt ind=0;ind<4;++ind){tmp[i](ii,jj,ind)=pixel_product_reform(0,ind);};
-    // 		    //beams[i](IPosition(3,ii,jj,0),IPosition(3,ii,jj,3))=pixel_product;
-    // 					//IM(ii,jj)=pixel_product;
-    // 	  	}
-    // 	    }
-    // 	};
-
-    return tmp;
+    
   }
-
-  Array<DComplex> LofarATerm::normalize(const Array<DComplex> &response)
-    const
-  {
-    const uint nX = response.shape()[0];
-    const uint nY = response.shape()[1];
-    const uint nFreq = response.shape()[3];
-    AlwaysAssert(response.shape()[2] == 4, SynthesisError);
-    AlwaysAssert(nX > 0 && nY > 0 && nFreq > 0, SynthesisError);
-
-    // Cast away const, to be able to use Array<T>::operator(IPosition,
-    // IPosition) to extract a slice (for reading).
-    Array<DComplex> &__response = const_cast<Array<DComplex>&>(response);
-
-    // Extract beam response for the central pixel at the central frequency.
-    IPosition start(4, floor(nX / 2.), floor(nY / 2.), 0, floor(nFreq / 2.));
-    IPosition end(4, floor(nX / 2.), floor(nY / 2.), 3, floor(nFreq / 2.));
-
-    // Use assignment operator to force a copy.
-    Vector<DComplex> factor;
-    factor = __response(start, end).nonDegenerate();
-
-    // Compute the inverse of the reponse.
-    Vector<DComplex> inverse(4);
-    DComplex determinant = factor(0) * factor(3) - factor(1) * factor(2);
-    inverse(0) = factor(3) / determinant;
-    inverse(1) = -factor(1) / determinant;
-    inverse(2) = -factor(2) / determinant;
-    inverse(3) = factor(0) / determinant;
-
-    // Multiply the beam response for all pixels, at all frequencies, by the
-    // computed inverse.
-    Array<DComplex> XX = __response(IPosition(4, 0, 0, 0, 0),
-      IPosition(4, nX - 1, nY - 1, 0, nFreq - 1));
-    Array<DComplex> XY = __response(IPosition(4, 0, 0, 1, 0),
-      IPosition(4, nX - 1, nY - 1, 1, nFreq - 1));
-    Array<DComplex> YX = __response(IPosition(4, 0, 0, 2, 0),
-      IPosition(4, nX - 1, nY - 1, 2, nFreq - 1));
-    Array<DComplex> YY = __response(IPosition(4, 0, 0, 3, 0),
-      IPosition(4, nX - 1, nY - 1, 3, nFreq - 1));
-
-    Array<DComplex> normal(response.shape());
-    Array<DComplex> nXX = normal(IPosition(4, 0, 0, 0, 0),
-      IPosition(4, nX - 1, nY - 1, 0, nFreq - 1));
-    Array<DComplex> nXY = normal(IPosition(4, 0, 0, 1, 0),
-      IPosition(4, nX - 1, nY - 1, 1, nFreq - 1));
-    Array<DComplex> nYX = normal(IPosition(4, 0, 0, 2, 0),
-      IPosition(4, nX - 1, nY - 1, 2, nFreq - 1));
-    Array<DComplex> nYY = normal(IPosition(4, 0, 0, 3, 0),
-      IPosition(4, nX - 1, nY - 1, 3, nFreq - 1));
-
-    nXX = inverse(0) * XX + inverse(1) * YX;
-    nXY = inverse(0) * XY + inverse(1) * YY;
-    nYX = inverse(2) * XX + inverse(3) * YX;
-    nYY = inverse(2) * XY + inverse(3) * YY;
-
-    return normal;
+  
+  void LofarATerm::setDirection(const casa::DirectionCoordinate &coordinates, const IPosition &shape) {
+    itsDirectionCoordinates = &coordinates;
+    itsShape = &shape;
   }
-
-  Array<DComplex> LofarATerm::evaluateElementBeam(const BeamCoeff &coeff,
-    const AntennaField &field,
-    const Cube<double> &map,
-    const Vector<double> &freq) const
+  
+  
+  void LofarATerm::setEpoch( const MEpoch &epoch )
   {
-    const Vector3 &p = field.axis(AntennaField::P);
-    const Vector3 &q = field.axis(AntennaField::Q);
-    const Vector3 &r = field.axis(AntennaField::R);
-
-    const uint nX = map.shape()[1];
-    const uint nY = map.shape()[2];
-    const uint nFreq = freq.shape()[0];
-
-    Array<DComplex> beam(IPosition(4, nX, nY, 4, nFreq), DComplex(0.0, 0.0));
-    for(uint j = 0; j < nY; ++j)
+    if (this->itsDirectionCoordinates) itsITRFDirectionMap = makeDirectionMap(*itsDirectionCoordinates, *itsShape, epoch);    
+    if (this->itsapplyIonosphere) 
     {
-      for(uint i = 0; i < nX; ++i)
-      {
-        if(map(0, i, j) == 0.0 && map(1, i, j) == 0.0 && map(2, i, j) == 0.0)
-        {
-          // Non-physical pixel.
-          continue;
-        }
+      this->time = epoch.get(casa::Unit("s")).getValue();
+      this->r0 = get_parmvalue("r_0");
+      this->beta = get_parmvalue("beta");
+      this->height = get_parmvalue("height");
+      for(uint i = 0; i < this->cal_pp_names.size(); ++i) {
+        this->cal_pp(0, i) = get_parmvalue("Piercepoint:X:" + this->cal_pp_names(i));
+        this->cal_pp(1, i) = get_parmvalue("Piercepoint:Y:" + this->cal_pp_names(i));
+        this->cal_pp(2, i) = get_parmvalue("Piercepoint:Z:" + this->cal_pp_names(i));
+        this->tec_white(i) = get_parmvalue("TECfit_white:0:" + this->cal_pp_names(i));
+      }
+    }
+  }
+  
+  double LofarATerm::get_parmvalue( std::string parmname ) 
+  {
+    double freq = 50e6; // the ionospheric parameters are not frequency dependent, so just pick an arbitrary frequency
+                         // this frequency should be within the range specified in the parmdbname
+                         // this range is again quite arbitrary
+    casa::Record result = this->pdb->getValues (parmname, freq, freq+0.5, 1.0, this->time, this->time + 0.5, 1.0 );
+    casa::Array<double> parmvalues;
+    result.subRecord(parmname).get("values", parmvalues);
+    return parmvalues(IPosition(2,0,0));
+  }
+  
+  
+  LofarATerm::ITRFDirectionMap
+  LofarATerm::makeDirectionMap(const DirectionCoordinate &coordinates,
+    const IPosition &shape, const MEpoch &epoch) const
+  {
+    AlwaysAssert(shape[0] > 0 && shape[1] > 0, SynthesisError);
 
-        // Compute the P and Q coordinate of the direction vector by projecting
-        // onto the positive P and Q axis.
-        double projectionP = map(0, i, j) * p[0] + map(1, i, j) * p[1] + map(2, i, j) * p[2];
-        double projectionQ = map(0, i, j) * q[0] + map(1, i, j) * q[1] + map(2, i, j) * q[2];
+    ITRFDirectionMap map;
+    map.epoch = epoch;
 
-        // Compute the inner product between the antenna field normal
-        // (R) and the direction vector to get the sine of the elevation
-        // (cosine of the zenith angle).
-        double sinEl = map(0, i, j) * r[0] + map(1, i, j) * r[1] + map(2, i, j) * r[2];
+    // Create conversion engine J2000 -> ITRF at epoch.
+    MDirection::Convert convertor = MDirection::Convert(MDirection::J2000,
+      MDirection::Ref(MDirection::ITRF,
+      MeasFrame(epoch, itsInstrument->position())));
 
-        double az = atan2(projectionP, projectionQ);
-        double el = asin(sinEl);
+    MVDirection mvRefDelay = convertor(itsRefDelay).getValue();
+    map.refDelay[0] = mvRefDelay(0);
+    map.refDelay[1] = mvRefDelay(1);
+    map.refDelay[2] = mvRefDelay(2);
 
-        // Evaluate beam.
-        // Correct azimuth for dipole orientation.
-        const double phi = az - 3.0 * C::pi_4;
+    MVDirection mvRefTile = convertor(itsRefTile).getValue();
+    map.refTile[0] = mvRefTile(0);
+    map.refTile[1] = mvRefTile(1);
+    map.refTile[2] = mvRefTile(2);
 
-        // NB: The model is parameterized in terms of zenith angle. The
-        // appropriate conversion is taken care of below.
-        const double theta = C::pi_2 - el;
+    MDirection world;
+    casa::Vector<Double> pixel = coordinates.referencePixel();
 
-        // Only compute the beam response for directions above the horizon.
-        if(theta < C::pi_2)
+    Cube<Double> mapITRF(3, shape[0], shape[1], 0.0);
+    for(pixel[1] = 0.0; pixel(1) < shape[1]; ++pixel[1])
+    {
+      for(pixel[0] = 0.0; pixel[0] < shape[0]; ++pixel[0])
+      {
+        // CoodinateSystem::toWorld()
+        // DEC range [-pi/2,pi/2]
+        // RA range [-pi,pi]
+        if(coordinates.toWorld(world, pixel))
         {
-          for(uint k = 0; k < nFreq; ++k)
-          {
-            // J-jones matrix (2x2 complex matrix)
-            DComplex J[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
-
-            // NB: The model is parameterized in terms of a normalized
-            // frequency in the range [-1, 1]. The appropriate conversion is
-            // taken care of below.
-            const double normFreq = (freq[k] - coeff.center()) / coeff.width();
-
-            for(uint l = 0; l < coeff.nHarmonics(); ++l)
-            {
-              // Compute diagonal projection matrix P for the current
-              // harmonic.
-              DComplex P[2] = {0.0, 0.0};
-
-              DComplex inner[2];
-              for(int m = coeff.nPowerTheta() - 1; m >= 0; --m)
-              {
-                inner[0] = coeff(0, coeff.nPowerFreq() - 1, m, l);
-                inner[1] = coeff(1, coeff.nPowerFreq() - 1, m, l);
-
-                for(int n = coeff.nPowerFreq() - 2; n >= 0; --n)
-                {
-                  inner[0] = inner[0] * normFreq + coeff(0, n, m, l);
-                  inner[1] = inner[1] * normFreq + coeff(1, n, m, l);
-                }
-
-                P[0] = P[0] * theta + inner[0];
-                P[1] = P[1] * theta + inner[1];
-              }
-
-              // Compute Jones matrix for this harmonic by rotating P over
-              // kappa * phi and add it to the result.
-              const double kappa = ((l & 1) == 0 ? 1.0 : -1.0) * (2.0 * l + 1.0);
-              const double cphi = cos(kappa * phi);
-              const double sphi = sin(kappa * phi);
-
-              J[0][0] += cphi * P[0];
-              J[0][1] += -sphi * P[1];
-              J[1][0] += sphi * P[0];
-              J[1][1] += cphi * P[1];
-            }
-
-            beam(IPosition(4, i, j, 0, k)) = J[0][0];
-            beam(IPosition(4, i, j, 1, k)) = J[0][1];
-            beam(IPosition(4, i, j, 2, k)) = J[1][0];
-            beam(IPosition(4, i, j, 3, k)) = J[1][1];
-          }
+          MVDirection mvITRF = convertor(world).getValue();
+          mapITRF(0, pixel[0], pixel[1]) = mvITRF(0);
+          mapITRF(1, pixel[0], pixel[1]) = mvITRF(1);
+          mapITRF(2, pixel[0], pixel[1]) = mvITRF(2);
         }
       }
     }
 
-    return beam;
+    map.directions.reference(mapITRF);
+    return map;
   }
 
-  Array<DComplex> LofarATerm::evaluateStationBeam(const Station &station,
-    const Vector3 &refDelay,
-    const Vector3 &refTile,
-    const Cube<Double> &map,
-    const Vector<Double> &freq) const
+  vector<Cube<Complex> > LofarATerm::evaluate(uint idStation,
+    const Vector<Double> &freq,
+    const Vector<Double> &reference, bool normalize) const
   {
-    const uint nX = map.shape()[1];
-    const uint nY = map.shape()[2];
-    const uint nFreq = freq.shape()[0];
+    const ITRFDirectionMap &map = itsITRFDirectionMap;
+    AlwaysAssert(idStation < itsInstrument->nStations(), SynthesisError);
+    BBS::Station::ConstPtr station = itsInstrument->station(idStation);
+
+    const uint nX = map.directions.shape()[1];
+    const uint nY = map.directions.shape()[2];
+    const uint nFreq = freq.size();
 
-    uint countX = 0, countY = 0;
     Array<DComplex> E(IPosition(4, nX, nY, 4, nFreq), DComplex(0.0, 0.0));
-    for(uint i = 0; i < station.nField(); ++i)
+    for(uint i = 0; i < station->nField(); ++i)
     {
-      const AntennaField &field = station.field(i);
+      BBS::AntennaField::ConstPtr field = station->field(i);
 
       // Compute element beam.
-      LOG_INFO("LofarATerm::computeStationBeam: Computing element beam...");
-      Array<DComplex> beam;
-      if(field.isHBA())
+      Array<DComplex> element;
+      if(field->isHBA())
       {
-        beam = evaluateElementBeam(m_coeffHBA, field, map, freq);
+        element.reference(computeElementResponse<ElementHBA>(field, map, freq));
       }
       else
       {
-        beam = evaluateElementBeam(m_coeffLBA, field, map, freq);
+        element.reference(computeElementResponse<ElementLBA>(field, map, freq));
       }
-      LOG_INFO("LofarATerm::computeStationBeam: Computing element beam... done.");
 
-      if(field.isHBA())
+      // Compute antenna field array factor.
+      Array<DComplex> fieldAF = computeFieldArrayFactor(station, i, map, freq,
+        reference);
+
+      // Multiply the element or tile response by the antenna field array
+      // factor.
+      for(uint j = 0; j < 2; ++j)
       {
-        // Compute tile array factor.
-        LOG_INFO("LofarATerm::computeStationBeam: Computing tile array factor...");
-        Cube<DComplex> tileAF = evaluateTileArrayFactor(field, refTile, map,
-          freq);
-        LOG_INFO("LofarATerm::computeStationBeam: Computing tile array factor... done.");
+        IPosition start(4, 0, 0, j, 0);
+        IPosition end(4, nX - 1, nY - 1, j, nFreq - 1);
+        Array<DComplex> slice = E(start, end);
 
-        Array<DComplex> tileAF4 = tileAF.reform(IPosition(4, nX, nY, 1, nFreq));
+        IPosition startAF(4, 0, 0, 0, 0);
+        IPosition endAF(4, nX - 1, nY - 1, 0, nFreq - 1);
+        slice += fieldAF(startAF, endAF) * element(start, end);
+      }
 
-        // Multiply the element beam by the tile array factor.
-        for(uint j = 0; j < 4; ++j)
-        {
-          IPosition start(4, 0, 0, j, 0);
-          IPosition end(4, nX - 1, nY - 1, j, nFreq - 1);
+      for(uint j = 2; j < 4; ++j)
+      {
+        IPosition startAF(4, 0, 0, 1, 0);
+        IPosition endAF(4, nX - 1, nY - 1, 1, nFreq - 1);
 
-          Array<DComplex> plane = beam(start, end);
-          plane *= tileAF4;
-        }
+        IPosition start(4, 0, 0, j, 0);
+        IPosition end(4, nX - 1, nY - 1, j, nFreq - 1);
+        Array<DComplex> slice = E(start, end);
+        slice += fieldAF(startAF, endAF) * element(start, end);
       }
+    }
 
-      LOG_INFO("LofarATerm::computeStationBeam: Computing station array factor...");
+    if(normalize)
+    {
+      rescale(E);
+    }
 
-      // Account for the case where the delay reference position is not equal to
-      // the field center (only applies to core HBA fields).
-      const Vector3 &fieldCenter = field.position();
-      MVPosition delayCenter = station.position().getValue();
-      Vector3 offsetShift = {{fieldCenter[0] - delayCenter(0),
-                              fieldCenter[1] - delayCenter(1),
-                              fieldCenter[2] - delayCenter(2)}};
+    return asVector(E);
+  }
 
-      // Compute field array factors.
-      Cube<DComplex> fieldAFX(nX, nY, nFreq, DComplex(0.0, 0.0));
-      Cube<DComplex> fieldAFY(nX, nY, nFreq, DComplex(0.0, 0.0));
-      Cube<DComplex> phase(nX, nY, nFreq, DComplex(0.0, 0.0));
+  vector<Matrix<Complex> > LofarATerm::evaluateArrayFactor(uint idStation,
+    uint idPolarization,
+    const Vector<Double> &freq, const Vector<Double> &reference, bool normalize)
+    const
+  {
+    AlwaysAssert(idStation < itsInstrument->nStations(), SynthesisError);
+    AlwaysAssert(idPolarization  < 2, SynthesisError);
 
-      for(uint j = 0; j < field.nElement(); ++j)
-      {
-        const AntennaField::Element &element = field.element(j);
-        if(element.flag[0] && element.flag[1])
-        {
-          continue;
-        }
+    const ITRFDirectionMap &map = itsITRFDirectionMap;
+    BBS::Station::ConstPtr station = itsInstrument->station(idStation);
+    Array<DComplex> AF = computeFieldArrayFactor(station, 0, map, freq,
+      reference);
 
-        // Compute the offset relative to the delay center.
-        Vector3 offset = {{element.offset[0] + offsetShift[0],
-                           element.offset[1] + offsetShift[1],
-                           element.offset[2] + offsetShift[2]}};
+    if(station->nField() > 1)
+    {
+      AF += computeFieldArrayFactor(station, 1, map, freq, reference);
+    }
 
-        // Compute the delay for a plane wave approaching from the delay
-        // reference direction with respect to the element position.
-        double delay0 = (refDelay[0] * offset[0] + refDelay[1] * offset[1]
-          + refDelay[2] * offset[2]) / casa::C::c;
-        double shift0 = C::_2pi * m_refFreq * delay0;
+    const uint nX = AF.shape()[0];
+    const uint nY = AF.shape()[1];
+    const uint nFreq = AF.shape()[3];
 
-        for(uint y = 0; y < nY; ++y)
-        {
-          for(uint x = 0; x < nX; ++x)
-          {
-            // Compute the delay for a plane wave approaching from the direction
-            // of interest with respect to the element position.
-            double delay = (map(0, x, y) * offset[0]
-                            + map(1, x, y) * offset[1]
-                            + map(2, x, y) * offset[2]) / casa::C::c;
-
-            for(uint k = 0; k < nFreq; ++k)
-            {
-              double shift = C::_2pi * freq[k] * delay - shift0;
-              phase(x, y, k) = DComplex(cos(shift), sin(shift));
-            }
-          }
-        }
+    IPosition start(4, 0, 0, idPolarization, 0);
+    IPosition end(4, nX - 1, nY - 1, idPolarization, nFreq - 1);
+    Cube<DComplex> slice = AF(start, end).reform(IPosition(3, nX, nY, nFreq));
 
-        if(!element.flag[0])
-        {
-          fieldAFX += phase;
-          ++countX;
-        }
+    if(normalize)
+    {
+      rescale(slice);
+    }
 
-        if(!element.flag[1])
-        {
-          fieldAFY += phase;
-          ++countY;
-        }
-      }
+    return asVector(slice);
+  }
 
-      LOG_INFO("LofarATerm::computeStationBeam: Computing station array factor... done.");
-      Array<DComplex> fieldAFX4 = fieldAFX.reform(IPosition(4, nX, nY, 1, nFreq));
-      for(uint k = 0; k < 2; ++k)
-      {
-        IPosition start(4, 0, 0, k, 0);
-        IPosition end(4, nX - 1, nY - 1, k, nFreq - 1);
-        Array<DComplex> plane = E(start, end);
-        plane += fieldAFX4 * beam(start, end);
-      }
+  vector<Cube<Complex> > LofarATerm::evaluateElementResponse(uint idStation,
+    uint idField, const Vector<Double> &freq,
+    bool normalize) const
+  {
+    AlwaysAssert(idStation < itsInstrument->nStations(), SynthesisError);
 
-      Array<DComplex> fieldAFY4 = fieldAFY.reform(IPosition(4, nX, nY, 1, nFreq));
-      for(uint k = 2; k < 4; ++k)
-      {
-        IPosition start(4, 0, 0, k, 0);
-        IPosition end(4, nX - 1, nY - 1, k, nFreq - 1);
-        Array<DComplex> plane = E(start, end);
-        plane += fieldAFY4 * beam(start, end);
-      }
-    } // fields
+    const ITRFDirectionMap &map = itsITRFDirectionMap;
+    BBS::AntennaField::ConstPtr field =
+      itsInstrument->station(idStation)->field(idField);
 
-    // Normalize.
-    if(countX > 0)
+    Array<DComplex> response;
+    if(field->isHBA())
     {
-      IPosition start(4, 0, 0, 0, 0);
-      IPosition end(4, nX - 1, nY - 1, 1, nFreq - 1);
-      Array<DComplex> plane = E(start, end);
-      plane /= static_cast<Double>(countX);
+      response.reference(computeElementResponse<ElementHBA>(field, map, freq));
+    }
+    else
+    {
+      response.reference(computeElementResponse<ElementLBA>(field, map, freq));
     }
 
-    if(countY > 0)
+    if(normalize)
     {
-      IPosition start(4, 0, 0, 2, 0);
-      IPosition end(4, nX - 1, nY - 1, 3, nFreq - 1);
-      Array<DComplex> plane = E(start, end);
-      plane /= static_cast<Double>(countY);
+      rescale(response);
     }
 
-    return E;
+    return asVector(response);
   }
 
-  Cube<DComplex> LofarATerm::evaluateTileArrayFactor(const AntennaField &field,
-    const Vector3 &reference,
-    const Cube<Double> &map,
-    const Vector<Double> &freq) const
+  vector<Cube<Complex> > LofarATerm::evaluateIonosphere(
+    uint station,
+    const Vector<Double> &freq,
+    bool normalize)
   {
-    const uint nX = map.shape()[1];
-    const uint nY = map.shape()[2];
-    const uint nFreq = freq.shape()[0];
+    const ITRFDirectionMap &map = itsITRFDirectionMap;
+
+//    AlwaysAssert(station < this->instrument.nStations(), SynthesisError);
+//    AlwaysAssert(shape[0] > 0 && shape[1] > 0, SynthesisError);
+//    AlwaysAssert(freq.size() > 0, SynthesisError);
+
+    // Create conversion engine (from J2000 -> ITRF).
 
-    Cube<DComplex> factor(nX, nY, nFreq, DComplex(0.0, 0.0));
-    for(uint y = 0; y < nY; ++y)
+    const uint nX = map.directions.shape()[1];
+    const uint nY = map.directions.shape()[2];
+    
+    const uint nFreq = freq.size();
+    
+    const casa::MVPosition p = this->itsInstrument->station(station)->position().getValue();
+    
+    const double earth_ellipsoid_a = 6378137.0;
+    const double earth_ellipsoid_a2 = earth_ellipsoid_a*earth_ellipsoid_a;
+    const double earth_ellipsoid_b = 6356752.3142;
+    const double earth_ellipsoid_b2 = earth_ellipsoid_b*earth_ellipsoid_b;
+    const double earth_ellipsoid_e2 = (earth_ellipsoid_a2 - earth_ellipsoid_b2) / earth_ellipsoid_a2;
+ 
+    const double ion_ellipsoid_a = earth_ellipsoid_a + height;
+    const double ion_ellipsoid_a2_inv = 1.0 / (ion_ellipsoid_a * ion_ellipsoid_a);
+    const double ion_ellipsoid_b = earth_ellipsoid_b + height;
+    const double ion_ellipsoid_b2_inv = 1.0 / (ion_ellipsoid_b * ion_ellipsoid_b);
+
+
+    double x = p(0)/ion_ellipsoid_a;
+    double y = p(1)/ion_ellipsoid_a;
+    double z = p(2)/ion_ellipsoid_b;
+    double c = x*x + y*y + z*z - 1.0;
+    
+    casa::Cube<double> piercepoints(4, nX, nY, 0.0);
+   
+    #pragma omp parallel
     {
-      for(uint x = 0; x < nX; ++x)
+    #pragma omp for
+    for(uint i = 0 ; i < nX; ++i) 
+    {
+      for(uint j = 0 ; j < nY; ++j) 
       {
-        // Instead of computing a phase shift for the pointing direction and a
-        // phase shift for the direction of interest and then computing the
-        // difference, compute the resultant phase shift in one go. Here we make
-        // use of the relation a . b + a . c = a . (b + c). The sign of k is
-        // related to the sign of the phase shift.
-        double k[3];
-        k[0] = map(0, x, y) - reference[0];
-        k[1] = map(1, x, y) - reference[1];
-        k[2] = map(2, x, y) - reference[2];
+        double dx = map.directions(0,i,j) / ion_ellipsoid_a;
+        double dy = map.directions(1,i,j) / ion_ellipsoid_a;
+        double dz = map.directions(2,i,j) / ion_ellipsoid_b;
+        double a = dx*dx + dy*dy + dz*dz;
+        double b = x*dx + y*dy  + z*dz;
+        double alpha = (-b + std::sqrt(b*b - a*c))/a;
+        piercepoints(0, i, j) = p(0) + alpha*map.directions(0,i,j);
+        piercepoints(1, i, j) = p(1) + alpha*map.directions(1,i,j);
+        piercepoints(2, i, j) = p(2) + alpha*map.directions(2,i,j);
+        double normal_x = piercepoints(0, i, j) * ion_ellipsoid_a2_inv;
+        double normal_y = piercepoints(1, i, j) * ion_ellipsoid_a2_inv;
+        double normal_z = piercepoints(2, i, j) * ion_ellipsoid_b2_inv;
+        double norm_normal2 = normal_x*normal_x + normal_y*normal_y + normal_z*normal_z;
+        double norm_normal = std::sqrt(norm_normal2);
+        double sin_lat2 = normal_z*normal_z / norm_normal2;
+//         double cos_za = (mapITRF(0,i,j)*normal_x + mapITRF(1,i,j)*normal_y + mapITRF(2,i,j)*normal_z) / norm_normal;
+//         piercepoints(3, i, j) = cos_za;
+
+//        casa::MPosition p1(casa::MVPosition(piercepoints(0, i, j), piercepoints(1, i, j), piercepoints(2, i, j)),casa::MPosition::ITRF);
+//        positionWGS84 = casa::MPosition::Convert(p1, casa::MPosition::WGS84)();
+//        piercepoints(2, i, j) = positionWGS84.getValue().getLength().getValue()-height;
+
+        double g = 1.0 - earth_ellipsoid_e2*sin_lat2;
+        double sqrt_g = std::sqrt(g);
+
+        double M = earth_ellipsoid_b2 / ( earth_ellipsoid_a * g * sqrt_g );
+        double N = earth_ellipsoid_a / sqrt_g;
+
+        double local_ion_ellipsoid_e2 = (M-N) / ((M+height)*sin_lat2 - N - height);
+        double local_ion_ellipsoid_a = (N+height) * std::sqrt(1.0 - local_ion_ellipsoid_e2*sin_lat2);
+        double local_ion_ellipsoid_b = local_ion_ellipsoid_a*std::sqrt(1.0 - local_ion_ellipsoid_e2);
+
+        double z_offset = ((1.0-earth_ellipsoid_e2)*N + height - (1.0-local_ion_ellipsoid_e2)*(N+height)) * std::sqrt(sin_lat2);
+
+        double x1 = p(0)/local_ion_ellipsoid_a;
+        double y1 = p(1)/local_ion_ellipsoid_a;
+        double z1 = (p(2)-z_offset)/local_ion_ellipsoid_b;
+        double c1 = x1*x1 + y1*y1 + z1*z1 - 1.0;
+
+        dx = map.directions(0,i,j) / local_ion_ellipsoid_a;
+        dy = map.directions(1,i,j) / local_ion_ellipsoid_a;
+        dz = map.directions(2,i,j) / local_ion_ellipsoid_b;
+        a = dx*dx + dy*dy + dz*dz;
+        b = x1*dx + y1*dy  + z1*dz;
+        alpha = (-b + std::sqrt(b*b - a*c1))/a;
+
+        piercepoints(0, i, j) = p(0) + alpha*map.directions(0,i,j);
+        piercepoints(1, i, j) = p(1) + alpha*map.directions(1,i,j);
+        piercepoints(2, i, j) = p(2) + alpha*map.directions(2,i,j);
+        normal_x = piercepoints(0, i, j) / (local_ion_ellipsoid_a * local_ion_ellipsoid_a);
+        normal_y = piercepoints(1, i, j) / (local_ion_ellipsoid_a * local_ion_ellipsoid_a);
+        normal_z = (piercepoints(2, i, j)-z_offset) / (local_ion_ellipsoid_b * local_ion_ellipsoid_b);
+        norm_normal2 = normal_x*normal_x + normal_y*normal_y + normal_z*normal_z;
+        norm_normal = std::sqrt(norm_normal2);
+        double cos_za_rec = norm_normal / (map.directions(0,i,j)*normal_x + map.directions(1,i,j)*normal_y + map.directions(2,i,j)*normal_z);
+        piercepoints(3, i, j) = cos_za_rec;
+
+//         p1 = casa::MPosition(casa::MVPosition(piercepoints(0, i, j), piercepoints(1, i, j), piercepoints(2, i, j)),casa::MPosition::ITRF);
+//        positionWGS84 = casa::MPosition::Convert(p1, casa::MPosition::WGS84)();
+//        piercepoints(0, i, j) = positionWGS84.getValue().getLength().getValue()-height;
+//        cout << positionWGS84.getValue().getLength().getValue()-height << endl;
 
-        for(uint j = 0; j < field.nTileElement(); ++j)
+      }
+    }
+    }  
+    Matrix<Double> tec(nX, nY, 0.0);
+    
+    Double r0sqr = r0 * r0;
+    Double beta_2 = 0.5 * beta;
+    #pragma omp parallel
+    {
+    #pragma omp for
+    for(uint i = 0 ; i < nX; ++i) 
+    {
+      for(uint j = 0 ; j < nY; ++j) 
+      {
+        for(uint k = 0 ; k < cal_pp_names.size(); ++k) 
         {
-          // Compute the effective delay for a plane wave approaching from the
-          // direction of interest with respect to the position of element i
-          // when beam forming in the reference direction using time delays.
-          const Vector3 &offset = field.tileElement(j);
-          double delay = (k[0] * offset[0] + k[1] * offset[1] + k[2] * offset[2])
-            / C::c;
-
-          // Turn the delay into a phase shift.
-          for(uint k = 0; k < nFreq; ++k)
-          {
-            double shift = C::_2pi * freq[k] * delay;
-            factor(x, y, k) += DComplex(cos(shift), sin(shift));
-          }
+          Double dx = cal_pp(0, k) - piercepoints(0,i,j);
+          Double dy = cal_pp(1, k) - piercepoints(1,i,j);
+          Double dz = cal_pp(2, k) - piercepoints(2,i,j);
+          Double weight = pow((dx * dx + dy * dy + dz * dz) / r0sqr, beta_2);
+          tec(i,j) += weight * tec_white(k);
         }
+        tec(i,j) *= (-0.5 * piercepoints(3,i,j));
       }
     }
-
-    // Normalize.
-    if(field.nTileElement() > 0)
-    {
-      factor /= static_cast<Double>(field.nTileElement());
     }
 
-    return factor;
-  }
-
-  Cube<double> LofarATerm::computeITRFMap(const DirectionCoordinate &coordinates,
-    const IPosition &shape,
-    MDirection::Convert convertor) const
-  {
-    MDirection world;
-    Vector<double> pixel = coordinates.referencePixel();
+    // Convert an Array<DComplex> to a vector<Cube<Complex> >.
 
-    Cube<double> map(3, shape[0], shape[1], 0.0);
-    for(pixel[1] = 0.0; pixel(1) < shape[1]; ++pixel[1])
+    vector<Cube<Complex> > tmp;
+//    cout << "freq: " << freq[0] << endl;
+    tmp.reserve(nFreq);
+    for (uint i = 0; i < freq.size(); ++i)
+    {
+      Double a = (8.44797245e9 / freq[i]);
+      Cube<Complex> planef(IPosition(3, nX, nY, 4), Complex(0.0, 0.0));
+      for(uint j = 0 ; j < nX; ++j) 
       {
-        for(pixel[0] = 0.0; pixel[0] < shape[0]; ++pixel[0])
-          {
-            // CoodinateSystem::toWorld()
-            // DEC range [-pi/2,pi/2]
-            // RA range [-pi,pi]
-            if(coordinates.toWorld(world, pixel))
-              {
-                MVDirection mvITRF(convertor(world).getValue());
-                map(0, pixel[0], pixel[1]) = mvITRF(0);
-                map(1, pixel[0], pixel[1]) = mvITRF(1);
-                map(2, pixel[0], pixel[1]) = mvITRF(2);
-              }
-          }
+        for(uint k = 0 ; k < nY; ++k) 
+        {
+          Double phase = -tec(j,k) * a;
+          Complex phasor(cos(phase), sin(phase));
+          planef(j,k, 0) = phasor;
+          planef(j,k, 3) = phasor;
+        }
       }
-
-    return map;
+//      cout << planef << endl;
+      tmp.push_back(planef);
+    }
+    return tmp;
   }
-
-  void LofarATerm::initInstrument(const MeasurementSet &ms)
+  
+  
+namespace
+{
+  vector<Cube<Complex> > asVector(Array<DComplex> &response)
   {
-    // Get station names and positions in ITRF coordinates.
-    ROMSAntennaColumns antenna(ms.antenna());
-    ROMSObservationColumns observation(ms.observation());
-    ASSERT(observation.nrow() > 0);
-    ASSERT(!observation.flagRow()(0));
-
-    // Get instrument name.
-    String name = observation.telescopeName()(0);
-
-    // Get station positions.
-    MVPosition centroid;
-    vector<Station> stations(antenna.nrow());
-    for(uint i = 0; i < stations.size(); ++i)
-      {
-        // Get station name and ITRF position.
-        MPosition position =
-          MPosition::Convert(antenna.positionMeas()(i),
-                             MPosition::ITRF)();
-
-        // Store station information.
-        stations[i] = initStation(ms, i, antenna.name()(i), position);
-
-        ASSERT(stations[i].nField() > 0);
-
-        // Update ITRF centroid.
-        centroid += position.getValue();
-      }
-
-    // Get the instrument position in ITRF coordinates, or use the centroid
-    // of the station positions if the instrument position is unknown.
-    MPosition position;
-    if(MeasTable::Observatory(position, name))
-      {
-        position = MPosition::Convert(position, MPosition::ITRF)();
-      }
-    else
-      {
-        LOG_INFO("LofarATerm initInstrument "
-                 "Instrument position unknown; will use centroid of stations.");
-        ASSERT(antenna.nrow() != 0);
-        centroid *= 1.0 / static_cast<double>(antenna.nrow());
-        position = MPosition(centroid, MPosition::ITRF);
-      }
+    vector<Cube<Complex> > result;
+    for(ArrayIterator<DComplex> it(response, 3); !it.pastEnd(); it.next())
+    {
+      Cube<Complex> slice(it.array().shape());
+      convertArray(slice, it.array());
+      result.push_back(slice);
+    }
 
-    m_instrument = Instrument(name, position, stations.begin(), stations.end());
+    return result;
   }
 
-  Station LofarATerm::initStation(const MeasurementSet &ms,
-    uint id,
-    const String &name,
-    const MPosition &position) const
+  vector<Matrix<Complex> > asVector(Cube<DComplex> &response)
   {
-    AlwaysAssert(ms.keywordSet().isDefined("LOFAR_ANTENNA_FIELD"), SynthesisError);
-
-    Table tab_field(ms.keywordSet().asTable("LOFAR_ANTENNA_FIELD"));
-    tab_field = tab_field(tab_field.col("ANTENNA_ID") == static_cast<Int>(id));
-
-    const uLong nFields = tab_field.nrow();
-    AlwaysAssert(nFields == 1 || nFields == 2, SynthesisError);
-
-    ROScalarColumn<String> c_name(tab_field, "NAME");
-    ROArrayQuantColumn<double> c_position(tab_field, "POSITION",
-                                          "m");
-    ROArrayQuantColumn<double> c_axes(tab_field, "COORDINATE_AXES",
-                                      "m");
-    ROArrayQuantColumn<double> c_tile_offset(tab_field,
-                                             "TILE_ELEMENT_OFFSET", "m");
-    ROArrayQuantColumn<double> c_offset(tab_field, "ELEMENT_OFFSET",
-                                        "m");
-    ROArrayColumn<Bool> c_flag(tab_field, "ELEMENT_FLAG");
-
-    AntennaField field[2];
-    for(uLong i = 0; i < nFields; ++i)
-      {
-        // Read antenna field center.
-        Vector<Quantum<double> > aips_position =
-          c_position(i);
-        ASSERT(aips_position.size() == 3);
-
-        Vector3 position = {{aips_position[0].getValue(),
-                             aips_position[1].getValue(),
-                             aips_position[2].getValue()}};
-
-        // Read antenna field coordinate axes.
-        Matrix<Quantum<double> > aips_axes = c_axes(i);
-        ASSERT(aips_axes.shape().isEqual(IPosition(2, 3, 3)));
-
-        Vector3 P = {{aips_axes(0, 0).getValue(), aips_axes(1, 0).getValue(),
-                      aips_axes(2, 0).getValue()}};
-        Vector3 Q = {{aips_axes(0, 1).getValue(), aips_axes(1, 1).getValue(),
-                      aips_axes(2, 1).getValue()}};
-        Vector3 R = {{aips_axes(0, 2).getValue(), aips_axes(1, 2).getValue(),
-                      aips_axes(2, 2).getValue()}};
-
-        // Store information as AntennaField.
-        field[i] = AntennaField(c_name(i), position, P, Q, R);
-
-        if(c_name(i) != "LBA")
-          {
-            // Read tile configuration for HBA antenna fields.
-            Matrix<Quantum<double> > aips_offset =
-              c_tile_offset(i);
-            ASSERT(aips_offset.nrow() == 3);
-
-            const uLong nElement = aips_offset.ncolumn();
-            for(uLong j = 0; j < nElement; ++j)
-              {
-                Vector3 offset = {{aips_offset(0, j).getValue(),
-                                   aips_offset(1, j).getValue(),
-                                   aips_offset(2, j).getValue()}};
-
-                field[i].appendTileElement(offset);
-              }
-          }
-
-        // Read element position offsets and flags.
-        Matrix<Quantum<double> > aips_offset = c_offset(i);
-        Matrix<Bool> aips_flag = c_flag(i);
-
-        const uLong nElement = aips_offset.ncolumn();
-        ASSERT(aips_offset.shape().isEqual(IPosition(2, 3, nElement)));
-        ASSERT(aips_flag.shape().isEqual(IPosition(2, 2, nElement)));
-
-        for(uLong j = 0; j < nElement; ++j)
-          {
-            AntennaField::Element element;
-            element.offset[0] = aips_offset(0, j).getValue();
-            element.offset[1] = aips_offset(1, j).getValue();
-            element.offset[2] = aips_offset(2, j).getValue();
-            element.flag[0] = aips_flag(0, j);
-            element.flag[1] = aips_flag(1, j);
-
-            field[i].appendElement(element);
-          }
-      }
+    vector<Matrix<Complex> > result;
+    for(ArrayIterator<DComplex> it(response, 2); !it.pastEnd(); it.next())
+    {
+      Matrix<Complex> slice(it.array().shape());
+      convertArray(slice, it.array());
+      result.push_back(slice);
+    }
 
-    return (nFields == 1 ? Station(name, position, field[0])
-            : Station(name, position, field[0], field[1]));
+    return result;
   }
 
-  void LofarATerm::initReferenceDirections(const MeasurementSet &ms,
-    uint idField)
+  void rescale(Array<DComplex> &response)
   {
-    // Get phase center as RA and DEC (J2000).
-    ROMSFieldColumns field(ms.field());
-    ASSERT(field.nrow() > idField);
-    ASSERT(!field.flagRow()(idField));
-
-    m_refDelay = MDirection::Convert(field.delayDirMeas(idField),
-      MDirection::J2000)();
+    AlwaysAssert(response.ndim() == 4, SynthesisError);
+    AlwaysAssert(response.shape()[2] == 4, SynthesisError);
 
-    // By default, the tile beam reference direction is assumed to be equal
-    // to the station beam reference direction (for backward compatibility,
-    // and for non-HBA measurements).
-    m_refTile = m_refDelay;
+    const uint nX = response.shape()[0];
+    const uint nY = response.shape()[1];
+    const uint centerX = nX / 2;
+    const uint centerY = nY / 2;
 
-    // The MeasurementSet class does not support LOFAR specific columns, so we
-    // use ROArrayMeasColumn to read the tile beam reference direction.
-    Table tab_field(ms.keywordSet().asTable("FIELD"));
-    static const String columnName = "LOFAR_TILE_BEAM_DIR";
-    if(tab_field.tableDesc().isColumn(columnName))
+    DComplex invXX, invXY, invYX, invYY;
+    for(ArrayIterator<DComplex> it(response, 3); !it.pastEnd(); it.next())
     {
-      ROArrayMeasColumn<MDirection> c_direction(tab_field, columnName);
-      if(c_direction.isDefined(idField))
+      Cube<DComplex> slice(it.array());
+
+      // Compute the inverse of the Jones matrix at the central pixel.
+      DComplex det = slice(centerX, centerY, 0) * slice(centerX, centerY, 3)
+        - slice(centerX, centerY, 1) * slice(centerX, centerY, 2);
+      invXX = slice(centerX, centerY, 3) / det;
+      invXY = -slice(centerX, centerY, 1) / det;
+      invYX = -slice(centerX, centerY, 2) / det;
+      invYY = slice(centerX, centerY, 0) / det;
+
+      // Apply the inverse of the Jones matrix at the central pixel to all Jones
+      // matrices.
+      Matrix<DComplex> XX = slice(IPosition(3, 0, 0, 0),
+        IPosition(3, nX - 1, nY - 1, 0)).nonDegenerate();
+      Matrix<DComplex> XY = slice(IPosition(3, 0, 0, 1),
+        IPosition(3, nX - 1, nY - 1, 1)).nonDegenerate();
+      Matrix<DComplex> YX = slice(IPosition(3, 0, 0, 2),
+        IPosition(3, nX - 1, nY - 1, 2)).nonDegenerate();
+      Matrix<DComplex> YY = slice(IPosition(3, 0, 0, 3),
+        IPosition(3, nX - 1, nY - 1, 3)).nonDegenerate();
+
+      DComplex normXX, normXY, normYX, normYY;
+      for(uint j = 0; j < nY; ++j)
       {
-        m_refTile = MDirection::Convert(c_direction(idField)(IPosition(1, 0)),
-          MDirection::J2000)();
+        for(uint i = 0; i < nX; ++i)
+        {
+          normXX = invXX * XX(i, j) + invXY * YX(i, j);
+          normXY = invXX * XY(i, j) + invXY * YY(i, j);
+          normYX = invYX * XX(i, j) + invYY * YX(i, j);
+          normYY = invYX * XY(i, j) + invYY * YY(i, j);
+
+          XX(i, j) = normXX;
+          XY(i, j) = normXY;
+          YX(i, j) = normYX;
+          YY(i, j) = normYY;
+        }
       }
     }
   }
 
-  void LofarATerm::initReferenceFreq(const MeasurementSet &ms,
-    uint idDataDescription)
+  void rescale(Cube<DComplex> &response)
   {
-    // Read polarization id and spectral window id.
-    ROMSDataDescColumns desc(ms.dataDescription());
-    ASSERT(desc.nrow() > idDataDescription);
-    ASSERT(!desc.flagRow()(idDataDescription));
-
-    const uint idWindow = desc.spectralWindowId()(idDataDescription);
-
-    // Get spectral information.
-    ROMSSpWindowColumns window(ms.spectralWindow());
-    ASSERT(window.nrow() > idWindow);
-    ASSERT(!window.flagRow()(idWindow));
-
-    m_refFreq = window.refFrequency()(idWindow);
+    const uint centerX = response.shape()[0] / 2;
+    const uint centerY = response.shape()[1] / 2;
+    for(ArrayIterator<DComplex> it(response, 2); !it.pastEnd(); it.next())
+    {
+      Matrix<DComplex> slice(it.array());
+      slice /= slice(centerX, centerY);
+    }
   }
 
-  BeamCoeff::BeamCoeff()
-    :   m_center(0.0),
-        m_width(1.0)
+  Array<DComplex> computeFieldArrayFactor(const BBS::Station::ConstPtr &station,
+    uint idField, const LofarATerm::ITRFDirectionMap &map,
+    const Vector<Double> &freq, const Vector<Double> &reference)
   {
-  }
+    const uint nX = map.directions.shape()[1];
+    const uint nY = map.directions.shape()[2];
+    const uint nFreq = freq.size();
 
-  void BeamCoeff::load(const Path &path)
-  {
-    // Open file.
-    String expandedPath = path.expandedName();
-    ifstream in(expandedPath.c_str());
-    cout<<"Reading "<<expandedPath<<endl;
-    if(!in)
-      {
-        THROW (Exception, "Unable to open beam coefficient file.");
-      }
+    // Account for the case where the delay reference position is not equal to
+    // the field center (only applies to core HBA fields).
+    BBS::AntennaField::ConstPtr field = station->field(idField);
+    const BBS::Vector3 &fieldCenter = field->position();
 
-    // Read file header.
-    String header, token0, token1, token2, token3, token4, token5;
-    getline(in, header);
+    MVPosition delayCenter = station->position().getValue();
+    BBS::Vector3 offsetShift = {{fieldCenter[0] - delayCenter(0),
+      fieldCenter[1] - delayCenter(1),
+      fieldCenter[2] - delayCenter(2)}};
 
-    uLong nElements, nHarmonics, nPowerTheta, nPowerFreq;
-    double freqAvg, freqRange;
+    // Compute field array factors.
+    Array<DComplex> AF(IPosition(4, nX, nY, 2, nFreq), DComplex(0.0, 0.0));
+    Cube<DComplex> weight(nX, nY, nFreq);
 
-    istringstream iss(header);
-    iss >> token0 >> nElements >> token1 >> nHarmonics >> token2 >> nPowerTheta
-        >> token3 >> nPowerFreq >> token4 >> freqAvg >> token5 >> freqRange;
-
-    if(!in || !iss || token0 != "d" || token1 != "k" || token2 != "pwrT"
-       || token3 != "pwrF" || token4 != "freqAvg" || token5 != "freqRange")
-      {
-        THROW (Exception, "Unable to parse header");
-      }
-
-    if(nElements * nHarmonics * nPowerTheta * nPowerFreq == 0)
+    for(uint i = 0; i < field->nElement(); ++i)
+    {
+      const BBS::AntennaField::Element &element = field->element(i);
+      if(element.flag[0] && element.flag[1])
       {
-        THROW (Exception, "The number of coefficients should be"
-               " larger than zero.");
+        continue;
       }
 
-    ASSERT(nElements == 2);
-    ASSERT(in.good());
+      // Compute the offset relative to the delay center.
+      BBS::Vector3 offset = {{element.offset[0] + offsetShift[0],
+        element.offset[1] + offsetShift[1],
+        element.offset[2] + offsetShift[2]}};
 
-    // Allocate coefficient matrix.
-    m_center = freqAvg;
-    m_width = freqRange;
-    m_coeff = Array<DComplex>(IPosition(4, 2, nPowerFreq, nPowerTheta, nHarmonics));
+      // Compute the delay for a plane wave approaching from the delay
+      // reference direction with respect to the element position.
+      double delay0 = (map.refDelay[0] * offset[0]
+        + map.refDelay[1] * offset[1]
+        + map.refDelay[2] * offset[2]) / C::c;
 
-    uLong nCoeff = 0;
-    while(in.good())
+      for(uint k = 0; k < nY; ++k)
       {
-        // Read line from file.
-        String line;
-        getline(in, line);
-
-        // Skip lines that contain only whitespace.
-        if(line.find_last_not_of(" ", String::npos) == String::npos)
-          {
-            continue;
-          }
-
-        // Parse line.
-        uLong element, harmonic, powerTheta, powerFreq;
-        double re, im;
-
-        iss.clear();
-        iss.str(line);
-        iss >> element >> harmonic >> powerTheta >> powerFreq >> re >> im;
+        for(uint j = 0; j < nX; ++j)
+        {
+          // Compute the delay for a plane wave approaching from the direction
+          // of interest with respect to the element position.
+          double delay = (map.directions(0, j, k) * offset[0]
+            + map.directions(1, j, k) * offset[1]
+            + map.directions(2, j, k) * offset[2]) / C::c;
 
-        if(!iss || element >= nElements || harmonic >= nHarmonics
-           || powerTheta >= nPowerTheta || powerFreq >= nPowerFreq)
+          for(uint l = 0; l < nFreq; ++l)
           {
-            THROW (Exception, "Error reading beam coefficient file.");
+            double shift = C::_2pi * (freq[l] * delay - reference[l] * delay0);
+            weight(j, k, l) = DComplex(cos(shift), sin(shift));
           }
-
-        // Store coefficient.
-        m_coeff(IPosition(4, element, powerFreq, powerTheta, harmonic)) = DComplex(re, im);
-
-        // Update coefficient counter.
-        ++nCoeff;
+        }
       }
 
-    if(!in.eof())
+      if(!element.flag[0])
       {
-        THROW (Exception, "Error reading beam coefficient"
-               " file.");
+        IPosition start(4, 0, 0, 0, 0);
+        IPosition end(4, nX - 1, nY - 1, 0, nFreq - 1);
+        Array<DComplex> slice = AF(start, end).reform(weight.shape());
+        slice += weight;
       }
 
-    if(nCoeff != nElements * nHarmonics * nPowerTheta * nPowerFreq)
+      if(!element.flag[1])
       {
-        THROW (Exception, "The number of coefficients"
-               " specified in the header does not match the number of coefficients"
-               " in the file.");
+        IPosition start(4, 0, 0, 1, 0);
+        IPosition end(4, nX - 1, nY - 1, 1, nFreq - 1);
+        Array<DComplex> slice = AF(start, end).reform(weight.shape());
+        slice += weight;
       }
-  }
-
-  AntennaField::AntennaField(const String &name,
-    const Vector3 &position,
-    const Vector3 &p,
-    const Vector3 &q,
-    const Vector3 &r)
-    :   m_name(name),
-        m_position(position)
-  {
-    m_axes[P] = p;
-    m_axes[Q] = q;
-    m_axes[R] = r;
-  }
-
-  const String &AntennaField::name() const
-  {
-    return m_name;
-  }
+    }
 
-  const Vector3 &AntennaField::position() const
-  {
-    return m_position;
-  }
+    // Normalize.
+    if(station->nActiveElement() > 0)
+    {
+      AF /= static_cast<Double>(station->nActiveElement());
+    }
 
-  const Vector3 &AntennaField::axis(Axis axis) const
-  {
-    return m_axes[axis];
-  }
+    if(field->isHBA())
+    {
+      // Compute tile array factor.
+      Cube<DComplex> tileAF = computeTileArrayFactor(field, map, freq);
 
-  Bool AntennaField::isHBA() const
-  {
-    return m_name != "LBA";
-  }
+      // Multiply the station array factor by the tile array factor.
+      for(uint i = 0; i < 2; ++i)
+      {
+        IPosition start(4, 0, 0, i, 0);
+        IPosition end(4, nX - 1, nY - 1, i, nFreq - 1);
+        Array<DComplex> slice = AF(start, end).reform(tileAF.shape());
+        slice *= tileAF;
+      }
+    }
 
-  void AntennaField::appendTileElement(const Vector3 &offset)
-  {
-    m_tileElements.push_back(offset);
+    return AF;
   }
 
-  void AntennaField::appendElement(const Element &element)
+  Cube<DComplex>
+  computeTileArrayFactor(const BBS::AntennaField::ConstPtr &field,
+    const LofarATerm::ITRFDirectionMap &map, const Vector<Double> &freq)
   {
-    m_elements.push_back(element);
-  }
+    const uint nX = map.directions.shape()[1];
+    const uint nY = map.directions.shape()[2];
+    const uint nFreq = freq.size();
 
-  Station::Station(const String &name,
-    const MPosition &position)
-    :   m_name(name),
-        m_position(position)
-  {
-  }
+    Cube<DComplex> AF(nX, nY, nFreq, DComplex(0.0, 0.0));
+    for(uint j = 0; j < nY; ++j)
+    {
+      for(uint i = 0; i < nX; ++i)
+      {
+        // Instead of computing a phase shift for the pointing direction and a
+        // phase shift for the direction of interest and then computing the
+        // difference, compute the resultant phase shift in one go. Here we make
+        // use of the relation a . b + a . c = a . (b + c). The sign of k is
+        // related to the sign of the phase shift.
+        double k[3];
+        k[0] = map.directions(0, i, j) - map.refTile[0];
+        k[1] = map.directions(1, i, j) - map.refTile[1];
+        k[2] = map.directions(2, i, j) - map.refTile[2];
 
-  Station::Station(const String &name,
-    const MPosition &position,
-    const AntennaField &field0)
-    :   m_name(name),
-        m_position(position)
-  {
-    m_fields.push_back(field0);
-  }
+        for(uint l = 0; l < field->nTileElement(); ++l)
+        {
+          // Compute the effective delay for a plane wave approaching from the
+          // direction of interest with respect to the position of element i
+          // when beam forming in the reference direction using time delays.
+          const BBS::Vector3 &offset = field->tileElement(l);
+          double delay = (k[0] * offset[0] + k[1] * offset[1] + k[2]
+            * offset[2]) / C::c;
 
-  Station::Station(const String &name,
-    const MPosition &position,
-    const AntennaField &field0,
-    const AntennaField &field1)
-    :   m_name(name),
-        m_position(position)
-  {
-    m_fields.push_back(field0);
-    m_fields.push_back(field1);
-  }
+          // Turn the delay into a phase shift.
+          for(uint m = 0; m < nFreq; ++m)
+          {
+            double shift = C::_2pi * freq[m] * delay;
+            AF(i, j, m) += DComplex(cos(shift), sin(shift));
+          }
+        }
+      }
+    }
 
-  const String &Station::name() const
-  {
-    return m_name;
-  }
+    // Normalize.
+    if(field->nTileElement() > 0)
+    {
+      AF /= static_cast<Double>(field->nTileElement());
+    }
 
-  const MPosition &Station::position() const
-  {
-    return m_position;
+    return AF;
   }
 
-  bool Station::isPhasedArray() const
+  struct ElementLBA
   {
-    return !m_fields.empty();
-  }
+    static void response(double freq, double theta, double phi,
+      DComplex (&response)[2][2])
+    {
+      element_response_lba(freq, theta, phi, response);
+    }
+  };
 
-  uint Station::nField() const
+  struct ElementHBA
   {
-    return m_fields.size();
-  }
+    static void response(double freq, double theta, double phi,
+      DComplex (&response)[2][2])
+    {
+      element_response_hba(freq, theta, phi, response);
+    }
+  };
 
-  const AntennaField &Station::field(uint i) const
+  template <typename T_ELEMENT>
+  Array<DComplex>
+  computeElementResponse(const BBS::AntennaField::ConstPtr &field,
+    const LofarATerm::ITRFDirectionMap &map, const Vector<Double> &freq)
   {
-    return m_fields[i];
-  }
+    const BBS::Vector3 &p = field->axis(BBS::AntennaField::P);
+    const BBS::Vector3 &q = field->axis(BBS::AntennaField::Q);
+    const BBS::Vector3 &r = field->axis(BBS::AntennaField::R);
 
-  Instrument::Instrument(const String &name,
-    const MPosition &position)
-    :   m_name(name),
-        m_position(position)
-  {
-  }
+    const uint nX = map.directions.shape()[1];
+    const uint nY = map.directions.shape()[2];
+    const uint nFreq = freq.size();
 
-  const String &Instrument::name() const
-  {
-    return m_name;
-  }
+    DComplex J[2][2];
+    Array<DComplex> E(IPosition(4, nX, nY, 4, nFreq), DComplex(0.0, 0.0));
+    for(uint j = 0; j < nY; ++j)
+    {
+      for(uint i = 0; i < nX; ++i)
+      {
+        BBS::Vector3 target = {{map.directions(0, i, j),
+          map.directions(1, i, j), map.directions(2, i, j)}};
 
-  const MPosition &Instrument::position() const
-  {
-    return m_position;
-  }
+        // Check for non-physical directions (the image is square while the
+        // projected sky is circular, therefore some image pixels may map to
+        // invalid directions.
+        if(target[0] == 0.0 && target[1] == 0.0 && target[2] == 0.0)
+        {
+          continue;
+        }
 
-  uint Instrument::nStations() const
-  {
-    return m_stations.size();
-  }
+        // Compute the cross product of the NCP and the target direction. This
+        // yields a vector tangent to the celestial sphere at the target
+        // direction, pointing towards the East (the direction of +Y in the IAU
+        // definition, or positive right ascension).
+        BBS::Vector3 v1 = {{-target[1], target[0], 0.0}};
+        double normv1 = sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);
+        v1[0] /= normv1;
+        v1[1] /= normv1;
+        v1[2] /= normv1;
+
+        // Compute the cross product of the antenna field normal (R) and the
+        // target direction. This yields a vector tangent to the topocentric
+        // spherical coordinate system at the target direction, pointing towards
+        // the direction of positive phi (which runs East over North around the
+        // pseudo zenith).
+        BBS::Vector3 v2 = {{r[1] * target[2] - r[2] * target[1],
+          r[2] * target[0] - r[0] * target[2],
+          r[0] * target[1] - r[1] * target[0]}};
+        double normv2 = sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2]);
+        v2[0] /= normv2;
+        v2[1] /= normv2;
+        v2[2] /= normv2;
+
+        // Compute the cosine and sine of the parallactic angle, i.e. the angle
+        // between v1 and v2, both tangent to a latitude circle of their
+        // respective spherical coordinate systems.
+        double coschi = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
+        double sinchi = (v1[1] * v2[2] - v1[2] * v2[1]) * target[0]
+          + (v1[2] * v2[0] - v1[0] * v2[2]) * target[1]
+          + (v1[0] * v2[1] - v1[1] * v2[0]) * target[2];
+
+        // The input coordinate system is a right handed system with its third
+        // axis along the direction of propagation (IAU +Z). The output
+        // coordinate system is right handed as well, but its third axis points
+        // in the direction of arrival (i.e. exactly opposite).
+        //
+        // Because the electromagnetic field is always perpendicular to the
+        // direction of propagation, we only need to relate the (X, Y) axes of
+        // the input system to the corresponding (theta, phi) axes of the output
+        // system.
+        //
+        // To this end, we first rotate the input system around its third axis
+        // to align the Y axis with the phi axis. The X and theta axis are
+        // parallel after this rotation, but point in opposite directions. To
+        // align the X axis with the theta axis, we flip it.
+        //
+        // The Jones matrix to align the Y axis with the phi axis when these are
+        // separated by an angle phi (measured counter-clockwise around the
+        // direction of propagation, looking towards the origin), is given by:
+        //
+        // [ cos(phi)  sin(phi)]
+        // [-sin(phi)  cos(phi)]
+        //
+        // Here, cos(phi) and sin(phi) can be computed directly, without having
+        // to compute phi first (see the computation of coschi and sinchi
+        // above).
+        //
+        // Now, sinchi as computed above is opposite to sin(phi), because the
+        // direction used in the computation is the direction of arrival instead
+        // of the direction of propagation. Therefore, the sign of sinchi needs
+        // to be reversed. Furthermore, as explained above, the X axis has to be
+        // flipped to align with the theta axis. The Jones matrix returned from
+        // this function is therefore given by:
+        //
+        // [-coschi  sinchi]
+        // [ sinchi  coschi]
 
-  const Station &Instrument::station(uint i) const
-  {
-    return m_stations[i];
-  }
+        // Compute the P and Q coordinate of the direction vector by projecting
+        // onto the positive P and Q axis.
+        double projectionP = target[0] * p[0] + target[1] * p[1] + target[2]
+          * p[2];
+        double projectionQ = target[0] * q[0] + target[1] * q[1] + target[2]
+          * q[2];
+
+        // Compute the inner product between the antenna field normal (R) and
+        // the direction vector to get the cosine of the zenith angle.
+        double projectionR = target[0] * r[0] + target[1] * r[1] + target[2]
+          * r[2];
+
+        double theta = acos(projectionR);
+        double phi = atan2(projectionQ, projectionP);
+
+        // The positive X dipole direction is SW of the reference orientation,
+        // which translates to a phi coordinate of 5/4*pi in the topocentric
+        // spherical coordinate system. The phi coordinate is corrected for this
+        // offset before evaluating the antenna model.
+        phi -= 5.0 * C::pi_4;
+
+        for(uint k = 0; k < nFreq; ++k)
+        {
+          T_ELEMENT::response(freq[k], theta, phi, J);
 
-  const Station &Instrument::station(const String &name) const
-  {
-    map<String, uint>::const_iterator it = m_index.find(name);
-    if(it == m_index.end())
-      {
-        THROW (Exception, "Unknown station: " + name);
+          E(IPosition(4, i, j, 0, k)) = J[0][0] * -coschi + J[0][1] * sinchi;
+          E(IPosition(4, i, j, 1, k)) = J[0][0] *  sinchi + J[0][1] * coschi;
+          E(IPosition(4, i, j, 2, k)) = J[1][0] * -coschi + J[1][1] * sinchi;
+          E(IPosition(4, i, j, 3, k)) = J[1][0] *  sinchi + J[1][1] * coschi;
+        }
       }
+    }
 
-    return m_stations[it->second];
+    return E;
   }
+  
+} // unnamed namespace
 
-  void Instrument::append(const Station &station)
-  {
-    m_stations.push_back(station);
-  }
 } // namespace LOFAR
diff --git a/CEP/Imager/LofarFT/src/LofarATermOld.cc b/CEP/Imager/LofarFT/src/LofarATermOld.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c2704db3f398a24b29578769cdff1773f3268791
--- /dev/null
+++ b/CEP/Imager/LofarFT/src/LofarATermOld.cc
@@ -0,0 +1,1038 @@
+//# LofarATermOld.cc: Compute the LOFAR beam response on the sky.
+//#
+//# Copyright (C) 2011
+//# 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 <LofarFT/LofarATermOld.h>
+#include <Common/LofarLogger.h>
+#include <Common/Exception.h>
+
+#include <casa/OS/Path.h>
+#include <casa/Arrays/ArrayIter.h>
+#include <casa/Arrays/Cube.h>
+#include <coordinates/Coordinates/DirectionCoordinate.h>
+#include <measures/Measures/MeasTable.h>
+#include <measures/Measures/MeasConvert.h>
+#include <measures/Measures/MCDirection.h>
+#include <measures/Measures/MCPosition.h>
+#include <ms/MeasurementSets/MeasurementSet.h>
+#include <ms/MeasurementSets/MSAntenna.h>
+#include <ms/MeasurementSets/MSAntennaParse.h>
+#include <ms/MeasurementSets/MSAntennaColumns.h>
+#include <ms/MeasurementSets/MSDataDescription.h>
+#include <ms/MeasurementSets/MSDataDescColumns.h>
+#include <ms/MeasurementSets/MSField.h>
+#include <ms/MeasurementSets/MSFieldColumns.h>
+#include <ms/MeasurementSets/MSObservation.h>
+#include <ms/MeasurementSets/MSObsColumns.h>
+#include <ms/MeasurementSets/MSPolarization.h>
+#include <ms/MeasurementSets/MSPolColumns.h>
+#include <ms/MeasurementSets/MSSpectralWindow.h>
+#include <ms/MeasurementSets/MSSpWindowColumns.h>
+#include <ms/MeasurementSets/MSSelection.h>
+#include <synthesis/MeasurementComponents/SynthesisError.h>
+
+// DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
+#include <iomanip>
+// DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
+
+using namespace casa;
+
+namespace LOFAR
+{
+  LofarATermOld::LofarATermOld(const MeasurementSet& ms,
+                         const String& beamElementPath)
+  {
+    if (beamElementPath.empty()) {
+      m_coeffLBA.load(Path("element_beam_HAMAKER_LBA.coeff"));
+      m_coeffHBA.load(Path("element_beam_HAMAKER_HBA.coeff"));
+    } else {
+      m_coeffLBA.load(Path(beamElementPath + "/element_beam_HAMAKER_LBA.coeff"));
+      m_coeffHBA.load(Path(beamElementPath + "/element_beam_HAMAKER_HBA.coeff"));
+    }
+     //    m_coeffLBA.load(Path("element_beam_LBA.coeff"));
+     //    m_coeffHBA.load(Path("element_beam_HBA.coeff"));
+
+    initInstrument(ms);
+    initReferenceFreq(ms, 0);
+    initReferenceDirections(ms, 0);
+  }
+
+  vector<Cube<Complex> > LofarATermOld::evaluate(const IPosition &shape,
+    const DirectionCoordinate &coordinates,
+    uint station,
+    const MEpoch &epoch,
+    const Vector<Double> &freq,
+    bool normalize) const
+  {
+    AlwaysAssert(station < m_instrument.nStations(), SynthesisError);
+    AlwaysAssert(shape[0] > 0 && shape[1] > 0, SynthesisError);
+    AlwaysAssert(freq.size() > 0, SynthesisError);
+
+    // Create conversion engine (from J2000 -> ITRF).
+    MDirection::Convert convertor = MDirection::Convert(MDirection::J2000,
+      MDirection::Ref(MDirection::ITRF,
+      MeasFrame(epoch, m_instrument.position())));
+
+    MVDirection mvRefDelay = convertor(m_refDelay).getValue();
+    Vector3 refDelay = {{mvRefDelay(0), mvRefDelay(1), mvRefDelay(2)}};
+
+    MVDirection mvRefTile = convertor(m_refTile).getValue();
+    Vector3 refTile = {{mvRefTile(0), mvRefTile(1), mvRefTile(2)}};
+
+    // Compute ITRF map.
+    LOG_INFO("LofarATermOld::evaluate(): Computing ITRF map...");
+    Cube<double> mapITRF = computeITRFMap(coordinates, shape, convertor);
+    LOG_INFO("LofarATermOld::evaluate(): Computing ITRF map... done.");
+
+    // Compute element beam response.
+    LOG_INFO("LofarATermOld::evaluate(): Computing station response...");
+    Array<DComplex> response =
+      evaluateStationBeam(m_instrument.station(station), refDelay, refTile,
+        mapITRF, freq);
+
+    // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
+//    MDirection world;
+//    Vector<double> refPixel = coordinates.referencePixel();
+
+//    cout << "shape: " << shape << " ref. pixel: " << refPixel << endl;
+//    coordinates.toWorld(world, refPixel);
+
+//    casa::Quantum<casa::Vector<casa::Double> > refAngles = world.getAngle();
+//    double ra = refAngles.getBaseValue()(0);
+//    double dec = refAngles.getBaseValue()(1);
+//    cout << "ref. world: " << std::setprecision(17) << ra << " " << dec << endl;
+
+//    cout << "station: " << station << endl;
+//    cout << "freq: " << std::setprecision(17) << freq << endl;
+//    cout << "time: " << std::setprecision(17) << epoch.getValue().getTime("s") << endl;
+//    IPosition st(4, refPixel(0), refPixel(1), 0, 0);
+//    IPosition en(4, refPixel(0), refPixel(1), 3, freq.size() - 1);
+//    Array<DComplex> tmpResponse = response(st, en).nonDegenerate();
+//    cout << "response shape: " << tmpResponse.shape() << endl;
+//    cout << "response: " << endl << tmpResponse << endl;
+
+//    refPixel = 0.0;
+//    coordinates.toWorld(world, refPixel);
+//    refAngles = world.getAngle();
+//    ra = refAngles.getBaseValue()(0);
+//    dec = refAngles.getBaseValue()(1);
+//    cout << "0 world: " << std::setprecision(17) << ra << " " << dec << endl;
+
+//    st = IPosition(4, 0, 0, 0, 0);
+//    en = IPosition(4, 0, 0, 3, freq.size() - 1);
+//    Array<DComplex> tmpResponse2 = response(st, en).nonDegenerate();
+//    cout << "response shape: " << tmpResponse2.shape() << endl;
+//    cout << "response: " << endl << tmpResponse2 << endl;
+
+//    AlwaysAssert(false, SynthesisError);
+    // DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
+
+
+
+    //Cyril
+    if(normalize)
+    {
+     response = this->normalize(response);
+    }
+    LOG_INFO("LofarATermOld::evaluate(): Computing station response... done.");
+
+    // Convert an Array<DComplex> to a vector<Cube<Complex> >.
+    vector<Cube<Complex> > tmp;
+    tmp.reserve(freq.size());
+    for (ArrayIterator<DComplex> iter(response, 3);
+         !iter.pastEnd(); iter.next())
+    {
+      Cube<Complex> planef(iter.array().shape());
+      convertArray (planef, iter.array());
+      tmp.push_back(planef);
+    }
+
+    // if(normalize)
+    //   MDirection::Convert convertor = MDirection::Convert(MDirection::J2000, MDirection::Ref(MDirection::ITRF, MeasFrame(epoch, m_instrument.position())));
+    // mapITRF = computeITRFMap(coordinates, shape, convertor);
+    // Cube<double> mapITRF_center;
+    // DirectionCoordinate coordinates_center(coordinates);
+    //   Vector<Double> Refpix(2,0.);
+    //   coordinates_center.setReferencePixel(Refpix);
+    //   mapITRF_center = computeITRFMap(coordinates_center, IPosition(2,1,1), convertor);
+    //   for(uInt i = 0; i < freq.size(); ++i){
+    // 	{
+    //   evaluateStationBeam(m_instrument.station(station), refDelay, refTile,
+    //     mapITRF, freq);
+    // 	  Cube<Complex> gain(evaluateStationBeam(mapITRF_center, convertor(m_phaseReference), m_instrument.station(station), freq[i]));
+    // 	  Matrix<Complex> central_gain(gain.xzPlane(0));
+    // 	  // central_gain.resize(2,2,true); //resize does not work:
+    // 	  // Central gain  Axis Lengths: [1, 4]  (NB: Matrix in Row/Column order)
+    // 	  //   [(-0.0235668,-0.000796029), (-0.0345345,-0.000373378), (0.030112,0.000938836), (-0.0268743,-0.000258621)]
+    // 	  // Central gain  Axis Lengths: [2, 2]  (NB: Matrix in Row/Column order)
+    // 	  //   [(-0.0235668,-0.000796029), (-0.0345345,-0.000373378)
+    // 	  //    (0,0), (0,0)]
+    // 	  Matrix<Complex> central_gain_reform(central_gain.reform(IPosition(2,2,2)));
+    // 	  Matrix<Complex> central_gain_invert(invert(central_gain_reform));
+
+    // 	  //Cube<Complex> IM=beams[i];
+    // 	  for(uInt ii=0;ii<shape[0];++ii)
+    // 	    {
+    // 	      for(uInt jj=0;jj<shape[1];++jj)
+    // 	  	{
+    // 	  	  Cube<Complex> pixel(tmp[i](IPosition(3,ii,jj,0),IPosition(3,ii,jj,3)).copy());
+    // 		  // cout<<"================="<<pixel<<endl;
+    // 		  // cout<<"pixel"<<pixel<<endl;
+    // 	  	  Matrix<Complex> pixel_reform(pixel.reform(IPosition(2,2,2)));
+    // 		  // cout<<"pixel_reform"<<pixel_reform<<endl;
+    // 	  	  Matrix<Complex> pixel_product=product(central_gain_invert,pixel_reform);
+    // 		  // cout<<"pixel_product"<<pixel_product<<endl;
+    // 		  Matrix<Complex> pixel_product_reform(pixel_product.reform(IPosition(2,1,4)));
+    // 		  // cout<<"pixel_product_reform"<<pixel_product_reform<<endl;
+
+    // 		  for(uInt ind=0;ind<4;++ind){tmp[i](ii,jj,ind)=pixel_product_reform(0,ind);};
+    // 		    //beams[i](IPosition(3,ii,jj,0),IPosition(3,ii,jj,3))=pixel_product;
+    // 					//IM(ii,jj)=pixel_product;
+    // 	  	}
+    // 	    }
+    // 	};
+
+    return tmp;
+  }
+
+  Array<DComplex> LofarATermOld::normalize(const Array<DComplex> &response)
+    const
+  {
+    const uint nX = response.shape()[0];
+    const uint nY = response.shape()[1];
+    const uint nFreq = response.shape()[3];
+    AlwaysAssert(response.shape()[2] == 4, SynthesisError);
+    AlwaysAssert(nX > 0 && nY > 0 && nFreq > 0, SynthesisError);
+
+    // Cast away const, to be able to use Array<T>::operator(IPosition,
+    // IPosition) to extract a slice (for reading).
+    Array<DComplex> &__response = const_cast<Array<DComplex>&>(response);
+
+    // Extract beam response for the central pixel at the central frequency.
+    IPosition start(4, floor(nX / 2.), floor(nY / 2.), 0, floor(nFreq / 2.));
+    IPosition end(4, floor(nX / 2.), floor(nY / 2.), 3, floor(nFreq / 2.));
+
+    // Use assignment operator to force a copy.
+    Vector<DComplex> factor;
+    factor = __response(start, end).nonDegenerate();
+
+    // Compute the inverse of the reponse.
+    Vector<DComplex> inverse(4);
+    DComplex determinant = factor(0) * factor(3) - factor(1) * factor(2);
+    inverse(0) = factor(3) / determinant;
+    inverse(1) = -factor(1) / determinant;
+    inverse(2) = -factor(2) / determinant;
+    inverse(3) = factor(0) / determinant;
+
+    // Multiply the beam response for all pixels, at all frequencies, by the
+    // computed inverse.
+    Array<DComplex> XX = __response(IPosition(4, 0, 0, 0, 0),
+      IPosition(4, nX - 1, nY - 1, 0, nFreq - 1));
+    Array<DComplex> XY = __response(IPosition(4, 0, 0, 1, 0),
+      IPosition(4, nX - 1, nY - 1, 1, nFreq - 1));
+    Array<DComplex> YX = __response(IPosition(4, 0, 0, 2, 0),
+      IPosition(4, nX - 1, nY - 1, 2, nFreq - 1));
+    Array<DComplex> YY = __response(IPosition(4, 0, 0, 3, 0),
+      IPosition(4, nX - 1, nY - 1, 3, nFreq - 1));
+
+    Array<DComplex> normal(response.shape());
+    Array<DComplex> nXX = normal(IPosition(4, 0, 0, 0, 0),
+      IPosition(4, nX - 1, nY - 1, 0, nFreq - 1));
+    Array<DComplex> nXY = normal(IPosition(4, 0, 0, 1, 0),
+      IPosition(4, nX - 1, nY - 1, 1, nFreq - 1));
+    Array<DComplex> nYX = normal(IPosition(4, 0, 0, 2, 0),
+      IPosition(4, nX - 1, nY - 1, 2, nFreq - 1));
+    Array<DComplex> nYY = normal(IPosition(4, 0, 0, 3, 0),
+      IPosition(4, nX - 1, nY - 1, 3, nFreq - 1));
+
+    nXX = inverse(0) * XX + inverse(1) * YX;
+    nXY = inverse(0) * XY + inverse(1) * YY;
+    nYX = inverse(2) * XX + inverse(3) * YX;
+    nYY = inverse(2) * XY + inverse(3) * YY;
+
+    return normal;
+  }
+
+  Array<DComplex> LofarATermOld::evaluateElementBeam(const BeamCoeff &coeff,
+    const AntennaField &field,
+    const Cube<double> &map,
+    const Vector<double> &freq) const
+  {
+    const Vector3 &p = field.axis(AntennaField::P);
+    const Vector3 &q = field.axis(AntennaField::Q);
+    const Vector3 &r = field.axis(AntennaField::R);
+
+    const uint nX = map.shape()[1];
+    const uint nY = map.shape()[2];
+    const uint nFreq = freq.shape()[0];
+
+    Array<DComplex> beam(IPosition(4, nX, nY, 4, nFreq), DComplex(0.0, 0.0));
+    for(uint j = 0; j < nY; ++j)
+    {
+      for(uint i = 0; i < nX; ++i)
+      {
+        if(map(0, i, j) == 0.0 && map(1, i, j) == 0.0 && map(2, i, j) == 0.0)
+        {
+          // Non-physical pixel.
+          continue;
+        }
+
+        // Compute the P and Q coordinate of the direction vector by projecting
+        // onto the positive P and Q axis.
+        double projectionP = map(0, i, j) * p[0] + map(1, i, j) * p[1] + map(2, i, j) * p[2];
+        double projectionQ = map(0, i, j) * q[0] + map(1, i, j) * q[1] + map(2, i, j) * q[2];
+
+        // Compute the inner product between the antenna field normal
+        // (R) and the direction vector to get the sine of the elevation
+        // (cosine of the zenith angle).
+        double sinEl = map(0, i, j) * r[0] + map(1, i, j) * r[1] + map(2, i, j) * r[2];
+
+        double az = atan2(projectionP, projectionQ);
+        double el = asin(sinEl);
+
+        // Evaluate beam.
+        // Correct azimuth for dipole orientation.
+        const double phi = az - 3.0 * C::pi_4;
+
+        // NB: The model is parameterized in terms of zenith angle. The
+        // appropriate conversion is taken care of below.
+        const double theta = C::pi_2 - el;
+
+        // Only compute the beam response for directions above the horizon.
+        if(theta < C::pi_2)
+        {
+          for(uint k = 0; k < nFreq; ++k)
+          {
+            // J-jones matrix (2x2 complex matrix)
+            DComplex J[2][2] = {{0.0, 0.0}, {0.0, 0.0}};
+
+            // NB: The model is parameterized in terms of a normalized
+            // frequency in the range [-1, 1]. The appropriate conversion is
+            // taken care of below.
+            const double normFreq = (freq[k] - coeff.center()) / coeff.width();
+
+            for(uint l = 0; l < coeff.nHarmonics(); ++l)
+            {
+              // Compute diagonal projection matrix P for the current
+              // harmonic.
+              DComplex P[2] = {0.0, 0.0};
+
+              DComplex inner[2];
+              for(int m = coeff.nPowerTheta() - 1; m >= 0; --m)
+              {
+                inner[0] = coeff(0, coeff.nPowerFreq() - 1, m, l);
+                inner[1] = coeff(1, coeff.nPowerFreq() - 1, m, l);
+
+                for(int n = coeff.nPowerFreq() - 2; n >= 0; --n)
+                {
+                  inner[0] = inner[0] * normFreq + coeff(0, n, m, l);
+                  inner[1] = inner[1] * normFreq + coeff(1, n, m, l);
+                }
+
+                P[0] = P[0] * theta + inner[0];
+                P[1] = P[1] * theta + inner[1];
+              }
+
+              // Compute Jones matrix for this harmonic by rotating P over
+              // kappa * phi and add it to the result.
+              const double kappa = ((l & 1) == 0 ? 1.0 : -1.0) * (2.0 * l + 1.0);
+              const double cphi = cos(kappa * phi);
+              const double sphi = sin(kappa * phi);
+
+              J[0][0] += cphi * P[0];
+              J[0][1] += -sphi * P[1];
+              J[1][0] += sphi * P[0];
+              J[1][1] += cphi * P[1];
+            }
+
+            beam(IPosition(4, i, j, 0, k)) = J[0][0];
+            beam(IPosition(4, i, j, 1, k)) = J[0][1];
+            beam(IPosition(4, i, j, 2, k)) = J[1][0];
+            beam(IPosition(4, i, j, 3, k)) = J[1][1];
+          }
+        }
+      }
+    }
+
+    return beam;
+  }
+
+  Array<DComplex> LofarATermOld::evaluateStationBeam(const Station &station,
+    const Vector3 &refDelay,
+    const Vector3 &refTile,
+    const Cube<Double> &map,
+    const Vector<Double> &freq) const
+  {
+    const uint nX = map.shape()[1];
+    const uint nY = map.shape()[2];
+    const uint nFreq = freq.shape()[0];
+
+    uint countX = 0, countY = 0;
+    Array<DComplex> E(IPosition(4, nX, nY, 4, nFreq), DComplex(0.0, 0.0));
+    for(uint i = 0; i < station.nField(); ++i)
+    {
+      const AntennaField &field = station.field(i);
+
+      // Compute element beam.
+      LOG_INFO("LofarATermOld::computeStationBeam: Computing element beam...");
+      Array<DComplex> beam;
+      if(field.isHBA())
+      {
+        beam = evaluateElementBeam(m_coeffHBA, field, map, freq);
+      }
+      else
+      {
+        beam = evaluateElementBeam(m_coeffLBA, field, map, freq);
+      }
+      LOG_INFO("LofarATermOld::computeStationBeam: Computing element beam... done.");
+
+      if(field.isHBA())
+      {
+        // Compute tile array factor.
+        LOG_INFO("LofarATermOld::computeStationBeam: Computing tile array factor...");
+        Cube<DComplex> tileAF = evaluateTileArrayFactor(field, refTile, map,
+          freq);
+        LOG_INFO("LofarATermOld::computeStationBeam: Computing tile array factor... done.");
+
+        Array<DComplex> tileAF4 = tileAF.reform(IPosition(4, nX, nY, 1, nFreq));
+
+        // Multiply the element beam by the tile array factor.
+        for(uint j = 0; j < 4; ++j)
+        {
+          IPosition start(4, 0, 0, j, 0);
+          IPosition end(4, nX - 1, nY - 1, j, nFreq - 1);
+
+          Array<DComplex> plane = beam(start, end);
+          plane *= tileAF4;
+        }
+      }
+
+      LOG_INFO("LofarATermOld::computeStationBeam: Computing station array factor...");
+
+      // Account for the case where the delay reference position is not equal to
+      // the field center (only applies to core HBA fields).
+      const Vector3 &fieldCenter = field.position();
+      MVPosition delayCenter = station.position().getValue();
+      Vector3 offsetShift = {{fieldCenter[0] - delayCenter(0),
+                              fieldCenter[1] - delayCenter(1),
+                              fieldCenter[2] - delayCenter(2)}};
+
+      // Compute field array factors.
+      Cube<DComplex> fieldAFX(nX, nY, nFreq, DComplex(0.0, 0.0));
+      Cube<DComplex> fieldAFY(nX, nY, nFreq, DComplex(0.0, 0.0));
+      Cube<DComplex> phase(nX, nY, nFreq, DComplex(0.0, 0.0));
+
+      for(uint j = 0; j < field.nElement(); ++j)
+      {
+        const AntennaField::Element &element = field.element(j);
+        if(element.flag[0] && element.flag[1])
+        {
+          continue;
+        }
+
+        // Compute the offset relative to the delay center.
+        Vector3 offset = {{element.offset[0] + offsetShift[0],
+                           element.offset[1] + offsetShift[1],
+                           element.offset[2] + offsetShift[2]}};
+
+        // Compute the delay for a plane wave approaching from the delay
+        // reference direction with respect to the element position.
+        double delay0 = (refDelay[0] * offset[0] + refDelay[1] * offset[1]
+          + refDelay[2] * offset[2]) / casa::C::c;
+        double shift0 = C::_2pi * m_refFreq * delay0;
+
+        for(uint y = 0; y < nY; ++y)
+        {
+          for(uint x = 0; x < nX; ++x)
+          {
+            // Compute the delay for a plane wave approaching from the direction
+            // of interest with respect to the element position.
+            double delay = (map(0, x, y) * offset[0]
+                            + map(1, x, y) * offset[1]
+                            + map(2, x, y) * offset[2]) / casa::C::c;
+
+            for(uint k = 0; k < nFreq; ++k)
+            {
+              double shift = C::_2pi * freq[k] * delay - shift0;
+              phase(x, y, k) = DComplex(cos(shift), sin(shift));
+            }
+          }
+        }
+
+        if(!element.flag[0])
+        {
+          fieldAFX += phase;
+          ++countX;
+        }
+
+        if(!element.flag[1])
+        {
+          fieldAFY += phase;
+          ++countY;
+        }
+      }
+
+      LOG_INFO("LofarATermOld::computeStationBeam: Computing station array factor... done.");
+      Array<DComplex> fieldAFX4 = fieldAFX.reform(IPosition(4, nX, nY, 1, nFreq));
+      for(uint k = 0; k < 2; ++k)
+      {
+        IPosition start(4, 0, 0, k, 0);
+        IPosition end(4, nX - 1, nY - 1, k, nFreq - 1);
+        Array<DComplex> plane = E(start, end);
+        plane += fieldAFX4 * beam(start, end);
+      }
+
+      Array<DComplex> fieldAFY4 = fieldAFY.reform(IPosition(4, nX, nY, 1, nFreq));
+      for(uint k = 2; k < 4; ++k)
+      {
+        IPosition start(4, 0, 0, k, 0);
+        IPosition end(4, nX - 1, nY - 1, k, nFreq - 1);
+        Array<DComplex> plane = E(start, end);
+        plane += fieldAFY4 * beam(start, end);
+      }
+    } // fields
+
+    // Normalize.
+    if(countX > 0)
+    {
+      IPosition start(4, 0, 0, 0, 0);
+      IPosition end(4, nX - 1, nY - 1, 1, nFreq - 1);
+      Array<DComplex> plane = E(start, end);
+      plane /= static_cast<Double>(countX);
+    }
+
+    if(countY > 0)
+    {
+      IPosition start(4, 0, 0, 2, 0);
+      IPosition end(4, nX - 1, nY - 1, 3, nFreq - 1);
+      Array<DComplex> plane = E(start, end);
+      plane /= static_cast<Double>(countY);
+    }
+
+    return E;
+  }
+
+  Cube<DComplex> LofarATermOld::evaluateTileArrayFactor(const AntennaField &field,
+    const Vector3 &reference,
+    const Cube<Double> &map,
+    const Vector<Double> &freq) const
+  {
+    const uint nX = map.shape()[1];
+    const uint nY = map.shape()[2];
+    const uint nFreq = freq.shape()[0];
+
+    Cube<DComplex> factor(nX, nY, nFreq, DComplex(0.0, 0.0));
+    for(uint y = 0; y < nY; ++y)
+    {
+      for(uint x = 0; x < nX; ++x)
+      {
+        // Instead of computing a phase shift for the pointing direction and a
+        // phase shift for the direction of interest and then computing the
+        // difference, compute the resultant phase shift in one go. Here we make
+        // use of the relation a . b + a . c = a . (b + c). The sign of k is
+        // related to the sign of the phase shift.
+        double k[3];
+        k[0] = map(0, x, y) - reference[0];
+        k[1] = map(1, x, y) - reference[1];
+        k[2] = map(2, x, y) - reference[2];
+
+        for(uint j = 0; j < field.nTileElement(); ++j)
+        {
+          // Compute the effective delay for a plane wave approaching from the
+          // direction of interest with respect to the position of element i
+          // when beam forming in the reference direction using time delays.
+          const Vector3 &offset = field.tileElement(j);
+          double delay = (k[0] * offset[0] + k[1] * offset[1] + k[2] * offset[2])
+            / C::c;
+
+          // Turn the delay into a phase shift.
+          for(uint k = 0; k < nFreq; ++k)
+          {
+            double shift = C::_2pi * freq[k] * delay;
+            factor(x, y, k) += DComplex(cos(shift), sin(shift));
+          }
+        }
+      }
+    }
+
+    // Normalize.
+    if(field.nTileElement() > 0)
+    {
+      factor /= static_cast<Double>(field.nTileElement());
+    }
+
+    return factor;
+  }
+
+  Cube<double> LofarATermOld::computeITRFMap(const DirectionCoordinate &coordinates,
+    const IPosition &shape,
+    MDirection::Convert convertor) const
+  {
+    MDirection world;
+    Vector<double> pixel = coordinates.referencePixel();
+
+    Cube<double> map(3, shape[0], shape[1], 0.0);
+    for(pixel[1] = 0.0; pixel(1) < shape[1]; ++pixel[1])
+      {
+        for(pixel[0] = 0.0; pixel[0] < shape[0]; ++pixel[0])
+          {
+            // CoodinateSystem::toWorld()
+            // DEC range [-pi/2,pi/2]
+            // RA range [-pi,pi]
+            if(coordinates.toWorld(world, pixel))
+              {
+                MVDirection mvITRF(convertor(world).getValue());
+                map(0, pixel[0], pixel[1]) = mvITRF(0);
+                map(1, pixel[0], pixel[1]) = mvITRF(1);
+                map(2, pixel[0], pixel[1]) = mvITRF(2);
+              }
+          }
+      }
+
+    return map;
+  }
+
+  void LofarATermOld::initInstrument(const MeasurementSet &ms)
+  {
+    // Get station names and positions in ITRF coordinates.
+    ROMSAntennaColumns antenna(ms.antenna());
+    ROMSObservationColumns observation(ms.observation());
+    ASSERT(observation.nrow() > 0);
+    ASSERT(!observation.flagRow()(0));
+
+    // Get instrument name.
+    String name = observation.telescopeName()(0);
+
+    // Get station positions.
+    MVPosition centroid;
+    vector<Station> stations(antenna.nrow());
+    for(uint i = 0; i < stations.size(); ++i)
+      {
+        // Get station name and ITRF position.
+        MPosition position =
+          MPosition::Convert(antenna.positionMeas()(i),
+                             MPosition::ITRF)();
+
+        // Store station information.
+        stations[i] = initStation(ms, i, antenna.name()(i), position);
+
+        ASSERT(stations[i].nField() > 0);
+
+        // Update ITRF centroid.
+        centroid += position.getValue();
+      }
+
+    // Get the instrument position in ITRF coordinates, or use the centroid
+    // of the station positions if the instrument position is unknown.
+    MPosition position;
+    if(MeasTable::Observatory(position, name))
+      {
+        position = MPosition::Convert(position, MPosition::ITRF)();
+      }
+    else
+      {
+        LOG_INFO("LofarATermOld initInstrument "
+                 "Instrument position unknown; will use centroid of stations.");
+        ASSERT(antenna.nrow() != 0);
+        centroid *= 1.0 / static_cast<double>(antenna.nrow());
+        position = MPosition(centroid, MPosition::ITRF);
+      }
+
+    m_instrument = Instrument(name, position, stations.begin(), stations.end());
+  }
+
+  Station LofarATermOld::initStation(const MeasurementSet &ms,
+    uint id,
+    const String &name,
+    const MPosition &position) const
+  {
+    AlwaysAssert(ms.keywordSet().isDefined("LOFAR_ANTENNA_FIELD"), SynthesisError);
+
+    Table tab_field(ms.keywordSet().asTable("LOFAR_ANTENNA_FIELD"));
+    tab_field = tab_field(tab_field.col("ANTENNA_ID") == static_cast<Int>(id));
+
+    const uLong nFields = tab_field.nrow();
+    AlwaysAssert(nFields == 1 || nFields == 2, SynthesisError);
+
+    ROScalarColumn<String> c_name(tab_field, "NAME");
+    ROArrayQuantColumn<double> c_position(tab_field, "POSITION",
+                                          "m");
+    ROArrayQuantColumn<double> c_axes(tab_field, "COORDINATE_AXES",
+                                      "m");
+    ROArrayQuantColumn<double> c_tile_offset(tab_field,
+                                             "TILE_ELEMENT_OFFSET", "m");
+    ROArrayQuantColumn<double> c_offset(tab_field, "ELEMENT_OFFSET",
+                                        "m");
+    ROArrayColumn<Bool> c_flag(tab_field, "ELEMENT_FLAG");
+
+    AntennaField field[2];
+    for(uLong i = 0; i < nFields; ++i)
+      {
+        // Read antenna field center.
+        Vector<Quantum<double> > aips_position =
+          c_position(i);
+        ASSERT(aips_position.size() == 3);
+
+        Vector3 position = {{aips_position[0].getValue(),
+                             aips_position[1].getValue(),
+                             aips_position[2].getValue()}};
+
+        // Read antenna field coordinate axes.
+        Matrix<Quantum<double> > aips_axes = c_axes(i);
+        ASSERT(aips_axes.shape().isEqual(IPosition(2, 3, 3)));
+
+        Vector3 P = {{aips_axes(0, 0).getValue(), aips_axes(1, 0).getValue(),
+                      aips_axes(2, 0).getValue()}};
+        Vector3 Q = {{aips_axes(0, 1).getValue(), aips_axes(1, 1).getValue(),
+                      aips_axes(2, 1).getValue()}};
+        Vector3 R = {{aips_axes(0, 2).getValue(), aips_axes(1, 2).getValue(),
+                      aips_axes(2, 2).getValue()}};
+
+        // Store information as AntennaField.
+        field[i] = AntennaField(c_name(i), position, P, Q, R);
+
+        if(c_name(i) != "LBA")
+          {
+            // Read tile configuration for HBA antenna fields.
+            Matrix<Quantum<double> > aips_offset =
+              c_tile_offset(i);
+            ASSERT(aips_offset.nrow() == 3);
+
+            const uLong nElement = aips_offset.ncolumn();
+            for(uLong j = 0; j < nElement; ++j)
+              {
+                Vector3 offset = {{aips_offset(0, j).getValue(),
+                                   aips_offset(1, j).getValue(),
+                                   aips_offset(2, j).getValue()}};
+
+                field[i].appendTileElement(offset);
+              }
+          }
+
+        // Read element position offsets and flags.
+        Matrix<Quantum<double> > aips_offset = c_offset(i);
+        Matrix<Bool> aips_flag = c_flag(i);
+
+        const uLong nElement = aips_offset.ncolumn();
+        ASSERT(aips_offset.shape().isEqual(IPosition(2, 3, nElement)));
+        ASSERT(aips_flag.shape().isEqual(IPosition(2, 2, nElement)));
+
+        for(uLong j = 0; j < nElement; ++j)
+          {
+            AntennaField::Element element;
+            element.offset[0] = aips_offset(0, j).getValue();
+            element.offset[1] = aips_offset(1, j).getValue();
+            element.offset[2] = aips_offset(2, j).getValue();
+            element.flag[0] = aips_flag(0, j);
+            element.flag[1] = aips_flag(1, j);
+
+            field[i].appendElement(element);
+          }
+      }
+
+    return (nFields == 1 ? Station(name, position, field[0])
+            : Station(name, position, field[0], field[1]));
+  }
+
+  void LofarATermOld::initReferenceDirections(const MeasurementSet &ms,
+    uint idField)
+  {
+    // Get phase center as RA and DEC (J2000).
+    ROMSFieldColumns field(ms.field());
+    ASSERT(field.nrow() > idField);
+    ASSERT(!field.flagRow()(idField));
+
+    m_refDelay = MDirection::Convert(field.delayDirMeas(idField),
+      MDirection::J2000)();
+
+    // By default, the tile beam reference direction is assumed to be equal
+    // to the station beam reference direction (for backward compatibility,
+    // and for non-HBA measurements).
+    m_refTile = m_refDelay;
+
+    // The MeasurementSet class does not support LOFAR specific columns, so we
+    // use ROArrayMeasColumn to read the tile beam reference direction.
+    Table tab_field(ms.keywordSet().asTable("FIELD"));
+    static const String columnName = "LOFAR_TILE_BEAM_DIR";
+    if(tab_field.tableDesc().isColumn(columnName))
+    {
+      ROArrayMeasColumn<MDirection> c_direction(tab_field, columnName);
+      if(c_direction.isDefined(idField))
+      {
+        m_refTile = MDirection::Convert(c_direction(idField)(IPosition(1, 0)),
+          MDirection::J2000)();
+      }
+    }
+  }
+
+  void LofarATermOld::initReferenceFreq(const MeasurementSet &ms,
+    uint idDataDescription)
+  {
+    // Read polarization id and spectral window id.
+    ROMSDataDescColumns desc(ms.dataDescription());
+    ASSERT(desc.nrow() > idDataDescription);
+    ASSERT(!desc.flagRow()(idDataDescription));
+
+    const uint idWindow = desc.spectralWindowId()(idDataDescription);
+
+    // Get spectral information.
+    ROMSSpWindowColumns window(ms.spectralWindow());
+    ASSERT(window.nrow() > idWindow);
+    ASSERT(!window.flagRow()(idWindow));
+
+    m_refFreq = window.refFrequency()(idWindow);
+  }
+
+  BeamCoeff::BeamCoeff()
+    :   m_center(0.0),
+        m_width(1.0)
+  {
+  }
+
+  void BeamCoeff::load(const Path &path)
+  {
+    // Open file.
+    String expandedPath = path.expandedName();
+    ifstream in(expandedPath.c_str());
+    cout<<"Reading "<<expandedPath<<endl;
+    if(!in)
+      {
+        THROW (Exception, "Unable to open beam coefficient file.");
+      }
+
+    // Read file header.
+    String header, token0, token1, token2, token3, token4, token5;
+    getline(in, header);
+
+    uLong nElements, nHarmonics, nPowerTheta, nPowerFreq;
+    double freqAvg, freqRange;
+
+    istringstream iss(header);
+    iss >> token0 >> nElements >> token1 >> nHarmonics >> token2 >> nPowerTheta
+        >> token3 >> nPowerFreq >> token4 >> freqAvg >> token5 >> freqRange;
+
+    if(!in || !iss || token0 != "d" || token1 != "k" || token2 != "pwrT"
+       || token3 != "pwrF" || token4 != "freqAvg" || token5 != "freqRange")
+      {
+        THROW (Exception, "Unable to parse header");
+      }
+
+    if(nElements * nHarmonics * nPowerTheta * nPowerFreq == 0)
+      {
+        THROW (Exception, "The number of coefficients should be"
+               " larger than zero.");
+      }
+
+    ASSERT(nElements == 2);
+    ASSERT(in.good());
+
+    // Allocate coefficient matrix.
+    m_center = freqAvg;
+    m_width = freqRange;
+    m_coeff = Array<DComplex>(IPosition(4, 2, nPowerFreq, nPowerTheta, nHarmonics));
+
+    uLong nCoeff = 0;
+    while(in.good())
+      {
+        // Read line from file.
+        String line;
+        getline(in, line);
+
+        // Skip lines that contain only whitespace.
+        if(line.find_last_not_of(" ", String::npos) == String::npos)
+          {
+            continue;
+          }
+
+        // Parse line.
+        uLong element, harmonic, powerTheta, powerFreq;
+        double re, im;
+
+        iss.clear();
+        iss.str(line);
+        iss >> element >> harmonic >> powerTheta >> powerFreq >> re >> im;
+
+        if(!iss || element >= nElements || harmonic >= nHarmonics
+           || powerTheta >= nPowerTheta || powerFreq >= nPowerFreq)
+          {
+            THROW (Exception, "Error reading beam coefficient file.");
+          }
+
+        // Store coefficient.
+        m_coeff(IPosition(4, element, powerFreq, powerTheta, harmonic)) = DComplex(re, im);
+
+        // Update coefficient counter.
+        ++nCoeff;
+      }
+
+    if(!in.eof())
+      {
+        THROW (Exception, "Error reading beam coefficient"
+               " file.");
+      }
+
+    if(nCoeff != nElements * nHarmonics * nPowerTheta * nPowerFreq)
+      {
+        THROW (Exception, "The number of coefficients"
+               " specified in the header does not match the number of coefficients"
+               " in the file.");
+      }
+  }
+
+  AntennaField::AntennaField(const String &name,
+    const Vector3 &position,
+    const Vector3 &p,
+    const Vector3 &q,
+    const Vector3 &r)
+    :   m_name(name),
+        m_position(position)
+  {
+    m_axes[P] = p;
+    m_axes[Q] = q;
+    m_axes[R] = r;
+  }
+
+  const String &AntennaField::name() const
+  {
+    return m_name;
+  }
+
+  const Vector3 &AntennaField::position() const
+  {
+    return m_position;
+  }
+
+  const Vector3 &AntennaField::axis(Axis axis) const
+  {
+    return m_axes[axis];
+  }
+
+  Bool AntennaField::isHBA() const
+  {
+    return m_name != "LBA";
+  }
+
+  void AntennaField::appendTileElement(const Vector3 &offset)
+  {
+    m_tileElements.push_back(offset);
+  }
+
+  void AntennaField::appendElement(const Element &element)
+  {
+    m_elements.push_back(element);
+  }
+
+  Station::Station(const String &name,
+    const MPosition &position)
+    :   m_name(name),
+        m_position(position)
+  {
+  }
+
+  Station::Station(const String &name,
+    const MPosition &position,
+    const AntennaField &field0)
+    :   m_name(name),
+        m_position(position)
+  {
+    m_fields.push_back(field0);
+  }
+
+  Station::Station(const String &name,
+    const MPosition &position,
+    const AntennaField &field0,
+    const AntennaField &field1)
+    :   m_name(name),
+        m_position(position)
+  {
+    m_fields.push_back(field0);
+    m_fields.push_back(field1);
+  }
+
+  const String &Station::name() const
+  {
+    return m_name;
+  }
+
+  const MPosition &Station::position() const
+  {
+    return m_position;
+  }
+
+  bool Station::isPhasedArray() const
+  {
+    return !m_fields.empty();
+  }
+
+  uint Station::nField() const
+  {
+    return m_fields.size();
+  }
+
+  const AntennaField &Station::field(uint i) const
+  {
+    return m_fields[i];
+  }
+
+  Instrument::Instrument(const String &name,
+    const MPosition &position)
+    :   m_name(name),
+        m_position(position)
+  {
+  }
+
+  const String &Instrument::name() const
+  {
+    return m_name;
+  }
+
+  const MPosition &Instrument::position() const
+  {
+    return m_position;
+  }
+
+  uint Instrument::nStations() const
+  {
+    return m_stations.size();
+  }
+
+  const Station &Instrument::station(uint i) const
+  {
+    return m_stations[i];
+  }
+
+  const Station &Instrument::station(const String &name) const
+  {
+    map<String, uint>::const_iterator it = m_index.find(name);
+    if(it == m_index.end())
+      {
+        THROW (Exception, "Unknown station: " + name);
+      }
+
+    return m_stations[it->second];
+  }
+
+  void Instrument::append(const Station &station)
+  {
+    m_stations.push_back(station);
+  }
+} // namespace LOFAR
diff --git a/CEP/Imager/LofarFT/src/LofarConvolutionFunction.cc b/CEP/Imager/LofarFT/src/LofarConvolutionFunction.cc
index 226fda025dea172629ae5f81ec81636f5b1a5259..087b1451e59d4bd15bd78f917ea1b47dc56ce9c0 100644
--- a/CEP/Imager/LofarFT/src/LofarConvolutionFunction.cc
+++ b/CEP/Imager/LofarFT/src/LofarConvolutionFunction.cc
@@ -25,12 +25,16 @@
 #include <Common/LofarLogger.h>
 #include <Common/OpenMP.h>
 
+#include <BBSKernel/MeasurementAIPS.h>
+
 #include <casa/Logging/LogIO.h>
 #include <casa/Logging/LogOrigin.h>
 #include <casa/Arrays/Cube.h>
 #include <casa/Arrays/Matrix.h>
 #include <casa/Arrays/MatrixMath.h>
 #include <casa/Arrays/ArrayMath.h>
+#include <casa/Arrays/ArrayUtil.h>
+#include <casa/Arrays/ArrayIter.h>
 
 #include <ms/MeasurementSets/MeasurementSet.h>
 #include <measures/Measures/MDirection.h>
@@ -59,6 +63,9 @@
 #include <casa/sstream.h>
 #include <iomanip>
 
+#include <lattices/Lattices/ArrayLattice.h>
+#include <lattices/Lattices/LatticeFFT.h>
+
 namespace LOFAR
 {
 
@@ -68,13 +75,20 @@ namespace LOFAR
    const MeasurementSet& ms,
    uInt nW, double Wmax,
    uInt oversample,
-   const String& beamElementPath,
    Int verbose,
    Int maxsupport,
-   const String& imgName)
+   const String& imgName,
+   Bool Use_EJones,
+   Bool Apply_Element,
+   const casa::Record& parameters
+  )
+  // ,
+  //Int TaylorTerm,
+    //Double RefFreq
     : m_shape(shape),
       m_coordinates(coordinates),
-      m_aTerm(ms, beamElementPath),
+      itsParameters(parameters),
+      m_aTerm(ms, parameters),
       m_maxW(Wmax), //maximum W set by ft machine to flag the w>wmax
       m_nWPlanes(nW),
       m_oversampling(oversample),
@@ -92,7 +106,6 @@ namespace LOFAR
       itsTimeCFpar(0),
       itsTimeCFfft(0),
       itsTimeCFcnt(0)
-      //Not sure how useful that is
   {
     if (itsVerbose > 0) {
       cout<<"LofarConvolutionFunction:shape  "<<shape<<endl;
@@ -101,17 +114,29 @@ namespace LOFAR
 
     //    m_maxCFSupport=0; //need this parameter to stack all the CF for average PB estimate
 
-    m_wScale = WScale(m_maxW, m_nWPlanes);
+    //itsTaylorTerm=TaylorTerm;
+    //itsRefFreq=RefFreq;
+    //cout<<"itsTaylorTerm itsRefFreq "<<itsTaylorTerm<<" "<<itsRefFreq<<endl;
+      m_wScale = WScale(m_maxW, m_nWPlanes);
     MEpoch start = observationStartTime(ms, 0);
 
-    m_refFrequency = observationReferenceFreq(ms, 0);
-
+    m_refFrequency = BBS::readFreqReference(ms, 0);
+    its_Use_EJones=Use_EJones;
+    its_Apply_Element=Apply_Element;
+    its_count_time=0;
+    //if(!its_Use_EJones){cout<<"Not using the beam in the calculation of the CFs...."<<endl;}
     if (m_oversampling%2 == 0) {
       // Make OverSampling an odd number
       m_oversampling++;
     }
 
-    list_freq   = Vector<Double>(1, m_refFrequency);
+    //list_freq   = Vector<Double>(1, m_refFrequency);
+    ROMSSpWindowColumns window(ms.spectralWindow());
+    list_freq.resize(window.nrow());
+    for(uInt i=0; i<window.nrow();++i){
+      list_freq[i]=window.refFrequency()(i);
+    };
+
     m_nChannel  = list_freq.size();
     ROMSAntennaColumns antenna(ms.antenna());
     m_nStations = antenna.nrow();
@@ -131,6 +156,35 @@ namespace LOFAR
 
     // Precalculate the Wtwerm fft for all w-planes.
     store_all_W_images();
+    itsFilledVectorMasks=false;
+
+    // Build the cutted spheroidal for the element beam image
+    Double pixelSize = abs(m_coordinates.increment()[0]);
+    Double imageDiameter = pixelSize * m_shape(0);
+    DirectionCoordinate coordinate = m_coordinates;
+    Double aPixelAngSize = min(m_pixelSizeSpheroidal,
+    			       estimateAResolution(m_shape, m_coordinates));
+    //Double aPixelAngSize = estimateAResolution(m_shape, m_coordinates, 30);
+    Int nPixelsConv = imageDiameter / aPixelAngSize;
+    Matrix<Complex> spheroid_cut_element(IPosition(2,nPixelsConv,nPixelsConv),1.);
+    taper(spheroid_cut_element);
+    //Matrix<Complex> spheroid_cut_element_fft=give_normalized_fft_lapack(spheroid_cut_element, true);
+    normalized_fft(spheroid_cut_element, true);
+    spheroid_cut_element_fft=spheroid_cut_element;
+    Matrix<Complex> spheroid_cut_element_padfft(zero_padding(spheroid_cut_element_fft, m_shape(0)));
+    //Matrix<Complex> spheroid_cut_element_padfft_fft=give_normalized_fft_lapack (spheroid_cut_element_padfft, false);
+    normalized_fft (spheroid_cut_element_padfft, false);
+    Matrix<Complex> spheroid_cut_element_padfft_fft(spheroid_cut_element_padfft);
+    float threshold = 1.e-6;
+    for (Int jj=0; jj<m_shape[1]; ++jj) {
+      for (Int ii=0; ii<m_shape[0]; ++ii) {
+	Float absVal = abs(spheroid_cut_element_padfft_fft(ii,jj));
+	spheroid_cut_element_padfft_fft(ii,jj) = std::max (absVal, threshold);
+      }
+    }
+    Spheroid_cut_im_element.reference (real(spheroid_cut_element_padfft_fft));
+    store(m_coordinates,Spheroid_cut_im_element,"Spheroid_cut_im_element.img");
+
   }
 
   //      ~LofarConvolutionFunction ()
@@ -140,6 +194,7 @@ namespace LOFAR
   // Precalculate all W-terms in the fourier domain
   void LofarConvolutionFunction::store_all_W_images()
   {
+    logIO()<<"LofarConvolutionFunction::store_all_W_images() "<<"Computing the Wterms..."<< LogIO::POST;//<<endl;
     PrecTimer wTimer;
     wTimer.start();
     Double pixelSize = abs(m_coordinates.increment()[0]);
@@ -166,7 +221,7 @@ namespace LOFAR
         if (itsVerbose > 0) {
           cout<<"Number of pixel in the "<<i<<"-wplane: "<<nPixelsConv
               <<"  (w="<<w<<")"<<endl;
-        }
+	}
         if (nPixelsConv > itsMaxSupport) {
           nPixelsConv = itsMaxSupport;
         }
@@ -194,8 +249,17 @@ namespace LOFAR
 #pragma omp atomic
       itsTimeWpar += ptime;
     } // end omp parallel
+
+    its_MaxWSupport=0;
+    for (uInt i=0; i<m_nWPlanes; ++i) {
+      if(m_WplanesStore[i].shape()[0]>its_MaxWSupport){its_MaxWSupport=m_WplanesStore[i].shape()[0];};
+    }
+
+
+
     wTimer.stop();
     itsTimeW = wTimer.getReal();
+    logIO()<<"LofarConvolutionFunction::store_all_W_images() "<<"... Done!"<< LogIO::POST;//<<endl;
   }
 
 
@@ -204,6 +268,9 @@ namespace LOFAR
   // Put it in a map object with a (double time) key.
   void LofarConvolutionFunction::computeAterm (Double time)
   {
+    //logIO()<<"LofarConvolutionFunction::computeAterm "<<"Computing the Aterms for t="<<time<<", and maximum Wupport="<<its_MaxWSupport<< LogIO::POST;//<<endl;
+    PrecTimer timerCyril;
+    timerCyril.start();
     if (m_AtermStore.find(time) != m_AtermStore.end()) {
       // Already done.
       return;
@@ -215,73 +282,173 @@ namespace LOFAR
     // Try to avoid making copies when inserting elements in vector or map.
     // Therefore first create the elements and resize them.
     m_AtermStore[time] = vector< vector< Cube<Complex> > >();
+    m_AtermStore_element[time] = vector< vector< Cube<Complex> > >();
+    m_AtermStore_station[time] = vector< vector< Cube<Complex> > >();
     vector< vector< Cube<Complex> > >& aTermList = m_AtermStore[time];
+    vector< vector< Cube<Complex> > >& aTermList_element = m_AtermStore_element[time];
+    vector< vector< Cube<Complex> > >& aTermList_station = m_AtermStore_station[time];
     // Calculate the A-term and fill the vector for all stations.
     aTermList.resize (m_nStations);
+    aTermList_element.resize (m_nStations);
+    aTermList_station.resize (m_nStations);
     ///#pragma omp parallel
     {
       // Thread private variables.
       PrecTimer timerFFT;
       PrecTimer timerPar;
+
       ///#pragma omp for
+      DirectionCoordinate coordinate = m_coordinates;
+      Double aPixelAngSize = min(m_pixelSizeSpheroidal, estimateAResolution(m_shape, m_coordinates));
+      Int nPixelsConv = imageDiameter / aPixelAngSize;
+      if (nPixelsConv > itsMaxSupport) {
+	nPixelsConv = itsMaxSupport;
+      }
+      // Make odd and optimal.
+      nPixelsConv = FFTCMatrix::optimalOddFFTSize (nPixelsConv);
+      aPixelAngSize = imageDiameter / nPixelsConv;
+      IPosition shape(2, nPixelsConv, nPixelsConv);
+      Vector<Double> increment_old(coordinate.increment());
+      Vector<Double> increment(2);
+      increment[0] = aPixelAngSize*sign(increment_old[0]);
+      increment[1] = aPixelAngSize*sign(increment_old[1]);
+      coordinate.setIncrement(increment);
+      Vector<Double> refpix(2, 0.5*(nPixelsConv-1));
+      coordinate.setReferencePixel(refpix);
+      
+      DirectionCoordinate coordinate_element = m_coordinates;
+      //Double aPixelAngSize_element = estimateAResolution(m_shape, m_coordinates, 30.);
+      Double aPixelAngSize_element = min(m_pixelSizeSpheroidal, estimateAResolution(m_shape, m_coordinates));
+      Int nPixelsConv_element = imageDiameter / aPixelAngSize_element;
+      //cout<<"Element_beam size:"<<"1 "<<nPixelsConv_element<<", 2 "<<aPixelAngSize_element<<endl;
+      nPixelsConv_element = FFTCMatrix::optimalOddFFTSize (nPixelsConv_element);
+      aPixelAngSize_element = imageDiameter / nPixelsConv_element;
+      //cout<<"Element_beam size:"<<"1 "<<nPixelsConv_element<<", 2 "<<aPixelAngSize_element<<endl;
+      IPosition shape_element(2, nPixelsConv_element, nPixelsConv_element);
+      Vector<Double> increment_element(2);
+      increment_element[0] = aPixelAngSize_element*sign(increment_old[0]);
+      increment_element[1] = aPixelAngSize_element*sign(increment_old[1]);
+      coordinate_element.setIncrement(increment_element);
+      Vector<Double> refpix_element(2, 0.5*(nPixelsConv_element-1));
+      coordinate_element.setReferencePixel(refpix_element);
+      
+      //hier is het
+      
+      m_aTerm.setDirection(coordinate, shape);
+      
+      MEpoch binEpoch;
+      binEpoch.set(Quantity(time, "s"));
+      
+      m_aTerm.setEpoch(binEpoch);
+//       LofarATerm::ITRFDirectionMap dirMap = m_aTerm.makeDirectionMap(coordinate, shape, binEpoch);
+
       for (uInt i=0; i<m_nStations; ++i) {
         timerPar.start();
-	DirectionCoordinate coordinate = m_coordinates;
-        Double aPixelAngSize = min(m_pixelSizeSpheroidal,
-                                   estimateAResolution(m_shape, m_coordinates));
-        Int nPixelsConv = imageDiameter / aPixelAngSize;
-        if (nPixelsConv > itsMaxSupport) {
-          nPixelsConv = itsMaxSupport;
-        }
-        // Make odd and optimal.
-        nPixelsConv = FFTCMatrix::optimalOddFFTSize (nPixelsConv);
-        aPixelAngSize = imageDiameter / nPixelsConv;
-        if (itsVerbose > 0) {
-          cout.precision(20);
-          cout<<"Number of pixel in the Aplane of "<<i<<": "<<nPixelsConv
-              <<", time="<<fixed<<time<<endl;
-        }
-        IPosition shape(2, nPixelsConv, nPixelsConv);
-        Vector<Double> increment_old(coordinate.increment());
-        Vector<Double> increment(2);
-        increment[0] = aPixelAngSize*sign(increment_old[0]);
-        increment[1] = aPixelAngSize*sign(increment_old[1]);
-        coordinate.setIncrement(increment);
-        Vector<Double> refpix(2, 0.5*(nPixelsConv-1));
-        coordinate.setReferencePixel(refpix);
 
         //======================================
-        // Disable the beam
+        // Separated element and station
         //======================================
-        //Cube<Complex> aterm_cube(IPosition(3,nPixels_Conv,nPixels_Conv,4),1.);
-        //for (uInt iiii=0;iiii<nPixels_Conv;++iiii) {
-        //  for (uInt iiiii=0;iiiii<nPixels_Conv;++iiiii) {
-        //    aterm_cube(iiii,iiiii,1)=0.;
-        //    aterm_cube(iiii,iiiii,2)=0.;
-        //  }
-        //}
-        //vector< Cube<Complex> > aTermA;
-        //aTermA.push_back(aterm_cube);
+	vector< Cube<Complex> > aTermA_element;
+	vector< Cube<Complex> > aTermA_array;
+
+	vector< Matrix<Complex> > aTermA_array_plane(m_aTerm.evaluateArrayFactor(i, 0, list_freq , list_freq , true));
+	aTermA_array.resize(m_nChannel);
+        for (uInt ch=0; ch<m_nChannel; ++ch) {
+	  aTermA_array[ch].resize(IPosition(3,shape[0],shape[0],4));
+	  aTermA_array[ch]=0.;
+	}
+        for (uInt ch=0; ch<m_nChannel; ++ch) {
+	  Matrix<Complex> plane(aTermA_array[ch].xyPlane(0));
+	  plane=aTermA_array_plane[ch].copy();
+	  Matrix<Complex> plane2(aTermA_array[ch].xyPlane(3));
+	  plane2=aTermA_array_plane[ch].copy();
+	}
+
+	aTermA_element=m_aTerm.evaluateElementResponse(i, 0, list_freq, true);
+
+	//store(coordinate,aTermA_element[0],"aTermA_element."+String::toString(i)+".img");
+	//store(coordinate,aTermA_array[0],"aTermA_array."+String::toString(i)+".img");
+
+        //vector< Cube<Complex> > aTermA = m_aTerm.evaluate(i, dirMap, list_freq, list_freq, false);
+	//store(coordinate,aTermA[0],"aTermA."+String::toString(i)+".orig.img");
+
+//	aTermAtmp = m_aTerm.evaluateSeparated(shape_element,
+//					   coordinate_element,
+//					   i, binEpoch,
+//					   list_freq, true);
+//	aTermA_element=aTermAtmp[0];
+//	aTermAtmp2 = m_aTerm.evaluateSeparated(shape,
+//					   coordinate,
+//					   i, binEpoch,
+//					   list_freq, true);
+//	aTermA_station=aTermAtmp2[1];
+	//store(aTermA_element[0],"aTermA_element.img");
+	//store(aTermA_station[0],"aTermA_station.img");
+
+	//vector< Cube<Complex> > aTermA;
+	// if(!its_Use_EJones){
+
+        // for (uInt ch=0; ch<m_nChannel; ++ch) {
+	//   Matrix<Complex> slice0=aTermA_element[ch].xyPlane(0);
+	//   slice0=1.;
+	//   Matrix<Complex> slice1=aTermA_element[ch].xyPlane(1);
+	//   slice1=0.;
+	//   Matrix<Complex> slice2=aTermA_element[ch].xyPlane(2);
+	//   slice2=0.;
+	//   Matrix<Complex> slice3=aTermA_element[ch].xyPlane(3);
+	//   slice3=1.;
+	// }
+        // for (uInt ch=0; ch<m_nChannel; ++ch) {
+	//   Matrix<Complex> slice0=aTermA_array[ch].xyPlane(0);
+	//   slice0=1.;
+	//   Matrix<Complex> slice1=aTermA_array[ch].xyPlane(1);
+	//   slice1=0.;
+	//   Matrix<Complex> slice2=aTermA_array[ch].xyPlane(2);
+	//   slice2=0.;
+	//   Matrix<Complex> slice3=aTermA_array[ch].xyPlane(3);
+	//   slice3=1.;
+	// }
+
+	// }
+	// else{
         //======================================
         // Enable the beam
         //======================================
-        MEpoch binEpoch;
-        binEpoch.set(Quantity(time, "s"));
-        vector< Cube<Complex> > aTermA = m_aTerm.evaluate(shape,
-                                                          coordinate,
-                                                          i, binEpoch,
-                                                          list_freq, true);
+//	aTermA = m_aTerm.evaluate(shape,
+//				  coordinate,
+//				  i, binEpoch,
+//				  list_freq, true);
+	// }
+
+
+//        // JVZ: Direction map should be computed only once for all stations.
+//        // However, this requires the DirectionCoordinate instance and shape to
+//        // be exactly equal for all stations.
+
+//        vector< Cube<Complex> > aTermA = m_aTerm.evaluate(i, dirMap, list_freq,
+//          list_freq, true);
+
         // Compute the fft on the beam
+	vector< Cube<Complex> > aTermAs;
+	aTermAs.resize(m_nChannel);
+	aTermAs[0].resize(IPosition(3,its_MaxWSupport,its_MaxWSupport,4));
         for (uInt ch=0; ch<m_nChannel; ++ch) {
           for (uInt pol=0; pol<4; ++pol) {
-            Matrix<Complex> plane (aTermA[ch].xyPlane(pol));
-            AlwaysAssert (plane.contiguousStorage(), AipsError);
-            normalized_fft (timerFFT, plane);
+
+            Matrix<Complex> plane1 (aTermA_array[ch].xyPlane(pol));
+	    //Matrix< Complex > plane0int = LinearInterpol2(plane1,200.);
+            normalized_fft (timerFFT, plane1);
+
+
           }
         }
+	// store(coordinate,aTermA_array[0],"aTermA_array.fft."+String::toString(i)+".img");
+
         // Note that push_back uses the copy constructor, so for the Cubes
         // in the vector the copy constructor is called too (which is cheap).
-        aTermList[i] = aTermA;
+        //aTermList[i] = aTermA;
+        aTermList_element[i] = aTermA_element;
+        aTermList_station[i] = aTermA_array;
         timerPar.stop();
       } // end omp for
       // Update the timing info.
@@ -297,8 +464,424 @@ namespace LOFAR
     } // end omp parallel
     aTimer.stop();
     itsTimeA = aTimer.getReal();
+    //logIO()<<"LofarConvolutionFunction::computeAterm "<<"...Done!"<< LogIO::POST;//<<endl;
+    timerCyril.stop();
+    //cout.precision(20);
+    //cout<<"For time: "<<time<<endl;
+    //assert(false);
+    //timerCyril.show(cout,"LofarConvolutionFunction::computeAterm");
   }
 
+
+  Array<Complex> LofarConvolutionFunction::ApplyElementBeam(Array<Complex> input_grid, Double time, uInt spw, const Matrix<bool>& Mask_Mueller_in, bool degridding_step)
+  {
+
+    map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter_element = m_AtermStore_element.find(time);
+    AlwaysAssert (aiter_element!=m_AtermStore_element.end(), AipsError);
+    const vector< vector< Cube<Complex> > >& aterm_element = aiter_element->second;
+
+
+
+    vector< vector< IPosition > > Mueller_Coordinates;
+    Mueller_Coordinates.resize(4);
+    for(uInt i=0;i<4;++i){
+      Mueller_Coordinates[i].resize(4);
+      IPosition pos(2,2,1);
+      for(uInt j=0;j<4;++j){
+	Mueller_Coordinates[i][j]=pos;
+      }
+    }
+
+
+    uInt ind0;
+    uInt ind1;
+    uInt ii = 0;
+    IPosition cfShape;
+    Bool allElem = True;
+    for (uInt row0=0; row0<=1; ++row0) {
+      for (uInt col0=0; col0<=1; ++col0) {
+	vector < Matrix<Complex> > Row(4);
+	vector < Matrix<Complex> > Row_non_padded(4);
+	uInt jj = 0;
+	for (uInt row1=0; row1<=1; ++row1) {
+	  for (uInt col1=0; col1<=1; ++col1) {
+	    // This Mueller ordering is for polarisation given as XX,XY,YX YY
+	    ind0 = row0 + 2*row1;
+	    ind1 = col0 + 2*col1;
+	    IPosition pos(2,2,1);
+	    pos[0]=ind0;
+	    pos[1]=ind1;
+	    Mueller_Coordinates[ii][jj]=pos;
+	    ++jj;
+	  }
+	}
+	++ii;
+      }
+    }
+
+
+
+    vector< vector< Matrix<Complex> > > vec_element_product;
+    vec_element_product.resize(4);
+    vector< vector< Matrix<Complex> > > vec_plane_product;
+    vec_plane_product.resize(4);
+    if (!degridding_step) {
+      for (uInt i=0; i<4; ++i) {
+    	for (uInt j=i; j<4; ++j) {
+	  IPosition pos_tmp(Mueller_Coordinates[i][j]);
+	  Mueller_Coordinates[i][j]=Mueller_Coordinates[j][i];
+	  Mueller_Coordinates[j][i]=pos_tmp;
+        }
+      }
+    }
+
+    Int nx(input_grid.shape()[0]);
+    Int ny(input_grid.shape()[1]);
+    Int npol(input_grid.shape()[2]);
+
+    Cube<Complex> aTermA(aterm_element[0][spw].copy());
+    Array<Complex> grid_out(input_grid.shape(),0.);
+
+
+    if(!degridding_step){
+
+      logIO() <<"LofarConvolutionFunction::ApplyElementBeam "<<"FFT of the gridded data for this timeslot" << LogIO::POST;//<<endl;
+
+      for(uInt channel=0;channel< input_grid.shape()[3];++channel){
+	{
+#pragma omp parallel for
+	for(uInt jj=0;jj<npol;++jj){
+	  //cout<<"jj="<<jj<<endl;
+	  Matrix<Complex> plane_array_in  = input_grid(Slicer(IPosition(4, 0, 0, jj, 0),
+							      IPosition(4, nx, nx, 1, 1))).nonDegenerate();
+	  //store(plane_array_in,"plane_array_in"+String::toString(jj)+".img");
+	  normalized_fft (plane_array_in, false);
+	  //store(plane_array_in,"plane_array_in"+String::toString(jj)+".img");
+	}
+	}
+      }
+    }
+
+
+
+    //cout<<"LofarConvolutionFunction::ApplyElementBeam "<<"Calculate element beams"<<endl;
+    logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Calculate element beams"<< LogIO::POST;//<<endl;
+    for(uInt ii=0;ii<4;++ii){
+      vec_element_product[ii].resize(4);
+      vec_plane_product[ii].resize(4);
+      for(uInt jj=0;jj<4;++jj){
+	if(Mask_Mueller_in(ii,jj)==true){
+	  vec_element_product[ii][jj].resize(IPosition(2, nx, nx));
+	  vec_plane_product[ii][jj].resize(aTermA.xyPlane(0).shape());
+	  vec_plane_product[ii][jj]=aTermA.xyPlane((Mueller_Coordinates[ii][jj])[0]) * aTermA.xyPlane((Mueller_Coordinates[ii][jj])[1]);
+	  taper(vec_plane_product[ii][jj]);
+	  if(!degridding_step){vec_plane_product[ii][jj]=conj(vec_plane_product[ii][jj]);};
+	}
+	//store(vec_plane_product[ii][jj],"vec_plane_product"+String::toString(ii)+String::toString(jj)+".img");
+      }
+    }
+
+
+    logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"FFT - Zero Pad - IFFT"<< LogIO::POST;//<<endl;
+    //#pragma omp parallel
+    {
+      Int ii;
+      Int jj;
+#pragma omp parallel for private(ii,jj)
+      for(uInt iii=0;iii<16;++iii){
+	jj=floor(float(iii)/4.);
+	ii=floor((float(iii)/4.-jj)*4.);
+	//cout<<"iii"<<iii<<" "<<ii<<" "<<jj<<endl;
+	if(Mask_Mueller_in(ii,jj)==true){
+	  normalized_fft (vec_plane_product[ii][jj], true);
+	  vec_element_product[ii][jj]=zero_padding(vec_plane_product[ii][jj], nx);
+	  normalized_fft (vec_element_product[ii][jj], false);
+	  //store(vec_element_product[ii][jj],"vec_element_product"+String::toString(ii)+String::toString(jj)+".img");
+	}
+
+      }
+    }
+
+    //    assert(false);
+
+
+    //#pragma omp parallel
+    if(npol==4)
+      {
+	logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Multiply element and data in the image plane"<< LogIO::POST;//<<endl;
+	int y=0;
+	uInt ii=0;
+	uInt jj=0;
+#pragma omp parallel for private(y,ii,jj)
+	for(int x=0 ; x<nx ; ++x){
+	  //cout<<"x="<<x<<endl;
+	  for(y=0 ; y<nx ; ++y){
+
+	    for(ii=0;ii<4;++ii){
+	      for(jj=0;jj<4;++jj){
+		if(Mask_Mueller_in(ii,jj)==true){
+		  grid_out(IPosition(4,x,y,jj,0)) += vec_element_product[ii][jj](x,y) * input_grid(IPosition(4,x,y,ii,0))/Spheroid_cut_im_element(x,y);
+
+		}
+	      }
+	    }
+	  }
+	}
+      }
+
+    if(npol==1)
+      {
+	logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Multiply element and data in the image plane"<< LogIO::POST;//<<endl;
+	int y=0;
+	uInt ii=0;
+	uInt jj=0;
+#pragma omp parallel for private(y,ii,jj)
+	for(int x=0 ; x<nx ; ++x){
+	  //cout<<"x="<<x<<endl;
+	  for(y=0 ; y<nx ; ++y){
+
+	    for(ii=0;ii<4;++ii){
+	      for(jj=0;jj<4;++jj){
+		if(Mask_Mueller_in(ii,jj)==true){
+		  grid_out(IPosition(4,x,y,0,0)) += vec_element_product[ii][jj](x,y) * input_grid(IPosition(4,x,y,0,0))/(2.*Spheroid_cut_im_element(x,y));
+		}
+	      }
+	    }
+	  }
+	}
+
+      }
+
+    logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Shapes InputGrid:"<<input_grid.shape()<<", Shapes OutputGrid:"<< LogIO::POST;//<<grid_out.shape()<<endl;
+
+
+    return grid_out;
+
+  }
+
+  //==================================================================
+  //==================================================================
+  Array<Complex> LofarConvolutionFunction::ApplyElementBeam2(Array<Complex>& input_grid, Double time, uInt spw, const Matrix<bool>& Mask_Mueller_in2, bool degridding_step, Int UsedMask)
+  {
+
+    Matrix<bool> Mask_Mueller_in(Mask_Mueller_in2.copy());
+    for(uInt i=0;i<4;++i){
+      for(uInt j=0;j<4;++j){
+    	Mask_Mueller_in(i,j)=true;
+      }
+    }
+    map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter_element = m_AtermStore_element.find(time);
+    AlwaysAssert (aiter_element!=m_AtermStore_element.end(), AipsError);
+    const vector< vector< Cube<Complex> > >& aterm_element = aiter_element->second;
+
+
+
+    vector< vector< IPosition > > Mueller_Coordinates;
+    Mueller_Coordinates.resize(4);
+    for(uInt i=0;i<4;++i){
+      Mueller_Coordinates[i].resize(4);
+      IPosition pos(2,2,1);
+      for(uInt j=0;j<4;++j){
+	Mueller_Coordinates[i][j]=pos;
+      }
+    }
+
+    {
+    uInt ind0;
+    uInt ind1;
+    uInt ii = 0;
+    IPosition cfShape;
+    Bool allElem = True;
+    for (uInt row0=0; row0<=1; ++row0) {
+      for (uInt col0=0; col0<=1; ++col0) {
+	vector < Matrix<Complex> > Row(4);
+	vector < Matrix<Complex> > Row_non_padded(4);
+	uInt jj = 0;
+	for (uInt row1=0; row1<=1; ++row1) {
+	  for (uInt col1=0; col1<=1; ++col1) {
+	    // This Mueller ordering is for polarisation given as XX,XY,YX YY
+	    ind0 = row0 + 2*row1;
+	    ind1 = col0 + 2*col1;
+	    //ind0 = 2.*row0 + row1;
+	    //ind1 = 2.*col0 + col1;
+	    IPosition pos(2,2,1);
+	    pos[0]=ind0;
+	    pos[1]=ind1;
+	    Mueller_Coordinates[ii][jj]=pos;
+	    ++jj;
+	  }
+	}
+	++ii;
+      }
+    }
+    }
+
+    if (!degridding_step) {
+      for (uInt i=0; i<4; ++i) {
+	for (uInt j=i; j<4; ++j) {
+	  IPosition pos_tmp(Mueller_Coordinates[i][j]);
+	  Mueller_Coordinates[i][j]=Mueller_Coordinates[j][i];
+	  Mueller_Coordinates[j][i]=pos_tmp;
+	  Bool bool_tmp(Mask_Mueller_in(i,j));
+	  Mask_Mueller_in(i,j)=Mask_Mueller_in(j,i);
+	  Mask_Mueller_in(i,j)=bool_tmp;
+	}
+      }
+    }
+
+    Cube<Complex> aTermA(aterm_element[0][spw].copy());
+    Array<Complex> grid_out(input_grid.shape(),0.);
+    Int nx(input_grid.shape()[0]);
+    Int ny(input_grid.shape()[1]);
+    Int npol(input_grid.shape()[2]);
+
+    vector< vector< Matrix<Complex> > > vec_plane_product;
+    vec_plane_product.resize(4);
+
+
+    //logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Calculate element beams"<< LogIO::POST;//<<endl;
+    for(uInt ii=0;ii<4;++ii){
+      vec_plane_product[ii].resize(4);
+      for(uInt jj=0;jj<4;++jj){
+	if(Mask_Mueller_in(ii,jj)==true){
+	  vec_plane_product[ii][jj].resize(aTermA.xyPlane(0).shape());
+	  vec_plane_product[ii][jj]=aTermA.xyPlane((Mueller_Coordinates[ii][jj])[0]) * conj(aTermA.xyPlane((Mueller_Coordinates[ii][jj])[1]));
+	  taper(vec_plane_product[ii][jj]);
+	  if(!degridding_step){vec_plane_product[ii][jj]=conj(vec_plane_product[ii][jj]);};
+	  //store(vec_plane_product[ii][jj],"vec_plane_product."+String::toString(ii)+"."+String::toString(jj)+".img");
+	  normalized_fft(vec_plane_product[ii][jj],true);
+	}
+      }
+    }
+
+    //assert(false);
+    //#pragma omp parallel
+    if(GridsMueller.size()==0){
+      //logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"...Declare GridsMueller Matrix"<< LogIO::POST;//<<endl;
+      GridsMueller.resize(4);
+      for(uInt ii=0;ii<4;++ii){
+	GridsMueller[ii].resize(4);
+	for(uInt jj=0;jj<4;++jj){
+	  if(Mask_Mueller_in(ii,jj)==true){
+	    GridsMueller[ii][jj].resize(IPosition(2,nx,nx));
+	    GridsMueller[ii][jj]=Complex();
+	  }
+	}
+      }
+    } else {
+      for(uInt ii=0;ii<4;++ii){
+    	for(uInt jj=0;jj<4;++jj){
+    	  if(Mask_Mueller_in(ii,jj)==true){
+    	    GridsMueller[ii][jj]=Complex();
+    	  }
+    	}
+      }
+    }
+
+    //logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Convolve..."<< LogIO::POST;//<<endl;
+    {
+      Int ii;
+      Int jj;
+#pragma omp parallel for private(ii,jj)
+      for(uInt iii=0;iii<16;++iii){
+	ii=floor(float(iii)/4.);
+	jj=floor((float(iii)/4.-ii)*4.);
+	//cout<<"iii"<<iii<<" "<<ii<<" "<<jj<<" M="<<Mask_Mueller_in(jj,ii)<<endl;
+	if(Mask_Mueller_in(ii,jj)==true){
+	  Matrix<Complex> ConvFunc(vec_plane_product[ii][jj]);
+
+	  //ConvolveGerArray(input_grid, ii, GridsMueller[ii][jj], ConvFunc);
+
+	  if(npol==1){
+	    if(!(UsedMask>-1)){
+	      ConvolveGerArray(input_grid, 0, GridsMueller[ii][jj], ConvFunc);
+	    } else {
+	      ConvolveGerArrayMask(input_grid, 0, GridsMueller[ii][jj], ConvFunc, UsedMask);
+	    }
+	  }
+	  if(npol==4){
+	    if(!(UsedMask>-1)){
+	      ConvolveGerArray(input_grid, ii, GridsMueller[ii][jj], ConvFunc);
+	    } else {
+	      ConvolveGerArrayMask(input_grid, ii, GridsMueller[ii][jj], ConvFunc, UsedMask);
+	    }
+	  }
+
+
+	}
+
+      }
+    }
+
+    //logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Convolve ... Done!"<< LogIO::POST;//<<endl;
+    // Int ii;
+    // Int jj;
+    // for(uInt iii=0;iii<16;++iii){
+    //   jj=floor(float(iii)/4.);
+    //   ii=floor((float(iii)/4.-jj)*4.);
+    //   //cout<<"iii"<<iii<<" "<<ii<<" "<<jj<<endl;
+    //   if(Mask_Mueller_in(ii,jj)==true){
+    // 	store(GridsMueller[ii][jj],"grid_out"+String::toString(ii)+String::toString(jj)+".img");
+    //   }
+    // }
+
+
+
+
+
+    //    #pragma omp parallel
+    if(npol==4)
+      {
+	int y=0;
+	uInt ii=0;
+	uInt jj=0;
+	#pragma omp parallel for private(y,ii,jj)
+	for(int x=0 ; x<nx ; ++x){
+	  //cout<<"x="<<x<<endl;
+	  for(y=0 ; y<nx ; ++y){
+
+	    for(ii=0;ii<4;++ii){
+	      for(jj=0;jj<4;++jj){
+		//if(Mask_Mueller_in(ii,jj)==true){
+		  grid_out(IPosition(4,x,y,jj,0)) += GridsMueller[ii][jj](x,y) ;///Spheroid_cut_im_element(x,y);
+
+		//}
+	      }
+	    }
+	  }
+	}
+      }
+
+
+    if(npol==1)
+      {
+    	int y=0;
+    	uInt ii=0;
+    	#pragma omp parallel for private(y,ii)
+    	for(int x=0 ; x<nx ; ++x){
+    	  for(y=0 ; y<nx ; ++y){
+    	    for(ii=0;ii<4;++ii){
+    	      grid_out(IPosition(4,x,y,0,0)) += 0.5*(GridsMueller[0][ii](x,y) + GridsMueller[3][ii](x,y));///Spheroid_cut_im_element(x,y);
+
+    	    }
+    	  }
+    	}
+      }
+
+
+
+    //logIO()<<"LofarConvolutionFunction::ApplyElementBeam "<<"Shapes InputGrid:"<<input_grid.shape()<<", Shapes OutputGrid:"<< LogIO::POST;//<<grid_out.shape()<<endl;
+
+
+    return grid_out;
+
+  }
+
+  //==================================================================
+  //==================================================================
+
+
+
   //================================================
   // Compute the convolution function for all channel, for the polarisations specified in the Mueller_mask matrix
   // Also specify weither to compute the Mueller matrix for the forward or the backward step. A dirty way to calculate
@@ -307,34 +890,52 @@ namespace LOFAR
 
   LofarCFStore LofarConvolutionFunction::makeConvolutionFunction
   (uInt stationA, uInt stationB, Double time, Double w,
-   const Matrix<bool>& Mask_Mueller, bool degridding_step,
+   const Matrix<bool>& Mask_Mueller_in, bool degridding_step,
    double Append_average_PB_CF, Matrix<Complex>& Stack_PB_CF,
-   double& sum_weight_square)
+   double& sum_weight_square, uInt spw, Int TaylorTerm, double RefFreq)
   {
     // Initialize timers.
     PrecTimer timerFFT;
     PrecTimer timerPar;
+    PrecTimer timerCyril;
     timerPar.start();
 
+    Matrix<bool> Mask_Mueller(IPosition(2,4,4),false);
+    Mask_Mueller(0,0)=true;
+
     // Stack_PB_CF should be called Sum_PB_CF (it is a sum, no stack).
     CountedPtr<CFTypeVec> res (new vector< vector< vector < Matrix<Complex> > > >());
     CFTypeVec& result = *res;
     vector< vector< vector < Matrix<Complex> > > > result_non_padded;
 
+
     // Stack the convolution function if averagepb.img don't exist
-    Matrix<Complex> Stack_PB_CF_fft(IPosition(2,m_shape(0),m_shape(0)),0.);
+    //Matrix<Complex> Stack_PB_CF_fft(IPosition(2,m_shape(0),m_shape(0)),0.);
     Bool Stack = (Append_average_PB_CF != 0.);
 
+
+
     // If the beam is not in memory, compute it
-        
-    map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter =
-      m_AtermStore.find(time);
-    AlwaysAssert (aiter!=m_AtermStore.end(), AipsError);
-    const vector< vector< Cube<Complex> > >& aterm = aiter->second;
+
+    // map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter =
+    //   m_AtermStore.find(time);
+    // AlwaysAssert (aiter!=m_AtermStore.end(), AipsError);
+    // const vector< vector< Cube<Complex> > >& aterm = aiter->second;
+
+
+    map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter_station =
+      m_AtermStore_station.find(time);
+    AlwaysAssert (aiter_station!=m_AtermStore_station.end(), AipsError);
+    const vector< vector< Cube<Complex> > >& aterm_station = aiter_station->second;
+
+
+
+
     ///        if(m_AtermStore.find(time)==m_AtermStore.end()){computeAterm(time);}
 
     // Load the Wterm
-    uInt w_index = m_wScale.plane(w);
+    double ratio_freqs=list_freq[0]/list_freq[spw];
+    uInt w_index = m_wScale.plane(w*ratio_freqs);
     Matrix<Complex> wTerm;
     wTerm = m_WplanesStore[w_index];
     Int Npix_out = 0;
@@ -353,17 +954,36 @@ namespace LOFAR
       wTerm.reference (conj(wTerm));
     }
 
-    for (uInt ch=0; ch<m_nChannel; ++ch) {
+    uInt ch(spw);
+    //for (uInt ch=0; ch<m_nChannel; ++ch) {
       // Load the Aterm
-      const Cube<Complex>& aTermA(aterm[stationA][ch]);
-      const Cube<Complex>& aTermB(aterm[stationB][ch]);
+    //const Cube<Complex> aTermA(aterm_station[stationA][ch].copy());
+    Cube<Complex> aTermA(aterm_station[stationA][ch].copy());
+
+
+    //const Cube<Complex>& aTermB(aterm_station[stationB][ch]);
+    Cube<Complex> aTermB(aterm_station[stationB][ch].copy());
+      //==============================
+      //==============================
+      // Cyr: MFS
+      //==============================
+      //==============================
+      // if( TaylorTerm > 0 )
+      // 	{
+      // 	  Float freq=0.0,mulfactor=1.0;
+      // 	  freq = list_freq[ch];
+      // 	  mulfactor = ((freq-RefFreq)/RefFreq);
+      // 	  //cout<<"mulfactor "<<mulfactor<<endl;
+      // 	  Cube<Complex> slice(aTermA);
+      // 	  slice *= pow(mulfactor,TaylorTerm);//mulfactor;
+      // 	}
+      //==============================
+      //==============================
       // Determine maximum support of A, W, and Spheroidal function for zero padding
       Npix_out = std::max(std::max(aTermA.shape()[0], aTermB.shape()[0]),
                           std::max(wTerm.shape()[0], Spheroid_cut.shape()[0]));
-      if (itsVerbose > 0) {
-        cout<<"Number of pixel in the final conv function for baseline ["<< stationA<<", "<<stationB<<"] = "<<Npix_out
-            <<" "<<aTermA.shape()[0]<<" "<<aTermB.shape()[0]<<" "<<wTerm.shape()[0]<<endl;
-      }
+
+      //cout << "CF Shapes, Wterm:" << wTerm.shape()[0] << ", Beam " << aTermA.shape()[0] << ", Spheroid: " << Spheroid_cut.shape()[0] << endl;
 
       // Zero pad to make the image planes of the A1, A2, and W term have the same resolution in the image plane
       Matrix<Complex> Spheroid_cut_paddedf(zero_padding(Spheroid_cut,Npix_out));
@@ -378,10 +998,9 @@ namespace LOFAR
         cout << "fft shapes " << wTerm_paddedf.shape() << ' ' << Spheroid_cut_paddedf.shape()
              << ' ' << aTermA_padded.shape() << ' ' << aTermB_padded.shape() << endl;
       }
+
+
       for (uInt i=0; i<4; ++i) {
-        //Matrix<Complex> planeAf(aTermA_padded.xyPlane(i));
-        //Matrix<Complex> planeBf(aTermB_padded.xyPlane(i));
-        // AlwaysAssert(planeAf.contiguousStorage(), AipsError);
         // Make a matrix referencing the data in the cube's plane.
         Matrix<Complex> planeAf(aTermA_padded.xyPlane(i));
         Matrix<Complex> planeBf(aTermB_padded.xyPlane(i));
@@ -390,30 +1009,62 @@ namespace LOFAR
         normalized_fft (timerFFT, planeBf, false);
       }
 
+      //if (itsVerbose > 0) {
+      // if((stationA==3)&( stationB==0)){
+      //   cout<<"Number of pixel in the final conv function for baseline ["<< stationA<<", "<<stationB<<"] = "<<Npix_out
+      //       <<" "<<aTermA.shape()[0]<<" "<<aTermB.shape()[0]<<" "<<wTerm.shape()[0]<<endl;
+      // 	store(aTermA,"aTermAfft."+String::toString(its_count_time)+".img");
+      // 	store(aTermB,"aTermBfft."+String::toString(its_count_time)+".img");
+      // 	store(aTermA_padded,"aTermAfft."+String::toString(its_count_time)+".fft.img");
+      // 	store(aTermB_padded,"aTermBfft."+String::toString(its_count_time)+".fft.img");
+      // 	its_count_time+=1;
+      // 	//assert(false);
+      // }
       // Create the vectors of Matrices giving the convolution functions
       // for each Mueller element.
       vector< vector < Matrix<Complex> > > Kron_Product;
       Kron_Product.reserve(4);
 
-      // Something I still don't completely understand: for the average PB calculation.
+      // timerCyril.reset();
+      // timerCyril.start();
+      // //TEST!!!!
+      // Matrix<Complex> Spheroid_cut_paddedf(LinearInterpol(Spheroid_cut,Npix_out));
+      // Matrix<Complex> wTerm_paddedf(LinearInterpol(wTerm, Npix_out));
+      // Cube<Complex> aTermA_padded(IPosition(3,Npix_out,Npix_out,4),0.);
+      // Cube<Complex> aTermB_padded(IPosition(3,Npix_out,Npix_out,4),0.);
+      // for (uInt i=0; i<4; ++i) {
+      // 	Matrix<Complex> planeAf=aTermA_padded.xyPlane(i);
+      // 	Matrix<Complex> planeAf=aTermA_padded.xyPlane(i);
+      //   planeAf=LinearInterpol(aTermA.xyPlane(i), Npix_out);
+      //   planeBf=LinearInterpol(aTermA.xyPlane(i), Npix_out);
+      // }
+      // timerCyril.stop();
+      // timerCyril.show(cout,"linear");
+
+
+
+     // Something I still don't completely understand: for the average PB calculation.
       // The convolution functions padded with a higher value than the minimum one give a
       // better result in the end. If you try Npix_out2=Npix_out, then the average PB shows
       // structure like aliasing, producing high values in the devided disrty map... This
       // is likely to be due to the way fft works?...
-      // FIX: I now do the average of the PB by stacking the CF, FFT the result and square 
-      // it in the end. This is not the way to do in principle but the result is almost the 
+      // FIX: I now do the average of the PB by stacking the CF, FFT the result and square
+      // it in the end. This is not the way to do in principle but the result is almost the
       // same. It should pose no problem I think.
       Matrix<Complex> Spheroid_cut_padded2f;
+      Matrix<Complex> spheroid_cut_element_fft2;
       Cube<Complex> aTermA_padded2;
       Cube<Complex> aTermB_padded2;
 
       // Keep the non-padded convolution functions for average PB calculation.
       vector< vector < Matrix<Complex> > > Kron_Product_non_padded;
       Kron_Product_non_padded.reserve(4);
-	    
+
       if (Stack) {
         Npix_out2 = Npix_out;
         Spheroid_cut_padded2f = zero_padding(Spheroid_cut, Npix_out2);
+	spheroid_cut_element_fft2 = zero_padding(spheroid_cut_element_fft, Npix_out2);
+	normalized_fft (timerFFT, spheroid_cut_element_fft2, false);
         aTermA_padded2 = zero_padding(aTermA, Npix_out2);
         aTermB_padded2 = zero_padding(aTermB, Npix_out2);
         normalized_fft (timerFFT, Spheroid_cut_padded2f, false);
@@ -448,6 +1099,7 @@ namespace LOFAR
                                                aTermA_padded.xyPlane(ind1));
                 plane_product *= wTerm_paddedf;
                 plane_product *= Spheroid_cut_paddedf;
+
                 Matrix<Complex> plane_product_paddedf
                   (zero_padding(plane_product,
                                 plane_product.shape()[0] * m_oversampling));
@@ -471,6 +1123,7 @@ namespace LOFAR
                   Matrix<Complex> plane_productf(aTermB_padded2.xyPlane(ind0)*
                                                  aTermA_padded2.xyPlane(ind1));
                   plane_productf *= Spheroid_cut_padded2f;
+		  if(its_Apply_Element){plane_productf *= spheroid_cut_element_fft2;}
                   normalized_fft (timerFFT, plane_productf);
                   Row_non_padded[jj].reference (plane_productf);
                 }
@@ -493,7 +1146,12 @@ namespace LOFAR
       if (degridding_step) {
         for (uInt i=0; i<4; ++i) {
           for (uInt j=i; j<4; ++j) {
-            AlwaysAssert (Mask_Mueller(i,j) == Mask_Mueller(j,i), AipsError);
+            //AlwaysAssert (Mask_Mueller(i,j) == Mask_Mueller(j,i), AipsError);
+	    if ((Mask_Mueller(i,j)==false)&&(Mask_Mueller(j,i)==true)){
+	      Matrix<Complex> a(Kron_Product[i][j].copy());
+	      a=0.;
+	      Kron_Product[i][j]=a.copy();
+	    };
             if (Mask_Mueller(i,j)) {
               if (i!=j) {
                 Matrix<Complex> conj_product(conj(Kron_Product[i][j]));
@@ -523,8 +1181,8 @@ namespace LOFAR
       if (Stack) {
         result_non_padded.push_back(Kron_Product_non_padded);
       }
-    }
-          
+      //}
+
     // Stacks the weighted quadratic sum of the convolution function of
     // average PB estimate (!!!!! done for channel 0 only!!!)
     if (Stack) {
@@ -552,7 +1210,7 @@ namespace LOFAR
         }
       }
     }
-	
+
     // Put the resulting vec(vec(vec))) in a LofarCFStore object
     CoordinateSystem csys;
     Vector<Float> samp(2, m_oversampling);
@@ -575,12 +1233,14 @@ namespace LOFAR
 #pragma omp atomic
     itsTimeCFpar += ptime;
 
+
     return LofarCFStore (res, csys, samp,  xsup, ysup, maxXSup, maxYSup,
                          PA, mosPointing, Mask_Mueller);
   }
 
+
   //================================================
-      
+
   // Returns the average Primary Beam from the disk
   Matrix<Float> LofarConvolutionFunction::Give_avg_pb()
   {
@@ -615,21 +1275,34 @@ namespace LOFAR
         cout<<"..... Compute average PB"<<endl;
       }
       Sum_Stack_PB_CF /= float(sum_weight_square);
-      //store(Stack_PB_CF,"Stack_PB_CF.img");
+      //store(Sum_Stack_PB_CF,"Stack_PB_CF.img");
 
       normalized_fft(Sum_Stack_PB_CF, false);
-      //store(Im_Stack_PB_CF00,"Im_Stack_PB_CF00.img");
+      //store(Sum_Stack_PB_CF,"Im_Stack_PB_CF00.img");
+      //store(Sum_Stack_PB_CF, itsImgName + ".before");
       Im_Stack_PB_CF0.resize (IPosition(2, m_shape[0], m_shape[1]));
-	
-      float threshold = 1.e-6;
+
+      float maxPB(0.);
+      float maxPB_noabs(0.);
+      for(uInt i=0;i<m_shape[1];++i){
+	for(uInt j=0;j<m_shape[1];++j){
+	    Complex pixel(Sum_Stack_PB_CF(i,j));
+	    if(abs(pixel)>maxPB){
+	      maxPB=abs(pixel);
+	      //maxPB_noabs=pixel;
+	    };
+	}
+      }
+      float threshold = 1.e-8;
       for (Int jj=0; jj<m_shape[1]; ++jj) {
         for (Int ii=0; ii<m_shape[0]; ++ii) {
           Float absVal = abs(Sum_Stack_PB_CF(ii,jj));
-          Im_Stack_PB_CF0(ii,jj) = std::max (absVal*absVal, threshold);
+          Im_Stack_PB_CF0(ii,jj) = std::max (absVal*absVal, threshold*maxPB);
+	  //Im_Stack_PB_CF0(ii,jj) = sqrt(Im_Stack_PB_CF0(ii,jj))*sign(maxPB_noabs);
         }
       }
       // Make it persistent.
-      store(Im_Stack_PB_CF0, itsImgName + ".avgpb");
+      store(m_coordinates,Im_Stack_PB_CF0, itsImgName + ".avgpb");
     }
     return Im_Stack_PB_CF0;
   }
@@ -642,15 +1315,17 @@ namespace LOFAR
     if (Image.shape()[0] == Npixel_Out) {
       return Image.copy();
     }
-    if ((Npixel_Out%2) != 1) {
-      Npixel_Out++;
-    }
+
+    // if ((Npixel_Out%2) != 1) {
+    //   Npixel_Out++;
+    // }
+
     Cube<Complex> Image_Enlarged(Npixel_Out,Npixel_Out,Image.shape()[2]);
     uInt Dii = Image.shape()(0)/2;
     uInt Start_image_enlarged=Npixel_Out/2-Dii; //Is an even number, Assume square image
-    if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
-      Start_image_enlarged += 0.5; //If number of pixel odd then 0th order at the center, shifted by one otherwise
-    }
+    // if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
+    //   Start_image_enlarged += 0.5; //If number of pixel odd then 0th order at the center, shifted by one otherwise
+    // }
     /* cout<<Start_image_enlarged<<"  "<<floor(Start_image_enlarged)<<endl; */
     /* if((Start_image_enlarged-floor(Start_image_enlarged))!=0.){ */
     /*   cout<<"Not even!!!"<<endl; */
@@ -681,9 +1356,6 @@ namespace LOFAR
     if (Image.shape()[0] == Npixel_Out) {
       return Image.copy();
     }
-    if (Npixel_Out%2 != 1) {
-      Npixel_Out++;
-    }
     IPosition shape_im_out(2, Npixel_Out, Npixel_Out);
     Matrix<Complex> Image_Enlarged(shape_im_out, 0.);
 
@@ -695,9 +1367,9 @@ namespace LOFAR
     uInt Start_image_enlarged = shape_im_out[0]/2-Dii;
     //Is an even number, Assume square image
     //If number of pixel odd then 0th order at the center, shifted by one otherwise
-    if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
-      Start_image_enlarged += 0.5;
-    }
+    // if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
+    //   Start_image_enlarged += 0.5;
+    // }
 
     /* cout<<Start_image_enlarged<<"  "<<floor(Start_image_enlarged)<<endl; */
     /* if((Start_image_enlarged-floor(Start_image_enlarged))!=0.){ */
@@ -705,7 +1377,7 @@ namespace LOFAR
     /*   Start_image_enlarged+=0.5;} */
     for (Int jj=0; jj<Image.shape()[1]; ++jj) {
       for (Int ii=0; ii<Image.shape()[0]; ++ii) {
-        Image_Enlarged(Start_image_enlarged+ii,Start_image_enlarged+jj) = 
+        Image_Enlarged(Start_image_enlarged+ii,Start_image_enlarged+jj) =
           ratio*Image(ii,jj);
       }
     }
@@ -716,6 +1388,7 @@ namespace LOFAR
   void LofarConvolutionFunction::normalized_fft
   (Matrix<Complex> &im, bool toFreq)
   {
+    //cout<<" "<<im.ncolumn()<<" "<<im.nrow()<<" "<<im.size()<<" "<<im.contiguousStorage()<<endl;
     AlwaysAssert (im.ncolumn() == im.nrow()  &&  im.size() > 0  &&
                   im.contiguousStorage(), AipsError);
     int tnr = OpenMP::threadNum();
@@ -746,28 +1419,6 @@ namespace LOFAR
     return observation.timeRangeMeas()(0)(IPosition(1, 0));
   }
 
-  //=================================================
-  Double LofarConvolutionFunction::observationReferenceFreq
-  (const MeasurementSet &ms, uInt idDataDescription)
-  {
-    // Read polarization id and spectral window id.
-    ROMSDataDescColumns desc(ms.dataDescription());
-    AlwaysAssert(desc.nrow() > idDataDescription, SynthesisError);
-    AlwaysAssert(!desc.flagRow()(idDataDescription), SynthesisError);
-
-    const uInt idWindow = desc.spectralWindowId()(idDataDescription);
-
-    /*        logIO() << LogOrigin("LofarATerm", "initReferenceFreq") << LogIO::NORMAL
-              << "spectral window: " << desc.spectralWindowId()(idDataDescription) << LogIO::POST;*/
-    //            << "spectral window: " << desc.spectralWindowId() << LogIO::POST;
-    // Get spectral information.
-    ROMSSpWindowColumns window(ms.spectralWindow());
-    AlwaysAssert(window.nrow() > idWindow, SynthesisError);
-    AlwaysAssert(!window.flagRow()(idWindow), SynthesisError);
-
-    return window.refFrequency()(idWindow);
-  }
-
   //=================================================
   // Estime spheroidal convolution function from the support of the fft of the spheroidal in the image plane
 
@@ -816,7 +1467,7 @@ namespace LOFAR
     store(Spheroid_cut_im, itsImgName + ".spheroid_cut_im");
     if (itsVerbose > 0) {
       store(Spheroid_cut, itsImgName + ".spheroid_cut");
-    }	
+    }
     return Pixel_Size_Spheroidal;
   }
 
@@ -869,12 +1520,12 @@ namespace LOFAR
   // Return the angular resolution required for making the image of the angular size determined by
   // coordinates and shape. The resolution is assumed to be the same on both direction axes.
   Double LofarConvolutionFunction::estimateAResolution
-  (const IPosition &shape, const DirectionCoordinate &coordinates) const
+  (const IPosition &shape, const DirectionCoordinate &coordinates, double station_diam) const
   {
     Double res_ini=abs(coordinates.increment()(0));                      // pixel size in image in radian
     Double diam_image=res_ini*shape(0);                                  // image diameter in radian
-    Double station_diam = 70.;                                           // station diameter in meters: To be adapted to the individual station size.
-    Double Res_beam_image= ((C::c/m_refFrequency)/station_diam)/2.;      // pixel size in A-term image in radian
+    //Double station_diam = 70.;                                           // station diameter in meters: To be adapted to the individual station size.
+    Double Res_beam_image= 0.5*((C::c/m_refFrequency)/station_diam)/2.;      // pixel size in A-term image in radian
     uInt Npix=floor(diam_image/Res_beam_image);                         // Number of pixel size in A-term image
     Res_beam_image=diam_image/Npix;
     if (Npix%2 != 1) {
@@ -920,7 +1571,7 @@ namespace LOFAR
       bot += Q[part][k] * delnusqPow;
       delnusqPow *= delnusq;
     }
-	
+
     double result = (bot == 0  ?  0 : (1.0 - nusq) * (top / bot));
     //if(result<1.e-3){result=1.e-3;}
     return result;
diff --git a/CEP/Imager/LofarFT/src/LofarConvolutionFunctionOld.cc b/CEP/Imager/LofarFT/src/LofarConvolutionFunctionOld.cc
new file mode 100644
index 0000000000000000000000000000000000000000..de9946a8da70cd2c4ff4853c8d6773be83944b9f
--- /dev/null
+++ b/CEP/Imager/LofarFT/src/LofarConvolutionFunctionOld.cc
@@ -0,0 +1,965 @@
+//# LofarConvolutionFunctionOld.cc: Compute the LOFAR convolution function
+//#
+//# Copyright (C) 2011
+//# 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 <LofarFT/LofarConvolutionFunctionOld.h>
+#include <LofarFT/LofarConvolutionFunction.h>   // needed for store function
+#include <Common/LofarLogger.h>
+#include <Common/OpenMP.h>
+
+#include <casa/Logging/LogIO.h>
+#include <casa/Logging/LogOrigin.h>
+#include <casa/Arrays/Cube.h>
+#include <casa/Arrays/Matrix.h>
+#include <casa/Arrays/MatrixMath.h>
+#include <casa/Arrays/ArrayMath.h>
+
+#include <ms/MeasurementSets/MeasurementSet.h>
+#include <measures/Measures/MDirection.h>
+#include <measures/Measures/MeasConvert.h>
+#include <measures/Measures/MCDirection.h>
+#include <measures/Measures/MCPosition.h>
+#include <ms/MeasurementSets/MSAntenna.h>
+#include <ms/MeasurementSets/MSAntennaParse.h>
+#include <ms/MeasurementSets/MSAntennaColumns.h>
+#include <ms/MeasurementSets/MSDataDescription.h>
+#include <ms/MeasurementSets/MSDataDescColumns.h>
+#include <ms/MeasurementSets/MSField.h>
+#include <ms/MeasurementSets/MSFieldColumns.h>
+#include <ms/MeasurementSets/MSObservation.h>
+#include <ms/MeasurementSets/MSObsColumns.h>
+#include <ms/MeasurementSets/MSPolarization.h>
+#include <ms/MeasurementSets/MSPolColumns.h>
+#include <ms/MeasurementSets/MSSpectralWindow.h>
+#include <ms/MeasurementSets/MSSpWindowColumns.h>
+#include <ms/MeasurementSets/MSSelection.h>
+#include <measures/Measures/MeasTable.h>
+#include <coordinates/Coordinates/CoordinateSystem.h>
+#include <coordinates/Coordinates/SpectralCoordinate.h>
+#include <coordinates/Coordinates/StokesCoordinate.h>
+#include <casa/OS/PrecTimer.h>
+#include <casa/sstream.h>
+#include <iomanip>
+
+namespace LOFAR
+{
+
+  LofarConvolutionFunctionOld::LofarConvolutionFunctionOld
+  (const IPosition& shape,
+   const DirectionCoordinate& coordinates,
+   const MeasurementSet& ms,
+   uInt nW, double Wmax,
+   uInt oversample,
+   const String& beamElementPath,
+   Int verbose,
+   Int maxsupport,
+   const String& imgName)
+    : m_shape(shape),
+      m_coordinates(coordinates),
+      m_aTerm(ms, beamElementPath),
+      m_maxW(Wmax), //maximum W set by ft machine to flag the w>wmax
+      m_nWPlanes(nW),
+      m_oversampling(oversample),
+      itsVerbose (verbose),
+      itsMaxSupport(maxsupport),
+      itsImgName(imgName),
+      itsTimeW    (0),
+      itsTimeWpar (0),
+      itsTimeWfft (0),
+      itsTimeWcnt (0),
+      itsTimeA    (0),
+      itsTimeApar (0),
+      itsTimeAfft (0),
+      itsTimeAcnt (0),
+      itsTimeCFpar(0),
+      itsTimeCFfft(0),
+      itsTimeCFcnt(0)
+      //Not sure how useful that is
+  {
+    if (itsVerbose > 0) {
+      cout<<"LofarConvolutionFunctionOld:shape  "<<shape<<endl;
+    }
+    itsFFTMachines.resize (OpenMP::maxThreads());
+
+    //    m_maxCFSupport=0; //need this parameter to stack all the CF for average PB estimate
+
+    m_wScale = WScale(m_maxW, m_nWPlanes);
+    MEpoch start = observationStartTime(ms, 0);
+
+    m_refFrequency = observationReferenceFreq(ms, 0);
+
+    if (m_oversampling%2 == 0) {
+      // Make OverSampling an odd number
+      m_oversampling++;
+    }
+
+    list_freq   = Vector<Double>(1, m_refFrequency);
+    m_nChannel  = list_freq.size();
+    ROMSAntennaColumns antenna(ms.antenna());
+    m_nStations = antenna.nrow();
+
+    m_pixelSizeSpheroidal = makeSpheroidCut();
+    //Double PixelSize=abs(m_coordinates.increment()(0));
+    //Double ImageDiameter=PixelSize * m_shape(0);
+    //Double W_Pixel_Ang_Size=min(Pixel_Size_Spheroidal,estimateWResolution(m_shape, m_coordinates, m_maxW));
+    //m_maxCFSupport= ImageDiameter / W_Pixel_Ang_Size;
+    //Matrix<Complex> Stack_pb_cf0(IPosition(2,m_maxCFSupport,m_maxCFSupport),0.);
+    Matrix<Complex> Stack_pb_cf0(IPosition(2,m_shape(0),m_shape(0)),0.);
+    Matrix<float> Stack_pb_cf1(IPosition(2,m_shape(0),m_shape(0)),0.);
+
+    //Stack_pb_cf0(256,300)=1.;
+    //Matrix<Complex> Avg_PB_padded00(give_normalized_fft(Stack_pb_cf0,false));
+    //store(Avg_PB_padded00,"Avg_PB_padded00.img");
+
+    // Precalculate the Wtwerm fft for all w-planes.
+    store_all_W_images();
+  }
+
+  //      ~LofarConvolutionFunctionOld ()
+  //      {
+  //      }
+
+  // Precalculate all W-terms in the fourier domain
+  void LofarConvolutionFunctionOld::store_all_W_images()
+  {
+    PrecTimer wTimer;
+    wTimer.start();
+    Double pixelSize = abs(m_coordinates.increment()[0]);
+    Double imageDiameter = pixelSize * m_shape(0);
+    // Size the vector, but give each element its own default matrix,
+    // so the vector can be safely filled in parallel.
+    m_WplanesStore.reserve (m_nWPlanes);
+    for (uInt i=0; i<m_nWPlanes; ++i) {
+      m_WplanesStore.push_back (Matrix<Complex>());
+    }
+#pragma omp parallel
+    {
+      // Thread private variables.
+      PrecTimer timerFFT;
+      PrecTimer timerPar;
+#pragma omp for schedule(dynamic)
+      for (uInt i=0; i<m_nWPlanes; ++i) {
+        timerPar.start();
+        Double w = m_wScale.center(i);
+        Double wPixelAngSize = min(m_pixelSizeSpheroidal,
+                                   estimateWResolution(m_shape,
+                                                       pixelSize, w));
+        Int nPixelsConv = imageDiameter / wPixelAngSize;
+        if (itsVerbose > 0) {
+          cout<<"Number of pixel in the "<<i<<"-wplane: "<<nPixelsConv
+              <<"  (w="<<w<<")"<<endl;
+        }
+        if (nPixelsConv > itsMaxSupport) {
+          nPixelsConv = itsMaxSupport;
+        }
+        // Make odd and optimal.
+        nPixelsConv = FFTCMatrix::optimalOddFFTSize (nPixelsConv);
+        wPixelAngSize = imageDiameter / nPixelsConv;
+        IPosition shape(2, nPixelsConv, nPixelsConv);
+        //Careful with the sign of increment!!!! To check!!!!!!!
+        Vector<Double> increment(2, wPixelAngSize);
+        double wavelength(C::c / list_freq[0]);
+        Matrix<Complex> wTerm = m_wTerm.evaluate(shape, increment,
+                                                 w/wavelength);
+        normalized_fft(timerFFT, wTerm);
+        m_WplanesStore[i].reference (wTerm);
+        timerPar.stop();
+      }
+      // Update the timing info.
+      double ftime = timerFFT.getReal();
+#pragma omp atomic
+      itsTimeWfft += ftime;
+      unsigned long long cnt = timerFFT.getCount();
+#pragma omp atomic
+      itsTimeWcnt += cnt;
+      double ptime = timerPar.getReal();
+#pragma omp atomic
+      itsTimeWpar += ptime;
+    } // end omp parallel
+    wTimer.stop();
+    itsTimeW = wTimer.getReal();
+  }
+
+
+  // Compute the fft of the beam at the minimal resolution for all antennas
+  // if not done yet.
+  // Put it in a map object with a (double time) key.
+  void LofarConvolutionFunctionOld::computeAterm (Double time)
+  {
+    if (m_AtermStore.find(time) != m_AtermStore.end()) {
+      // Already done.
+      return;
+    }
+    PrecTimer aTimer;
+    aTimer.start();
+    Double pixelSize = abs(m_coordinates.increment()[0]);
+    Double imageDiameter = pixelSize * m_shape(0);
+    // Try to avoid making copies when inserting elements in vector or map.
+    // Therefore first create the elements and resize them.
+    m_AtermStore[time] = vector< vector< Cube<Complex> > >();
+    vector< vector< Cube<Complex> > >& aTermList = m_AtermStore[time];
+    // Calculate the A-term and fill the vector for all stations.
+    aTermList.resize (m_nStations);
+    ///#pragma omp parallel
+    {
+      // Thread private variables.
+      PrecTimer timerFFT;
+      PrecTimer timerPar;
+      ///#pragma omp for
+      for (uInt i=0; i<m_nStations; ++i) {
+        timerPar.start();
+	DirectionCoordinate coordinate = m_coordinates;
+        Double aPixelAngSize = min(m_pixelSizeSpheroidal,
+                                   estimateAResolution(m_shape, m_coordinates));
+        Int nPixelsConv = imageDiameter / aPixelAngSize;
+        if (nPixelsConv > itsMaxSupport) {
+          nPixelsConv = itsMaxSupport;
+        }
+        // Make odd and optimal.
+        nPixelsConv = FFTCMatrix::optimalOddFFTSize (nPixelsConv);
+        aPixelAngSize = imageDiameter / nPixelsConv;
+        if (itsVerbose > 0) {
+          cout.precision(20);
+          cout<<"Number of pixel in the Aplane of "<<i<<": "<<nPixelsConv
+              <<", time="<<fixed<<time<<endl;
+        }
+        IPosition shape(2, nPixelsConv, nPixelsConv);
+        Vector<Double> increment_old(coordinate.increment());
+        Vector<Double> increment(2);
+        increment[0] = aPixelAngSize*sign(increment_old[0]);
+        increment[1] = aPixelAngSize*sign(increment_old[1]);
+        coordinate.setIncrement(increment);
+        Vector<Double> refpix(2, 0.5*(nPixelsConv-1));
+        coordinate.setReferencePixel(refpix);
+
+        //======================================
+        // Disable the beam
+        //======================================
+        //Cube<Complex> aterm_cube(IPosition(3,nPixels_Conv,nPixels_Conv,4),1.);
+        //for (uInt iiii=0;iiii<nPixels_Conv;++iiii) {
+        //  for (uInt iiiii=0;iiiii<nPixels_Conv;++iiiii) {
+        //    aterm_cube(iiii,iiiii,1)=0.;
+        //    aterm_cube(iiii,iiiii,2)=0.;
+        //  }
+        //}
+        //vector< Cube<Complex> > aTermA;
+        //aTermA.push_back(aterm_cube);
+        //======================================
+        // Enable the beam
+        //======================================
+        MEpoch binEpoch;
+        binEpoch.set(Quantity(time, "s"));
+        vector< Cube<Complex> > aTermA = m_aTerm.evaluate(shape,
+                                                          coordinate,
+                                                          i, binEpoch,
+                                                          list_freq, true);
+        // Compute the fft on the beam
+        for (uInt ch=0; ch<m_nChannel; ++ch) {
+          for (uInt pol=0; pol<4; ++pol) {
+            Matrix<Complex> plane (aTermA[ch].xyPlane(pol));
+            AlwaysAssert (plane.contiguousStorage(), AipsError);
+            normalized_fft (timerFFT, plane);
+          }
+        }
+        // Note that push_back uses the copy constructor, so for the Cubes
+        // in the vector the copy constructor is called too (which is cheap).
+        aTermList[i] = aTermA;
+        timerPar.stop();
+      } // end omp for
+      // Update the timing info.
+      double ftime = timerFFT.getReal();
+      ///#pragma omp atomic
+      itsTimeAfft += ftime;
+      unsigned long long cnt = timerFFT.getCount();
+      ///#pragma omp atomic
+      itsTimeAcnt += cnt;
+      double ptime = timerPar.getReal();
+      ///#pragma omp atomic
+      itsTimeApar += ptime;
+    } // end omp parallel
+    aTimer.stop();
+    itsTimeA = aTimer.getReal();
+  }
+
+  //================================================
+  // Compute the convolution function for all channel, for the polarisations specified in the Mueller_mask matrix
+  // Also specify weither to compute the Mueller matrix for the forward or the backward step. A dirty way to calculate
+  // the average beam has been implemented, by specifying the beam correcping to the given baseline and timeslot.
+  // RETURNS in a LofarCFStore: result[channel][Mueller row][Mueller column]
+
+  LofarCFStore LofarConvolutionFunctionOld::makeConvolutionFunction
+  (uInt stationA, uInt stationB, Double time, Double w,
+   const Matrix<bool>& Mask_Mueller, bool degridding_step,
+   double Append_average_PB_CF, Matrix<Complex>& Stack_PB_CF,
+   double& sum_weight_square)
+  {
+    // Initialize timers.
+    PrecTimer timerFFT;
+    PrecTimer timerPar;
+    timerPar.start();
+
+    // Stack_PB_CF should be called Sum_PB_CF (it is a sum, no stack).
+    CountedPtr<CFTypeVec> res (new vector< vector< vector < Matrix<Complex> > > >());
+    CFTypeVec& result = *res;
+    vector< vector< vector < Matrix<Complex> > > > result_non_padded;
+
+    // Stack the convolution function if averagepb.img don't exist
+    Matrix<Complex> Stack_PB_CF_fft(IPosition(2,m_shape(0),m_shape(0)),0.);
+    Bool Stack = (Append_average_PB_CF != 0.);
+
+    // If the beam is not in memory, compute it
+        
+    map<Double, vector< vector< Cube<Complex> > > >::const_iterator aiter =
+      m_AtermStore.find(time);
+    AlwaysAssert (aiter!=m_AtermStore.end(), AipsError);
+    const vector< vector< Cube<Complex> > >& aterm = aiter->second;
+    ///        if(m_AtermStore.find(time)==m_AtermStore.end()){computeAterm(time);}
+
+    // Load the Wterm
+    uInt w_index = m_wScale.plane(w);
+    Matrix<Complex> wTerm;
+    wTerm = m_WplanesStore[w_index];
+    Int Npix_out = 0;
+    Int Npix_out2 = 0;
+
+    // Matrix<Complex> Term_test(IPosition(2,101,101),1.);
+    // normalized_fft(Term_test);
+    // store (Term_test,"Term_test.img");
+    // normalized_fft(Term_test,false);
+    // store (Term_test,"Term_test_0.img");
+    // normalized_fft(Term_test);
+    // store (Term_test,"Term_test_1.img");
+    // assert(false);
+
+    if (w > 0.) {
+      wTerm.reference (conj(wTerm));
+    }
+
+    for (uInt ch=0; ch<m_nChannel; ++ch) {
+      // Load the Aterm
+      const Cube<Complex>& aTermA(aterm[stationA][ch]);
+      const Cube<Complex>& aTermB(aterm[stationB][ch]);
+      // Determine maximum support of A, W, and Spheroidal function for zero padding
+      Npix_out = std::max(std::max(aTermA.shape()[0], aTermB.shape()[0]),
+                          std::max(wTerm.shape()[0], Spheroid_cut.shape()[0]));
+      if (itsVerbose > 0) {
+        cout<<"Number of pixel in the final conv function for baseline ["<< stationA<<", "<<stationB<<"] = "<<Npix_out
+            <<" "<<aTermA.shape()[0]<<" "<<aTermB.shape()[0]<<" "<<wTerm.shape()[0]<<endl;
+      }
+
+      // Zero pad to make the image planes of the A1, A2, and W term have the same resolution in the image plane
+      Matrix<Complex> Spheroid_cut_paddedf(zero_padding(Spheroid_cut,Npix_out));
+      Matrix<Complex> wTerm_paddedf(zero_padding(wTerm, Npix_out));
+      Cube<Complex> aTermA_padded(zero_padding(aTermA, Npix_out));
+      Cube<Complex> aTermB_padded(zero_padding(aTermB, Npix_out));
+
+      // FFT (backward) the A and W terms
+      normalized_fft (timerFFT, wTerm_paddedf, false);
+      normalized_fft (timerFFT, Spheroid_cut_paddedf, false);
+      if (itsVerbose > 0) {
+        cout << "fft shapes " << wTerm_paddedf.shape() << ' ' << Spheroid_cut_paddedf.shape()
+             << ' ' << aTermA_padded.shape() << ' ' << aTermB_padded.shape() << endl;
+      }
+      for (uInt i=0; i<4; ++i) {
+        //Matrix<Complex> planeAf(aTermA_padded.xyPlane(i));
+        //Matrix<Complex> planeBf(aTermB_padded.xyPlane(i));
+        // AlwaysAssert(planeAf.contiguousStorage(), AipsError);
+        // Make a matrix referencing the data in the cube's plane.
+        Matrix<Complex> planeAf(aTermA_padded.xyPlane(i));
+        Matrix<Complex> planeBf(aTermB_padded.xyPlane(i));
+        AlwaysAssert(planeAf.contiguousStorage(), AipsError);
+        normalized_fft (timerFFT, planeAf, false);
+        normalized_fft (timerFFT, planeBf, false);
+      }
+
+      // Create the vectors of Matrices giving the convolution functions
+      // for each Mueller element.
+      vector< vector < Matrix<Complex> > > Kron_Product;
+      Kron_Product.reserve(4);
+
+      // Something I still don't completely understand: for the average PB calculation.
+      // The convolution functions padded with a higher value than the minimum one give a
+      // better result in the end. If you try Npix_out2=Npix_out, then the average PB shows
+      // structure like aliasing, producing high values in the devided disrty map... This
+      // is likely to be due to the way fft works?...
+      // FIX: I now do the average of the PB by stacking the CF, FFT the result and square 
+      // it in the end. This is not the way to do in principle but the result is almost the 
+      // same. It should pose no problem I think.
+      Matrix<Complex> Spheroid_cut_padded2f;
+      Cube<Complex> aTermA_padded2;
+      Cube<Complex> aTermB_padded2;
+
+      // Keep the non-padded convolution functions for average PB calculation.
+      vector< vector < Matrix<Complex> > > Kron_Product_non_padded;
+      Kron_Product_non_padded.reserve(4);
+	    
+      if (Stack) {
+        Npix_out2 = Npix_out;
+        Spheroid_cut_padded2f = zero_padding(Spheroid_cut, Npix_out2);
+        aTermA_padded2 = zero_padding(aTermA, Npix_out2);
+        aTermB_padded2 = zero_padding(aTermB, Npix_out2);
+        normalized_fft (timerFFT, Spheroid_cut_padded2f, false);
+        for (uInt i=0; i<4; ++i) {
+          Matrix<Complex> planeA2f(aTermA_padded2.xyPlane(i));
+          Matrix<Complex> planeB2f(aTermB_padded2.xyPlane(i));
+          normalized_fft (timerFFT, planeA2f, false);
+          normalized_fft (timerFFT, planeB2f, false);
+        }
+      }
+
+      // Compute the Mueller matrix considering the Mueller Mask
+      uInt ind0;
+      uInt ind1;
+      uInt ii = 0;
+      IPosition cfShape;
+      Bool allElem = True;
+      for (uInt row0=0; row0<=1; ++row0) {
+        for (uInt col0=0; col0<=1; ++col0) {
+          vector < Matrix<Complex> > Row(4);
+          vector < Matrix<Complex> > Row_non_padded(4);
+          uInt jj = 0;
+          for (uInt row1=0; row1<=1; ++row1) {
+            for (uInt col1=0; col1<=1; ++col1) {
+              // This Mueller ordering is for polarisation given as XX,XY,YX YY
+              ind0 = row0 + 2*row1;
+              ind1 = col0 + 2*col1;
+              // Compute the convolution function for the given Mueller element
+              if (Mask_Mueller(ii,jj)) {
+                // Padded version for oversampling the convolution function
+                Matrix<Complex> plane_product (aTermB_padded.xyPlane(ind0) *
+                                               aTermA_padded.xyPlane(ind1));
+                plane_product *= wTerm_paddedf;
+                plane_product *= Spheroid_cut_paddedf;
+                Matrix<Complex> plane_product_paddedf
+                  (zero_padding(plane_product,
+                                plane_product.shape()[0] * m_oversampling));
+                normalized_fft (timerFFT, plane_product_paddedf);
+
+                plane_product_paddedf *= static_cast<Float>(m_oversampling *
+                                                            m_oversampling);
+		if (itsVerbose>3 && row0==0 && col0==0 && row1==0 && col1==0) {
+		  store (plane_product_paddedf, "awfft"+String::toString(stationA)+'-'+String::toString(stationB));
+		}
+
+                // Maybe to do:
+                // Find circle (from outside to inside) until value > peak*1e-3.
+                // Cut out that box to use as the convolution function.
+                // See nPBWProjectFT.cc (findSupport).
+
+                Row[jj].reference (plane_product_paddedf);
+                cfShape = plane_product_paddedf.shape();
+                // Non padded version for PB calculation (no W-term)
+                if (Stack) {
+                  Matrix<Complex> plane_productf(aTermB_padded2.xyPlane(ind0)*
+                                                 aTermA_padded2.xyPlane(ind1));
+                  plane_productf *= Spheroid_cut_padded2f;
+                  normalized_fft (timerFFT, plane_productf);
+                  Row_non_padded[jj].reference (plane_productf);
+                }
+              } else {
+                allElem = False;
+              }
+              ++jj;
+            }
+          }
+          ++ii;
+          Kron_Product.push_back(Row);
+          if (Stack) {
+            // Keep non-padded for primary beam calculation.
+            Kron_Product_non_padded.push_back(Row_non_padded);
+          }
+        }
+      }
+
+      // When degridding, transpose and use conjugate.
+      if (degridding_step) {
+        for (uInt i=0; i<4; ++i) {
+          for (uInt j=i; j<4; ++j) {
+            AlwaysAssert (Mask_Mueller(i,j) == Mask_Mueller(j,i), AipsError);
+            if (Mask_Mueller(i,j)) {
+              if (i!=j) {
+                Matrix<Complex> conj_product(conj(Kron_Product[i][j]));
+                Kron_Product[i][j].reference (conj(Kron_Product[j][i]));
+                Kron_Product[j][i].reference (conj_product);
+              } else {
+                Kron_Product[i][j].reference (conj(Kron_Product[i][j]));
+              }
+            }
+          }
+        }
+      }
+
+      // Put similarly shaped matrix with zeroes for missing Mueller elements.
+      if (!allElem) {
+        Matrix<Complex> zeroCF(cfShape);
+        for (uInt i=0; i<4; ++i) {
+          for (uInt j=0; j<4; ++j) {
+            if (! Mask_Mueller(i,j)) {
+              Kron_Product[i][j].reference (zeroCF);
+            }
+          }
+        }
+      }
+      // Add the conv.func. for this channel to the result.
+      result.push_back(Kron_Product);
+      if (Stack) {
+        result_non_padded.push_back(Kron_Product_non_padded);
+      }
+    }
+          
+    // Stacks the weighted quadratic sum of the convolution function of
+    // average PB estimate (!!!!! done for channel 0 only!!!)
+    if (Stack) {
+      //	  cout<<"...Stack CF for PB estimate"<<endl;
+      double weight_square = 4. * Append_average_PB_CF * Append_average_PB_CF;
+      double weight_sqsq = weight_square * weight_square;
+      for (uInt i=0; i<4; ++i) {
+        //if((i==2)||(i==1)) break;
+        for (uInt j=0; j<4; ++j) {
+          // Only use diagonal terms for average primary beam.
+          if (i==j  &&  Mask_Mueller(i,j)) {
+            //Stack_PB_CF=0.;
+            double istart = 0.5 * (m_shape[0] - Npix_out2);
+            if (istart-floor(istart) != 0.) {
+              istart += 0.5; //If number of pixel odd then 0th order at the center, shifted by one otherwise
+            }
+            for (Int jj=0; jj<Npix_out2; ++jj) {
+              for (Int ii=0; ii<Npix_out2; ++ii) {
+                Complex gain = result_non_padded[0][i][j](ii,jj);
+                Stack_PB_CF(istart+ii,istart+jj) += gain*weight_sqsq;
+              }
+            }
+            sum_weight_square += weight_sqsq;
+          }
+        }
+      }
+    }
+	
+    // Put the resulting vec(vec(vec))) in a LofarCFStore object
+    CoordinateSystem csys;
+    Vector<Float> samp(2, m_oversampling);
+    Vector<Int> xsup(1, Npix_out/2);
+    Vector<Int> ysup(1, Npix_out/2);
+    Int maxXSup(Npix_out);///2);
+    Int maxYSup(Npix_out);///2);
+    Quantity PA(0., "deg");
+    Int mosPointing(0);
+
+    // Update the timing info.
+    timerPar.stop();
+    double ftime = timerFFT.getReal();
+#pragma omp atomic
+    itsTimeCFfft += ftime;
+    unsigned long long cnt = timerFFT.getCount();
+#pragma omp atomic
+    itsTimeCFcnt += cnt;
+    double ptime = timerPar.getReal();
+#pragma omp atomic
+    itsTimeCFpar += ptime;
+
+    return LofarCFStore (res, csys, samp,  xsup, ysup, maxXSup, maxYSup,
+                         PA, mosPointing, Mask_Mueller);
+  }
+
+  //================================================
+      
+  // Returns the average Primary Beam from the disk
+  Matrix<Float> LofarConvolutionFunctionOld::Give_avg_pb()
+  {
+    // Only read if not available.
+    if (Im_Stack_PB_CF0.empty()) {
+      if (itsVerbose > 0) {
+        cout<<"==============Give_avg_pb()"<<endl;
+      }
+      String PBFile_name(itsImgName + ".avgpb");
+      File PBFile(PBFile_name);
+      if (! PBFile.exists()) {
+        throw SynthesisError (PBFile_name + " not found");
+      }
+      if (itsVerbose > 0) {
+        cout<<"..... loading Primary Beam image from disk ....."<<endl;
+      }
+      PagedImage<Float> tmp(PBFile_name);
+      IPosition shape(tmp.shape());
+      AlwaysAssert (shape[0]==m_shape[0] && shape[1]==m_shape[1], AipsError);
+      tmp.get (Im_Stack_PB_CF0, True);   // remove degenerate axes.
+    }
+    return Im_Stack_PB_CF0;
+  }
+
+  // Compute the average Primary Beam from the Stack of convolution functions
+  Matrix<Float> LofarConvolutionFunctionOld::Compute_avg_pb
+  (Matrix<Complex>& Sum_Stack_PB_CF, double sum_weight_square)
+  {
+    // Only calculate if not done yet.
+    if (Im_Stack_PB_CF0.empty()) {
+      if (itsVerbose > 0) {
+        cout<<"..... Compute average PB"<<endl;
+      }
+      Sum_Stack_PB_CF /= float(sum_weight_square);
+      //store(Stack_PB_CF,"Stack_PB_CF.img");
+
+      normalized_fft(Sum_Stack_PB_CF, false);
+      //store(Im_Stack_PB_CF00,"Im_Stack_PB_CF00.img");
+      Im_Stack_PB_CF0.resize (IPosition(2, m_shape[0], m_shape[1]));
+	
+      float threshold = 1.e-6;
+      for (Int jj=0; jj<m_shape[1]; ++jj) {
+        for (Int ii=0; ii<m_shape[0]; ++ii) {
+          Float absVal = abs(Sum_Stack_PB_CF(ii,jj));
+          Im_Stack_PB_CF0(ii,jj) = std::max (absVal*absVal, threshold);
+        }
+      }
+      // Make it persistent.
+      store(Im_Stack_PB_CF0, itsImgName + ".avgpb");
+    }
+    return Im_Stack_PB_CF0;
+  }
+
+  //================================================
+  // Does Zeros padding of a Cube
+  Cube<Complex> LofarConvolutionFunctionOld::zero_padding
+  (const Cube<Complex>& Image, int Npixel_Out)
+  {
+    if (Image.shape()[0] == Npixel_Out) {
+      return Image.copy();
+    }
+    if ((Npixel_Out%2) != 1) {
+      Npixel_Out++;
+    }
+    Cube<Complex> Image_Enlarged(Npixel_Out,Npixel_Out,Image.shape()[2]);
+    uInt Dii = Image.shape()(0)/2;
+    uInt Start_image_enlarged=Npixel_Out/2-Dii; //Is an even number, Assume square image
+    if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
+      Start_image_enlarged += 0.5; //If number of pixel odd then 0th order at the center, shifted by one otherwise
+    }
+    /* cout<<Start_image_enlarged<<"  "<<floor(Start_image_enlarged)<<endl; */
+    /* if((Start_image_enlarged-floor(Start_image_enlarged))!=0.){ */
+    /*   cout<<"Not even!!!"<<endl; */
+    /*   Start_image_enlarged+=0.5;} */
+
+    //double ratio(double(Npixel_Out)*double(Npixel_Out)/(Image.shape()(0)*Image.shape()(0)));
+    //if(!toFrequency){ratio=1./ratio;}
+    double ratio=1.;
+
+    for (Int pol=0; pol<Image.shape()[2]; ++pol) {
+      //cout<<"pol: "<<pol<<endl;
+      for (Int jj=0; jj<Image.shape()[1]; ++jj) {
+        for (Int ii=0; ii<Image.shape()[0]; ++ii) {
+          Image_Enlarged(Start_image_enlarged+ii,
+                         Start_image_enlarged+jj,pol) = ratio*Image(ii,jj,pol);
+        }
+      }
+    }
+    return Image_Enlarged;
+  }
+
+  //================================================
+  // Zeros padding of a Matrix
+
+  Matrix<Complex> LofarConvolutionFunctionOld::zero_padding
+  (const Matrix<Complex>& Image, int Npixel_Out)
+  {
+    if (Image.shape()[0] == Npixel_Out) {
+      return Image.copy();
+    }
+    if (Npixel_Out%2 != 1) {
+      Npixel_Out++;
+    }
+    IPosition shape_im_out(2, Npixel_Out, Npixel_Out);
+    Matrix<Complex> Image_Enlarged(shape_im_out, 0.);
+
+    double ratio=1.;
+
+    //if(!toFrequency){ratio=double(Npixel_Out)*double(Npixel_Out)/(Image.shape()(0)*Image.shape()(0));}
+
+    uInt Dii = Image.shape()[0]/2;
+    uInt Start_image_enlarged = shape_im_out[0]/2-Dii;
+    //Is an even number, Assume square image
+    //If number of pixel odd then 0th order at the center, shifted by one otherwise
+    if ((Start_image_enlarged-floor(Start_image_enlarged))!=0.) {
+      Start_image_enlarged += 0.5;
+    }
+
+    /* cout<<Start_image_enlarged<<"  "<<floor(Start_image_enlarged)<<endl; */
+    /* if((Start_image_enlarged-floor(Start_image_enlarged))!=0.){ */
+    /*   cout<<"Not even!!!"<<endl; */
+    /*   Start_image_enlarged+=0.5;} */
+    for (Int jj=0; jj<Image.shape()[1]; ++jj) {
+      for (Int ii=0; ii<Image.shape()[0]; ++ii) {
+        Image_Enlarged(Start_image_enlarged+ii,Start_image_enlarged+jj) = 
+          ratio*Image(ii,jj);
+      }
+    }
+    return Image_Enlarged;
+  }
+
+  //================================================
+  void LofarConvolutionFunctionOld::normalized_fft
+  (Matrix<Complex> &im, bool toFreq)
+  {
+    AlwaysAssert (im.ncolumn() == im.nrow()  &&  im.size() > 0  &&
+                  im.contiguousStorage(), AipsError);
+    int tnr = OpenMP::threadNum();
+    if (toFreq) {
+      itsFFTMachines[tnr].normalized_forward (im.nrow(), im.data());
+    } else {
+      itsFFTMachines[tnr].normalized_backward (im.nrow(), im.data());
+    }
+  }
+
+  void LofarConvolutionFunctionOld::normalized_fft
+  (PrecTimer& timer, Matrix<Complex> &im, bool toFreq)
+  {
+    timer.start();
+    normalized_fft (im, toFreq);
+    timer.stop();
+  }
+
+  //=================================================
+  MEpoch LofarConvolutionFunctionOld::observationStartTime
+  (const MeasurementSet &ms, uInt idObservation) const
+  {
+    // Get phase center as RA and DEC (J2000).
+    ROMSObservationColumns observation(ms.observation());
+    AlwaysAssert(observation.nrow() > idObservation, SynthesisError);
+    AlwaysAssert(!observation.flagRow()(idObservation), SynthesisError);
+
+    return observation.timeRangeMeas()(0)(IPosition(1, 0));
+  }
+
+  //=================================================
+  Double LofarConvolutionFunctionOld::observationReferenceFreq
+  (const MeasurementSet &ms, uInt idDataDescription)
+  {
+    // Read polarization id and spectral window id.
+    ROMSDataDescColumns desc(ms.dataDescription());
+    AlwaysAssert(desc.nrow() > idDataDescription, SynthesisError);
+    AlwaysAssert(!desc.flagRow()(idDataDescription), SynthesisError);
+
+    const uInt idWindow = desc.spectralWindowId()(idDataDescription);
+
+    /*        logIO() << LogOrigin("LofarATerm", "initReferenceFreq") << LogIO::NORMAL
+              << "spectral window: " << desc.spectralWindowId()(idDataDescription) << LogIO::POST;*/
+    //            << "spectral window: " << desc.spectralWindowId() << LogIO::POST;
+    // Get spectral information.
+    ROMSSpWindowColumns window(ms.spectralWindow());
+    AlwaysAssert(window.nrow() > idWindow, SynthesisError);
+    AlwaysAssert(!window.flagRow()(idWindow), SynthesisError);
+
+    return window.refFrequency()(idWindow);
+  }
+
+  //=================================================
+  // Estime spheroidal convolution function from the support of the fft of the spheroidal in the image plane
+
+  Double LofarConvolutionFunctionOld::makeSpheroidCut()
+  {
+    // Only calculate if not done yet.
+    if (! Spheroid_cut_im.empty()) {
+      return m_pixelSizeSpheroidal;
+    }
+    Matrix<Complex> spheroidal(m_shape[0], m_shape[1], 1.);
+    taper(spheroidal);
+    if (itsVerbose > 0) {
+      store(spheroidal, itsImgName + ".spheroidal");
+    }
+    normalized_fft(spheroidal);
+    Double Support_Speroidal = findSupport(spheroidal, 0.0001);
+    if (itsVerbose > 0) {
+      store(spheroidal, itsImgName + ".spheroidal_fft");
+    }
+
+    Double res_ini = abs(m_coordinates.increment()(0));
+    Double diam_image = res_ini*m_shape[0];
+    Double Pixel_Size_Spheroidal = diam_image/Support_Speroidal;
+    uInt Npix = floor(diam_image/Pixel_Size_Spheroidal);
+    if (Npix%2 != 1) {
+    // Make the resulting image have an even number of pixel (to make the zeros padding step easier)
+      ++Npix;
+      Pixel_Size_Spheroidal = diam_image/Npix;
+    }
+    Matrix<Complex> Spheroid_cut0(IPosition(2,Npix,Npix),0.);
+    Spheroid_cut=Spheroid_cut0;
+    double istart(m_shape[0]/2.-Npix/2.);
+    if ((istart-floor(istart))!=0.) {
+      //If number of pixel odd then 0th order at the center, shifted by one otherwise
+      istart += 0.5;
+    }
+    for (uInt j=0; j<Npix; ++j) {
+      for (uInt i=0; i<Npix; ++i) {
+        Spheroid_cut(i,j) = spheroidal(istart+i,istart+j);
+      }
+    }
+    Matrix<Complex> Spheroid_cut_paddedf=zero_padding(Spheroid_cut,m_shape[0]);
+    normalized_fft(Spheroid_cut_paddedf, false);
+    Spheroid_cut_im.reference (real(Spheroid_cut_paddedf));
+    // Only this one is really needed.
+    store(Spheroid_cut_im, itsImgName + ".spheroid_cut_im");
+    if (itsVerbose > 0) {
+      store(Spheroid_cut, itsImgName + ".spheroid_cut");
+    }	
+    return Pixel_Size_Spheroidal;
+  }
+
+  const Matrix<Float>& LofarConvolutionFunctionOld::getSpheroidCut()
+  {
+    if (Spheroid_cut_im.empty()) {
+      makeSpheroidCut();
+    }
+    return Spheroid_cut_im;
+  }
+
+  Matrix<Float> LofarConvolutionFunctionOld::getSpheroidCut (const String& imgName)
+  {
+    PagedImage<Float> im(imgName+".spheroid_cut_im");
+    return im.get (True);
+  }
+
+  Matrix<Float> LofarConvolutionFunctionOld::getAveragePB (const String& imgName)
+  {
+    PagedImage<Float> im(imgName+".avgpb");
+    return im.get (True);
+  }
+
+  //=================================================
+  // Return the angular resolution required for making the image of the angular size determined by
+  // coordinates and shape. The resolution is assumed to be the same on both direction axes.
+  Double LofarConvolutionFunctionOld::estimateWResolution
+  (const IPosition &shape, Double pixelSize,
+   Double w) const
+  {
+    Double diam_image = pixelSize*shape[0];         // image diameter in radian
+    if (w == 0.) {
+      return diam_image;
+    }
+    // Get pixel size in W-term image in radian
+    Double Res_w_image = 0.5/(sqrt(2.)*w*(shape[0]/2.)*pixelSize);
+    // Get number of pixel size in W-term image
+    uInt Npix=floor(diam_image/Res_w_image);
+    Res_w_image = diam_image/Npix;
+    if (Npix%2 != 1) {
+      // Make the resulting image have an even number of pixel
+      // (to make the zeros padding step easier)
+      ++Npix;
+      Res_w_image = diam_image/Npix;
+    }
+    return Res_w_image;
+  }
+
+  //=================================================
+  // Return the angular resolution required for making the image of the angular size determined by
+  // coordinates and shape. The resolution is assumed to be the same on both direction axes.
+  Double LofarConvolutionFunctionOld::estimateAResolution
+  (const IPosition &shape, const DirectionCoordinate &coordinates) const
+  {
+    Double res_ini=abs(coordinates.increment()(0));                      // pixel size in image in radian
+    Double diam_image=res_ini*shape(0);                                  // image diameter in radian
+    Double station_diam = 70.;                                           // station diameter in meters: To be adapted to the individual station size.
+    Double Res_beam_image= ((C::c/m_refFrequency)/station_diam)/2.;      // pixel size in A-term image in radian
+    uInt Npix=floor(diam_image/Res_beam_image);                         // Number of pixel size in A-term image
+    Res_beam_image=diam_image/Npix;
+    if (Npix%2 != 1) {
+      // Make the resulting image have an even number of pixel (to make the zeros padding step easier)
+      ++Npix;
+      Res_beam_image = diam_image/Npix;
+    }
+    return Res_beam_image;
+  }
+
+  //=================================================
+  Double LofarConvolutionFunctionOld::spheroidal(Double nu) const
+  {
+    static Double P[2][5] = {{ 8.203343e-2, -3.644705e-1, 6.278660e-1,
+                              -5.335581e-1,  2.312756e-1},
+                             { 4.028559e-3, -3.697768e-2, 1.021332e-1,
+                              -1.201436e-1, 6.412774e-2}};
+    static Double Q[2][3] = {{1.0000000e0, 8.212018e-1, 2.078043e-1},
+                             {1.0000000e0, 9.599102e-1, 2.918724e-1}};
+    uInt part = 0;
+    Double end = 0.0;
+    if (nu >= 0.0 && nu < 0.75) {
+      part = 0;
+      end = 0.75;
+    } else if (nu >= 0.75 && nu <= 1.00) {
+      part = 1;
+      end = 1.00;
+    } else {
+      return 0.0;
+    }
+    Double nusq = nu * nu;
+    Double delnusq = nusq - end * end;
+    Double delnusqPow = delnusq;
+    Double top = P[part][0];
+    for (uInt k=1; k<5; ++k) {
+      top += P[part][k] * delnusqPow;
+      delnusqPow *= delnusq;
+    }
+
+    Double bot = Q[part][0];
+    delnusqPow = delnusq;
+    for (uInt k=1; k<3; ++k) {
+      bot += Q[part][k] * delnusqPow;
+      delnusqPow *= delnusq;
+    }
+	
+    double result = (bot == 0  ?  0 : (1.0 - nusq) * (top / bot));
+    //if(result<1.e-3){result=1.e-3;}
+    return result;
+  }
+
+  void LofarConvolutionFunctionOld::showTimings (ostream& os,
+                                              double duration,
+					      double timeCF) const
+  {
+    os << "  Wterm calculation ";
+    showPerc1 (os, itsTimeW, duration);
+    os << "    fft-part ";
+    showPerc1 (os, itsTimeWfft, itsTimeW);
+    os << "  (";
+    showPerc1 (os, itsTimeWfft, duration);
+    os << " of total;   #ffts=" << itsTimeWcnt << ')' << endl;
+    os << "  Aterm calculation ";
+    showPerc1 (os, itsTimeA, duration);
+    os << "    fft-part ";
+    showPerc1 (os, itsTimeAfft, itsTimeA);
+    os << "  (";
+    showPerc1 (os, itsTimeAfft, duration);
+    os << " of total;   #ffts=" << itsTimeAcnt << ')' << endl;
+    os << "  CFunc calculation ";
+    showPerc1 (os, timeCF, duration);
+    os << "    fft-part ";
+    showPerc1 (os, itsTimeCFfft, timeCF);
+    os << "  (";
+    showPerc1 (os, itsTimeCFfft, duration);
+    os << " of total;   #ffts=" << itsTimeCFcnt << ')' << endl;
+  }
+
+  void LofarConvolutionFunctionOld::showPerc1 (ostream& os,
+                                            double value, double total)
+  {
+    int perc = (total==0  ?  0 : int(1000. * value / total + 0.5));
+    os << std::setw(3) << perc/10 << '.' << perc%10 << '%';
+  }
+
+
+} //# end namespace casa
diff --git a/CEP/Imager/LofarFT/src/LofarCubeSkyEquation.cc b/CEP/Imager/LofarFT/src/LofarCubeSkyEquation.cc
index de087459d25efce5f28cbf85cbbe14fd71607a43..64450723415e81e25056d257e816fedfb88ded81 100644
--- a/CEP/Imager/LofarFT/src/LofarCubeSkyEquation.cc
+++ b/CEP/Imager/LofarFT/src/LofarCubeSkyEquation.cc
@@ -25,6 +25,7 @@
 //#
 //# $Id$
 
+#include <lofar_config.h>
 #include <casa/iostream.h>
 #include <casa/Exceptions/Error.h>
 #include <casa/Utilities/Assert.h>
@@ -35,6 +36,7 @@
 #include <casa/OS/HostInfo.h>
 #include <casa/System/ProgressMeter.h>
 #include <casa/Utilities/CountedPtr.h>
+#include <lattices/Lattices/ArrayLattice.h>
 
 #include <coordinates/Coordinates/CoordinateSystem.h>
 #include <coordinates/Coordinates/DirectionCoordinate.h>
@@ -74,6 +76,8 @@
 #include <msvis/MSVis/VisBufferAsync.h>
 //#include <synthesis/Utilities/ThreadTimers.h>
 
+#include <casa/OS/PrecTimer.h>
+
 namespace casa { //# NAMESPACE CASA - BEGIN
 
 LofarCubeSkyEquation::LofarCubeSkyEquation(SkyModel& sm, VisSet& vs, FTMachine& ft,
@@ -85,7 +89,6 @@ LofarCubeSkyEquation::LofarCubeSkyEquation(SkyModel& sm, VisSet& vs, FTMachine&
   firstOneChangesPut_p(False),
   firstOneChangesGet_p(False)
 {
-
     init(ft);
 
 }
@@ -107,19 +110,19 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
 
   doflat_p=False;
   nchanPerSlice_p = 1;
-  
-   if(sm_->numberOfTaylorTerms()>1) 
+
+   if(sm_->numberOfTaylorTerms()>1)
     {
       nmod = (sm_->numberOfModels()/sm_->numberOfTaylorTerms()) * (2 * sm_->numberOfTaylorTerms() - 1);
     }
-  
+
   //case of component ft only
   if(nmod==0)
     nmod=1;
-  
+
   ftm_p.resize(nmod, True);
   iftm_p.resize(nmod, True);
-  
+
   //make a distinct ift_ as gridding and degridding can occur simultaneously
   if(ft.name() == "MosaicFT"){
     ft_=new MosaicFT(static_cast<MosaicFT &>(ft));
@@ -127,9 +130,9 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
     ftm_p[0]=ft_;
     iftm_p[0]=ift_;
     //For mosaic ...outlier fields get normal GridFT's
-    
+
     MPosition loc=ift_->getLocation();
-    for (Int k=1; k < (nmod); ++k){ 
+    for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new GridFT(1000000, 16, "SF", loc, 1.0, False);
       iftm_p[k]=new GridFT(1000000, 16, "SF", loc, 1.0, False);
     }
@@ -144,9 +147,9 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
     static_cast<WProjectFT &>(*ftm_p[0]).setConvFunc(sharedconvFunc);
     static_cast<WProjectFT &>(*iftm_p[0]).setConvFunc(sharedconvFunc);
     // For now have all the fields have WProjectFt machines....
-    //but should be seperated between GridFT's for the outliers and 
+    //but should be seperated between GridFT's for the outliers and
     //WProject for the facets.
-    for (Int k=1; k < (nmod); ++k){ 
+    for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new WProjectFT(static_cast<WProjectFT &>(*ft_));
       iftm_p[k]=new WProjectFT(static_cast<WProjectFT &>(*ift_));
       // Give each pair of FTMachine a convolution function set to share
@@ -171,7 +174,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
      iftm_p[0]=ift_;
      if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
        throw(AipsError("No multifield with pb-projection allowed"));
-     for (Int k=1; k < (nmod); ++k){ 
+     for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new nPBWProjectFT(static_cast<nPBWProjectFT &>(*ft_));
       iftm_p[k]=new nPBWProjectFT(static_cast<nPBWProjectFT &>(*ift_));
     }
@@ -184,7 +187,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
      iftm_p[0]=ift_;
      if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
        throw(AipsError("No multifield with a-projection allowed"));
-     for (Int k=1; k < (nmod); ++k){ 
+     for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new AWProjectFT(static_cast<AWProjectFT &>(*ft_));
       iftm_p[k]=new AWProjectFT(static_cast<AWProjectFT &>(*ift_));
       //      iftm_p[k]=ftm_p[k];
@@ -198,10 +201,10 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
      iftm_p[0]=ift_;
      // if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
      //   throw(AipsError("No multifield with a-projection allowed"));
-     for (Int k=1; k < (nmod); ++k){ 
+     for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new AWProjectWBFT(static_cast<AWProjectWBFT &>(*ft_));
       iftm_p[k]=new AWProjectWBFT(static_cast<AWProjectWBFT &>(*ift_));
-      if(sm_->numberOfTaylorTerms()>1) 
+      if(sm_->numberOfTaylorTerms()>1)
 	{
 	  for (Int model=0; model < (sm_->numberOfModels()) ; ++model)
 	    {
@@ -221,7 +224,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
      iftm_p[0]=ift_;
      if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
        throw(AipsError("No multifield with pb-mosaic allowed"));
-     for (Int k=1; k < (nmod); ++k){ 
+     for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new PBMosaicFT(static_cast<PBMosaicFT &>(*ft_));
       iftm_p[k]=new PBMosaicFT(static_cast<PBMosaicFT &>(*ift_));
     }
@@ -232,7 +235,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
     // ftm_p[0]=CountedPtr<FTMachine>(ft_, False);
     ftm_p[0]=ft_;
     iftm_p[0]=ift_;
-    for (Int k=1; k < (nmod); ++k){ 
+    for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new rGridFT(static_cast<rGridFT &>(*ft_));
       iftm_p[k]=new rGridFT(static_cast<rGridFT &>(*ift_));
     }
@@ -242,11 +245,11 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
     ift_=new MultiTermFT(static_cast<MultiTermFT &>(ft));
     ftm_p[0]=ft_;
     iftm_p[0]=ift_;
-    for (Int k=1; k < (nmod); ++k){ 
+    for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new MultiTermFT(static_cast<MultiTermFT &>(*ft_));
       iftm_p[k]=new MultiTermFT(static_cast<MultiTermFT &>(*ift_));
     }
-     for (Int k=0; k < (nmod); ++k){ 
+     for (Int k=0; k < (nmod); ++k){
       ftm_p[k]->setMiscInfo(sm_->getTaylorIndex(k));
       iftm_p[k]->setMiscInfo(sm_->getTaylorIndex(k));
     }
@@ -257,13 +260,30 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
      //     ift_=ft_;
      ftm_p[0]=ft_;
      iftm_p[0]=ift_;
-     if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
-       throw(AipsError("No multifield with a-projection allowed"));
-     for (Int k=1; k < (nmod); ++k){ 
+     ftm_p[0]->setMiscInfo(0);
+     iftm_p[0]->setMiscInfo(0);
+     cout<<"nmod="<<nmod<<endl;
+     //if(nmod != (2 * sm_->numberOfTaylorTerms() - 1)) /* MFS */
+     //  throw(AipsError("No multifield with a-projection allowed"));
+     for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new LOFAR::LofarFTMachine(static_cast<LOFAR::LofarFTMachine &>(*ft_));
       iftm_p[k]=new LOFAR::LofarFTMachine(static_cast<LOFAR::LofarFTMachine &>(*ift_));
+      // test MSMFT for LOFAR
+      ftm_p[k]->setMiscInfo(0);//sm_->getTaylorIndex(k));
+      iftm_p[k]->setMiscInfo(0);//sm_->getTaylorIndex(k));
+
+     }
+      // if(sm_->numberOfTaylorTerms()>1)
+      // 	{
+      // 	  for (Int model=0; model < (sm_->numberOfModels()) ; ++model)
+      // 	    {
+      // 	      ftm_p[model]->setMiscInfo(sm_->getTaylorIndex(model));
+      // 	      iftm_p[model]->setMiscInfo(sm_->getTaylorIndex(model));
+
+      // 	    }
+      // 	}
       //      iftm_p[k]=ftm_p[k];
-    }
+     //}
   }
   else {
     ft_=new GridFT(static_cast<GridFT &>(ft));
@@ -271,7 +291,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
     // ftm_p[0]=CountedPtr<FTMachine>(ft_, False);
     ftm_p[0]=ft_;
     iftm_p[0]=ift_;
-    for (Int k=1; k < (nmod); ++k){ 
+    for (Int k=1; k < (nmod); ++k){
       ftm_p[k]=new GridFT(static_cast<GridFT &>(*ft_));
       iftm_p[k]=new GridFT(static_cast<GridFT &>(*ift_));
     }
@@ -284,7 +304,7 @@ void LofarCubeSkyEquation::init(FTMachine& ft){
 }
 
 LofarCubeSkyEquation::~LofarCubeSkyEquation(){
-  //As we  make an explicit ift_ in the constructor we need 
+  //As we  make an explicit ift_ in the constructor we need
   //to take care of it here...
   //if(ift_ && (ift_ != ft_))
   //  delete ift_;
@@ -300,7 +320,7 @@ void  LofarCubeSkyEquation::predict(Bool incremental, MS::PredefinedColumns col)
   VisibilityIterator::DataColumn visCol=VisibilityIterator::Model;
   if(col==MS::DATA){
     visCol=VisibilityIterator::Observed;
-  } 
+  }
   if(col==MS::CORRECTED_DATA){
     visCol=VisibilityIterator::Corrected;
   }
@@ -310,7 +330,7 @@ void  LofarCubeSkyEquation::predict(Bool incremental, MS::PredefinedColumns col)
   if(sm_->numberOfModels()!= 0)  AlwaysAssert(ok(),AipsError);
   if(noModelCol_p)
     throw(AipsError("Cannot predict visibilities without using scratch columns yet"));
-  // Initialize 
+  // Initialize
   VisIter& vi=*wvi_p;
   //Lets get the channel selection for later use
   vi.getChannelSelection(blockNumChanGroup_p, blockChanStart_p,
@@ -323,16 +343,16 @@ void  LofarCubeSkyEquation::predict(Bool incremental, MS::PredefinedColumns col)
   Bool initialized=False;
   predictComponents(incremental, initialized);
   //set to zero then loop over model...check for size...subimage then loop over  subimages
-  
-  
+
+
   Bool isEmpty=True;
   for (Int model=0; model < (sm_->numberOfModels());++model){
-    isEmpty=isEmpty &&  (sm_->isEmpty(model));                
-    
+    isEmpty=isEmpty &&  (sm_->isEmpty(model));
+
   }
-  
-  
-  if( (sm_->numberOfModels() >0) && isEmpty  && !initialized && !incremental){ 
+
+
+  if( (sm_->numberOfModels() >0) && isEmpty  && !initialized && !incremental){
     // We are at the begining with an empty model as starting point
     for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
       for (vi.origin(); vi.more(); vi++) {
@@ -341,15 +361,15 @@ void  LofarCubeSkyEquation::predict(Bool incremental, MS::PredefinedColumns col)
       }
     }
   }
-  
+
     //If all model is zero...no need to continue
-  if(isEmpty) 
+  if(isEmpty)
     return;
-  
-  
-  
+
+
+
   // Now do the images
-  for (Int model=0; model < (sm_->numberOfModels());++model){ 
+  for (Int model=0; model < (sm_->numberOfModels());++model){
     // Change the model polarization frame
     if(vb->polFrame()==MSIter::Linear) {
       StokesImageUtil::changeCStokesRep(sm_->cImage(model),
@@ -389,22 +409,22 @@ void  LofarCubeSkyEquation::predict(Bool incremental, MS::PredefinedColumns col)
     finalizeGetSlice();
     if(!incremental&&!initialized) initialized=True;
   }
-  
+
   for(Int model=0; model < sm_->numberOfModels(); ++model){
       //For now unscale test on name of ft_
     ft_=&(*ftm_p[model]);
     unScaleImage(model, incremental);
   }
   ft_=&(*ftm_p[0]);
-  
+
   //lets return original selection back to iterator
   if(changedVI)
-    vi.selectChannel(blockNumChanGroup_p, blockChanStart_p, 
-		     blockChanWidth_p, blockChanInc_p, blockSpw_p); 
-  
+    vi.selectChannel(blockNumChanGroup_p, blockChanStart_p,
+		     blockChanWidth_p, blockChanInc_p, blockSpw_p);
+
 }
 
-void LofarCubeSkyEquation::makeApproxPSF(PtrBlock<TempImage<Float> * >& psfs) 
+void LofarCubeSkyEquation::makeApproxPSF(PtrBlock<TempImage<Float> * >& psfs)
 {
 
   if(iftm_p[0]->name()=="MosaicFT")
@@ -451,7 +471,7 @@ void LofarCubeSkyEquation::makeMosaicPSF(PtrBlock<TempImage<Float> * >& psfs){
 	planeMax =  LEN.getFloat();
 	if( (planeMax >0.0) && (planeMax < 0.8 *peak)){
 	  psfSub.put(goodplane);
-	  
+
 	}
       }
     }
@@ -480,6 +500,17 @@ void LofarCubeSkyEquation::makeMosaicPSF(PtrBlock<TempImage<Float> * >& psfs){
 
 void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
 
+  //  PrecTimer TimerCyril;
+  //  TimerCyril.start();
+
+//  cout<<"psfs[0].name() "<<psfs[0]->name()<<endl;
+//File myFile("Cube_dirty.img"+String::toString(count_cycle));
+//  if(!myFile.exists()){
+//       }
+
+
+
+
   Int nmodels=psfs.nelements();
     LogIO os(LogOrigin("LofarCubeSkyEquation", "makeSimplePSF"));
     ft_->setNoPadding(noModelCol_p);
@@ -499,6 +530,11 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
     VisBufferAutoPtr vb (vi);
     vi.originChunks();
     vi.origin();
+    //  TimerCyril.stop();
+    //  TimerCyril.show(cout,"1");
+    //  TimerCyril.reset();
+    //  TimerCyril.start();
+
     // Change the model polarization frame
     for (Int model=0; model < nmodels; ++model){
         if(vb->polFrame()==MSIter::Linear) {
@@ -514,6 +550,10 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
 
     Int nCubeSlice=1;
     isLargeCube(sm_->cImage(0), nCubeSlice);
+    //  TimerCyril.stop();
+    //  TimerCyril.show(cout,"2");
+    //  TimerCyril.reset();
+    //  TimerCyril.start();
     for (Int cubeSlice=0; cubeSlice< nCubeSlice; ++cubeSlice){
         changedVI= getFreqRange(vi, sm_->cImage(0).coordinates(),
                                 cubeSlice, nCubeSlice) || changedVI;
@@ -527,8 +567,16 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
 
         initializePutSlice(* vb, cubeSlice, nCubeSlice);
 
+  	//  TimerCyril.stop();
+  	//  TimerCyril.show(cout,"3");
+  	//  TimerCyril.reset();
+  	//  TimerCyril.start();
         for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
             for (vi.origin(); vi.more(); vi++) {
+  	      //  TimerCyril.stop();
+  	      //  TimerCyril.show(cout,"4a");
+  	      //  TimerCyril.reset();
+  	      //  TimerCyril.start();
                 if(noModelCol_p) {
                     //This here forces the modelVisCube shape and prevents reading model column
                     vb->setModelVisCube(Complex(0.0,0.0));
@@ -537,12 +585,16 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
                 cohDone+=vb->nRow();
                 pm.update(Double(cohDone));
 
+  		//  TimerCyril.stop();
+  		//  TimerCyril.show(cout,"4b");
+  		//  TimerCyril.reset();
+  		//  TimerCyril.start();
             }
         }
         finalizePutSlice(* vb, cubeSlice, nCubeSlice);
     }
 
-    //lets return original selection back to iterator
+   //lets return original selection back to iterator
 
 
     if(changedVI)
@@ -552,6 +604,10 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
     fixImageScale();
     for(Int model=0; model < nmodels; ++model){
         {
+  	  //  TimerCyril.stop();
+  	  //  TimerCyril.show(cout,"5a");
+  	  //  TimerCyril.reset();
+  	  //  TimerCyril.start();
             //Normalize the gS image
             Int nXX=sm_->ggS(model).shape()(0);
             Int nYY=sm_->ggS(model).shape()(1);
@@ -561,6 +617,10 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
             IPosition trc(4, nXX, nYY, npola, nchana);
             blc(0)=0; blc(1)=0; trc(0)=nXX-1; trc(1)=nYY-1;
             //max weights per plane
+  	    //  TimerCyril.stop();
+  	    //  TimerCyril.show(cout,"5b");
+  	    //  TimerCyril.reset();
+  	    //  TimerCyril.start();
             for (Int j=0; j < npola; ++j){
                 for (Int k=0; k < nchana ; ++k){
 
@@ -583,40 +643,119 @@ void LofarCubeSkyEquation::makeSimplePSF(PtrBlock<TempImage<Float> * >& psfs) {
                     }
                 }
             }
+  	    //  TimerCyril.stop();
+  	    //  TimerCyril.show(cout,"6");
+  	    //  TimerCyril.reset();
+  	    //  TimerCyril.start();
             //
         }
 
+  //PtrBlock<TempImage<Float> * >& psfs
+
+
+	// Cyril: Gets the PSF from disk
+	// String nameii("PSF.keep");
+	// ostringstream nameiii(nameii);
+	// PagedImage<Float> tmpi(nameiii.str().c_str());
+	// Slicer slicei(IPosition(4,0,0,0,0), tmpi.shape(), IPosition(4,1,1,1,1));
+	// Array<Float> PSF_Disk;
+	// tmpi.doGetSlice(PSF_Disk, slicei);
+	// CountedPtr<Lattice<Float> > PSF_Lattice;
+	// PSF_Lattice = new ArrayLattice<Float>(PSF_Disk);
+	// SubImage<Float> psfSub(*(psfs[0]), slicei, True);
+	// psfSub.copyData(*PSF_Lattice);
+
         /*
     if(0){
       PagedImage<Float> thisScreen(psfs[model]->shape(), psfs[model]->coordinates(), String("ELPSF).psf"));
 	LatticeExpr<Float> le(*psfs[model]);
 	thisScreen.copyData(le);
-      } 
+      }
          */
-        LatticeExprNode maxPSF=max(*psfs[model]);
-        Float maxpsf=maxPSF.getFloat();
-        if(abs(maxpsf-1.0) > 1e-3) {
-            os << "Maximum of approximate PSF for field " << model << " = "
-                    << maxpsf << " : renormalizing to unity" <<  LogIO::POST;
-        }
-        if(maxpsf > 0.0 ){
-            LatticeExpr<Float> len((*psfs[model])/maxpsf);
-            psfs[model]->copyData(len);
-        }
-        else{
-            if(sm_->numberOfTaylorTerms()>1) { /* MFS */
-                os << "PSF calculation resulted in a PSF with its peak being 0 or less. This is ok for MS-MFS." << LogIO::POST;
-            }
-            else{
-                throw(PSFZero("SkyEquation:: PSF calculation resulted in a PSF with its peak being 0 or less!"));
-            }
-        }
+
+	//===============================================
+	//Cyril: For MF cleaning, Itry take this of
+	//===============================================
+	// LatticeExprNode maxPSF=max(*psfs[model]);
+        // Float maxpsf=maxPSF.getFloat();
+        // if(abs(maxpsf-1.0) > 1e-3) {
+        //    os << "Maximum of approximate PSF for field " << model << " = "
+        //            << maxpsf << " : renormalizing to unity" <<  LogIO::POST;
+        // }
+        // if(maxpsf > 0.0 ){
+	//   LatticeExpr<Float> len((*psfs[model])/maxpsf);
+	//   psfs[model]->copyData(len);
+        // }
+        // else{
+        //     if(sm_->numberOfTaylorTerms()>1) { /* MFS */
+        //         os << "PSF calculation resulted in a PSF with its peak being 0 or less. This is ok for MS-MFS." << LogIO::POST;
+        //     }
+        //     else{
+        //         throw(PSFZero("SkyEquation:: PSF calculation resulted in a PSF with its peak being 0 or less!"));
+        //     }
+        // }
+	//===============================================
+
+
+
     }
 
     isPSFWork_p=False; // resetting this flag so that subsequent calculation uses
     // the right SkyJones correction;
 }
 
+
+
+
+// //============================ ADDED by Cyril
+
+// void LofarCubeSkyEquation::setExistingPSF(PtrBlock<TempImage<Float> * >& psfs) {
+
+//   Int nmodels=psfs.nelements();
+//   String FileName("test.img.psf");
+//   PagedImage<Float> myimage (FileName);
+//   for(Int model=0; model < nmodels; ++model){
+//     {
+//       Int nXX=sm_->ggS(model).shape()(0);
+//       Int nYY=sm_->ggS(model).shape()(1);
+//       Int npola= sm_->ggS(model).shape()(2);
+//       Int nchana= sm_->ggS(model).shape()(3);
+//       IPosition blc(4,nXX, nYY, npola, nchana);
+//       IPosition trc(4, nXX, nYY, npola, nchana);
+//       blc(0)=0; blc(1)=0; trc(0)=nXX-1; trc(1)=nYY-1;
+//       for (Int j=0; j < npola; ++j){
+// 	for (Int k=0; k < nchana ; ++k){
+
+// 	  blc(2)=j; trc(2)=j;
+// 	  blc(3)=k; trc(3)=k;
+// 	  Slicer sl(blc, trc, Slicer::endIsLast);
+// 	  SubImage<Float> gSSub(sm_->gS(model), sl, False);
+// 	  SubImage<Float> ggSSub(sm_->ggS(model), sl, False);
+// 	  SubImage<Float> psfSub(*(psfs[model]), sl, True);
+// 	  Float planeMax;
+// 	  LatticeExprNode LEN = max( ggSSub );
+// 	  planeMax =  LEN.getFloat();
+// 	  if(planeMax !=0){
+// 	    psfSub.copyData( (LatticeExpr<Float>)
+// 			     (iif(ggSSub > (0.0),
+// 				  (gSSub/planeMax),0.0)));
+// 	  }
+// 	  else{
+// 	    psfSub.set(0.0);
+// 	  }
+// 	}
+//       }
+
+//     }
+
+//     isPSFWork_p=False;
+//   }
+
+// // ======================== END added by Cyril
+
+
+
+
 void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
 
 
@@ -687,9 +826,9 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
     checkVisIterNumRows(*rvi_p);
     VisBufferAutoPtr vb (rvi_p);
     //    Timers tVisAutoPtr=Timers::getTime();
-    
+
     /**** Do we need to do this
-  if( (sm_->isEmpty(0))  && !initialized && !incremental){ 
+  if( (sm_->isEmpty(0))  && !initialized && !incremental){
     // We are at the begining with an empty model as starting point
     for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
       for (vi.origin(); vi.more(); vi++) {
@@ -777,11 +916,12 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
             for (rvi_p->origin(); rvi_p->more(); (*rvi_p)++) {
 
 	      //	      Timers tInitModel=Timers::getTime();
+
                 if(!incremental && !predictedComp) {
                     //This here forces the modelVisCube shape and prevents reading model column
                     vb->setModelVisCube(Complex(0.0,0.0));
                 }
-                // get the model visibility and write it to the model MS
+                 // get the model visibility and write it to the model MS
 		//	Timers tGetSlice=Timers::getTime();
 		//		Timers tgetSlice=Timers::getTime();
                 if(!isEmpty)
@@ -794,7 +934,7 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
                 // Now lets grid the -ve of residual
                 // use visCube if there is no correctedData
 		//		Timers tGetRes=Timers::getTime();
-		
+
 		if(!iftm_p[0]->canComputeResiduals()){
 		  cout<<"CANNOT!!!!"<<endl;
 		  if(!useCorrected) vb->modelVisCube()-=vb->visCube();
@@ -805,10 +945,11 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
 		//		Timers tPutSlice = Timers::getTime();
                 //putSlice(* vb, False, FTMachine::MODEL, cubeSlice, nCubeSlice);
 
-                putSlice(* vb, False, FTMachine::MODEL, cubeSlice, nCubeSlice);		
+                putSlice(* vb, False, FTMachine::MODEL, cubeSlice, nCubeSlice);
 
                 cohDone+=vb->nRow();
                 pm.update(Double(cohDone));
+
 		// Timers tDoneGridding=Timers::getTime();
 		// aInitModel += tgetSlice - tInitModel;
 		// aGetSlice += tsetModel - tgetSlice;
@@ -825,7 +966,7 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
 	//	Timers tFinalizePutSlice=Timers::getTime();
         finalizePutSlice(* vb, cubeSlice, nCubeSlice);
 	//	Timers tDoneFinalizePutSlice=Timers::getTime();
-	
+
 	// aFinalizeGetSlice += tFinalizePutSlice - tFinalizeGetSlice;
 	// aFinalizePutSlice += tDoneFinalizePutSlice - tFinalizePutSlice;
     }
@@ -853,31 +994,31 @@ void LofarCubeSkyEquation::gradientsChiSquared(Bool /*incr*/, Bool commitModel){
         rvi_p = oldRvi;      // make the old vi the current vi
     }
    // cerr << "gradChiSq: "
-   // 	<< "InitGrad = " << aInitGrad.formatAverage().c_str() << " " 
-   // 	<< "GetChanSel = " << aGetChanSel.formatAverage().c_str() << " " 
-   // 	<< "ChangeStokes = " << aChangeStokes.formatAverage().c_str() << " " 
-   // 	<< "CheckVisRows = " << aCheckVisRows.formatAverage().c_str() << " " 
-   // 	<< "GetFreq = " << aGetFreq.formatAverage().c_str() << " " 
-   // 	<< "OrigChunks = " << aOrigChunks.formatAverage().c_str() << " " 
-   // 	<< "VBInValid = " << aVBInValid.formatAverage().c_str() << " " 
-   // 	<< "InitGetSlice = " << aInitGetSlice.formatAverage().c_str() << " " 
-   // 	<< "InitPutSlice = " << aInitPutSlice.formatAverage().c_str() << " " 
-   // 	<< "PutSlice = " << aPutSlice.formatAverage().c_str() << " " 
-   // 	<< "FinalGetSlice = " << aFinalizeGetSlice.formatAverage().c_str() << " " 
-   // 	<< "FinalPutSlice = " << aFinalizePutSlice.formatAverage().c_str() << " " 
+   // 	<< "InitGrad = " << aInitGrad.formatAverage().c_str() << " "
+   // 	<< "GetChanSel = " << aGetChanSel.formatAverage().c_str() << " "
+   // 	<< "ChangeStokes = " << aChangeStokes.formatAverage().c_str() << " "
+   // 	<< "CheckVisRows = " << aCheckVisRows.formatAverage().c_str() << " "
+   // 	<< "GetFreq = " << aGetFreq.formatAverage().c_str() << " "
+   // 	<< "OrigChunks = " << aOrigChunks.formatAverage().c_str() << " "
+   // 	<< "VBInValid = " << aVBInValid.formatAverage().c_str() << " "
+   // 	<< "InitGetSlice = " << aInitGetSlice.formatAverage().c_str() << " "
+   // 	<< "InitPutSlice = " << aInitPutSlice.formatAverage().c_str() << " "
+   // 	<< "PutSlice = " << aPutSlice.formatAverage().c_str() << " "
+   // 	<< "FinalGetSlice = " << aFinalizeGetSlice.formatAverage().c_str() << " "
+   // 	<< "FinalPutSlice = " << aFinalizePutSlice.formatAverage().c_str() << " "
    // 	<< endl;
-   
-   // cerr << "VB loop: " 
-   // 	<< "InitModel = " << aInitModel.formatAverage().c_str() << " " 
-   // 	<< "GetSlice = " << aGetSlice.formatAverage().c_str() << " " 
-   // 	<< "SetModel = " << aSetModel.formatAverage().c_str() << " " 
-   // 	<< "GetRes = " << aGetRes.formatAverage().c_str() << " " 
-   // 	<< "PutSlice = " << aPutSlice.formatAverage().c_str() << " " 
-   // 	<< "Extra = " << aExtra.formatAverage().c_str() << " " 
+
+   // cerr << "VB loop: "
+   // 	<< "InitModel = " << aInitModel.formatAverage().c_str() << " "
+   // 	<< "GetSlice = " << aGetSlice.formatAverage().c_str() << " "
+   // 	<< "SetModel = " << aSetModel.formatAverage().c_str() << " "
+   // 	<< "GetRes = " << aGetRes.formatAverage().c_str() << " "
+   // 	<< "PutSlice = " << aPutSlice.formatAverage().c_str() << " "
+   // 	<< "Extra = " << aExtra.formatAverage().c_str() << " "
    // 	<< endl;
 }
 
-void  LofarCubeSkyEquation::isLargeCube(ImageInterface<Complex>& theIm, 
+void  LofarCubeSkyEquation::isLargeCube(ImageInterface<Complex>& theIm,
 				   Int& nslice) {
 
   //non-cube
@@ -896,7 +1037,7 @@ void  LofarCubeSkyEquation::isLargeCube(ImageInterface<Complex>& theIm,
     if(memtot < 512000){
       ostringstream oss;
       oss << "The amount of memory reported " << memtot << " kB is too small to work with" << endl;
-      throw(AipsError(String(oss))); 
+      throw(AipsError(String(oss)));
 
     }
     Long pixInMem=(memtot/8)*1024;
@@ -923,9 +1064,10 @@ void  LofarCubeSkyEquation::isLargeCube(ImageInterface<Complex>& theIm,
   }
 }
 
-void LofarCubeSkyEquation::initializePutSlice(const VisBuffer& vb, 
+void LofarCubeSkyEquation::initializePutSlice(const VisBuffer& vb,
 					 Int cubeSlice, Int nCubeSlice) {
 
+
   AlwaysAssert(ok(),AipsError);
   Bool dirDep= (ej_ != NULL);
   for(Int model=0; model < (sm_->numberOfModels()) ; ++model){
@@ -960,7 +1102,7 @@ LofarCubeSkyEquation::putSlice(VisBuffer & vb, Bool dopsf, FTMachine::Type col,
     firstOneChangesPut_p=False;  // Has this VB changed from the previous one?
     if((ftm_p[0]->name() != "MosaicFT")    && (ftm_p[0]->name() != "PBWProjectFT") &&
        (ftm_p[0]->name() != "AWProjectFT") && (ftm_p[0]->name() != "AWProjectWBFT") &&
-       (ftm_p[0]->name() != "LofarFTMachine") ) 
+       (ftm_p[0]->name() != "LofarFTMachine") )
     {
         changedSkyJonesLogic(vb, firstOneChangesPut_p, internalChangesPut_p);
     }
@@ -988,6 +1130,7 @@ LofarCubeSkyEquation::putSlice(VisBuffer & vb, Bool dopsf, FTMachine::Type col,
             }
 
             for (Int model=0; model<sm_->numberOfModels(); ++model){
+	      //  cout<<"model = "<<model<<endl;
                      iftm_p[model]->put(vb, row, dopsf, col);
             }
         }
@@ -1003,11 +1146,13 @@ LofarCubeSkyEquation::putSlice(VisBuffer & vb, Bool dopsf, FTMachine::Type col,
         initializePutSlice(vb, cubeSlice, nCubeSlice);
         isBeginingOfSkyJonesCache_p=False;
         for (Int model=0; model<sm_->numberOfModels(); ++model){
+	  //cout<<"modelb = "<<model<<endl;
                  iftm_p[model]->put(vb, -1, dopsf, col);
         }
     }
     else {
         for (Int model=0; model<sm_->numberOfModels(); ++model){
+	  //  cout<<"modelc = "<<model<<endl;
                 iftm_p[model]->put(vb, -1, dopsf, col);
         }
     }
@@ -1016,7 +1161,7 @@ LofarCubeSkyEquation::putSlice(VisBuffer & vb, Bool dopsf, FTMachine::Type col,
 
 }
 
-void LofarCubeSkyEquation::finalizePutSlice(const VisBuffer& vb,  
+void LofarCubeSkyEquation::finalizePutSlice(const VisBuffer& vb,
 				       Int cubeSlice, Int nCubeSlice) {
   for (Int model=0; model < sm_->numberOfModels(); ++model){
     //the different apply...jones use ft_ and ift_
@@ -1024,11 +1169,11 @@ void LofarCubeSkyEquation::finalizePutSlice(const VisBuffer& vb,
     ift_=&(*iftm_p[model]);
     // Actually do the transform. Update weights as we do so.
     iftm_p[model]->finalizeToSky();
-    // 1. Now get the (unnormalized) image and add the 
+    // 1. Now get the (unnormalized) image and add the
     // weight to the summed weight
     Matrix<Float> delta;
     imPutSlice_p[model]->copyData(iftm_p[model]->getImage(delta, False));
-    
+
 
 
 
@@ -1052,11 +1197,11 @@ void LofarCubeSkyEquation::finalizePutSlice(const VisBuffer& vb,
 		     *gSSlice);
     SubImage<Float> *ggSSlice;
     sliceCube(ggSSlice, sm_->ggS(model), cubeSlice, nCubeSlice);
-  
+
     // 3. Apply the square of the SkyJones and add this to gradgrad chisquared
     applySkyJonesSquare(vb, -1, weightSlice_p[model], *workSlice,
 			*ggSSlice);
-  
+
 
     delete workSlice;
     delete gSSlice;
@@ -1068,9 +1213,9 @@ void LofarCubeSkyEquation::finalizePutSlice(const VisBuffer& vb,
   sm_->addStatistics(sumwt, chisq);
 }
 
-void LofarCubeSkyEquation::initializeGetSlice(const VisBuffer& vb, 
-					   Int row, 
-					   Bool incremental, Int cubeSlice, 
+void LofarCubeSkyEquation::initializeGetSlice(const VisBuffer& vb,
+					   Int row,
+					   Bool incremental, Int cubeSlice,
 					   Int nCubeSlice){
   imGetSlice_p.resize(sm_->numberOfModels(), True, False);
   for(Int model=0; model < sm_->numberOfModels(); ++model){
@@ -1090,11 +1235,11 @@ void LofarCubeSkyEquation::initializeGetSlice(const VisBuffer& vb,
   }
   ft_=&(*ftm_p[0]);
   ift_=&(*iftm_p[0]);
-  
+
 
 }
 
-void LofarCubeSkyEquation::sliceCube(CountedPtr<ImageInterface<Complex> >& slice,Int model, Int cubeSlice, 
+void LofarCubeSkyEquation::sliceCube(CountedPtr<ImageInterface<Complex> >& slice,Int model, Int cubeSlice,
 				Int nCubeSlice, Int typeOfSlice){
 
   IPosition blc(4,0,0,0,0);
@@ -1110,8 +1255,8 @@ void LofarCubeSkyEquation::sliceCube(CountedPtr<ImageInterface<Complex> >& slice
   sl_p=Slicer (blc, trc, Slicer::endIsLast);
   SubImage<Complex>* sliceIm= new SubImage<Complex>(sm_->cImage(model), sl_p, False);
   //  cerr << "SliceCube: " << beginChannel << " " << endChannel << endl;
-  if(typeOfSlice==0){    
-    
+  if(typeOfSlice==0){
+
     Double memoryMB=HostInfo::memoryTotal(true)/1024.0/(8.0*(sm_->numberOfModels()));
     slice=new TempImage<Complex> (sliceIm->shape(), sliceIm->coordinates(), memoryMB);
     //slice.copyData(sliceIm);
@@ -1126,7 +1271,7 @@ void LofarCubeSkyEquation::sliceCube(CountedPtr<ImageInterface<Complex> >& slice
 }
 
 void LofarCubeSkyEquation::sliceCube(SubImage<Float>*& slice,
-				  ImageInterface<Float>& image, Int cubeSlice, 
+				  ImageInterface<Float>& image, Int cubeSlice,
 				  Int nCubeSlice){
   IPosition blc(4,0,0,0,0);
   IPosition trc(4,image.shape()(0)-1,
@@ -1143,7 +1288,7 @@ void LofarCubeSkyEquation::sliceCube(SubImage<Float>*& slice,
   slice=  new SubImage<Float> (image, sl_p, True);
 }
 
-VisBuffer& LofarCubeSkyEquation::getSlice(VisBuffer& result,  
+VisBuffer& LofarCubeSkyEquation::getSlice(VisBuffer& result,
 				     Bool incremental,
 				     Int cubeSlice, Int nCubeSlice) {
 
@@ -1175,7 +1320,7 @@ VisBuffer& LofarCubeSkyEquation::getSlice(VisBuffer& result,
     Matrix<Complex> refvb;
     for (Int row=0; row<nRow; row++) {
       finalizeGetSlice();
-      initializeGetSlice(result, row, False, cubeSlice, 
+      initializeGetSlice(result, row, False, cubeSlice,
 			 nCubeSlice);
       if(incremental || (nmodels > 1)){
 	for (Int model=0; model < nmodels; ++model){
@@ -1228,6 +1373,7 @@ LofarCubeSkyEquation::finalizeGetSlice(){
   //        ftm_p[model]->finalizeToVis();
 }
 
+
 Bool
 LofarCubeSkyEquation::getFreqRange(ROVisibilityIterator& vi,
                               const CoordinateSystem& coords,
@@ -1259,7 +1405,7 @@ LofarCubeSkyEquation::getFreqRange(ROVisibilityIterator& vi,
     if(nslice==1)
         return False;
 
-    Double start=0.0; 
+    Double start=0.0;
     Double end=0.0;
     Double chanwidth=1.0;
     Int specIndex=coords.findCoordinate(Coordinate::SPECTRAL);
@@ -1286,8 +1432,8 @@ LofarCubeSkyEquation::getFreqRange(ROVisibilityIterator& vi,
     if(spwb.nelements()==0)
         return False;
 
-    //vi.selectChannel(1, startb[0][0], nchanb[0][0], 1, spwb[0][0]); 
-    vi.selectChannel(blockNumChanGroup_p, startb, nchanb, incrb, spwb); 
+    //vi.selectChannel(1, startb[0][0], nchanb[0][0], 1, spwb[0][0]);
+    vi.selectChannel(blockNumChanGroup_p, startb, nchanb, incrb, spwb);
 
     return True;
 
@@ -1298,27 +1444,27 @@ void LofarCubeSkyEquation::fixImageScale()
   LogIO os(LogOrigin("LofarCubeSkyEquation", "fixImageScale"));
 
   // make a minimum value to ggS
-  // This has the same effect as Sault Weighting, but 
+  // This has the same effect as Sault Weighting, but
   // is implemented somewhat differently.
   // We also keep the fluxScale(mod) images around to
   // undo the weighting.
   Float ggSMax=0.0;
   for (Int model=0;model<sm_->numberOfModels();model++) {
-    
+
     LatticeExprNode LEN = max( sm_->ggS(model) );
     ggSMax =  max(ggSMax,LEN.getFloat());
   }
   ggSMax_p=ggSMax;
   Float ggSMin1;
   Float ggSMin2;
-  
+
   ggSMin1 = ggSMax * constPB_p * constPB_p;
   ggSMin2 = ggSMax * minPB_p * minPB_p;
-    
+
   for (Int model=0;model<sm_->numberOfModels();model++) {
     if(ej_ || (ftm_p[model]->name() == "MosaicFT") ) {
-      
-      
+
+
 
     /*Don't print this for now
       if (scaleType_p == "SAULT") {
@@ -1331,7 +1477,7 @@ void LofarCubeSkyEquation::fixImageScale()
     sm_->fluxScale(model).removeRegion ("mask0", RegionHandler::Any, False);
     if ((ftm_p[model]->name()!="MosaicFT")) {
       if(scaleType_p=="SAULT"){
-	
+
 	  // Adjust flux scale to account for ggS being truncated at ggSMin1
 	  // Below ggSMin2, set flux scale to 0.0
 	  // FluxScale * image => true brightness distribution, but
@@ -1339,47 +1485,47 @@ void LofarCubeSkyEquation::fixImageScale()
 	  // if ggS < ggSMin2, set to Zero;
 	  // if ggS > ggSMin2 && < ggSMin1, set to ggSMin1/ggS
 	  // if ggS > ggSMin1, set to 1.0
-	
-	sm_->fluxScale(model).copyData( (LatticeExpr<Float>) 
+
+	sm_->fluxScale(model).copyData( (LatticeExpr<Float>)
 					(iif(sm_->ggS(model) < (ggSMin2), 0.0,
 					     sqrt((sm_->ggS(model))/ggSMin1) )) );
-	sm_->fluxScale(model).copyData( (LatticeExpr<Float>) 
+	sm_->fluxScale(model).copyData( (LatticeExpr<Float>)
 					(iif(sm_->ggS(model) > (ggSMin1), 1.0,
 					     (sm_->fluxScale(model)) )) );
 	// truncate ggS at ggSMin1
-	sm_->ggS(model).copyData( (LatticeExpr<Float>) 
-				  (iif(sm_->ggS(model) < (ggSMin1), ggSMin1*(sm_->fluxScale(model)), 
+	sm_->ggS(model).copyData( (LatticeExpr<Float>)
+				  (iif(sm_->ggS(model) < (ggSMin1), ggSMin1*(sm_->fluxScale(model)),
 				       sm_->ggS(model)) )
 				  );
-	
+
 	}
 
 	else{
 
-	  sm_->fluxScale(model).copyData( (LatticeExpr<Float>) 
+	  sm_->fluxScale(model).copyData( (LatticeExpr<Float>)
 					  (iif(sm_->ggS(model) < (ggSMin2), 0.0,
 					       sqrt((sm_->ggS(model))/ggSMax) )) );
-	  sm_->ggS(model).copyData( (LatticeExpr<Float>) 
+	  sm_->ggS(model).copyData( (LatticeExpr<Float>)
 					  (iif(sm_->ggS(model) < (ggSMin2), 0.0,
 					       sqrt((sm_->ggS(model))*ggSMax) )) );
 
 	}
 
       } else {
-	
+
 	  Int nXX=sm_->ggS(model).shape()(0);
 	  Int nYY=sm_->ggS(model).shape()(1);
 	  Int npola= sm_->ggS(model).shape()(2);
 	  Int nchana= sm_->ggS(model).shape()(3);
 	  IPosition blc(4,nXX, nYY, npola, nchana);
 	  IPosition trc(4, nXX, nYY, npola, nchana);
-	  blc(0)=0; blc(1)=0; trc(0)=nXX-1; trc(1)=nYY-1; 
+	  blc(0)=0; blc(1)=0; trc(0)=nXX-1; trc(1)=nYY-1;
 
-	  //Those damn weights per plane can be wildly different so 
+	  //Those damn weights per plane can be wildly different so
 	  //deal with it properly here
 	  for (Int j=0; j < npola; ++j){
 	    for (Int k=0; k < nchana ; ++k){
-	      
+
 	      blc(2)=j; trc(2)=j;
 	      blc(3)=k; trc(3)=k;
 	      Slicer sl(blc, trc, Slicer::endIsLast);
@@ -1399,49 +1545,49 @@ void LofarCubeSkyEquation::fixImageScale()
 	      ///lets be conservative and go to 1% of ggsMin2
 	      if(planeMax !=0){
 		if(doflat_p){
-		  fscalesub.copyData( (LatticeExpr<Float>) 
-				      (iif(ggSSub < (ggSMin2/100.0), 
+		  fscalesub.copyData( (LatticeExpr<Float>)
+				      (iif(ggSSub < (ggSMin2/100.0),
 					   0.0, sqrt(ggSSub/planeMax))));
-		  ggSSub.copyData( (LatticeExpr<Float>) 
-				   (iif(ggSSub < (ggSMin2/100.0), 0.0, 
+		  ggSSub.copyData( (LatticeExpr<Float>)
+				   (iif(ggSSub < (ggSMin2/100.0), 0.0,
 					sqrt(planeMax*ggSSub))));
 		}
 		else{
-		  fscalesub.copyData( (LatticeExpr<Float>) 
-				      (iif(ggSSub < (ggSMin2/100.0), 
+		  fscalesub.copyData( (LatticeExpr<Float>)
+				      (iif(ggSSub < (ggSMin2/100.0),
 					   0.0, (ggSSub/planeMax))));
-		  ggSSub.copyData( (LatticeExpr<Float>) 
-				   (iif(ggSSub < (ggSMin2/100.0), 0.0, 
+		  ggSSub.copyData( (LatticeExpr<Float>)
+				   (iif(ggSSub < (ggSMin2/100.0), 0.0,
 					(planeMax))));
 		}
 
-		//ggSSub.copyData( (LatticeExpr<Float>) 
-		//		 (iif(ggSSub < (ggSMin2/100.0), 0.0, 
+		//ggSSub.copyData( (LatticeExpr<Float>)
+		//		 (iif(ggSSub < (ggSMin2/100.0), 0.0,
 		//		      planeMax)));
-	
+
 
 	      }
 	    }
 
 	  }
 	  /*
-	    
+
 	  ftm_p[model]->getFluxImage(sm_->fluxScale(model));
-	  
-	  sm_->fluxScale(model).copyData( (LatticeExpr<Float>) 
+
+	  sm_->fluxScale(model).copyData( (LatticeExpr<Float>)
 					  (iif(sm_->ggS(model) < (ggSMin2), 0.0,
 					  (sm_->ggS(model)/ggSMax) )) );
 
 	  */
-	  //}	
+	  //}
       }
-    
+
       //because for usual ft machines a applySJoneInv is done on the gS
       //in the finalizeput stage...need to understand if its necessary
       /*need to understand that square business
       if( (ft_->name() != "MosaicFT") && (!isPSFWork_p)){
-	sm_->gS(model).copyData( (LatticeExpr<Float>) 
-				 (iif(sm_->fluxScale(model) > 0.0, 
+	sm_->gS(model).copyData( (LatticeExpr<Float>)
+				 (iif(sm_->fluxScale(model) > 0.0,
 				      ((sm_->gS(model))/(sm_->fluxScale(model))), 0.0 )) );
 
       }
diff --git a/CEP/Imager/LofarFT/src/LofarFTMachine.cc b/CEP/Imager/LofarFT/src/LofarFTMachine.cc
index cc1bc5188a31ed334fffc71793aae94aa70a2bb0..5985558dad5aa892d354de316472b041d6b3311f 100644
--- a/CEP/Imager/LofarFT/src/LofarFTMachine.cc
+++ b/CEP/Imager/LofarFT/src/LofarFTMachine.cc
@@ -21,9 +21,9 @@
 //# $Id$
 
 #include <lofar_config.h>
-// #include <Common/LofarLogger.h>
-// #include <Common/Exception.h>
-#include <Common/OpenMP.h>
+// #include <Common/OpenMP.h>
+// #include <omp.h>
+
 #include <msvis/MSVis/VisibilityIterator.h>
 #include <casa/Quanta/UnitMap.h>
 #include <casa/Quanta/UnitVal.h>
@@ -76,6 +76,8 @@
 #include <casa/Utilities/CompositeNumber.h>
 #include <casa/OS/PrecTimer.h>
 #include <casa/sstream.h>
+#include <casa/OS/HostInfo.h>
+#include <casa/BasicMath/Random.h>
 #define DORES True
 
 
@@ -107,23 +109,39 @@ LofarFTMachine::LofarFTMachine(Long icachesize, Int itilesize,
                                const MeasurementSet& ms, Int nwPlanes,
                                MPosition mLocation, Float padding, Bool usezero,
                                Bool useDoublePrec, double wmax,
-			       const String& beamPath, Int verbose,
+                               Int verbose,
                                Int maxsupport, Int oversample,
                                const String& imgName,
                                const Matrix<bool>& gridMuellerMask,
-                               const Matrix<bool>& degridMuellerMask)
+                               const Matrix<bool>& degridMuellerMask,
+			       Double RefFreq,
+			       Bool Use_Linear_Interp_Gridder, 
+			       Bool Use_EJones, 
+			       int StepApplyElement, 
+			       Double PBCut, 
+			       Bool PredictFT, 
+			       String PsfOnDisk, 
+			       Bool UseMasksDegrid,
+			       Bool reallyDoPSF, 
+                               const Record& parameters
+                              )//, 
+			       //Double FillFactor)
   : FTMachine(), padding_p(padding), imageCache(0), cachesize(icachesize),
     tilesize(itilesize), gridder(0), isTiled(False), convType(iconvType),
     maxAbsData(0.0), centerLoc(IPosition(4,0)),
     offsetLoc(IPosition(4,0)), usezero_p(usezero), noPadding_p(False),
     usePut2_p(False), machineName_p("LofarFTMachine"), itsMS(ms),
-    itsNWPlanes(nwPlanes), itsWMax(wmax), itsConvFunc(0), itsBeamPath(beamPath),
+    itsNWPlanes(nwPlanes), itsWMax(wmax), itsConvFunc(0),
     itsVerbose(verbose),
     itsMaxSupport(maxsupport), itsOversample(oversample), itsImgName(imgName),
     itsGridMuellerMask(gridMuellerMask),
     itsDegridMuellerMask(degridMuellerMask),
-    itsGriddingTime(0), itsDegriddingTime(0), itsCFTime(0)
+    itsGriddingTime(0), itsDegriddingTime(0), itsCFTime(0), itsParameters(parameters)
 {
+  cout << "=======LofarFTMachine====================================" << endl;
+  cout << itsParameters << endl;
+  cout << "=========================================================" << endl;
+  
   logIO() << LogOrigin("LofarFTMachine", "LofarFTMachine")  << LogIO::NORMAL;
   logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
   mLocation_p=mLocation;
@@ -137,6 +155,32 @@ LofarFTMachine::LofarFTMachine(Long icachesize, Int itilesize,
   itsSumPB.resize (itsNThread);
   itsSumCFWeight.resize (itsNThread);
   itsSumWeight.resize (itsNThread);
+  itsRefFreq=RefFreq;
+  itsNamePsfOnDisk=PsfOnDisk;
+  its_Use_Linear_Interp_Gridder=Use_Linear_Interp_Gridder;
+  its_Use_EJones=Use_EJones;
+  its_UseMasksDegrid=UseMasksDegrid;
+  its_PBCut=PBCut;
+  its_reallyDoPSF=reallyDoPSF;
+  //its_FillFactor=FillFactor;
+  itsStepApplyElement=StepApplyElement;
+  its_Apply_Element=false;
+  itsPredictFT=PredictFT;
+  if(itsStepApplyElement>0){its_Apply_Element=true;}
+
+  if(its_Use_Linear_Interp_Gridder){
+    cout<<"Gridding using oversampling of 1 only"<<endl;
+    itsOversample=1;
+  };
+  //cout<<"FTMahin: itsRefFreq "<<itsRefFreq<<endl;
+
+  ROMSSpWindowColumns window(ms.spectralWindow());
+  itsListFreq.resize(window.nrow());
+  for(uInt i=0; i<window.nrow();++i){
+    itsListFreq[i]=window.refFrequency()(i);
+    cout<<"SPW"<<i<<", freq="<<itsListFreq[i]<<endl;
+  };
+  its_Already_Initialized=false;
 }
 
 //LofarFTMachine::LofarFTMachine(Long icachesize, Int itilesize,
@@ -224,6 +268,20 @@ LofarFTMachine& LofarFTMachine::operator=(const LofarFTMachine& other)
     itsNWPlanes = other.itsNWPlanes;
     itsWMax = other.itsWMax;
     itsConvFunc = other.itsConvFunc;
+    //cyrr: mfs
+    itsRefFreq=other.itsRefFreq;
+    thisterm_p=other.thisterm_p;
+    its_Use_Linear_Interp_Gridder= other.its_Use_Linear_Interp_Gridder;
+    its_Use_EJones= other.its_Use_EJones;
+    its_UseMasksDegrid=other.its_UseMasksDegrid;
+    its_Apply_Element= other.its_Apply_Element;
+    itsStepApplyElement=other.itsStepApplyElement;
+    its_Already_Initialized= other.its_Already_Initialized;
+    its_reallyDoPSF = other.its_reallyDoPSF;
+    its_PBCut= other.its_PBCut;
+    //its_FillFactor=other.its_FillFactor;
+     //cyrr: mfs
+
     ConjCFMap_p = other.ConjCFMap_p;
     CFMap_p = other.CFMap_p;
     itsNThread = other.itsNThread;
@@ -232,16 +290,17 @@ LofarFTMachine& LofarFTMachine::operator=(const LofarFTMachine& other)
     itsSumPB.resize (itsNThread);
     itsSumCFWeight.resize (itsNThread);
     itsSumWeight.resize (itsNThread);
-    itsBeamPath = other.itsBeamPath;
     itsVerbose = other.itsVerbose;
     itsMaxSupport = other.itsMaxSupport;
     itsOversample = other.itsOversample;
+    itsPredictFT = other.itsPredictFT;
     itsImgName = other.itsImgName;
     itsGridMuellerMask = other.itsGridMuellerMask;
     itsDegridMuellerMask = other.itsDegridMuellerMask;
     itsGriddingTime = other.itsGriddingTime;
     itsDegriddingTime = other.itsDegriddingTime;
     itsCFTime = other.itsCFTime;
+    itsParameters = other.itsParameters;
   }
   return *this;
 }
@@ -267,6 +326,7 @@ void LofarFTMachine::init() {
   logIO() << LogOrigin("LofarFTMachine", "init")  << LogIO::NORMAL;
   canComputeResiduals_p = DORES;
   ok();
+  //  cout<<"LofarFTMachine::init()" <<endl;
 
   /* hardwiring isTiled is False
   // Padding is possible only for non-tiled processing
@@ -280,6 +340,9 @@ void LofarFTMachine::init() {
   else {
   */
     // We are padding.
+
+  //cout<<"padding_p!!!!! "<<padding_p<<endl;
+
   isTiled=False;
   if(!noPadding_p){
     CompositeNumber cn(uInt(image->shape()(0)*2));
@@ -334,14 +397,19 @@ void LofarFTMachine::init() {
   itsConvFunc = new LofarConvolutionFunction(padded_shape,
                                              image->coordinates().directionCoordinate (image->coordinates().findCoordinate(Coordinate::DIRECTION)),
                                              itsMS, itsNWPlanes, itsWMax,
-                                             itsOversample, itsBeamPath,
-					     itsVerbose, itsMaxSupport,
-                                             itsImgName);
+                                             itsOversample,
+                                             itsVerbose, itsMaxSupport,
+                                             itsImgName+String::toString(thisterm_p),
+					     its_Use_EJones,
+					     its_Apply_Element,
+                                             itsParameters);
 
   // Set up image cache needed for gridding. For BOX-car convolution
   // we can use non-overlapped tiles. Otherwise we need to use
   // overlapped tiles and additive gridding so that only increments
   // to a tile are written.
+  its_Already_Initialized=true;
+
   if(imageCache) delete imageCache; imageCache=0;
 
   if(isTiled) {
@@ -364,6 +432,12 @@ void LofarFTMachine::init() {
 					   (tileOverlap>0.0));
 
   }
+  itsCyrilTimer.start();
+  itsTStartObs=1.e30;
+  itsDeltaTime=0.;
+  itsNextApplyTime=0.;;
+  itsCounterTimes=0;
+
 }
 
 // This is nasty, we should use CountedPointers here.
@@ -377,9 +451,11 @@ LofarFTMachine::~LofarFTMachine()
 
 const Matrix<Float>& LofarFTMachine::getAveragePB() const
 {
+  //cout<<"return beam"<<endl;
   // Read average beam from disk if not present.
   if (itsAvgPB.empty()) {
-    PagedImage<Float> pim(itsImgName + ".avgpb");
+    //cout<<"...read beam "<<itsImgName+String::toString(thisterm_p) + ".avgpb"<<endl;
+    PagedImage<Float> pim(itsImgName+String::toString(thisterm_p) + ".avgpb");
     Array<Float> arr = pim.get();
     itsAvgPB.reference (arr.nonDegenerate(2));
   }
@@ -391,13 +467,10 @@ const Matrix<Float>& LofarFTMachine::getAveragePB() const
 void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
                                      const VisBuffer& vb)
 {
-  if (itsVerbose > 0) {
-    cout<<"---------------------------> initializeToVis"<<endl;
-  }
   image=&iimage;
 
   ok();
-  init();
+  if(!its_Already_Initialized){init();};//init();
 
   // Initialize the maps for polarization and channel. These maps
   // translate visibility indices into image indices
@@ -425,6 +498,8 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
   // Note the other itsGriddedData buffers are assigned later.
   itsGriddedData[0].resize (gridShape);
   itsGriddedData[0] = Complex();
+  its_stacked_GriddedData.resize (gridShape);
+  its_stacked_GriddedData = Complex();
   for (int i=0; i<itsNThread; ++i) {
     itsSumPB[i].resize (padded_shape[0], padded_shape[1]);
     itsSumPB[i] = Complex();
@@ -432,6 +507,11 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
     itsSumWeight[i].resize(npol, nchan);
     itsSumWeight[i] = 0.;
   }
+  itsCounterTimes=0;
+  itsTStartObs=1.e30;
+  itsDeltaTime=0.;
+  itsTotalStepsGrid=0;
+  itsTotalStepsDeGrid=0;
 
   //griddedData can be a reference of image data...if not using model col
   //hence using an undocumented feature of resize that if
@@ -446,10 +526,10 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
         <<blc<<" "<<trc<<" "<<nx<<" "<<ny<<" "<<image->shape()<<endl;
   }
   IPosition start(4, 0);
-  itsGriddedData[0](blc, trc) = image->getSlice(start, image->shape());
+  its_stacked_GriddedData(blc, trc) = image->getSlice(start, image->shape());
   //if(arrayLattice) delete arrayLattice; arrayLattice=0;
   //======================CHANGED
-  arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+  arrayLattice = new ArrayLattice<Complex>(its_stacked_GriddedData);
   // Array<Complex> result(IPosition(4, nx, ny, npol, nchan),0.);
   // griddedData=result;
   // arrayLattice = new ArrayLattice<Complex>(griddedData);
@@ -480,10 +560,9 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
     // }
 
     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-    // Normalising clean components by the beam 
-    
-    // const Matrix<Float>& datai = getSpheroidCut();
+    // Normalising clean components by the beam
 
+    // const Matrix<Float>& datai = getSpheroidCut();
     const Matrix<Float>& data = getAveragePB();
     //    cout<<"tmp.shape() "<<data.shape()<<"  "<<lattice->shape()<<endl;
     IPosition pos(4,lattice->shape()[0],lattice->shape()[1],1,1);
@@ -493,17 +572,43 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
     pos2[2]=0.;
     pos2[3]=0.;
     Int offset_pad(floor(data.shape()[0]-lattice->shape()[0])/2.);
-    
+
     //    cout<<"LofarFTMachine::initializeToVis lattice->shape() == "<<lattice->shape()<<endl;
+    String nameii(itsImgName+String::toString(thisterm_p) + ".spheroid_cut_im");
+    ostringstream nameiii(nameii);
+    PagedImage<Float> tmpi(nameiii.str().c_str());
+    Slicer slicei(IPosition(4,0,0,0,0), tmpi.shape(), IPosition(4,1,1,1,1));
+    Array<Float> datai;
+    tmpi.doGetSlice(datai, slicei);
+
+    String nameii_element("Spheroid_cut_im_element.img");
+    ostringstream nameiii_element(nameii_element);
+    PagedImage<Float> tmpi_element(nameiii_element.str().c_str());
+    Slicer slicei_element(IPosition(4,0,0,0,0), tmpi_element.shape(), IPosition(4,1,1,1,1));
+    Array<Float> spheroidCutElement;
+    tmpi_element.doGetSlice(spheroidCutElement, slicei_element);
 
     Complex ff;
     double I=100.;
-    double Q=40.;
-    double U=20.;
-    double V=10.;
+    double Q=0.;
+    double U=0.;
+    double V=0.;
+
+    double maxPB(0.);
+    double minPB(1e10);
+    for(uInt i=0;i<lattice->shape()[0];++i){
+      for(uInt j=0;j<lattice->shape()[0];++j){
+	double pixel(data(i+offset_pad,j+offset_pad));
+	if(abs(pixel)>maxPB){maxPB=abs(pixel);};
+	if(abs(pixel)<minPB){minPB=abs(pixel);};
+      }
+    }
+
     for(Int k=0;k<lattice->shape()[2];++k){
       ff=0.;
+      //cout<<"k="<<k<<endl;
       if(k==0){ff=I+Q;}
+      // if(k==1){ff=I-Q;}
       if(k==1){ff=Complex(U,0.)+Complex(0.,V);}
       if(k==2){ff=Complex(U,0.)-Complex(0.,V);}
       if(k==3){ff=I-Q;}
@@ -518,27 +623,38 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
 	  double fact(1.);
 
 	  // pixel=0.;
-	  // if((pos[0]==351.)&&(pos[1]==319.)){//319
+	  // if((pos[0]==372.)&&(pos[1]==370.)){//319
 	  //   pixel=ff;//*139./143;//-100.;
-	  //   if(datai(pos2)>1e-6){fact/=datai(pos2);};//*datai(pos2);};
+	  //   //if(datai(pos2)>1e-6){fact/=datai(pos2)*datai(pos2);};//*datai(pos2);};
+	  //   //if(datai(pos2)>1e-6){fact*=sqrt(maxPB)/sqrt(data(pos2));};
+	  //   fact*=sqrt(maxPB)/sqrt(data(pos2));
 	  //   //if(data(pos2)>1e-6){fact/=sqrt(data(pos2));};//*datai(pos2);};
 	  //   pixel*=Complex(fact);
 	  // }
-	  
-	  fact/=sqrt(data(pos2));
+
+	  if(!itsPredictFT){
+	    fact*=sqrt(maxPB)/sqrt(data(pos2));
+	  } else {
+	    fact/=datai(pos2);//*datai(pos2);
+	    if(its_Apply_Element){fact/=spheroidCutElement(pos2);}
+	  }
 	  pixel*=Complex(fact);
-	  
-	  lattice->putAt(pixel,pos);
+
+	  if((data(pos2)>(minPB))&&(abs(pixel)>0.)){
+	    lattice->putAt(pixel,pos);
+	  };
 	}
       }
     }
 
-
     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
     // Now do the FFT2D in place
     LatticeFFT::cfft2d(*lattice);
 
+    if((!(itsConvFunc->itsFilledVectorMasks))&&(its_Apply_Element)){itsConvFunc->ReadMaskDegrid();}
+    //if((!(itsConvFunc->VectorMaskIsFilled()))&&(its_Apply_Element)){itsConvFunc->ReadMaskDegrid();}
+
     logIO() << LogIO::DEBUGGING
 	    << "Finished grid correction and FFT of image" << LogIO::POST;
 
@@ -550,7 +666,7 @@ void LofarFTMachine::initializeToVis(ImageInterface<Complex>& iimage,
     // 	  pos[2]=k;
     // 	  Complex pixel(lattice->getAt(pos));
     // 	  //cout<<"i,j,pixel value: "<<i<<" "<<j<<" "<<pixel<<endl;
-	  
+
     // 	};
     //   };
     // };
@@ -574,10 +690,10 @@ void LofarFTMachine::initializeToSky(ImageInterface<Complex>& iimage,
 {
   // image always points to the image
   image=&iimage;
-  if (itsVerbose > 0) {
-    cout<<"---------------------------> initializeToSky"<<endl;
-  }
-  init();
+  //if (itsVerbose > 0) {
+  //cout<<"---------------------------> initializeToSky"<<" its_Already_Initialized : "<<its_Already_Initialized<<endl;
+  //}
+    if(!its_Already_Initialized){init();};
 
   // Initialize the maps for polarization and channel. These maps
   // translate visibility indices into image indices
@@ -593,6 +709,8 @@ void LofarFTMachine::initializeToSky(ImageInterface<Complex>& iimage,
   AlwaysAssert (!isTiled, AipsError);
   IPosition gridShape(4, nx, ny, npol, nchan);
   // Size and initialize the grid buffer per thread.
+  its_stacked_GriddedData.resize (gridShape);
+  its_stacked_GriddedData = Complex();
   for (int i=0; i<itsNThread; ++i) {
     itsGriddedData[i].resize (gridShape);
     itsGriddedData[i] = Complex();
@@ -604,10 +722,15 @@ void LofarFTMachine::initializeToSky(ImageInterface<Complex>& iimage,
   }
   weight.resize(itsSumWeight[0].shape());
   weight=0.0;
+  itsCounterTimes=0;
+  itsTStartObs=1.e30;
+  itsDeltaTime=0.;
+  itsTotalStepsGrid=0;
+  itsTotalStepsDeGrid=0;
 
   //iimage.get(griddedData, False);
   //if(arrayLattice) delete arrayLattice; arrayLattice=0;
-  arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+  arrayLattice = new ArrayLattice<Complex>(its_stacked_GriddedData);
   lattice=arrayLattice;
   // if(useDoubleGrid_p) visResampler_p->initializePutBuffers(griddedData2, sumWeight);
   // else                visResampler_p->initializePutBuffers(griddedData, sumWeight);
@@ -628,41 +751,61 @@ void LofarFTMachine::finalizeToSky()
     cout<<"---------------------------> finalizeToSky"<<endl;
   }
   // DEBUG: Store the grid per thread
-  uInt nx(itsGriddedData[0].shape()[0]);
-  IPosition shapecube(3,nx,nx,4);
-  for (int ii=0; ii<itsNThread; ++ii) {
-    Cube<Complex> tempimage(shapecube,0.);
-    for(Int k=0;k<4;++k){
-      for(uInt i=0;i<nx;++i){
-  	for(uInt j=0;j<nx;++j){
-	  IPosition pos(4,i,j,k,0);
-	  Complex pixel(itsGriddedData[ii](pos));
-	  tempimage(i,j,k)=pixel;
-  	}
-      }
+  // uInt nx(itsGriddedData[0].shape()[0]);
+  // IPosition shapecube(3,nx,nx,4);
+  // for (int ii=0; ii<itsNThread; ++ii) {
+  //   Cube<Complex> tempimage(shapecube,0.);
+  //   for(Int k=0;k<itsGriddedData[0].shape()[2];++k){
+  //     for(uInt i=0;i<nx;++i){
+  // 	for(uInt j=0;j<nx;++j){
+  // 	  IPosition pos(4,i,j,k,0);
+  // 	  Complex pixel(itsGriddedData[ii](pos));
+  // 	  tempimage(i,j,k)=pixel;
+  // 	}
+  //     }
+  //   }
+  //   store(tempimage,"Grid"+String::toString(ii)+".img");
+  // }
+
+  // Add all buffers into the first one.
+
+  // for(uInt channel=0;channel< its_stacked_GriddedData.shape()[3];++channel){
+  //   for(uInt jj=0;jj<its_stacked_GriddedData.shape()[2];++jj){
+  //     cout<<"Add all buffers into the first one. jj="<<jj<<endl;
+  //     Matrix<Complex> plane_array_out  = its_stacked_GriddedData(Slicer(IPosition(4, 0, 0, jj, 0),
+  // 									IPosition(4, nx, nx, 1, 1))).nonDegenerate();
+  //     ArrayLattice<Complex> lattice(plane_array_out);
+  //     LatticeFFT::cfft2d(lattice, true);
+  //     plane_array_out/=static_cast<Float>(plane_array_out.shape()(0)*plane_array_out.shape()(1));
+  //   }
+  // }
+
+  if(!its_Apply_Element){
+    SumGridsOMP(its_stacked_GriddedData, itsGriddedData);
+    for (int i=0; i<itsNThread; ++i) {
+      itsGriddedData[i]=Complex();
     }
-    store(tempimage,"Grid"+String::toString(ii)+".img");
   }
 
-  // Add all buffers into the first one.
+
   for (int i=1; i<itsNThread; ++i) {
-    itsGriddedData[0] += itsGriddedData[i];
+    //itsGriddedData[0] += itsGriddedData[i];
     itsSumWeight[0]   += itsSumWeight[i];
     itsSumCFWeight[0] += itsSumCFWeight[i];
     itsSumPB[0]       += itsSumPB[i];
   }
 
-  Cube<Complex> tempimage(shapecube,0.);
-  for(Int k=0;k<4;++k){
-    for(uInt i=0;i<nx;++i){
-      for(uInt j=0;j<nx;++j){
-	IPosition pos(4,i,j,k,0);
-	Complex pixel(itsGriddedData[0](pos));
-	tempimage(i,j,k)=pixel;
-      }
-    }
-  }
-  store(tempimage,"Grid00.img");
+  // Cube<Complex> tempimage(IPosition(3,nx,nx,4),0.);
+  // for(Int k=0;k<4;++k){
+  //   for(uInt i=0;i<nx;++i){
+  //     for(uInt j=0;j<nx;++j){
+  // 	IPosition pos(4,i,j,k,0);
+  // 	Complex pixel(its_stacked_GriddedData(pos));
+  // 	tempimage(i,j,k)=pixel;
+  //     }
+  //   }
+  // }
+  // store(tempimage,"Grid00.img");
 
   // if(useDoubleGrid_p) visResamplers_p[0].GatherGrids(griddedData2, sumWeight);
   // else                visResamplers_p[0].GatherGrids(griddedData, sumWeight);
@@ -687,11 +830,16 @@ Array<Complex>* LofarFTMachine::getDataPointer(const IPosition& centerLoc2D,
 void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
                          FTMachine::Type type)
 {
-  if (itsVerbose > 0) {
+
+  itsCyrilTimer.stop();
+  //PrecTimer TimerCyril;
+  //TimerCyril.start();
+
+    if (itsVerbose > 0) {
     logIO() << LogOrigin("LofarFTMachine", "put") << LogIO::NORMAL
             << "I am gridding " << vb.nRow() << " row(s)."  << LogIO::POST;
     logIO() << LogIO::NORMAL << "Padding is " << padding_p  << LogIO::POST;
-  }
+    }
 
 
   gridOk(gridder->cSupport()(0));
@@ -709,16 +857,21 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
     chanMap=multiChanMap_p[vb.spectralWindow()];
   }
 
+
+
+
+  //cout<<"... Gridding Spectral Window:    "<<vb.spectralWindow()<<", with Taylor Term: "<< thisterm_p<<endl;
+
+  uInt spw(vb.spectralWindow());
+
   //No point in reading data if it's not matching in frequency
   if(max(chanMap)==-1) return;
 
   const Matrix<Float> *imagingweight;
   imagingweight=&(vb.imagingWeight());
 
-  // dopsf=true;
-
+  if(its_reallyDoPSF) {dopsf=true;}
   if(dopsf) {type=FTMachine::PSF;}
-
   Cube<Complex> data;
   //Fortran gridder need the flag as ints
   Cube<Int> flags;
@@ -737,10 +890,27 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
   // irrelevant for other cases.
   Matrix<Double> uvw(3, vb.uvw().nelements());  uvw=0.0;
   Vector<Double> dphase(vb.uvw().nelements());  dphase=0.0;
+
+
+  // // const Vector<Double>& times = vb.timeCentroid();
+  // // double time = 0.5 * (times[times.size()-1] + times[0]);
+  // const Vector<Double>& freq = vb.lsrFrequency();
+  // const Vector<Int>& obs = vb.observationId();
+  // Vector<Double> lsrFreq(0);
+  // Bool condoo=False;
+  // vb.lsrFrequency(0, lsrFreq, condoo);
+  // cout<<"mmm " <<lsrFreq<<" "<<condoo<<endl;
+  // vb.lsrFrequency(1, lsrFreq, condoo);
+  // cout<<"mmmmm " <<lsrFreq<<" "<<condoo<<endl;
+  //const Vector<Double>& timess = vb.timeCentroid();
+
   //NEGATING to correct for an image inversion problem
   for (Int i=startRow;i<=endRow;i++) {
     for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
     uvw(2,i)=vb.uvw()(i)(2);
+    // cout << "freq  "<< freq[i]   << endl;
+    // cout << "obsid "<< obs[i]    << vb.dataDescriptionId() <<endl;
+    // cout << "times "<< timess[i] << endl;
   }
 
   rotateUVW(uvw, dphase, vb);
@@ -784,6 +954,7 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
 	  blEnd.push_back (i-1);
 	}
       }
+
       // Skip auto-correlations and high W-values.
       // All w values are close, so if first w is too high, skip baseline.
       usebl = false;
@@ -826,6 +997,8 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
   // However the VBS objects should ultimately be references
   // directly to bool cubes.
   //**************
+
+
   vbs.flagCube_p.resize(flags.shape());    vbs.flagCube_p = False; vbs.flagCube_p(flags!=0) = True;
   //  vbs.flagCube_p.reference(vb.flagCube());
   //**************
@@ -835,36 +1008,73 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
   visResamplers_p.setMaps(chanMap, polMap);
 
   // First compute the A-terms for all stations (if needed).
+  PrecTimer CyrilTimer2Aterm;
+  CyrilTimer2Aterm.start();
   itsConvFunc->computeAterm (time);
+  CyrilTimer2Aterm.stop();
+  double Taterm=CyrilTimer2Aterm.getReal();
 
   uInt Nchannels = vb.nChannel();
 
   itsTotalTimer.start();
-#pragma omp parallel 
+
+  vector< Bool> done;
+  done.resize(int(blStart.size()));
+  for(int i=0; i<int(blStart.size()); ++i) {done[i]=false;};
+
+  Bool all_done(false);
+  Int doagain(0);
+
+  ///  Int Max_Num_Threads(itsNThread);
+  ///  omp_set_num_threads(Max_Num_Threads);
+
+
+  //logIO() <<"============================== Gridding data " << LogIO::POST;
+  //cout<<"... gridding with t= "<<time<<endl;
+  PrecTimer CyrilTimer2grid;
+    PrecTimer CyrilTimer2conv;
+    PrecTimer CyrilTimer2gridconv;
+    CyrilTimer2gridconv.start();
+    //    CyrilTimer2conv.reset();
+
+  while(!all_done){
+
+#pragma omp parallel
   {
     // Thread-private variables.
     PrecTimer gridTimer;
     PrecTimer cfTimer;
+    PrecTimer CyrilTimer;
     // The for loop can be parallellized. This must be done dynamically,
     // because the execution times of iterations can vary greatly.
+
+
 #pragma omp for schedule(dynamic)
     for (int i=0; i<int(blStart.size()); ++i) {
       Int ist  = blIndex[blStart[i]];
       Int iend = blIndex[blEnd[i]];
+      if(done[i]==true){continue;};
+      //if(doagain>0){
+	//cout<<"Doing again (doagain) baseline: A1="<<ant1[ist]<<", A2="<<ant2[ist]<<endl;
+      //}
+
+      try{
 
       // compute average weight for baseline for CF averaging
-      double average_weight(0.);
-      uInt Nvis(0);
+	double average_weight=0.;
+      uInt Nvis=0;
       for(Int j=ist; j<iend; ++j){
         uInt row=blIndex[j];
         if(!vbs.rowFlag()[row]){
           Nvis+=1;
-          for(uint k=0; k<Nchannels; ++k) {
+          for(uInt k=0; k<Nchannels; ++k) {
             average_weight=average_weight+vbs.imagingWeight()(k,row);
           }
         }
       }
-      average_weight=average_weight/Nvis;
+      if(Nvis>0){
+	average_weight=average_weight/Nvis;
+      } else {average_weight=0.;}
       ///        itsSumWeight += average_weight * average_weight;
       if (itsVerbose > 1) {
         cout<<"average weights= "<<average_weight<<", Nvis="<<Nvis<<endl;
@@ -877,27 +1087,31 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
         cout.precision(20);
         cout<<"A1="<<ant1[ist]<<", A2="<<ant2[ist]<<", time="<<fixed<<time<<endl;
       }
-      LofarCFStore cfStore;
       //#pragma omp critical(LofarFTMachine_makeConvolutionFunction)
       //{
+      CyrilTimer2conv.start();
       cfTimer.start();
-      cfStore =
+      Double Wmean=0.5*(vbs.uvw()(2,ist) + vbs.uvw()(2,iend));
+      //cout<< Wmean<<endl;
+      LofarCFStore cfStore =
         itsConvFunc->makeConvolutionFunction (ant1[ist], ant2[ist], time,
-                                              0.5*(vbs.uvw()(2,ist) + vbs.uvw()(2,iend)),
+                                              Wmean,
                                               itsGridMuellerMask, false,
                                               average_weight,
                                               itsSumPB[threadNum],
-                                              itsSumCFWeight[threadNum]);
-      cfTimer.stop();
-      //};
+                                              itsSumCFWeight[threadNum],
+					      spw,thisterm_p,itsRefFreq
+					      );
+      
 
 
-      //cout<<"DONE LOADING CF..."<<endl;
-      //Double or single precision gridding.
-      //	cout<<"============================================"<<endl;
-      //	cout<<"Antenna "<<ant1[ist]<<" and "<<ant2[ist]<<endl;
-      //#pragma omp critical(LofarFTMachine_makeConvolutionFunction)
-      //{
+      //cfTimer.stop();
+      CyrilTimer2conv.stop();
+
+      Int nConvX = (*(cfStore.vdata))[0][0][0].shape()[0];
+      //cout<<ant1[ist]<<" "<<ant2[ist]<<" " <<nConvX/5<<endl;
+      //double cfstep=CyrilTimer2conv.getReal();
+      CyrilTimer2grid.start();
       if (useDoubleGrid_p) {
         visResamplers_p.lofarDataToGrid(itsGriddedData2[threadNum], vbs, blIndex,
                                         blStart[i], blEnd[i],
@@ -907,13 +1121,35 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
           cout<<"  gridding"<<" thread="<<threadNum<<'('<<itsNThread<<"), A1="<<ant1[ist]<<", A2="<<ant2[ist]<<", time=" <<time<<endl;
         }
         gridTimer.start();
-        visResamplers_p.lofarDataToGrid
-          (itsGriddedData[threadNum], vbs, blIndex, blStart[i],
-           blEnd[i], itsSumWeight[threadNum], dopsf, cfStore);
-        gridTimer.stop();
+	if(!its_Use_Linear_Interp_Gridder){
+	  //cout<<"itsGriddedData[threadNum] "<<itsGriddedData[threadNum].shape()<<endl;
+	  visResamplers_p.lofarDataToGrid
+	    (itsGriddedData[threadNum], vbs, blIndex, blStart[i],
+	     blEnd[i], itsSumWeight[threadNum], dopsf, cfStore);
+	} else{
+	  visResamplers_p.lofarDataToGrid_linear
+	    (itsGriddedData[threadNum], vbs, blIndex, blStart[i],
+	     blEnd[i], itsSumWeight[threadNum], dopsf, cfStore);
+
+	};
+	  gridTimer.stop();
       }
+      CyrilTimer2grid.stop();
+      //cout<<"Gridding calculation: "<<nConvX<<" "<<cfstep<<" "<<CyrilTimer2grid.getReal()<<endl;
+      //CyrilTimer2grid.reset();
+      //CyrilTimer2conv.reset();
+      //CyrilTimer.reset();
+      done[i]=true;
+      } catch (std::bad_alloc &)
+	{
+	  cout<<"-----------------------------------------"<<endl;
+	  cout<<"!!!!!!! GRIDDING: Skipping baseline: "<<ant1[ist]<<" | "<<ant2[ist]<<endl;
+	  cout<<"memoryUsed() "<< HostInfo::memoryUsed()<< ", Free: "<<HostInfo::memoryFree()<<endl;
+	  cout<<"-----------------------------------------"<<endl;
+	};
       // } // end omp critical
     } // end omp for
+
     double cftime = cfTimer.getReal();
 #pragma omp atomic
     itsCFTime += cftime;
@@ -921,16 +1157,73 @@ void LofarFTMachine::put(const VisBuffer& vb, Int row, Bool dopsf,
 #pragma omp atomic
     itsGriddingTime += gtime;
   } // end omp parallel
+
+    all_done=true;
+    int number_missed(0);
+    for (int i=0; i<int(blStart.size()); ++i) {
+      if(done[i]==false){all_done=false;number_missed+=1;};
+    };
+    if(all_done==false){
+      //cout<<"================================"<<endl;
+      //cout<<"Memory exception returned by "<<number_missed<<" threads"<<endl;
+      //cout<<"Reducing number of threads to: "<<int(omp_get_num_threads()/2.)<<endl;
+      //cout<<"================================"<<endl;
+      doagain+=1;
+      //omp_set_num_threads(int(omp_get_num_threads()/2.));
+    };
+
+  }//end While loop
+
+  CyrilTimer2gridconv.stop();
+  double Tgridconv=CyrilTimer2gridconv.getReal();
+
+  PrecTimer CyrilTimer2elem;
+  if(itsDeltaTime<(times[times.size()-1] - times[0])){itsDeltaTime=(times[times.size()-1] - times[0]);};
+  Bool lastchunk(false);
+  if((times[times.size()-1] - times[0])<0.95*itsDeltaTime){
+    lastchunk=true;
+    itsDeltaTime=0.;
+  }
+
+  //cout<<"time: "<<time<<" "<<itsStepApplyElement<<" "<<its_Apply_Element<<endl;
+  CyrilTimer2elem.start();
+
+  if(itsCounterTimes==(itsStepApplyElement-1)/2){itsNextApplyTime=time;}
+  if(its_Apply_Element){
+    if((itsCounterTimes==itsStepApplyElement-1)||(lastchunk)){
+      Array<Complex> tmp_stacked_GriddedData;
+      tmp_stacked_GriddedData.resize (itsGriddedData[0].shape());
+      tmp_stacked_GriddedData = Complex();
+      SumGridsOMP(tmp_stacked_GriddedData, itsGriddedData);
+      //itsConvFunc->MakeMaskDegrid(tmp_stacked_GriddedData, itsTotalStepsGrid);
+      Array<Complex> tmp_stacked_GriddedData_appliedelement=itsConvFunc->ApplyElementBeam2 (tmp_stacked_GriddedData, itsNextApplyTime, spw, itsGridMuellerMask, false);
+      if(its_UseMasksDegrid){
+	itsConvFunc->MakeMaskDegrid(tmp_stacked_GriddedData_appliedelement, itsTotalStepsGrid);
+      }
+      SumGridsOMP(its_stacked_GriddedData, tmp_stacked_GriddedData_appliedelement);
+      CyrilTimer2elem.stop();
+      itsCounterTimes=0;
+      for (int i=0; i<itsNThread; ++i) {
+	itsGriddedData[i]=Complex();
+      }
+      itsTotalStepsGrid+=1;
+    } else {
+      itsCounterTimes+=1;
+    }
+  }
+
+  CyrilTimer2elem.stop();
+  //cout<<"times: aterm:"<<Taterm<<", conv: "<<CyrilTimer2conv.getReal()<<", grid: "<<CyrilTimer2grid.getReal()<<", gridconv: "<<Tgridconv<<", sum: "<<CyrilTimer2elem.getReal()<<", other: "<<itsCyrilTimer.getReal()<<endl;
+  //cout<<"times: conv:"<<CyrilTimer2conv.getReal()<<", grid:"<<CyrilTimer2grid.getReal()<<", element:"<<CyrilTimer2elem.getReal()<<endl;
   itsTotalTimer.stop();
+  itsCyrilTimer.reset();
+  itsCyrilTimer.start();
 }
 
 
 // Degrid
 void LofarFTMachine::get(VisBuffer& vb, Int row)
 {
-  if (itsVerbose > 0) {
-    cout<<"///////////////////// GET!!!!!!!!!!!!!!!!!!"<<endl;
-  }
   gridOk(gridder->cSupport()(0));
   // If row is -1 then we pass through all rows
   Int startRow, endRow, nRow;
@@ -950,6 +1243,8 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
 
   //Check if ms has changed then cache new spw and chan selection
   if(vb.newMS())  matchAllSpwChans(vb);
+  uInt spw(vb.spectralWindow());
+  //cout<<"... De-Gridding Spectral Window: "<<vb.spectralWindow()<<", with Taylor Term: "<< thisterm_p<<endl;
 
 
   //Channel matching for the actual spectral window of buffer
@@ -980,7 +1275,7 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
   vbs.uvw_p.reference(uvw);
   //    vbs.imagingWeight.reference(elWeight);
   vbs.visCube_p.reference(data);
-  
+
   vbs.freq_p.reference(interpVisFreq_p);
   vbs.rowFlag_p.resize(0); vbs.rowFlag_p = vb.flagRow();
   if(!usezero_p)
@@ -1066,7 +1361,71 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
   // First compute the A-terms for all stations (if needed).
   itsConvFunc->computeAterm (time);
 
+  if(times[0]<itsTStartObs){itsTStartObs=times[0];}
+  if(itsDeltaTime<(times[times.size()-1] - times[0])){itsDeltaTime=(times[times.size()-1] - times[0]);};
+  if(itsDeltaTime<(times[times.size()-1] - times[0])){itsDeltaTime=(times[times.size()-1] - times[0]);};
+
   itsTotalTimer.start();
+
+  vector< Bool> done;
+  done.resize(int(blStart.size()));
+  for(int i=0; i<int(blStart.size()); ++i) {done[i]=false;};
+
+  Bool all_done(false);
+  ///  Int Max_Num_Threads(itsNThread);
+  ///  omp_set_num_threads(Max_Num_Threads);
+
+  PrecTimer CyrilElement;
+  CyrilElement.start();
+  cout.precision(20);
+  //cout<<" ======================= De-Grid ... time="<<time<<", at "<<itsCounterTimes<<endl;
+  if(its_Apply_Element){
+    //cout<<"itsCounterTimes= "<<itsCounterTimes<<endl;
+    if(itsCounterTimes==0){
+     double TimeElement(itsTStartObs+itsDeltaTime*itsStepApplyElement/2.);
+     //cout<<"... Appying element with t="<<TimeElement<<", itsTStartObs="<<itsTStartObs<<", itsDeltaTime="<<itsDeltaTime<<endl;
+     itsConvFunc->computeAterm(TimeElement);
+     if(its_UseMasksDegrid){
+       itsGridToDegrid.reference(itsConvFunc->ApplyElementBeam2(its_stacked_GriddedData, TimeElement, spw, itsGridMuellerMask, true, itsTotalStepsDeGrid));
+     }else{
+       itsGridToDegrid.reference(itsConvFunc->ApplyElementBeam2(its_stacked_GriddedData, TimeElement, spw, itsGridMuellerMask, true));
+     }
+     itsTotalStepsDeGrid+=1;
+    }
+    itsCounterTimes+=1;
+    if(itsCounterTimes==itsStepApplyElement){
+      itsTStartObs=1.e30;
+      itsCounterTimes=0;
+    }
+    Bool lastchunk(false);
+    if((times[times.size()-1] - times[0])<0.95*itsDeltaTime){
+      //cout<<"Last Chunk Degrid!!!"<<endl;
+      lastchunk=true;
+      itsDeltaTime=0.;
+      itsTStartObs=1e12;
+    }
+
+
+  } else{
+    itsGridToDegrid.reference(its_stacked_GriddedData);
+  }
+  CyrilElement.stop();
+
+  // arrayLattice = new ArrayLattice<Complex>(tmp_stacked_GriddedData2);
+  // cout<<"LofarConvolutionFunction::ApplyElementBeam "<<"FFT the element corrected model image"<<endl;
+  // lattice=arrayLattice;
+  // LatticeFFT::cfft2d(*lattice);
+
+  //logIO() <<"============================== De-Gridding data " << LogIO::POST;
+  PrecTimer CyrilConv;
+  PrecTimer CyrilGrid;
+
+
+  while(!all_done){
+
+
+
+
 #pragma omp parallel
   {
     // Thread-private variables.
@@ -1080,12 +1439,16 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
       // {
       Int ist  = blIndex[blStart[i]];
       Int iend = blIndex[blEnd[i]];
+      if(done[i]==true){continue;};
+      try {
       int threadNum = OpenMP::threadNum();
       // Get the convolution function for degridding.
       if (itsVerbose > 1) {
 	cout<<"ANTENNA "<<ant1[ist]<<" "<<ant2[ist]<<endl;
       }
       cfTimer.start();
+      CyrilConv.start();
+
       LofarCFStore cfStore =
         itsConvFunc->makeConvolutionFunction (ant1[ist], ant2[ist], time,
                                               0.5*(vbs.uvw()(2,ist) + vbs.uvw()(2,iend)),
@@ -1093,15 +1456,29 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
                                               true,
                                               0.0,
                                               itsSumPB[threadNum],
-                                              itsSumCFWeight[threadNum]);
+                                              itsSumCFWeight[threadNum]
+					      ,spw,thisterm_p,itsRefFreq);
       cfTimer.stop();
 
-      //Double or single precision gridding.
-      //      cout<<"GRID "<<ant1[ist]<<" "<<ant2[ist]<<endl;
+      CyrilConv.stop();
+      CyrilGrid.start();
+
       degridTimer.start();
-      visResamplers_p.lofarGridToData(vbs, itsGriddedData[0],
+      visResamplers_p.lofarGridToData(vbs, itsGridToDegrid,//its_stacked_GriddedData,//itsGriddedData[0],
                                       blIndex, blStart[i], blEnd[i], cfStore);
+      CyrilGrid.stop();
+
       degridTimer.stop();
+      done[i]=true;
+
+      } catch (std::bad_alloc &)
+	{
+	  cout<<"-----------------------------------------"<<endl;
+	  cout<<"!!!!!!! DE-GRIDDING: Skipping baseline: "<<ant1[ist]<<" | "<<ant2[ist]<<endl;
+	  cout<<"memoryUsed() "<< HostInfo::memoryUsed()<< ", Free: "<<HostInfo::memoryFree()<<endl;
+	  cout<<"-----------------------------------------"<<endl;
+	}
+
     } // end omp for
     double cftime = cfTimer.getReal();
 #pragma omp atomic
@@ -1110,6 +1487,27 @@ void LofarFTMachine::get(VisBuffer& vb, Int row)
 #pragma omp atomic
     itsGriddingTime += gtime;
   } // end omp parallel
+
+    all_done=true;
+    int number_missed(0);
+    for (int i=0; i<int(blStart.size()); ++i) {
+      //cout<<"done: "<<i<<" "<<done[i]<<endl;
+      if(done[i]==false){all_done=false;number_missed+=1;};
+    };
+    if(all_done==false){
+      //cout<<"================================"<<endl;
+      //cout<<"Memory exception returned by "<<number_missed<<" threads"<<endl;
+      //cout<<"Reducing number of threads to: "<<int(omp_get_num_threads()/2.)<<endl;
+      //cout<<"================================"<<endl;
+      //omp_set_num_threads(int(omp_get_num_threads()/2.));
+    };
+
+  }//end While loop
+
+  //cout<<"Element: "<<CyrilElement.getReal()<<", Conv: "<<CyrilConv.getReal()<<", Grid: "<<CyrilGrid.getReal()<<endl;;
+
+
+
   itsTotalTimer.stop();
   interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
 }
@@ -1125,9 +1523,6 @@ ImageInterface<Complex>& LofarFTMachine::getImage(Matrix<Float>& weights, Bool n
   AlwaysAssert(image, AipsError);
   logIO() << LogOrigin("LofarFTMachine", "getImage") << LogIO::NORMAL;
 
-  if (itsVerbose > 0) {
-    cout<<"GETIMAGE"<<endl;
-  }
   itsAvgPB.reference (itsConvFunc->Compute_avg_pb(itsSumPB[0], itsSumCFWeight[0]));
 
   //cout<<"weights.shape() "<<weights.shape()<<"  "<<sumWeight<<endl;
@@ -1236,10 +1631,10 @@ ImageInterface<Complex>& LofarFTMachine::getImage(Matrix<Float>& weights, Bool n
     // posi[2]=0.;
     // posi[3]=0.;
     // posi2[2]=0.;
-    // posi2[3]=0.;    
+    // posi2[3]=0.;
     // Int offset_pad(floor(data.shape()[0]-lattice->shape()[0])/2.);
 
-    
+
 
 
     // for(uInt k=0;k<lattice->shape()[2];++k){
@@ -1267,6 +1662,19 @@ ImageInterface<Complex>& LofarFTMachine::getImage(Matrix<Float>& weights, Bool n
     Cube<Complex> tempimage(IPosition(3,shapeout,shapeout,lattice->shape()[2]));
 
     pos[3]=0.;
+    double minPB(1e10);
+    double maxPB(0.);
+    for(uInt i=0;i<shapeout;++i){
+      for(uInt j=0;j<shapeout;++j){
+	double pixel(itsAvgPB(i+istart,j+istart));
+	if(abs(pixel)>maxPB){maxPB=abs(pixel);};
+	if(abs(pixel)<minPB){minPB=abs(pixel);};
+      }
+    }
+
+    const Matrix<Float>& sphe = getSpheroidCut();
+
+    //maxPB=1.;
     for(Int k=0;k<lattice->shape()[2];++k){
       for(uInt i=0;i<shapeout;++i){
     	for(uInt j=0;j<shapeout;++j){
@@ -1274,26 +1682,40 @@ ImageInterface<Complex>& LofarFTMachine::getImage(Matrix<Float>& weights, Bool n
     	  pos[1]=j+istart;
     	  pos[2]=k;
     	  Complex pixel(lattice->getAt(pos));
-    	  //cout<<"pixel value: "<<pixel<<", Primary beam: "<<avg_PB(i,j)<<endl;
-    	  pixel/=sqrt(itsAvgPB(i+istart,j+istart));//*sqrt(avg_PB(i+istart,j+istart));
-    	  //pixel*=(lattice->shape()[0]*lattice->shape()[0]);
+
+    	  pixel*=sqrt(maxPB)/sqrt(itsAvgPB(i+istart,j+istart));
+
+
+	  //if(itsAvgPB(pos)<1e-6*maxPB){pixel=0.;}
+	  if((sqrt(itsAvgPB(pos))/sphe(pos)<its_PBCut)||(itsAvgPB(pos)<2.*minPB)){pixel=0.;}
     	  lattice->putAt(pixel,pos);
-    	  //tempimage(i,j,k)=pixel/weights(0,0);
+    	  tempimage(i,j,k)=pixel;///weights(0,0);
     	}
       }
     }
+
     // uInt count_cycle(0);
     // Bool written(false);
 
     // while(!written){
+    //   Cube<Complex> tempimagePB(IPosition(3,shapeout,shapeout,lattice->shape()[2]));
+    //   for(Int k=0;k<lattice->shape()[2];++k){
+    // 	for(uInt i=0;i<shapeout;++i){
+    // 	  for(uInt j=0;j<shapeout;++j){
+    // 	    tempimagePB(i,j,k)=itsAvgPB(i,j);
+    // 	  };
+    // 	};
+    //   };
     //   cout<<"count_cycle ======================= "<<count_cycle<<" "<<normalize<<endl;
     //   File myFile("Cube_dirty.img"+String::toString(count_cycle));
     //   if(!myFile.exists()){
-    // 	written=true;
-    // 	store(tempimage,"Cube_dirty.img"+String::toString(count_cycle));
+    //   	written=true;
+    //   	store(tempimage,"Cube_dirty.img"+String::toString(count_cycle));
+    //   	store(tempimagePB,"Cube_dirty.img"+String::toString(count_cycle)+".pb");
+
     //   }
     //   else{
-    // 	count_cycle++;
+    //   	count_cycle++;
     //   };
     // };
 
@@ -1310,7 +1732,7 @@ ImageInterface<Complex>& LofarFTMachine::getImage(Matrix<Float>& weights, Bool n
       IPosition trc(blc+image->shape()-stride);
       // Do the copy
       IPosition start(4, 0);
-      image->put(itsGriddedData[0](blc, trc));
+      image->put(its_stacked_GriddedData(blc, trc));
     }
   }
 
@@ -1448,16 +1870,16 @@ Bool LofarFTMachine::fromRecord(String& error, const RecordInterface& inRec)
       // Make the grid the correct shape and turn it into an array lattice
       // Check the section from the image BEFORE converting to a lattice
       IPosition gridShape(4, nx, ny, npol, nchan);
-      itsGriddedData[0].resize(gridShape);
-      itsGriddedData[0]=Complex(0.0);
+      its_stacked_GriddedData.resize(gridShape);
+      its_stacked_GriddedData=Complex(0.0);
       IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2, (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
       IPosition start(4, 0);
       IPosition stride(4, 1);
       IPosition trc(blc+image->shape()-stride);
-      itsGriddedData[0](blc, trc)=image->getSlice(start, image->shape());
+      its_stacked_GriddedData(blc, trc)=image->getSlice(start, image->shape());
 
       //if(arrayLattice) delete arrayLattice; arrayLattice=0;
-      arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+      arrayLattice = new ArrayLattice<Complex>(its_stacked_GriddedData);
       lattice=arrayLattice;
     }
 
@@ -1555,7 +1977,11 @@ String LofarFTMachine::name(){
 
 void LofarFTMachine::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
 {
+
+  //cout<<"LofarFTMachine::ComputeResiduals "<<vb.corrType()<<endl;
   LofarVBStore vbs;
+  PrecTimer TimerResid;
+  TimerResid.start();
   vbs.nRow_p = vb.nRow();
   vbs.beginRow_p = 0;
   vbs.endRow_p = vbs.nRow_p;
@@ -1563,12 +1989,15 @@ void LofarFTMachine::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
   if (useCorrected) vbs.correctedCube_p.reference(vb.correctedVisCube());
   else vbs.visCube_p.reference(vb.visCube());
   //  cout<<"BLA===="<<vb.visCube()<<"    "<<useCorrected<<endl;
-  
+
   //for(uInt i=0;i<vbs.nRow_p;++i){cout<<"ROW "<<i<<" "<<vb.antenna1()(i)<<" "<<vb.antenna2()(i)<<endl;};
 
   vbs.useCorrected_p = useCorrected;
   visResamplers_p.lofarComputeResiduals(vbs);
 
+  TimerResid.stop();
+  //cout<<"Residuals: "<<TimerResid.getReal()<<endl;
+
   //  vb.correctedVisCube()=0.;//vb.modelVisCube();
 }
 
@@ -1576,6 +2005,7 @@ void LofarFTMachine::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
 					 const ImageInterface<Complex>& imageTemplate,
 					 ImageInterface<Float>& sensitivityImage)
   {
+    cout<<"============================== makeSensitivityImage"<<endl;
     if (convFuncCtor_p->makeAverageResponse(vb, imageTemplate, sensitivityImage))
       cfCache_p->flush(sensitivityImage,sensitivityPatternQualifierStr_p);
   }
@@ -1928,6 +2358,7 @@ void LofarFTMachine::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
   {
     LogIO log_l(LogOrigin("LofarFTMachine", "findPointingOffsets"));
     Vector<Int> msStokes = vb.corrType();
+    //cout<<"LofarFTMachine findPointingOffsets "<< msStokes << " "<<locCfStokes<<endl;
     Int nPol = msStokes.nelements();
     polM.resize(polMap.shape());
     polM = -1;
@@ -1978,7 +2409,7 @@ void LofarFTMachine::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
     conjPolMap = cfPolMap;
 
     Int i,j,N = cfPolMap.nelements();
-    
+
     for(i=0;i<N;i++)
       if (cfPolMap[i] > -1)
 	{
diff --git a/CEP/Imager/LofarFT/src/LofarFTMachineOld.cc b/CEP/Imager/LofarFT/src/LofarFTMachineOld.cc
new file mode 100644
index 0000000000000000000000000000000000000000..63de319cb5653155980cdc93d330b6db028bb0bf
--- /dev/null
+++ b/CEP/Imager/LofarFT/src/LofarFTMachineOld.cc
@@ -0,0 +1,2037 @@
+//# LofarFTMachineOld.cc: Gridder for LOFAR data correcting for DD effects
+//#
+//# Copyright (C) 2011
+//# 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 <Common/LofarLogger.h>
+// #include <Common/Exception.h>
+#include <Common/OpenMP.h>
+#include <msvis/MSVis/VisibilityIterator.h>
+#include <casa/Quanta/UnitMap.h>
+#include <casa/Quanta/UnitVal.h>
+#include <measures/Measures/Stokes.h>
+#include <coordinates/Coordinates/CoordinateSystem.h>
+#include <coordinates/Coordinates/DirectionCoordinate.h>
+#include <coordinates/Coordinates/SpectralCoordinate.h>
+#include <coordinates/Coordinates/StokesCoordinate.h>
+#include <coordinates/Coordinates/Projection.h>
+#include <ms/MeasurementSets/MSColumns.h>
+#include <casa/BasicSL/Constants.h>
+#include <scimath/Mathematics/FFTServer.h>
+#include <LofarFT/LofarFTMachineOld.h>
+#include <LofarFT/LofarCFStore.h>
+#include <LofarFT/LofarConvolutionFunctionOld.h>
+#include <synthesis/MeasurementComponents/Utils.h>
+#include <LofarFT/LofarVisResamplerOld.h>
+#include <synthesis/MeasurementComponents/CFStore.h>
+#include <LofarFT/LofarVBStore.h>
+#include <scimath/Mathematics/RigidVector.h>
+#include <msvis/MSVis/StokesVector.h>
+#include <synthesis/MeasurementEquations/StokesImageUtil.h>
+#include <msvis/MSVis/VisBuffer.h>
+#include <msvis/MSVis/VisSet.h>
+#include <images/Images/ImageInterface.h>
+#include <images/Images/PagedImage.h>
+#include <casa/Containers/Block.h>
+#include <casa/Containers/Record.h>
+#include <casa/Arrays/ArrayLogical.h>
+#include <casa/Arrays/ArrayMath.h>
+#include <casa/Arrays/Array.h>
+#include <casa/Arrays/MaskedArray.h>
+#include <casa/Arrays/Vector.h>
+#include <casa/Arrays/Slicer.h>
+#include <casa/Arrays/Matrix.h>
+#include <casa/Arrays/Cube.h>
+#include <casa/Arrays/MatrixIter.h>
+#include <casa/BasicSL/String.h>
+#include <casa/Utilities/Assert.h>
+#include <casa/Exceptions/Error.h>
+#include <lattices/Lattices/ArrayLattice.h>
+#include <measures/Measures/UVWMachine.h>
+#include <lattices/Lattices/SubLattice.h>
+#include <lattices/Lattices/LCBox.h>
+#include <lattices/Lattices/LatticeCache.h>
+#include <lattices/Lattices/LatticeFFT.h>
+#include <lattices/Lattices/LatticeIterator.h>
+#include <lattices/Lattices/LatticeStepper.h>
+#include <scimath/Mathematics/ConvolveGridder.h>
+#include <casa/Utilities/CompositeNumber.h>
+#include <casa/OS/PrecTimer.h>
+#include <casa/sstream.h>
+#define DORES True
+
+
+using namespace casa;
+
+namespace LOFAR { //# NAMESPACE CASA - BEGIN
+
+//  LofarFTMachineOld::LofarFTMachineOld(Long icachesize, Int itilesize,
+//                                 CountedPtr<VisibilityResamplerBase>&,
+//                                 String iconvType, Float padding,
+//                                 Bool usezero, Bool useDoublePrec)
+//: FTMachine(), padding_p(padding), imageCache(0), cachesize(icachesize), tilesize(itilesize),
+//  gridder(0), isTiled(False), convType(iconvType),
+//  maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
+//  usezero_p(usezero), noPadding_p(False), usePut2_p(False),
+//  machineName_p("LofarFTMachineOld")
+
+//{
+////   LOG_INFO ("LofarFTMachineOld::LofarFTMachineOld" << 1.0);
+////   logIO() << LogOrigin("LofarFTMachineOld", "LofarFTMachineOld")  << LogIO::NORMAL;
+//  logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
+//  useDoubleGrid_p=useDoublePrec;
+//  canComputeResiduals_p=DORES;
+//}
+
+LofarFTMachineOld::LofarFTMachineOld(Long icachesize, Int itilesize,
+                               CountedPtr<VisibilityResamplerBase>&,
+                               String iconvType,
+                               const MeasurementSet& ms, Int nwPlanes,
+                               MPosition mLocation, Float padding, Bool usezero,
+                               Bool useDoublePrec, double wmax,
+			       const String& beamPath, Int verbose,
+                               Int maxsupport, Int oversample,
+                               const String& imgName,
+                               const Matrix<bool>& gridMuellerMask,
+                               const Matrix<bool>& degridMuellerMask)
+  : FTMachine(), padding_p(padding), imageCache(0), cachesize(icachesize),
+    tilesize(itilesize), gridder(0), isTiled(False), convType(iconvType),
+    maxAbsData(0.0), centerLoc(IPosition(4,0)),
+    offsetLoc(IPosition(4,0)), usezero_p(usezero), noPadding_p(False),
+    usePut2_p(False), machineName_p("LofarFTMachineOld"), itsMS(ms),
+    itsNWPlanes(nwPlanes), itsWMax(wmax), itsConvFunc(0), itsBeamPath(beamPath),
+    itsVerbose(verbose),
+    itsMaxSupport(maxsupport), itsOversample(oversample), itsImgName(imgName),
+    itsGridMuellerMask(gridMuellerMask),
+    itsDegridMuellerMask(degridMuellerMask),
+    itsGriddingTime(0), itsDegriddingTime(0), itsCFTime(0)
+{
+  logIO() << LogOrigin("LofarFTMachineOld", "LofarFTMachineOld")  << LogIO::NORMAL;
+  logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
+  mLocation_p=mLocation;
+  tangentSpecified_p=False;
+  useDoubleGrid_p=useDoublePrec;
+  canComputeResiduals_p=DORES;
+  itsNThread = OpenMP::maxThreads();
+  AlwaysAssert (itsNThread>0, AipsError);
+  itsGriddedData.resize (itsNThread);
+  itsGriddedData2.resize (itsNThread);
+  itsSumPB.resize (itsNThread);
+  itsSumCFWeight.resize (itsNThread);
+  itsSumWeight.resize (itsNThread);
+}
+
+//LofarFTMachineOld::LofarFTMachineOld(Long icachesize, Int itilesize,
+//		 CountedPtr<VisibilityResamplerBase>&,
+//		 String iconvType,
+//		 MDirection mTangent, Float padding, Bool usezero, Bool useDoublePrec)
+//: FTMachine(), padding_p(padding), imageCache(0), cachesize(icachesize),
+//  tilesize(itilesize), gridder(0), isTiled(False), convType(iconvType), maxAbsData(0.0), centerLoc(IPosition(4,0)),
+//  offsetLoc(IPosition(4,0)), usezero_p(usezero), noPadding_p(False),
+//  usePut2_p(False), machineName_p("LofarFTMachineOld")
+//{
+//  logIO() << LogOrigin("LofarFTMachineOld", "LofarFTMachineOld")  << LogIO::NORMAL;
+//  logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
+//  mTangent_p=mTangent;
+//  tangentSpecified_p=True;
+//  useDoubleGrid_p=useDoublePrec;
+//  canComputeResiduals_p=DORES;
+//}
+
+//LofarFTMachineOld::LofarFTMachineOld(Long icachesize, Int itilesize,
+//		 CountedPtr<VisibilityResamplerBase>&,
+//		 String iconvType, MPosition mLocation, MDirection mTangent, Float padding,
+//		 Bool usezero, Bool useDoublePrec)
+//: FTMachine(), padding_p(padding), imageCache(0), cachesize(icachesize),
+//  tilesize(itilesize), gridder(0), isTiled(False), convType(iconvType), maxAbsData(0.0), centerLoc(IPosition(4,0)),
+//  offsetLoc(IPosition(4,0)), usezero_p(usezero), noPadding_p(False),
+//  usePut2_p(False),machineName_p("LofarFTMachineOld")
+//{
+//  logIO() << LogOrigin("LofarFTMachineOld", "LofarFTMachineOld")  << LogIO::NORMAL;
+//  logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
+//  mLocation_p=mLocation;
+//  mTangent_p=mTangent;
+//  tangentSpecified_p=True;
+//  useDoubleGrid_p=useDoublePrec;
+//  canComputeResiduals_p=DORES;
+//}
+
+//LofarFTMachineOld::LofarFTMachineOld(const RecordInterface& stateRec)
+//  : FTMachine()
+//{
+//  // Construct from the input state record
+//  logIO() << LogOrigin("LofarFTMachineOld", "LofarFTMachineOld(RecordInterface)")  << LogIO::NORMAL;
+//  logIO() << "You are using a non-standard FTMachine" << LogIO::WARN << LogIO::POST;
+//  String error;
+//  if (!fromRecord(error, stateRec))
+//    throw (AipsError("Failed to create gridder: " + error));
+//  canComputeResiduals_p=DORES;
+//}
+
+//----------------------------------------------------------------------
+LofarFTMachineOld& LofarFTMachineOld::operator=(const LofarFTMachineOld& other)
+{
+  if(this!=&other) {
+    //Do the base parameters
+    FTMachine::operator=(other);
+
+    //private params
+    imageCache=other.imageCache;
+    cachesize=other.cachesize;
+    tilesize=other.tilesize;
+    convType=other.convType;
+    uvScale.resize();
+    uvOffset.resize();
+    uvScale=other.uvScale;
+    uvOffset=other.uvOffset;
+    if(other.gridder==0)
+      gridder=0;
+    else{
+      gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
+						     uvScale, uvOffset,
+						     convType);
+    }
+    isTiled=other.isTiled;
+    //lattice=other.lattice;
+    lattice=0;
+    tilesize=other.tilesize;
+    arrayLattice=0;
+    maxAbsData=other.maxAbsData;
+    centerLoc=other.centerLoc;
+    offsetLoc=other.offsetLoc;
+    padding_p=other.padding_p;
+    usezero_p=other.usezero_p;
+    noPadding_p=other.noPadding_p;
+    itsMS = other.itsMS;
+    itsNWPlanes = other.itsNWPlanes;
+    itsWMax = other.itsWMax;
+    itsConvFunc = other.itsConvFunc;
+    ConjCFMap_p = other.ConjCFMap_p;
+    CFMap_p = other.CFMap_p;
+    itsNThread = other.itsNThread;
+    itsGriddedData.resize (itsNThread);
+    itsGriddedData2.resize (itsNThread);
+    itsSumPB.resize (itsNThread);
+    itsSumCFWeight.resize (itsNThread);
+    itsSumWeight.resize (itsNThread);
+    itsBeamPath = other.itsBeamPath;
+    itsVerbose = other.itsVerbose;
+    itsMaxSupport = other.itsMaxSupport;
+    itsOversample = other.itsOversample;
+    itsImgName = other.itsImgName;
+    itsGridMuellerMask = other.itsGridMuellerMask;
+    itsDegridMuellerMask = other.itsDegridMuellerMask;
+    itsGriddingTime = other.itsGriddingTime;
+    itsDegriddingTime = other.itsDegriddingTime;
+    itsCFTime = other.itsCFTime;
+  }
+  return *this;
+}
+
+//----------------------------------------------------------------------
+  LofarFTMachineOld::LofarFTMachineOld(const LofarFTMachineOld& other) : FTMachine(), machineName_p("LofarFTMachineOld")
+  {
+    //  visResampler_p.init(useDoubleGrid_p);
+    operator=(other);
+  }
+
+//----------------------------------------------------------------------
+//  CountedPtr<LofarFTMachineOld> LofarFTMachineOld::clone() const
+  LofarFTMachineOld* LofarFTMachineOld::clone() const
+  {
+    LofarFTMachineOld* newftm = new LofarFTMachineOld(*this);
+    return newftm;
+  }
+
+//----------------------------------------------------------------------
+void LofarFTMachineOld::init() {
+
+  logIO() << LogOrigin("LofarFTMachineOld", "init")  << LogIO::NORMAL;
+  canComputeResiduals_p = DORES;
+  ok();
+
+  /* hardwiring isTiled is False
+  // Padding is possible only for non-tiled processing
+  if((padding_p*padding_p*image->shape().product())>cachesize) {
+    isTiled=True;
+    nx    = image->shape()(0);
+    ny    = image->shape()(1);
+    npol  = image->shape()(2);
+    nchan = image->shape()(3);
+  }
+  else {
+  */
+    // We are padding.
+  isTiled=False;
+  if(!noPadding_p){
+    CompositeNumber cn(uInt(image->shape()(0)*2));
+    nx    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(0))-0.5));
+    ny    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(1))-0.5));
+  }
+  else{
+    nx    = image->shape()(0);
+    ny    = image->shape()(1);
+  }
+  npol  = image->shape()(2);
+  nchan = image->shape()(3);
+    // }
+
+  uvScale.resize(3);
+  uvScale=0.0;
+  uvScale(0)=Float(nx)*image->coordinates().increment()(0);
+  uvScale(1)=Float(ny)*image->coordinates().increment()(1);
+  uvScale(2)=Float(1)*abs(image->coordinates().increment()(0));
+
+  uvOffset.resize(3);
+  uvOffset(0)=nx/2;
+  uvOffset(1)=ny/2;
+  uvOffset(2)=0;
+
+  // Now set up the gridder. The possibilities are BOX and SF
+  if(gridder) delete gridder; gridder=0;
+  gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
+						 uvScale, uvOffset,
+						 convType);
+
+  // Setup the CFStore object to carry relavent info. of the Conv. Func.
+  cfs_p.xSupport = gridder->cSupport();
+  cfs_p.ySupport = gridder->cSupport();
+  cfs_p.sampling.resize(2);
+  cfs_p.sampling = gridder->cSampling();
+  if (cfs_p.rdata.null())
+    cfs_p.rdata = new Array<Double>(gridder->cFunction());
+  // else
+  //   (*cfs_p.rdata) = gridder->cFunction();
+
+  padded_shape = image->shape();
+  padded_shape(0) = nx;
+  padded_shape(1) = ny;
+  if (itsVerbose > 0) {
+    cout << "Original shape " << image->shape()(0) << ","
+         << image->shape()(1) << endl;
+    cout << "Padded shape " << padded_shape(0) << ","
+         << padded_shape(1) << endl;
+  }
+  //assert(padded_shape(0)!=image->shape()(0));
+  itsConvFunc = new LofarConvolutionFunctionOld(padded_shape,
+                                             image->coordinates().directionCoordinate (image->coordinates().findCoordinate(Coordinate::DIRECTION)),
+                                             itsMS, itsNWPlanes, itsWMax,
+                                             itsOversample, itsBeamPath,
+					     itsVerbose, itsMaxSupport,
+                                             itsImgName);
+
+  // Set up image cache needed for gridding. For BOX-car convolution
+  // we can use non-overlapped tiles. Otherwise we need to use
+  // overlapped tiles and additive gridding so that only increments
+  // to a tile are written.
+  if(imageCache) delete imageCache; imageCache=0;
+
+  if(isTiled) {
+    Float tileOverlap=0.5;
+    if(convType=="box") {
+      tileOverlap=0.0;
+    }
+    else {
+      tileOverlap=0.5;
+      tilesize=max(12,tilesize);
+    }
+    IPosition tileShape=IPosition(4,tilesize,tilesize,npol,nchan);
+    Vector<Float> tileOverlapVec(4);
+    tileOverlapVec=0.0;
+    tileOverlapVec(0)=tileOverlap;
+    tileOverlapVec(1)=tileOverlap;
+    Int tmpCacheVal=static_cast<Int>(cachesize);
+    imageCache=new LatticeCache <Complex> (*image, tmpCacheVal, tileShape,
+					   tileOverlapVec,
+					   (tileOverlap>0.0));
+
+  }
+}
+
+// This is nasty, we should use CountedPointers here.
+LofarFTMachineOld::~LofarFTMachineOld()
+{
+  if(imageCache) delete imageCache; imageCache=0;
+  //if(arrayLattice) delete arrayLattice; arrayLattice=0;
+  if(gridder) delete gridder; gridder=0;
+//  delete itsConvFunc;
+}
+
+const Matrix<Float>& LofarFTMachineOld::getAveragePB() const
+{
+  // Read average beam from disk if not present.
+  if (itsAvgPB.empty()) {
+    PagedImage<Float> pim(itsImgName + ".avgpb");
+    Array<Float> arr = pim.get();
+    itsAvgPB.reference (arr.nonDegenerate(2));
+  }
+  return itsAvgPB;
+}
+
+// Initialize for a transform from the Sky domain. This means that
+// we grid-correct, and FFT the image
+void LofarFTMachineOld::initializeToVis(ImageInterface<Complex>& iimage,
+                                     const VisBuffer& vb)
+{
+  if (itsVerbose > 0) {
+    cout<<"---------------------------> initializeToVis"<<endl;
+  }
+  image=&iimage;
+
+  ok();
+  init();
+
+  // Initialize the maps for polarization and channel. These maps
+  // translate visibility indices into image indices
+  initMaps(vb);
+
+  visResamplers_p.init(useDoubleGrid_p);
+  visResamplers_p.setMaps(chanMap, polMap);
+  visResamplers_p.setCFMaps(CFMap_p, ConjCFMap_p);
+
+  // Need to reset nx, ny for padding
+  // Padding is possible only for non-tiled processing
+
+  // If we are memory-based then read the image in and create an
+  // ArrayLattice otherwise just use the PagedImage
+  AlwaysAssert (!isTiled, AipsError);
+
+  //  cout<<"LofarFTMachineOld::initializeToVis === is_NOT_Tiled!"<<endl;
+  //======================CHANGED
+  //nx=640;
+  //ny=640;
+  //======================END CHANGED
+  //cout << "npol="<<npol<<endl;
+  IPosition gridShape(4, nx, ny, npol, nchan);
+  // Size and initialize the grid buffer per thread.
+  // Note the other itsGriddedData buffers are assigned later.
+  itsGriddedData[0].resize (gridShape);
+  itsGriddedData[0] = Complex();
+  for (int i=0; i<itsNThread; ++i) {
+    itsSumPB[i].resize (padded_shape[0], padded_shape[1]);
+    itsSumPB[i] = Complex();
+    itsSumCFWeight[i] = 0.;
+    itsSumWeight[i].resize(npol, nchan);
+    itsSumWeight[i] = 0.;
+  }
+
+  //griddedData can be a reference of image data...if not using model col
+  //hence using an undocumented feature of resize that if
+  //the size is the same as old data it is not changed.
+  //if(!usePut2_p) griddedData.set(0);
+
+  IPosition stride(4, 1);
+  IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2, (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
+  IPosition trc(blc+image->shape()-stride);
+  if (itsVerbose > 0) {
+    cout<<"LofarFTMachineOld::initializeToVis === blc,trc,nx,ny,image->shape()"
+        <<blc<<" "<<trc<<" "<<nx<<" "<<ny<<" "<<image->shape()<<endl;
+  }
+  IPosition start(4, 0);
+  itsGriddedData[0](blc, trc) = image->getSlice(start, image->shape());
+  //if(arrayLattice) delete arrayLattice; arrayLattice=0;
+  //======================CHANGED
+  arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+  // Array<Complex> result(IPosition(4, nx, ny, npol, nchan),0.);
+  // griddedData=result;
+  // arrayLattice = new ArrayLattice<Complex>(griddedData);
+  //======================END CHANGED
+  lattice=arrayLattice;
+
+  //AlwaysAssert(lattice, AipsError);
+
+  logIO() << LogIO::DEBUGGING
+	  << "Starting grid correction and FFT of image" << LogIO::POST;
+
+  //==========================
+  // Cyr: I have commeneted that part which does the spheroidal correction of the clean components in the image plane.
+  // We do this based on our estimate of the spheroidal function, stored in an image
+  // Do the Grid-correction.
+    // {
+    //   Vector<Complex> correction(nx);
+    //   correction=Complex(1.0, 0.0);
+    //   // Do the Grid-correction
+    //   IPosition cursorShape(4, nx, 1, 1, 1);
+    //   IPosition axisPath(4, 0, 1, 2, 3);
+    //   LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
+    //   LatticeIterator<Complex> lix(*lattice, lsx);
+    //   for(lix.reset();!lix.atEnd();lix++) {
+    //     gridder->correctX1D(correction, lix.position()(1));
+    // 	lix.rwVectorCursor()/=correction;
+    //   }
+    // }
+
+    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    // Normalising clean components by the beam 
+    
+    // const Matrix<Float>& datai = getSpheroidCut();
+
+    const Matrix<Float>& data = getAveragePB();
+    //    cout<<"tmp.shape() "<<data.shape()<<"  "<<lattice->shape()<<endl;
+    IPosition pos(4,lattice->shape()[0],lattice->shape()[1],1,1);
+    IPosition pos2(2,lattice->shape()[0],lattice->shape()[1]);
+    pos[2]=0.;
+    pos[3]=0.;
+    pos2[2]=0.;
+    pos2[3]=0.;
+    Int offset_pad(floor(data.shape()[0]-lattice->shape()[0])/2.);
+    
+    //    cout<<"LofarFTMachineOld::initializeToVis lattice->shape() == "<<lattice->shape()<<endl;
+
+    Complex ff;
+    double I=100.;
+    double Q=40.;
+    double U=20.;
+    double V=10.;
+    for(Int k=0;k<lattice->shape()[2];++k){
+      ff=0.;
+      if(k==0){ff=I+Q;}
+      if(k==1){ff=Complex(U,0.)+Complex(0.,V);}
+      if(k==2){ff=Complex(U,0.)-Complex(0.,V);}
+      if(k==3){ff=I-Q;}
+      for(Int i=0;i<lattice->shape()[0];++i){
+	for(Int j=0;j<lattice->shape()[0];++j){
+	  pos[0]=i;
+	  pos[1]=j;
+	  pos[2]=k;
+	  pos2[0]=i+offset_pad;
+	  pos2[1]=j+offset_pad;
+	  Complex pixel(lattice->getAt(pos));
+	  double fact(1.);
+
+	  // pixel=0.;
+	  // if((pos[0]==351.)&&(pos[1]==319.)){//319
+	  //   pixel=ff;//*139./143;//-100.;
+	  //   if(datai(pos2)>1e-6){fact/=datai(pos2);};//*datai(pos2);};
+	  //   //if(data(pos2)>1e-6){fact/=sqrt(data(pos2));};//*datai(pos2);};
+	  //   pixel*=Complex(fact);
+	  // }
+	  
+	  fact/=sqrt(data(pos2));
+	  pixel*=Complex(fact);
+	  
+	  lattice->putAt(pixel,pos);
+	}
+      }
+    }
+
+
+    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+    // Now do the FFT2D in place
+    LatticeFFT::cfft2d(*lattice);
+
+    logIO() << LogIO::DEBUGGING
+	    << "Finished grid correction and FFT of image" << LogIO::POST;
+
+    // for(uInt k=0;k<lattice->shape()[2];++k){
+    //   for(uInt i=0;i<lattice->shape()[0];++i){
+    // 	for(uInt j=0;j<lattice->shape()[0];++j){
+    // 	  pos[0]=i;
+    // 	  pos[1]=j;
+    // 	  pos[2]=k;
+    // 	  Complex pixel(lattice->getAt(pos));
+    // 	  //cout<<"i,j,pixel value: "<<i<<" "<<j<<" "<<pixel<<endl;
+	  
+    // 	};
+    //   };
+    // };
+}
+
+
+
+
+void LofarFTMachineOld::finalizeToVis()
+{
+  if (itsVerbose > 0) {
+    cout<<"---------------------------> finalizeToVis"<<endl;
+  }
+}
+
+
+// Initialize the FFT to the Sky. Here we have to setup and initialize the
+// grid.
+void LofarFTMachineOld::initializeToSky(ImageInterface<Complex>& iimage,
+			     Matrix<Float>& weight, const VisBuffer& vb)
+{
+  // image always points to the image
+  image=&iimage;
+  if (itsVerbose > 0) {
+    cout<<"---------------------------> initializeToSky"<<endl;
+  }
+  init();
+
+  // Initialize the maps for polarization and channel. These maps
+  // translate visibility indices into image indices
+  initMaps(vb);
+
+  visResamplers_p.init(useDoubleGrid_p);
+  visResamplers_p.setMaps(chanMap, polMap);
+  visResamplers_p.setCFMaps(CFMap_p, ConjCFMap_p);
+
+  // Initialize for in memory or to disk gridding. lattice will
+  // point to the appropriate Lattice, either the ArrayLattice for
+  // in memory gridding or to the image for to disk gridding.
+  AlwaysAssert (!isTiled, AipsError);
+  IPosition gridShape(4, nx, ny, npol, nchan);
+  // Size and initialize the grid buffer per thread.
+  for (int i=0; i<itsNThread; ++i) {
+    itsGriddedData[i].resize (gridShape);
+    itsGriddedData[i] = Complex();
+    itsSumPB[i].resize (padded_shape[0], padded_shape[1]);
+    itsSumPB[i] = Complex();
+    itsSumCFWeight[i] = 0.;
+    itsSumWeight[i].resize (npol, nchan);
+    itsSumWeight[i] = 0.;
+  }
+  weight.resize(itsSumWeight[0].shape());
+  weight=0.0;
+
+  //iimage.get(griddedData, False);
+  //if(arrayLattice) delete arrayLattice; arrayLattice=0;
+  arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+  lattice=arrayLattice;
+  // if(useDoubleGrid_p) visResampler_p->initializePutBuffers(griddedData2, sumWeight);
+  // else                visResampler_p->initializePutBuffers(griddedData, sumWeight);
+//// Are the following calls needed for LOFAR?
+///  if(useDoubleGrid_p) visResamplers_p.initializeToSky(griddedData2, sumWeight);
+///  else                visResamplers_p.initializeToSky(griddedData, sumWeight);
+  //AlwaysAssert(lattice, AipsError);
+}
+
+
+
+void LofarFTMachineOld::finalizeToSky()
+{
+  //AlwaysAssert(lattice, AipsError);
+  // Now we flush the cache and report statistics
+  // For memory based, we don't write anything out yet.
+  if (itsVerbose > 0) {
+    cout<<"---------------------------> finalizeToSky"<<endl;
+  }
+  // DEBUG: Store the grid per thread
+  uInt nx(itsGriddedData[0].shape()[0]);
+  IPosition shapecube(3,nx,nx,4);
+  for (int ii=0; ii<itsNThread; ++ii) {
+    Cube<Complex> tempimage(shapecube,0.);
+    for(Int k=0;k<4;++k){
+      for(uInt i=0;i<nx;++i){
+  	for(uInt j=0;j<nx;++j){
+	  IPosition pos(4,i,j,k,0);
+	  Complex pixel(itsGriddedData[ii](pos));
+	  tempimage(i,j,k)=pixel;
+  	}
+      }
+    }
+    store(tempimage,"Grid"+String::toString(ii)+".img");
+  }
+
+  // Add all buffers into the first one.
+  for (int i=1; i<itsNThread; ++i) {
+    itsGriddedData[0] += itsGriddedData[i];
+    itsSumWeight[0]   += itsSumWeight[i];
+    itsSumCFWeight[0] += itsSumCFWeight[i];
+    itsSumPB[0]       += itsSumPB[i];
+  }
+
+  Cube<Complex> tempimage(shapecube,0.);
+  for(Int k=0;k<4;++k){
+    for(uInt i=0;i<nx;++i){
+      for(uInt j=0;j<nx;++j){
+	IPosition pos(4,i,j,k,0);
+	Complex pixel(itsGriddedData[0](pos));
+	tempimage(i,j,k)=pixel;
+      }
+    }
+  }
+  store(tempimage,"Grid00.img");
+
+  // if(useDoubleGrid_p) visResamplers_p[0].GatherGrids(griddedData2, sumWeight);
+  // else                visResamplers_p[0].GatherGrids(griddedData, sumWeight);
+//// Are the following calls needed for LOFAR?
+///  if(useDoubleGrid_p) visResamplers_p.finalizeToSky(griddedData2, sumWeight);
+///  else                visResamplers_p.finalizeToSky(griddedData, sumWeight);
+}
+
+
+
+Array<Complex>* LofarFTMachineOld::getDataPointer(const IPosition& centerLoc2D,
+				       Bool readonly) {
+  Array<Complex>* result;
+  // Is tiled: get tiles and set up offsets
+  centerLoc(0)=centerLoc2D(0);
+  centerLoc(1)=centerLoc2D(1);
+  result=&imageCache->tile(offsetLoc,centerLoc, readonly);
+  gridder->setOffset(IPosition(2, offsetLoc(0), offsetLoc(1)));
+  return result;
+}
+
+void LofarFTMachineOld::put(const VisBuffer& vb, Int row, Bool dopsf,
+                         FTMachine::Type type)
+{
+  if (itsVerbose > 0) {
+    logIO() << LogOrigin("LofarFTMachineOld", "put") << LogIO::NORMAL
+            << "I am gridding " << vb.nRow() << " row(s)."  << LogIO::POST;
+    logIO() << LogIO::NORMAL << "Padding is " << padding_p  << LogIO::POST;
+  }
+
+
+  gridOk(gridder->cSupport()(0));
+
+  //Check if ms has changed then cache new spw and chan selection
+  if(vb.newMS())   matchAllSpwChans(vb);
+
+  //Here we redo the match or use previous match
+
+  //Channel matching for the actual spectral window of buffer
+  if (doConversion_p[vb.spectralWindow()]) {
+    matchChannel(vb.spectralWindow(), vb);
+  } else {
+    chanMap.resize();
+    chanMap=multiChanMap_p[vb.spectralWindow()];
+  }
+
+  //No point in reading data if it's not matching in frequency
+  if(max(chanMap)==-1) return;
+
+  const Matrix<Float> *imagingweight;
+  imagingweight=&(vb.imagingWeight());
+
+  // dopsf=true;
+
+  if(dopsf) {type=FTMachine::PSF;}
+
+  Cube<Complex> data;
+  //Fortran gridder need the flag as ints
+  Cube<Int> flags;
+  Matrix<Float> elWeight;
+  interpolateFrequencyTogrid(vb, *imagingweight,data, flags, elWeight, type);
+
+
+  Int startRow, endRow, nRow;
+  if (row==-1) { nRow=vb.nRow(); startRow=0; endRow=nRow-1; }
+  else         { nRow=1; startRow=row; endRow=row; }
+
+  // Get the uvws in a form that Fortran can use and do that
+  // necessary phase rotation. On a Pentium Pro 200 MHz
+  // when null, this step takes about 50us per uvw point. This
+  // is just barely noticeable for Stokes I continuum and
+  // irrelevant for other cases.
+  Matrix<Double> uvw(3, vb.uvw().nelements());  uvw=0.0;
+  Vector<Double> dphase(vb.uvw().nelements());  dphase=0.0;
+  //NEGATING to correct for an image inversion problem
+  for (Int i=startRow;i<=endRow;i++) {
+    for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
+    uvw(2,i)=vb.uvw()(i)(2);
+  }
+
+  rotateUVW(uvw, dphase, vb);
+  refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
+
+  // Set up VBStore object to point to the relevant info of the VB.
+  LofarVBStore vbs;
+  makeCFPolMap(vb,cfStokes_p,CFMap_p);
+  makeConjPolMap(vb,CFMap_p,ConjCFMap_p);
+
+  // Determine the baselines in the VisBuffer.
+  const Vector<Int>& ant1 = vb.antenna1();
+  const Vector<Int>& ant2 = vb.antenna2();
+  int nrant = 1 + max(max(ant1), max(ant2));
+  // Sort on baseline (use a baseline nr which is faster to sort).
+  Vector<Int> blnr(nrant*ant1);
+  blnr += ant2;  // This is faster than nrant*ant1+ant2 in a single line
+  Vector<uInt> blIndex;
+  GenSortIndirect<Int>::sort (blIndex, blnr);
+  // Now determine nr of unique baselines and their start index.
+  vector<int> blStart, blEnd;
+  blStart.reserve (nrant*(nrant+1)/2);
+  blEnd.reserve   (nrant*(nrant+1)/2);
+  Int  lastbl     = -1;
+  Int  lastIndex  = 0;
+  bool usebl      = false;
+  bool allFlagged = true;
+  const Vector<Bool>& flagRow = vb.flagRow();
+  for (uint i=0; i<blnr.size(); ++i) {
+    Int inx = blIndex[i];
+    Int bl = blnr[inx];
+    if (bl != lastbl) {
+      // New baseline. Write the previous end index if applicable.
+      if (usebl  &&  !allFlagged) {
+	double Wmean(0.5*(vb.uvw()[blIndex[lastIndex]](2) + vb.uvw()[blIndex[i-1]](2)));
+	if (abs(Wmean) <= itsWMax) {
+	  if (itsVerbose > 1) {
+	    cout<<"using w="<<Wmean<<endl;
+	  }
+	  blStart.push_back (lastIndex);
+	  blEnd.push_back (i-1);
+	}
+      }
+      // Skip auto-correlations and high W-values.
+      // All w values are close, so if first w is too high, skip baseline.
+      usebl = false;
+
+      if (ant1[inx] != ant2[inx]) {
+	usebl = true;
+      }
+      lastbl=bl;
+      lastIndex=i;
+    }
+    // Test if the row is flagged.
+    if (! flagRow[inx]) {
+      allFlagged = false;
+    }
+  }
+  // Write the last end index if applicable.
+  if (usebl  &&  !allFlagged) {
+    double Wmean(0.5*(vb.uvw()[blIndex[lastIndex]](2) + vb.uvw()[blIndex[blnr.size()-1]](2)));
+    if (abs(Wmean) <= itsWMax) {
+      if (itsVerbose > 1) {
+	cout<<"...using w="<<Wmean<<endl;
+      }
+      blStart.push_back (lastIndex);
+      blEnd.push_back (blnr.size()-1);
+    }
+  }
+  // Determine the time center of this data chunk.
+  const Vector<Double>& times = vb.timeCentroid();
+  double time = 0.5 * (times[times.size()-1] + times[0]);
+
+  vbs.nRow_p = vb.nRow();
+  vbs.uvw_p.reference(uvw);
+  vbs.imagingWeight_p.reference(elWeight);
+  vbs.visCube_p.reference(data);
+  //  vbs.visCube_p.reference(vb.modelVisCube());
+  vbs.freq_p.reference(interpVisFreq_p);
+  vbs.rowFlag_p.reference(vb.flagRow());
+
+  // Really nice way of converting a Cube<Int> to Cube<Bool>.
+  // However the VBS objects should ultimately be references
+  // directly to bool cubes.
+  //**************
+  vbs.flagCube_p.resize(flags.shape());    vbs.flagCube_p = False; vbs.flagCube_p(flags!=0) = True;
+  //  vbs.flagCube_p.reference(vb.flagCube());
+  //**************
+
+   // Determine the terms of the Mueller matrix that should be calculated
+  visResamplers_p.setParams(uvScale,uvOffset,dphase);
+  visResamplers_p.setMaps(chanMap, polMap);
+
+  // First compute the A-terms for all stations (if needed).
+  itsConvFunc->computeAterm (time);
+
+  uInt Nchannels = vb.nChannel();
+
+  itsTotalTimer.start();
+#pragma omp parallel 
+  {
+    // Thread-private variables.
+    PrecTimer gridTimer;
+    PrecTimer cfTimer;
+    // The for loop can be parallellized. This must be done dynamically,
+    // because the execution times of iterations can vary greatly.
+#pragma omp for schedule(dynamic)
+    for (int i=0; i<int(blStart.size()); ++i) {
+      Int ist  = blIndex[blStart[i]];
+      Int iend = blIndex[blEnd[i]];
+
+      // compute average weight for baseline for CF averaging
+      double average_weight(0.);
+      uInt Nvis(0);
+      for(Int j=ist; j<iend; ++j){
+        uInt row=blIndex[j];
+        if(!vbs.rowFlag()[row]){
+          Nvis+=1;
+          for(uint k=0; k<Nchannels; ++k) {
+            average_weight=average_weight+vbs.imagingWeight()(k,row);
+          }
+        }
+      }
+      average_weight=average_weight/Nvis;
+      ///        itsSumWeight += average_weight * average_weight;
+      if (itsVerbose > 1) {
+        cout<<"average weights= "<<average_weight<<", Nvis="<<Nvis<<endl;
+      }
+
+      int threadNum = OpenMP::threadNum();
+
+      // Get the convolution function.
+      if (itsVerbose > 1) {
+        cout.precision(20);
+        cout<<"A1="<<ant1[ist]<<", A2="<<ant2[ist]<<", time="<<fixed<<time<<endl;
+      }
+      LofarCFStore cfStore;
+      //#pragma omp critical(LofarFTMachineOld_makeConvolutionFunction)
+      //{
+      cfTimer.start();
+      cfStore =
+        itsConvFunc->makeConvolutionFunction (ant1[ist], ant2[ist], time,
+                                              0.5*(vbs.uvw()(2,ist) + vbs.uvw()(2,iend)),
+                                              itsGridMuellerMask, false,
+                                              average_weight,
+                                              itsSumPB[threadNum],
+                                              itsSumCFWeight[threadNum]);
+      cfTimer.stop();
+      //};
+
+
+      //cout<<"DONE LOADING CF..."<<endl;
+      //Double or single precision gridding.
+      //	cout<<"============================================"<<endl;
+      //	cout<<"Antenna "<<ant1[ist]<<" and "<<ant2[ist]<<endl;
+      //#pragma omp critical(LofarFTMachineOld_makeConvolutionFunction)
+      //{
+      if (useDoubleGrid_p) {
+        visResamplers_p.lofarDataToGrid(itsGriddedData2[threadNum], vbs, blIndex,
+                                        blStart[i], blEnd[i],
+                                        itsSumWeight[threadNum], dopsf, cfStore);
+      } else {
+        if (itsVerbose > 1) {
+          cout<<"  gridding"<<" thread="<<threadNum<<'('<<itsNThread<<"), A1="<<ant1[ist]<<", A2="<<ant2[ist]<<", time=" <<time<<endl;
+        }
+        gridTimer.start();
+        visResamplers_p.lofarDataToGrid
+          (itsGriddedData[threadNum], vbs, blIndex, blStart[i],
+           blEnd[i], itsSumWeight[threadNum], dopsf, cfStore);
+        gridTimer.stop();
+      }
+      // } // end omp critical
+    } // end omp for
+    double cftime = cfTimer.getReal();
+#pragma omp atomic
+    itsCFTime += cftime;
+    double gtime = gridTimer.getReal();
+#pragma omp atomic
+    itsGriddingTime += gtime;
+  } // end omp parallel
+  itsTotalTimer.stop();
+}
+
+
+// Degrid
+void LofarFTMachineOld::get(VisBuffer& vb, Int row)
+{
+  if (itsVerbose > 0) {
+    cout<<"///////////////////// GET!!!!!!!!!!!!!!!!!!"<<endl;
+  }
+  gridOk(gridder->cSupport()(0));
+  // If row is -1 then we pass through all rows
+  Int startRow, endRow, nRow;
+  if (row < 0) { nRow=vb.nRow(); startRow=0; endRow=nRow-1;}
+  else         { nRow=1; startRow=row; endRow=row; }
+
+  // Get the uvws in a form that Fortran can use
+  Matrix<Double> uvw(3, vb.uvw().nelements());  uvw=0.0;
+  Vector<Double> dphase(vb.uvw().nelements());  dphase=0.0;
+  //NEGATING to correct for an image inversion problem
+  for (Int i=startRow;i<=endRow;i++) {
+    for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
+    uvw(2,i)=vb.uvw()(i)(2);
+  }
+  rotateUVW(uvw, dphase, vb);
+  refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
+
+  //Check if ms has changed then cache new spw and chan selection
+  if(vb.newMS())  matchAllSpwChans(vb);
+
+
+  //Channel matching for the actual spectral window of buffer
+  if(doConversion_p[vb.spectralWindow()])
+    matchChannel(vb.spectralWindow(), vb);
+  else
+    {
+      chanMap.resize();
+      chanMap=multiChanMap_p[vb.spectralWindow()];
+    }
+
+  //No point in reading data if its not matching in frequency
+  if(max(chanMap)==-1)    return;
+
+  Cube<Complex> data;
+  Cube<Int> flags;
+  getInterpolateArrays(vb, data, flags);
+
+  // Apparently we don't support "tiled gridding" any more (good! :)).
+  if(isTiled)
+    throw(SynthesisFTMachineError("LofarFTMachineOld::get(): Internal error.  isTiled is True. "));
+
+  LofarVBStore vbs;
+  vbs.nRow_p = vb.nRow();
+  vbs.beginRow_p = 0;
+  vbs.endRow_p = vbs.nRow_p;
+
+  vbs.uvw_p.reference(uvw);
+  //    vbs.imagingWeight.reference(elWeight);
+  vbs.visCube_p.reference(data);
+  
+  vbs.freq_p.reference(interpVisFreq_p);
+  vbs.rowFlag_p.resize(0); vbs.rowFlag_p = vb.flagRow();
+  if(!usezero_p)
+    for (Int rownr=startRow; rownr<=endRow; rownr++)
+      if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) vbs.rowFlag_p(rownr)=True;
+
+  // Really nice way of converting a Cube<Int> to Cube<Bool>.
+  // However these should ultimately be references directly to bool
+  // cubes.
+  vbs.flagCube_p.resize(flags.shape());    vbs.flagCube_p = False; vbs.flagCube_p(flags!=0) = True;
+  //    vbs.rowFlag.resize(rowFlags.shape());  vbs.rowFlag  = False; vbs.rowFlag(rowFlags) = True;
+
+  // Determine the terms of the Mueller matrix that should be calculated
+  visResamplers_p.setParams(uvScale,uvOffset,dphase);
+  visResamplers_p.setMaps(chanMap, polMap);
+
+
+  // Determine the baselines in the VisBuffer.
+  const Vector<Int>& ant1 = vb.antenna1();
+  const Vector<Int>& ant2 = vb.antenna2();
+  int nrant = 1 + max(max(ant1), max(ant2));
+  // Sort on baseline (use a baseline nr which is faster to sort).
+  Vector<Int> blnr(nrant*ant1);
+  blnr += ant2;  // This is faster than nrant*ant1+ant2 in a single line
+  Vector<uInt> blIndex;
+  GenSortIndirect<Int>::sort (blIndex, blnr);
+  // Now determine nr of unique baselines and their start index.
+  vector<int> blStart, blEnd;
+  blStart.reserve (nrant*(nrant+1)/2);
+  blEnd.reserve   (nrant*(nrant+1)/2);
+  Int  lastbl     = -1;
+  Int  lastIndex  = 0;
+  bool usebl      = false;
+  bool allFlagged = true;
+  const Vector<Bool>& flagRow = vb.flagRow();
+  for (uint i=0; i<blnr.size(); ++i) {
+    Int inx = blIndex[i];
+    Int bl = blnr[inx];
+    if (bl != lastbl) {
+      // New baseline. Write the previous end index if applicable.
+      if (usebl  &&  !allFlagged) {
+        double Wmean(0.5*(vb.uvw()[blIndex[lastIndex]](2) + vb.uvw()[blIndex[i-1]](2)));
+        if (abs(Wmean) <= itsWMax) {
+	  if (itsVerbose > 1) {
+	    cout<<"using w="<<Wmean<<endl;
+	  }
+	  blStart.push_back (lastIndex);
+	  blEnd.push_back (i-1);
+        }
+      }
+      // Skip auto-correlations and high W-values.
+      // All w values are close, so if first w is too high, skip baseline.
+      usebl = false;
+
+      if (ant1[inx] != ant2[inx]) {
+        usebl = true;
+      }
+      lastbl=bl;
+      lastIndex=i;
+    }
+    // Test if the row is flagged.
+    if (! flagRow[inx]) {
+      allFlagged = false;
+    }
+  }
+  // Write the last end index if applicable.
+  if (usebl  &&  !allFlagged) {
+    double Wmean(0.5*(vb.uvw()[blIndex[lastIndex]](2) + vb.uvw()[blIndex[blnr.size()-1]](2)));
+    if (abs(Wmean) <= itsWMax) {
+      if (itsVerbose > 1) {
+	cout<<"...using w="<<Wmean<<endl;
+      }
+      blStart.push_back (lastIndex);
+      blEnd.push_back (blnr.size()-1);
+    }
+  }
+
+  // Determine the time center of this data chunk.
+  const Vector<Double>& times = vb.timeCentroid();
+  double time = 0.5 * (times[times.size()-1] + times[0]);
+  //ROVisIter& via(vb.iter());
+
+  // First compute the A-terms for all stations (if needed).
+  itsConvFunc->computeAterm (time);
+
+  itsTotalTimer.start();
+#pragma omp parallel
+  {
+    // Thread-private variables.
+    PrecTimer degridTimer;
+    PrecTimer cfTimer;
+    // The for loop can be parallellized. This must be done dynamically,
+    // because the execution times of iterations can vary greatly.
+    #pragma omp for schedule(dynamic)
+    for (int i=0; i<int(blStart.size()); ++i) {
+      // #pragma omp critical(LofarFTMachineOld_lofarGridToData)
+      // {
+      Int ist  = blIndex[blStart[i]];
+      Int iend = blIndex[blEnd[i]];
+      int threadNum = OpenMP::threadNum();
+      // Get the convolution function for degridding.
+      if (itsVerbose > 1) {
+	cout<<"ANTENNA "<<ant1[ist]<<" "<<ant2[ist]<<endl;
+      }
+      cfTimer.start();
+      LofarCFStore cfStore =
+        itsConvFunc->makeConvolutionFunction (ant1[ist], ant2[ist], time,
+                                              0.5*(vbs.uvw()(2,ist) + vbs.uvw()(2,iend)),
+                                              itsDegridMuellerMask,
+                                              true,
+                                              0.0,
+                                              itsSumPB[threadNum],
+                                              itsSumCFWeight[threadNum]);
+      cfTimer.stop();
+
+      //Double or single precision gridding.
+      //      cout<<"GRID "<<ant1[ist]<<" "<<ant2[ist]<<endl;
+      degridTimer.start();
+      visResamplers_p.lofarGridToData(vbs, itsGriddedData[0],
+                                      blIndex, blStart[i], blEnd[i], cfStore);
+      degridTimer.stop();
+    } // end omp for
+    double cftime = cfTimer.getReal();
+#pragma omp atomic
+    itsCFTime += cftime;
+    double gtime = degridTimer.getReal();
+#pragma omp atomic
+    itsGriddingTime += gtime;
+  } // end omp parallel
+  itsTotalTimer.stop();
+  interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
+}
+
+
+
+// Finalize the FFT to the Sky. Here we actually do the FFT and
+// return the resulting image
+ImageInterface<Complex>& LofarFTMachineOld::getImage(Matrix<Float>& weights, Bool normalize)
+{
+  //AlwaysAssert(lattice, AipsError);
+  AlwaysAssert(gridder, AipsError);
+  AlwaysAssert(image, AipsError);
+  logIO() << LogOrigin("LofarFTMachineOld", "getImage") << LogIO::NORMAL;
+
+  if (itsVerbose > 0) {
+    cout<<"GETIMAGE"<<endl;
+  }
+  itsAvgPB.reference (itsConvFunc->Compute_avg_pb(itsSumPB[0], itsSumCFWeight[0]));
+
+  //cout<<"weights.shape() "<<weights.shape()<<"  "<<sumWeight<<endl;
+
+  weights.resize(itsSumWeight[0].shape());
+
+  convertArray(weights, itsSumWeight[0]);
+  // If the weights are all zero then we cannot normalize
+  // otherwise we don't care.
+  if(normalize&&max(weights)==0.0) {
+    logIO() << LogIO::SEVERE << "No useful data in LofarFTMachineOld: weights all zero"
+	    << LogIO::POST;
+  }
+  else {
+
+    const IPosition latticeShape = lattice->shape();
+
+    logIO() << LogIO::DEBUGGING
+	    << "Starting FFT and scaling of image" << LogIO::POST;
+
+
+
+    // if(useDoubleGrid_p){
+    //   convertArray(griddedData, griddedData2);
+    //   //Don't need the double-prec grid anymore...
+    //   griddedData2.resize();
+    // }
+
+    // x and y transforms
+    //    LatticeFFT::cfft2d(*lattice,False);
+    //
+    // Retain the double precision grid for FFT as well.  Convert it
+    // to single precision just after (since images are still single
+    // precision).
+    //
+    if(useDoubleGrid_p) {
+      ArrayLattice<DComplex> darrayLattice(itsGriddedData2[0]);
+      LatticeFFT::cfft2d(darrayLattice,False);
+      convertArray(itsGriddedData[0], itsGriddedData2[0]);
+      //Don't need the double-prec grid anymore...
+      ///griddedData2.resize();
+    } else {
+      LatticeFFT::cfft2d(*lattice, False);
+    }
+
+    if (itsVerbose > 0) {
+      cout<<"POLMAP:::::::  "<<polMap<<endl;
+      cout<<"POLMAP:::::::  "<<CFMap_p<<endl;
+    }
+    //cout<<"CFPOLMAP:::::::  "<<cfPolMap<<endl;
+    //Int i,j,N = cfPolMap.nelements();
+    //for(i=0;i<N;i++){
+    //  if (cfPolMap[i] > -1){cout<<"cfPolMap[i]<<visStokes[i]"<<cfPolMap[i]<<" "<<visStokes[i]<<endl;};
+    //};
+
+
+    // Cyr: This does a normalisation by the number of pixel and spheroidal
+    // function in the dirty image.
+    // I have commented out the spheroidal normalisation (correctX1D part)
+    {
+      Int inx = lattice->shape()(0);
+      Int iny = lattice->shape()(1);
+      Vector<Complex> correction(inx);
+      correction=Complex(1.0, 0.0);
+      // Do the Grid-correction
+      IPosition cursorShape(4, inx, 1, 1, 1);
+      IPosition axisPath(4, 0, 1, 2, 3);
+      LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
+      LatticeIterator<Complex> lix(*lattice, lsx);
+      for(lix.reset();!lix.atEnd();lix++) {
+        Int pol=lix.position()(2);
+	//cout<<"pol "<<pol<<endl;
+        Int chan=lix.position()(3);
+        if(weights(pol, chan)!=0.0) {
+          //gridder->correctX1D(correction, lix.position()(1));
+	  //cout<<"correction "<<correction<<endl;
+          //lix.rwVectorCursor()/=correction;
+          if(normalize) {
+            Complex rnorm(Float(inx)*Float(iny)/weights(pol,chan));
+            lix.rwCursor()*=rnorm;
+	    //cout<<"rnorm "<<rnorm<<endl;
+          }
+          else {
+            Complex rnorm(Float(inx)*Float(iny));
+            lix.rwCursor()*=rnorm;
+	    //cout<<"rnorm "<<rnorm<<endl;
+          }
+        }
+        else {
+          lix.woCursor()=0.0;
+        }
+      }
+    }
+
+    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    // Normalising dirty image by the spheroidal function
+
+    // String namei("sphe.img");
+    // ostringstream name(namei);
+    // PagedImage<Float> tmp(name.str().c_str());
+    // Slicer slice(IPosition(4,0,0,0,0), tmp.shape(), IPosition(4,1,1,1,1));
+    // Array<Float> data;
+    // tmp.doGetSlice(data, slice);
+    // IPosition posi(4,lattice->shape()[0],lattice->shape()[1],1,1);
+    // IPosition posi2(4,lattice->shape()[0],lattice->shape()[1],1,1);
+    // posi[2]=0.;
+    // posi[3]=0.;
+    // posi2[2]=0.;
+    // posi2[3]=0.;    
+    // Int offset_pad(floor(data.shape()[0]-lattice->shape()[0])/2.);
+
+    
+
+
+    // for(uInt k=0;k<lattice->shape()[2];++k){
+    //   for(uInt i=0;i<lattice->shape()[0];++i){
+    // 	for(uInt j=0;j<lattice->shape()[0];++j){
+    // 	  posi[0]=i;
+    // 	  posi[1]=j;
+    // 	  posi[2]=k;
+    // 	  posi2[0]=i+offset_pad;
+    // 	  posi2[1]=j+offset_pad;
+    // 	  Complex pixel(lattice->getAt(posi));
+    // 	  //pixel/=data(posi2);//*data(posi2);
+    // 	  lattice->putAt(pixel,posi);
+    // 	};
+    //   };
+    // };
+    //====================================================================================================================
+    //====================================================================================================================
+    //====================================================================================================================
+    // Cyr: Normalisation by the beam!!!!!
+    //cout<<"lattice shape: "<<lattice->shape()<<endl;
+    IPosition pos(4,lattice->shape()[0],lattice->shape()[1],1,1);
+    uInt shapeout(floor(lattice->shape()[0]/padding_p));
+    uInt istart(floor((lattice->shape()[0]-shapeout)/2.));
+    Cube<Complex> tempimage(IPosition(3,shapeout,shapeout,lattice->shape()[2]));
+
+    pos[3]=0.;
+    for(Int k=0;k<lattice->shape()[2];++k){
+      for(uInt i=0;i<shapeout;++i){
+    	for(uInt j=0;j<shapeout;++j){
+    	  pos[0]=i+istart;
+    	  pos[1]=j+istart;
+    	  pos[2]=k;
+    	  Complex pixel(lattice->getAt(pos));
+    	  //cout<<"pixel value: "<<pixel<<", Primary beam: "<<avg_PB(i,j)<<endl;
+    	  pixel/=sqrt(itsAvgPB(i+istart,j+istart));//*sqrt(avg_PB(i+istart,j+istart));
+    	  //pixel*=(lattice->shape()[0]*lattice->shape()[0]);
+    	  lattice->putAt(pixel,pos);
+    	  //tempimage(i,j,k)=pixel/weights(0,0);
+    	}
+      }
+    }
+    // uInt count_cycle(0);
+    // Bool written(false);
+
+    // while(!written){
+    //   cout<<"count_cycle ======================= "<<count_cycle<<" "<<normalize<<endl;
+    //   File myFile("Cube_dirty.img"+String::toString(count_cycle));
+    //   if(!myFile.exists()){
+    // 	written=true;
+    // 	store(tempimage,"Cube_dirty.img"+String::toString(count_cycle));
+    //   }
+    //   else{
+    // 	count_cycle++;
+    //   };
+    // };
+
+    //====================================================================================================================
+    //====================================================================================================================
+    //====================================================================================================================
+
+
+
+    if(!isTiled) {
+      // Check the section from the image BEFORE converting to a lattice
+      IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2, (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
+      IPosition stride(4, 1);
+      IPosition trc(blc+image->shape()-stride);
+      // Do the copy
+      IPosition start(4, 0);
+      image->put(itsGriddedData[0](blc, trc));
+    }
+  }
+
+  //store(*image,"last.img");
+  return *image;
+}
+
+// Get weight image
+void LofarFTMachineOld::getWeightImage(ImageInterface<Float>& weightImage, Matrix<Float>& weights)
+{
+
+  logIO() << LogOrigin("LofarFTMachineOld", "getWeightImage") << LogIO::NORMAL;
+
+  weights.resize(itsSumWeight[0].shape());
+  convertArray(weights,itsSumWeight[0]);
+
+  const IPosition latticeShape = weightImage.shape();
+
+  Int nx=latticeShape(0);
+  Int ny=latticeShape(1);
+
+  IPosition loc(2, 0);
+  IPosition cursorShape(4, nx, ny, 1, 1);
+  IPosition axisPath(4, 0, 1, 2, 3);
+  LatticeStepper lsx(latticeShape, cursorShape, axisPath);
+  LatticeIterator<Float> lix(weightImage, lsx);
+  for(lix.reset();!lix.atEnd();lix++) {
+    Int pol=lix.position()(2);
+    Int chan=lix.position()(3);
+    lix.rwCursor()=weights(pol,chan);
+  }
+}
+
+Bool LofarFTMachineOld::toRecord(String& error, RecordInterface& outRec,
+			Bool withImage) {
+
+  // Save the current LofarFTMachineOld object to an output state record
+  Bool retval = True;
+
+  Double cacheVal=(Double)cachesize;
+  outRec.define("cache", cacheVal);
+  outRec.define("tile", tilesize);
+  outRec.define("gridfunction", convType);
+
+  Vector<Double> phaseValue(2);
+  String phaseUnit;
+  phaseValue=mTangent_p.getAngle().getValue();
+  phaseUnit= mTangent_p.getAngle().getUnit();
+  outRec.define("phasevalue", phaseValue);
+  outRec.define("phaseunit", phaseUnit);
+
+  Vector<Double> dirValue(3);
+  String dirUnit;
+  dirValue=mLocation_p.get("m").getValue();
+  dirUnit=mLocation_p.get("m").getUnit();
+  outRec.define("dirvalue", dirValue);
+  outRec.define("dirunit", dirUnit);
+
+  outRec.define("padding", padding_p);
+  outRec.define("maxdataval", maxAbsData);
+
+  Vector<Int> center_loc(4), offset_loc(4);
+  for (Int k=0; k<4 ; k++){
+    center_loc(k)=centerLoc(k);
+    offset_loc(k)=offsetLoc(k);
+  }
+  outRec.define("centerloc", center_loc);
+  outRec.define("offsetloc", offset_loc);
+  outRec.define("sumofweights", itsSumWeight[0]);
+  if(withImage && image){
+    ImageInterface<Complex>& tempimage(*image);
+    Record imageContainer;
+    retval = (retval || tempimage.toRecord(error, imageContainer));
+    outRec.defineRecord("image", imageContainer);
+  }
+  return retval;
+}
+
+Bool LofarFTMachineOld::fromRecord(String& error, const RecordInterface& inRec)
+{
+  Bool retval = True;
+  gridder=0; imageCache=0; lattice=0; arrayLattice=0;
+  Double cacheVal;
+  inRec.get("cache", cacheVal);
+  cachesize=(Long)cacheVal;
+  inRec.get("tile", tilesize);
+  inRec.get("gridfunction", convType);
+
+  Vector<Double> phaseValue(2);
+  inRec.get("phasevalue",phaseValue);
+  String phaseUnit;
+  inRec.get("phaseunit",phaseUnit);
+  Quantity val1(phaseValue(0), phaseUnit);
+  Quantity val2(phaseValue(1), phaseUnit);
+  MDirection phasecenter(val1, val2);
+
+  mTangent_p=phasecenter;
+  // This should be passed down too but the tangent plane is
+  // expected to be specified in all meaningful cases.
+  tangentSpecified_p=True;
+  Vector<Double> dirValue(3);
+  String dirUnit;
+  inRec.get("dirvalue", dirValue);
+  inRec.get("dirunit", dirUnit);
+  MVPosition dummyMVPos(dirValue(0), dirValue(1), dirValue(2));
+  MPosition mLocation(dummyMVPos, MPosition::ITRF);
+  mLocation_p=mLocation;
+
+  inRec.get("padding", padding_p);
+  inRec.get("maxdataval", maxAbsData);
+
+  Vector<Int> center_loc(4), offset_loc(4);
+  inRec.get("centerloc", center_loc);
+  inRec.get("offsetloc", offset_loc);
+  uInt ndim4 = 4;
+  centerLoc=IPosition(ndim4, center_loc(0), center_loc(1), center_loc(2),
+		      center_loc(3));
+  offsetLoc=IPosition(ndim4, offset_loc(0), offset_loc(1), offset_loc(2),
+		      offset_loc(3));
+  inRec.get("sumofweights", itsSumWeight[0]);
+  if(inRec.nfields() > 12 ){
+    Record imageAsRec=inRec.asRecord("image");
+    if(!image) {
+      image= new TempImage<Complex>();
+    }
+    retval = (retval || image->fromRecord(error, imageAsRec));
+
+    // Might be changing the shape of sumWeight
+    init();
+
+    if(isTiled) {
+      lattice=CountedPtr<Lattice<Complex> >(image, False);
+    }
+    else {
+      // Make the grid the correct shape and turn it into an array lattice
+      // Check the section from the image BEFORE converting to a lattice
+      IPosition gridShape(4, nx, ny, npol, nchan);
+      itsGriddedData[0].resize(gridShape);
+      itsGriddedData[0]=Complex(0.0);
+      IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2, (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
+      IPosition start(4, 0);
+      IPosition stride(4, 1);
+      IPosition trc(blc+image->shape()-stride);
+      itsGriddedData[0](blc, trc)=image->getSlice(start, image->shape());
+
+      //if(arrayLattice) delete arrayLattice; arrayLattice=0;
+      arrayLattice = new ArrayLattice<Complex>(itsGriddedData[0]);
+      lattice=arrayLattice;
+    }
+
+    //AlwaysAssert(lattice, AipsError);
+    AlwaysAssert(gridder, AipsError);
+    AlwaysAssert(image, AipsError);
+  }
+  return retval;
+}
+
+void LofarFTMachineOld::ok() {
+  AlwaysAssert(image, AipsError);
+}
+
+// Make a plain straightforward honest-to-God image. This returns
+// a complex image, without conversion to Stokes. The representation
+// is that required for the visibilities.
+//----------------------------------------------------------------------
+void LofarFTMachineOld::makeImage(FTMachine::Type type,
+		       VisSet& vs,
+		       ImageInterface<Complex>& theImage,
+		       Matrix<Float>& weight) {
+
+
+  logIO() << LogOrigin("LofarFTMachineOld", "makeImage") << LogIO::NORMAL;
+
+  if(type==FTMachine::COVERAGE) {
+    logIO() << "Type COVERAGE not defined for Fourier transforms" << LogIO::EXCEPTION;
+  }
+
+
+  // Initialize the gradients
+  ROVisIter& vi(vs.iter());
+
+  // Loop over all visibilities and pixels
+  VisBuffer vb(vi);
+
+  // Initialize put (i.e. transform to Sky) for this model
+  vi.origin();
+
+  if(vb.polFrame()==MSIter::Linear) {
+    StokesImageUtil::changeCStokesRep(theImage, SkyModel::LINEAR);
+  }
+  else {
+    StokesImageUtil::changeCStokesRep(theImage, SkyModel::CIRCULAR);
+  }
+
+  initializeToSky(theImage,weight,vb);
+
+  // Loop over the visibilities, putting VisBuffers
+  for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
+    for (vi.origin(); vi.more(); vi++) {
+
+      switch(type) {
+      case FTMachine::RESIDUAL:
+        if (itsVerbose > 0) cout<<"FTMachine::RESIDUAL"<<endl;
+	vb.visCube()=vb.correctedVisCube();
+	vb.visCube()-=vb.modelVisCube();
+        put(vb, -1, False);
+        break;
+      case FTMachine::MODEL:
+	if (itsVerbose > 0) cout<<"FTMachine::MODEL"<<endl;
+	vb.visCube()=vb.modelVisCube();
+        put(vb, -1, False);
+        break;
+      case FTMachine::CORRECTED:
+	if (itsVerbose > 0) cout<<"FTMachine::CORRECTED"<<endl;
+	vb.visCube()=vb.correctedVisCube();
+        put(vb, -1, False);
+        break;
+      case FTMachine::PSF:
+	if (itsVerbose > 0) cout<<"FTMachine::PSF"<<endl;
+	vb.visCube()=Complex(1.0,0.0);
+        put(vb, -1, True);
+        break;
+      case FTMachine::OBSERVED:
+      default:
+	if (itsVerbose > 0) cout<<"FTMachine::OBSERVED"<<endl;
+        put(vb, -1, False);
+        break;
+      }
+    }
+  }
+  finalizeToSky();
+  // Normalize by dividing out weights, etc.
+  getImage(weight, True);
+}
+
+String LofarFTMachineOld::name(){
+
+  return machineName_p;
+
+
+}
+
+void LofarFTMachineOld::ComputeResiduals(VisBuffer&vb, Bool useCorrected)
+{
+  LofarVBStore vbs;
+  vbs.nRow_p = vb.nRow();
+  vbs.beginRow_p = 0;
+  vbs.endRow_p = vbs.nRow_p;
+  vbs.modelCube_p.reference(vb.modelVisCube());
+  if (useCorrected) vbs.correctedCube_p.reference(vb.correctedVisCube());
+  else vbs.visCube_p.reference(vb.visCube());
+  //  cout<<"BLA===="<<vb.visCube()<<"    "<<useCorrected<<endl;
+  
+  //for(uInt i=0;i<vbs.nRow_p;++i){cout<<"ROW "<<i<<" "<<vb.antenna1()(i)<<" "<<vb.antenna2()(i)<<endl;};
+
+  vbs.useCorrected_p = useCorrected;
+  visResamplers_p.lofarComputeResiduals(vbs);
+
+  //  vb.correctedVisCube()=0.;//vb.modelVisCube();
+}
+
+  void LofarFTMachineOld::makeSensitivityImage(const VisBuffer& vb,
+					 const ImageInterface<Complex>& imageTemplate,
+					 ImageInterface<Float>& sensitivityImage)
+  {
+    if (convFuncCtor_p->makeAverageResponse(vb, imageTemplate, sensitivityImage))
+      cfCache_p->flush(sensitivityImage,sensitivityPatternQualifierStr_p);
+  }
+  //
+  //---------------------------------------------------------------
+  //
+  void LofarFTMachineOld::normalizeAvgPB(ImageInterface<Complex>& inImage,
+				   ImageInterface<Float>& outImage)
+  {
+    LogIO log_l(LogOrigin("LofarFTMachineOld", "normalizeAvgPB"));
+    if (pbNormalized_p) return;
+    IPosition inShape(inImage.shape()),ndx(4,0,0,0,0);
+    Vector<Complex> peak(inShape(2));
+
+    outImage.resize(inShape);
+    outImage.setCoordinateInfo(inImage.coordinates());
+
+    Bool isRefIn, isRefOut;
+    Array<Complex> inBuf;
+    Array<Float> outBuf;
+
+    isRefIn  = inImage.get(inBuf);
+    isRefOut = outImage.get(outBuf);
+    log_l << "Normalizing the average PBs to unity"
+	  << LogIO::NORMAL << LogIO::POST;
+    //
+    // Normalize each plane of the inImage separately to unity.
+    //
+    Complex inMax = max(inBuf);
+    if (abs(inMax)-1.0 > 1E-3)
+      {
+	for(ndx(3)=0;ndx(3)<inShape(3);ndx(3)++)
+	  for(ndx(2)=0;ndx(2)<inShape(2);ndx(2)++)
+	    {
+	      peak(ndx(2)) = 0;
+	      for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
+		for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
+		  if (abs(inBuf(ndx)) > peak(ndx(2)))
+		    peak(ndx(2)) = inBuf(ndx);
+
+	      for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
+		for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
+		  //		      avgPBBuf(ndx) *= (pbPeaks(ndx(2))/peak(ndx(2)));
+		  inBuf(ndx) /= peak(ndx(2));
+	    }
+	if (isRefIn) inImage.put(inBuf);
+      }
+
+    ndx=0;
+    for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
+      for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
+	{
+	  IPosition plane1(ndx);
+	  plane1=ndx;
+	  plane1(2)=1; // The other poln. plane
+	  //	  avgPBBuf(ndx) = (avgPBBuf(ndx) + avgPBBuf(plane1))/2.0;
+	  outBuf(ndx) = sqrt(real(inBuf(ndx) * inBuf(plane1)));
+	}
+    //
+    // Rather convoluted way of copying Pol. plane-0 to Pol. plane-1!!!
+    //
+    for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
+      for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
+	{
+	  IPosition plane1(ndx);
+	  plane1=ndx;
+	  plane1(2)=1; // The other poln. plane
+	  outBuf(plane1) = outBuf(ndx);
+	}
+
+    pbNormalized_p = True;
+  }
+  //
+  //---------------------------------------------------------------
+  //
+  void LofarFTMachineOld::normalizeAvgPB()
+  {
+    LogIO log_l(LogOrigin("LofarFTMachineOld", "normalizeAvgPB"));
+    if (pbNormalized_p) return;
+    Bool isRefF;
+    Array<Float> avgPBBuf;
+    isRefF=avgPB_p->get(avgPBBuf);
+    //    Float pbMax = max(avgPBBuf);
+      {
+	pbPeaks.resize(avgPB_p->shape()(2),True);
+	// if (makingPSF) pbPeaks = 1.0;
+	// else pbPeaks /= (Float)noOfPASteps;
+	pbPeaks = 1.0;
+	log_l << "Normalizing the average PBs to " << 1.0
+	      << LogIO::NORMAL << LogIO::POST;
+
+	IPosition avgPBShape(avgPB_p->shape()),ndx(4,0,0,0,0);
+	Vector<Float> peak(avgPBShape(2));
+
+
+	Float pbMax = max(avgPBBuf);
+	if (fabs(pbMax-1.0) > 1E-3)
+	  {
+	    //	    avgPBBuf = avgPBBuf/noOfPASteps;
+	    for(ndx(3)=0;ndx(3)<avgPBShape(3);ndx(3)++)
+	      for(ndx(2)=0;ndx(2)<avgPBShape(2);ndx(2)++)
+		{
+		  peak(ndx(2)) = 0;
+		  for(ndx(1)=0;ndx(1)<avgPBShape(1);ndx(1)++)
+		    for(ndx(0)=0;ndx(0)<avgPBShape(0);ndx(0)++)
+		      if (abs(avgPBBuf(ndx)) > peak(ndx(2)))
+			peak(ndx(2)) = avgPBBuf(ndx);
+
+		  for(ndx(1)=0;ndx(1)<avgPBShape(1);ndx(1)++)
+		    for(ndx(0)=0;ndx(0)<avgPBShape(0);ndx(0)++)
+		      //		      avgPBBuf(ndx) *= (pbPeaks(ndx(2))/peak(ndx(2)));
+		      avgPBBuf(ndx) /= peak(ndx(2));
+		}
+	    if (isRefF) avgPB_p->put(avgPBBuf);
+	  }
+
+	ndx=0;
+	for(ndx(1)=0;ndx(1)<avgPBShape(1);ndx(1)++)
+	  for(ndx(0)=0;ndx(0)<avgPBShape(0);ndx(0)++)
+	    {
+	      IPosition plane1(ndx);
+	      plane1=ndx;
+	      plane1(2)=1; // The other poln. plane
+	      avgPBBuf(ndx) = (avgPBBuf(ndx) + avgPBBuf(plane1))/2.0;
+	      //	      avgPBBuf(ndx) = (avgPBBuf(ndx) * avgPBBuf(plane1));
+	    }
+	for(ndx(1)=0;ndx(1)<avgPBShape(1);ndx(1)++)
+	  for(ndx(0)=0;ndx(0)<avgPBShape(0);ndx(0)++)
+	    {
+	      IPosition plane1(ndx);
+	      plane1=ndx;
+	      plane1(2)=1; // The other poln. plane
+	      avgPBBuf(plane1) = avgPBBuf(ndx);
+	    }
+      }
+      pbNormalized_p = True;
+  }
+
+  void LofarFTMachineOld::normalizeImage(Lattice<Complex>& skyImage,
+				   const Matrix<Double>& sumOfWts,
+				   Lattice<Float>& sensitivityImage,
+				   Lattice<Complex>& sensitivitySqImage,
+				   Bool fftNorm)
+  {
+    //
+    // Apply the gridding correction
+    //
+    if (itsVerbose > 0) {
+      cout<<"LofarFTMachineOld::normalizeImage"<<endl;
+    }
+    Int inx = skyImage.shape()(0);
+    Int iny = skyImage.shape()(1);
+    Vector<Complex> correction(inx);
+
+    Vector<Float> sincConv(nx);
+    Float centerX=nx/2;
+    for (Int ix=0;ix<nx;ix++)
+      {
+	Float x=C::pi*Float(ix-centerX)/(Float(nx)*Float(convSampling));
+	if(ix==centerX) sincConv(ix)=1.0;
+	else 	    sincConv(ix)=sin(x)/x;
+      }
+
+    IPosition cursorShape(4, inx, 1, 1, 1);
+    IPosition axisPath(4, 0, 1, 2, 3);
+    LatticeStepper lsx(skyImage.shape(), cursorShape, axisPath);
+    LatticeIterator<Complex> lix(skyImage, lsx);
+
+    LatticeStepper lavgpb(sensitivityImage.shape(),cursorShape,axisPath);
+    LatticeIterator<Float> liavgpb(sensitivityImage, lavgpb);
+    LatticeStepper lavgpbSq(sensitivitySqImage.shape(),cursorShape,axisPath);
+    LatticeIterator<Complex> liavgpbSq(sensitivitySqImage, lavgpbSq);
+
+    for(lix.reset(),liavgpb.reset(),liavgpbSq.reset();
+	!lix.atEnd();
+	lix++,liavgpb++,liavgpbSq++)
+      {
+	Int pol=lix.position()(2);
+	Int chan=lix.position()(3);
+
+	if(sumOfWts(pol, chan)>0.0)
+	  {
+	    Int iy=lix.position()(1);
+	    gridder->correctX1D(correction,iy);
+
+	    Vector<Complex> PBCorrection(liavgpb.rwVectorCursor().shape());
+	    Vector<Float> avgPBVec(liavgpb.rwVectorCursor().shape());
+	    Vector<Complex> avgPBSqVec(liavgpbSq.rwVectorCursor().shape());
+
+	    avgPBSqVec= liavgpbSq.rwVectorCursor();
+	    avgPBVec = liavgpb.rwVectorCursor();
+
+	    for(int i=0;i<PBCorrection.shape();i++)
+	      {
+		//
+		// This with the PS functions
+		//
+		// PBCorrection(i)=FUNC(avgPBVec(i))*sincConv(i)*sincConv(iy);
+		// if ((abs(PBCorrection(i)*correction(i))) >= pbLimit_p)
+		// 	lix.rwVectorCursor()(i) /= PBCorrection(i)*correction(i);
+		// else if (!makingPSF)
+		// 	lix.rwVectorCursor()(i) /= correction(i)*sincConv(i)*sincConv(iy);
+		//
+		// This without the PS functions
+		//
+
+
+
+		// if (makingPSF)
+		PBCorrection(i)=(avgPBSqVec(i)/avgPBVec(i));///(sincConv(i)*sincConv(iy));
+		//		PBCorrection(i)=(avgPBSqVec(i));///(sincConv(i)*sincConv(iy));
+		//		PBCorrection(i)=avgPBVec(i);///(sincConv(i)*sincConv(iy));
+
+		// else
+		//		PBCorrection(i)=(avgPBVec(i));//*sincConv(i)*sincConv(iy);
+		//		if ((abs(avgPBSqVec(i))) >= pbLimit_p)
+		if ((abs(avgPBVec(i))) >= pbLimit_p)
+		  lix.rwVectorCursor()(i) /= PBCorrection(i);
+
+		// if ((abs(PBCorrection(i))) >= pbLimit_p)
+		//   lix.rwVectorCursor()(i) /= PBCorrection(i);
+		// else if (!makingPSF)
+		//   lix.rwVectorCursor()(i) /= sincConv(i)*sincConv(iy);
+
+
+		// PBCorrection(i)=FUNC(avgPBVec(i)/avgPBSqVec(i))/(sincConv(i)*sincConv(iy));
+		// lix.rwVectorCursor()(i) *= PBCorrection(i);
+
+		// if ((abs(avgPBSqVec(i))) >= pbLimit_p)
+		//   lix.rwVectorCursor()(i) *= PBCorrection(i);
+		// else if (!makingPSF)
+		//   lix.rwVectorCursor()(i) /= sincConv(i)*sincConv(iy);
+	      }
+
+	    if(fftNorm)
+	      {
+		Complex rnorm(Float(inx)*Float(iny)/sumOfWts(pol,chan));
+		lix.rwCursor()*=rnorm;
+	      }
+	    else
+	      {
+		Complex rnorm(Float(inx)*Float(iny));
+		lix.rwCursor()*=rnorm;
+	      }
+	  }
+	else
+	  lix.woCursor()=0.0;
+      }
+  }
+  //
+  //---------------------------------------------------------------
+  //
+  void LofarFTMachineOld::normalizeImage(Lattice<Complex>& skyImage,
+				   const Matrix<Double>& sumOfWts,
+				   Lattice<Float>& sensitivityImage,
+				   Bool fftNorm)
+  {
+    //
+    // Apply the gridding correction
+    //
+    if (itsVerbose > 0) {
+      cout<<"LofarFTMachineOld::normalizeImage<"<<endl;
+    }
+    Int inx = skyImage.shape()(0);
+    Int iny = skyImage.shape()(1);
+    Vector<Complex> correction(inx);
+
+    Vector<Float> sincConv(nx);
+    Float centerX=nx/2;
+    for (Int ix=0;ix<nx;ix++)
+      {
+	Float x=C::pi*Float(ix-centerX)/(Float(nx)*Float(convSampling));
+	if(ix==centerX) sincConv(ix)=1.0;
+	else 	    sincConv(ix)=sin(x)/x;
+      }
+
+    IPosition cursorShape(4, inx, 1, 1, 1);
+    IPosition axisPath(4, 0, 1, 2, 3);
+    LatticeStepper lsx(skyImage.shape(), cursorShape, axisPath);
+    //    LatticeIterator<Complex> lix(skyImage, lsx);
+    LatticeIterator<Complex> lix(skyImage, lsx);
+
+    LatticeStepper lavgpb(sensitivityImage.shape(),cursorShape,axisPath);
+    // Array<Float> senArray;sensitivityImage.get(senArray,True);
+    // ArrayLattice<Float> senLat(senArray,True);
+    //    LatticeIterator<Float> liavgpb(senLat, lavgpb);
+    LatticeIterator<Float> liavgpb(sensitivityImage, lavgpb);
+
+    for(lix.reset(),liavgpb.reset();
+	!lix.atEnd();
+	lix++,liavgpb++)
+      {
+	Int pol=lix.position()(2);
+	Int chan=lix.position()(3);
+
+	if(sumOfWts(pol, chan)>0.0)
+	  {
+	    Int iy=lix.position()(1);
+	    gridder->correctX1D(correction,iy);
+
+	    Vector<Float> avgPBVec(liavgpb.rwVectorCursor().shape());
+
+	    avgPBVec = liavgpb.rwVectorCursor();
+
+	    for(int i=0;i<avgPBVec.shape();i++)
+	      {
+		//
+		// This with the PS functions
+		//
+		// PBCorrection(i)=FUNC(avgPBVec(i))*sincConv(i)*sincConv(iy);
+		// if ((abs(PBCorrection(i)*correction(i))) >= pbLimit_p)
+		// 	lix.rwVectorCursor()(i) /= PBCorrection(i)*correction(i);
+		// else if (!makingPSF)
+		// 	lix.rwVectorCursor()(i) /= correction(i)*sincConv(i)*sincConv(iy);
+		//
+		// This without the PS functions
+		//
+		//                Float tt=sqrt(avgPBVec(i))/avgPBVec(i);
+		Float tt = pbFunc(avgPBVec(i),pbLimit_p);
+                  //		PBCorrection(i)=pbFunc(avgPBVec(i),pbLimit_p)*sincConv(i)*sincConv(iy);
+                  //                lix.rwVectorCursor()(i) /= PBCorrection(i);
+		//                lix.rwVectorCursor()(i) *= tt;
+
+		lix.rwVectorCursor()(i) /= tt;
+		// if ((abs(tt) >= pbLimit_p))
+		//   lix.rwVectorCursor()(i) /= tt;
+		// else if (!makingPSF)
+		//   lix.rwVectorCursor()(i) /= sincConv(i)*sincConv(iy);
+	      }
+
+	    if(fftNorm)
+	      {
+		Complex rnorm(Float(inx)*Float(iny)/sumOfWts(pol,chan));
+		lix.rwCursor()*=rnorm;
+	      }
+	    else
+	      {
+		Complex rnorm(Float(inx)*Float(iny));
+		lix.rwCursor()*=rnorm;
+	      }
+	  }
+	else
+	  lix.woCursor()=0.0;
+      }
+  }
+
+
+  void LofarFTMachineOld::makeCFPolMap(const VisBuffer& vb, const Vector<Int>& locCfStokes,
+				 Vector<Int>& polM)
+  {
+    LogIO log_l(LogOrigin("LofarFTMachineOld", "findPointingOffsets"));
+    Vector<Int> msStokes = vb.corrType();
+    Int nPol = msStokes.nelements();
+    polM.resize(polMap.shape());
+    polM = -1;
+
+    for(Int i=0;i<nPol;i++)
+      for(uInt j=0;j<locCfStokes.nelements();j++)
+	if (locCfStokes(j) == msStokes(i))
+	    {polM(i) = j;break;}
+  }
+  //
+  //---------------------------------------------------------------
+  //
+  // Given a polMap (mapping of which Visibility polarization is
+  // gridded onto which grid plane), make a map of the conjugate
+  // planes of the grid E.g, for Stokes-I and -V imaging, the two
+  // planes of the uv-grid are [LL,RR].  For input VisBuffer
+  // visibilites in order [RR,RL,LR,LL], polMap = [1,-1,-1,0].  The
+  // conjugate map will be [0,-1,-1,1].
+  //
+  void LofarFTMachineOld::makeConjPolMap(const VisBuffer& vb,
+				     const Vector<Int> cfPolMap,
+				     Vector<Int>& conjPolMap)
+  {
+    LogIO log_l(LogOrigin("LofarFTMachineOld", "makConjPolMap"));
+    //
+    // All the Natak (Drama) below with slicers etc. is to extract the
+    // Poln. info. for the first IF only (not much "information
+    // hiding" for the code to slice arrays in a general fashion).
+    //
+    // Extract the shape of the array to be sliced.
+    //
+    Array<Int> stokesForAllIFs = vb.msColumns().polarization().corrType().getColumn();
+    IPosition stokesShape(stokesForAllIFs.shape());
+    IPosition firstIFStart(stokesShape),firstIFLength(stokesShape);
+    //
+    // Set up the start and length IPositions to extract only the
+    // first column of the array.  The following is required since the
+    // array could have only one column as well.
+    //
+    firstIFStart(0)=0;firstIFLength(0)=stokesShape(0);
+    for(uInt i=1;i<stokesShape.nelements();i++) {firstIFStart(i)=0;firstIFLength(i)=1;}
+    //
+    // Construct the slicer and produce the slice.  .nonDegenerate
+    // required to ensure the result of slice is a pure vector.
+    //
+    Vector<Int> visStokes = stokesForAllIFs(Slicer(firstIFStart,firstIFLength)).nonDegenerate();
+
+    conjPolMap = cfPolMap;
+
+    Int i,j,N = cfPolMap.nelements();
+    
+    for(i=0;i<N;i++)
+      if (cfPolMap[i] > -1)
+	{
+	if      (visStokes[i] == Stokes::XX)
+	  {
+	    conjPolMap[i]=-1;
+	    for(j=0;j<N;j++) if (visStokes[j] == Stokes::YY) break;
+	    conjPolMap[i]=cfPolMap[j];
+	  }
+	else if (visStokes[i] == Stokes::YY)
+	  {
+	    conjPolMap[i]=-1;
+	    for(j=0;j<N;j++) if (visStokes[j] == Stokes::XX) break;
+	    conjPolMap[i]=cfPolMap[j];
+	  }
+	else if (visStokes[i] == Stokes::YX)
+	  {
+	    conjPolMap[i]=-1;
+	    for(j=0;j<N;j++) if (visStokes[j] == Stokes::XY) break;
+	    conjPolMap[i]=cfPolMap[j];
+	  }
+	else if (visStokes[i] == Stokes::XY)
+	  {
+	    conjPolMap[i]=-1;
+	    for(j=0;j<N;j++) if (visStokes[j] == Stokes::YX) break;
+	    conjPolMap[i]=cfPolMap[j];
+	  }
+	}
+  }
+
+  void LofarFTMachineOld::showTimings (ostream& os, double duration) const
+  {
+    // The total time is the real elapsed time.
+    // The cf and (de)gridding time is the sum of all threads, so scale
+    // them back to real time.
+    double total = itsCFTime + itsGriddingTime + itsDegriddingTime;
+    double scale = 1;
+    if (total > 0) {
+      scale = itsTotalTimer.getReal() / total;
+    }
+    itsConvFunc->showTimings (os, duration, itsCFTime*scale);
+    if (itsGriddingTime > 0) {
+      os << "  gridding          ";
+      LofarConvolutionFunctionOld::showPerc1 (os, itsGriddingTime*scale,
+                                           duration);
+      os << endl;
+    }
+    if (itsDegriddingTime > 0) {
+      os << "  degridding        ";
+      LofarConvolutionFunctionOld::showPerc1 (os, itsDegriddingTime*scale,
+                                           duration);
+      os << endl;
+    }
+  }
+
+} //# end namespace
diff --git a/CEP/Imager/LofarFT/src/LofarImager.cc b/CEP/Imager/LofarFT/src/LofarImager.cc
index 08068444b85b24d8fe605f6394c7a7ab61b38146..34fa5eb10411462a0e0c5f728a840f1d1f341624 100644
--- a/CEP/Imager/LofarFT/src/LofarImager.cc
+++ b/CEP/Imager/LofarFT/src/LofarImager.cc
@@ -40,10 +40,11 @@ namespace LOFAR
   // @brief Imager for LOFAR data correcting for DD effects
 
   LofarImager::LofarImager (MeasurementSet& ms, const Record& parameters)
-    : Imager(ms),
-      itsParameters (parameters)
+    : Imager(ms,false, true),
+      itsParameters (parameters),
+      itsMachine    (0),
+      itsMachineOld (0)
   {
-    cout << itsParameters<<endl;
   }
 
   LofarImager::~LofarImager()
@@ -53,7 +54,36 @@ namespace LOFAR
   {
     CountedPtr<VisibilityResamplerBase> visResampler;
     Bool useDoublePrecGrid = False;
-    itsMachine = new LofarFTMachine(cache_p/2, tile_p,
+    Double RefFreq((*sm_p).getReferenceFrequency());
+
+    if (itsParameters.asBool("splitbeam")) {
+      cout << itsParameters<<endl;
+      itsMachine = new LofarFTMachine(cache_p/2, tile_p,
+                                      visResampler, gridfunction_p,
+                                      *ms_p, wprojPlanes_p, mLocation_p,
+                                      padding_p, false, useDoublePrecGrid,
+                                      itsParameters.asDouble("wmax"),
+                                      itsParameters.asInt("verbose"),
+                                      itsParameters.asInt("maxsupport"),
+                                      itsParameters.asInt("oversample"),
+                                      itsParameters.asString("imagename"),
+                                      itsParameters.asArrayBool("mueller.grid"),
+                                      itsParameters.asArrayBool("mueller.degrid"),
+                                      RefFreq,
+                                      itsParameters.asBool("UseLIG"),
+                                      itsParameters.asBool("UseEJones"),
+                                      itsParameters.asInt("StepApplyElement"),
+                                      itsParameters.asDouble("PBCut"),
+                                      itsParameters.asBool("PredictFT"),
+                                      itsParameters.asString("PsfImage"),
+                                      itsParameters.asBool("UseMasksDegrid"),
+                                      itsParameters.asBool("doPSF"),
+                                      itsParameters);//,
+                                      //itsParameters.asDouble("FillFactor"));
+    
+      ft_p  = itsMachine;
+    } else {
+    itsMachineOld = new LofarFTMachineOld(cache_p/2, tile_p,
                                     visResampler, gridfunction_p,
                                     *ms_p, wprojPlanes_p, mLocation_p,
                                     padding_p, false, useDoublePrecGrid,
@@ -65,7 +95,9 @@ namespace LOFAR
                                     itsParameters.asString("imagename"),
                                     itsParameters.asArrayBool("mueller.grid"),
                                     itsParameters.asArrayBool("mueller.degrid"));
-    ft_p  = itsMachine;
+      ft_p  = itsMachineOld;
+    }
+
     cft_p = new SimpleComponentFTMachine();
 
     //setClarkCleanImageSkyModel();
@@ -79,9 +111,13 @@ namespace LOFAR
     Int nrowBlock = nrowPerTime * max(1,ntime);
     // Set row blocking in VisIter.
     rvi_p->setRowBlocking (nrowBlock);
+    if(itsParameters.asInt("RowBlock")>0){
+      rvi_p->setRowBlocking (itsParameters.asInt("RowBlock"));
+    };
 /*    os << LogIO::NORMAL
        << "vi.setRowBlocking(" << nrowBlock << ")"
        << LogIO::POST;*/
+    
     return True;
   }
 
@@ -89,6 +125,7 @@ namespace LOFAR
   {
     se_p = new LofarCubeSkyEquation(*sm_p, *rvi_p, *ft_p, *cft_p,
                                     !useModelCol_p);
+
     return;
   }
 
@@ -102,9 +139,12 @@ namespace LOFAR
   // Show the relative timings of the various steps.
   void LofarImager::showTimings (std::ostream&, double duration) const
   {
-    itsMachine->showTimings (cout, duration);
+    if (itsMachine) {
+      itsMachine->showTimings (cout, duration);
+    } else if (itsMachineOld) {
+      itsMachineOld->showTimings (cout, duration);
+    }
   }
 
 
 } //# end namespace
-
diff --git a/CEP/Imager/LofarFT/src/LofarVisResampler.cc b/CEP/Imager/LofarFT/src/LofarVisResampler.cc
index 5533e971bd620abf3fcca4e9e7e88ea5ffff31c7..a9249dd8ab1bbd2e7054eb2b1bd83b948bef0c41 100644
--- a/CEP/Imager/LofarFT/src/LofarVisResampler.cc
+++ b/CEP/Imager/LofarFT/src/LofarVisResampler.cc
@@ -20,15 +20,224 @@
 //#
 //# $Id$
 
+#include <lofar_config.h>
 #include <LofarFT/LofarVisResampler.h>
 #include <synthesis/MeasurementComponents/Utils.h>
 #include <coordinates/Coordinates/SpectralCoordinate.h>
 #include <coordinates/Coordinates/CoordinateSystem.h>
-#include<cassert>
+#include <cassert>
+#include <Common/OpenMP.h>
 
 namespace LOFAR {
 
     // Instantiate both templates.
+
+
+  template
+  void LofarVisResampler::DataToGridImpl_linear_p(Array<DComplex>& grid, LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+					Matrix<Double>& sumwt,const Bool& dopsf,
+					LofarCFStore& cfs) __restrict__;
+  template
+  void LofarVisResampler::DataToGridImpl_linear_p(Array<Complex>& grid, LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+					Matrix<Double>& sumwt,const Bool& dopsf,
+					LofarCFStore& cfs) __restrict__;
+
+
+  template <class T>
+  void LofarVisResampler::DataToGridImpl_linear_p(Array<T>& grid,  LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+                                           Matrix<Double>& sumwt,
+                                           const Bool& dopsf,
+                                           LofarCFStore& cfs) __restrict__
+  {
+    // grid[nx,ny,np,nf]
+    // vbs.data[np,nf,nrow]
+    // cfs[nmx,nmy,nf,ncx,ncy]   (mueller,freq,convsize)
+
+    // Get size of convolution functions.
+    Int nConvX = (*(cfs.vdata))[0][0][0].shape()[0];
+    Int nConvY = (*(cfs.vdata))[0][0][0].shape()[1];
+    // Get size of grid.
+    Int nGridX    = grid.shape()[0];
+    Int nGridY    = grid.shape()[1];
+    Int nGridPol  = grid.shape()[2];
+    Int nGridChan = grid.shape()[3];
+    //cout<<"nGridPol<<nGridChan "<<nGridPol<<" "<<nGridChan<<endl;
+
+    // Get visibility data size.
+    Int nVisPol   = vbs.flagCube_p.shape()[0];
+    Int nVisChan  = vbs.flagCube_p.shape()[1];
+    //cout<<"nVisPol<<nVisChan "<<nVisPol<<" "<<nVisChan<<endl;
+    // Get oversampling and support size.
+    Int sampx = SynthesisUtils::nint (cfs.sampling[0]);
+    Int sampy = SynthesisUtils::nint (cfs.sampling[1]);
+    Int supx = cfs.xSupport[0];
+    Int supy = cfs.ySupport[0];
+    ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
+    ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
+
+    Double* __restrict__ sumWtPtr = sumwt.data();
+    Complex psfValues[4];
+    psfValues[0] = psfValues[1] = psfValues[2] = psfValues[3] = Complex(1,0);
+
+    vector< Float > Weights_Lin_Interp;
+    Weights_Lin_Interp.resize(4);
+    vector< Int > deltax_pix_interp;
+    deltax_pix_interp.resize(4);
+    vector< Int > deltay_pix_interp;
+    deltay_pix_interp.resize(4);
+    for(uInt i=0;i<4;i++){
+      deltax_pix_interp[i]=0;
+      deltay_pix_interp[i]=0;
+    }
+
+    // Loop over all visibility rows to process.
+    for (Int inx=rbeg; inx<=rend; ++inx) {
+      Int irow = rows[inx];
+      const Double*  __restrict__ uvwPtr   = vbs.uvw_p.data() + irow*3;
+      const Float*   __restrict__ imgWtPtr = vbs.imagingWeight_p.data() +
+                                             irow * nVisChan;
+      // Loop over all channels in the visibility data.
+      // Map the visibility channel to the grid channel.
+      // Skip channel if data are not needed.
+      for (Int visChan=0; visChan<nVisChan; ++visChan) {
+        Int gridChan = chanMap_p[visChan];
+
+	//cout<<"visChan "<<visChan<<endl;
+        if (gridChan >= 0  &&  gridChan < nGridChan) {
+          // Determine the grid position from the UV coordinates in wavelengths.
+          Double recipWvl = vbs.freq_p[visChan] / C::c;
+          Double posx = uvwScale_p[0] * uvwPtr[0] * recipWvl + offset_p[0];
+          Double posy = uvwScale_p[1] * uvwPtr[1] * recipWvl + offset_p[1];
+          Int locx = floor(posx);//SynthesisUtils::nint (posx);    // location in grid
+          Int locy = floor(posy);//SynthesisUtils::nint (posy);
+          Double diffx = locx - posx;
+          //if (diffx < 0) diffx += 1;
+          Double diffy = locy - posy;
+
+ 	  if(diffx>0){
+	    deltax_pix_interp[0]=-1;
+	    deltax_pix_interp[1]=0;
+	    deltax_pix_interp[2]=-1;
+	    deltax_pix_interp[3]=0;
+	  } else {
+	    deltax_pix_interp[0]=0;
+	    deltax_pix_interp[1]=1;
+	    deltax_pix_interp[2]=0;
+	    deltax_pix_interp[3]=1;
+	  }
+	  if(diffy>0){
+	    deltay_pix_interp[0]=-1;
+	    deltay_pix_interp[1]=-1;
+	    deltay_pix_interp[2]=0;
+	    deltay_pix_interp[3]=0;
+	  } else {
+	    deltay_pix_interp[0]=0;
+	    deltay_pix_interp[1]=0;
+	    deltay_pix_interp[2]=1;
+	    deltay_pix_interp[3]=1;
+	  }
+
+	  Double diff_floor_x(abs(posx-floor(posx)));
+	  Double diff_floor_y(abs(posy-floor(posy)));
+
+
+	  Weights_Lin_Interp[0]=(1.-diff_floor_x)*(1.-diff_floor_y);
+	  Weights_Lin_Interp[1]=    diff_floor_x *(1.-diff_floor_y);
+	  Weights_Lin_Interp[2]=(1.-diff_floor_x)*    diff_floor_y ;
+	  Weights_Lin_Interp[3]=    diff_floor_x *    diff_floor_y ;
+
+	  //cout<<"diff_floor_x<<diff_floor_y "<<diff_floor_x<<" "<<diff_floor_y<<" "<<Weights_Lin_Interp[0]<<" "<<Weights_Lin_Interp[1]<<" "<<Weights_Lin_Interp[2]<<" "<<Weights_Lin_Interp[3]<<" "<<endl;
+
+          ///if (diffy < 0) diffy += 1;
+          Int offx = 0;//SynthesisUtils::nint (diffx * sampx); // location in
+          Int offy = 0;//SynthesisUtils::nint (diffy * sampy); // oversampling
+          ///          cout<<"  pos= ["<<posx<<", "<<posy<<"]"
+          ///              <<", loc= ["<<locx<<", "<<locy<<"]"
+          ///              <<", off= ["<<offx<<", "<<offy<<"]" << endl;
+          offx += (nConvX-1)/2;
+          offy += (nConvY-1)/2;
+
+          // Scaling with frequency is not necessary (according to Cyril).
+          Double freqFact = 1;   // = cfFreq / vbs.freq_p[visChan];
+          Int fsampx = SynthesisUtils::nint (sampx * freqFact);
+          Int fsampy = SynthesisUtils::nint (sampy * freqFact);
+          Int fsupx  = SynthesisUtils::nint (supx / freqFact);
+          Int fsupy  = SynthesisUtils::nint (supy / freqFact);
+
+          // Only use visibility point if the full support is within grid.
+          if (locx-supx >= 0  &&  locx+supx < nGridX  &&
+              locy-supy >= 0  &&  locy+supy < nGridY) {
+            ///            cout << "in grid"<<endl;
+            // Get pointer to data and flags for this channel.
+            Int doff = (irow * nVisChan + visChan) * nVisPol;
+            const Complex* __restrict__ visPtr  = vbs.visCube_p.data()  + doff;
+            const Bool*    __restrict__ flagPtr = vbs.flagCube_p.data() + doff;
+            if (dopsf) {
+              visPtr = psfValues;
+            }
+
+            // Handle a visibility if not flagged.
+	    for (Int w=0; w<4; w++) {
+	      Double weight_interp(Weights_Lin_Interp[w]);
+            for (Int ipol=0; ipol<nVisPol; ++ipol) {
+              if (! flagPtr[ipol]) {
+                // Map to grid polarization. Only use pol if needed.
+                Int gridPol = polMap_p(ipol);
+                if (gridPol >= 0  &&  gridPol < nGridPol) {
+		  //cout<<"ipol: "<<ipol<<endl;
+                  // Get the offset in the grid data array.
+                  Int goff = (gridChan*nGridPol + gridPol) * nGridX * nGridY;
+                  // Loop over the scaled support.
+                  for (Int sy=-fsupy; sy<=fsupy; ++sy) {
+                    // Get the pointer in the grid for the first x in this y.
+                    T* __restrict__ gridPtr = grid.data() + goff +
+                                              (locy+sy+deltay_pix_interp[w])*nGridX + locx-supx+deltax_pix_interp[w];
+		    //cout<<"goff<<locy<<sy<<nGridX<<locx<<supx "<<goff<<" "<<locy<<" "<<sy<<" "<<nGridX<<" "<<locx<<" "<<supx<<endl;
+                    // Get pointers to the first element to use in the 4
+                    // convolution functions for this channel,pol.
+                    const Complex* __restrict__ cf[4];
+
+                    Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+		    //cout<<"cfoff<<offy<<fsampy<<nConvX<<offx<<fsupx<<fsampx "<<cfoff<<" "<<offy<<" "<<fsampy<<" "<<nConvX<<" "<<offx<<" "<<fsupx<<" "<<fsampx<<endl;
+                    for (int i=0; i<4; ++i) {
+                      cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
+                    }
+                    for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+                      // Loop over polarizations to correct for leakage.
+                      Complex polSum(0,0);
+                      for (Int i=0; i<4; ++i) {
+                        ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
+			//cout<<"visPtr[i] <<" "<< *cf[i] == "<<visPtr[i] <<" "<< *cf[i]<<endl;
+                        polSum += (visPtr[i] * *cf[i])* weight_interp ;
+                        cf[i] += fsampx;
+		      }
+                      ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<visPtr[i]<<endl;
+		      polSum *= (*imgWtPtr);
+                      *gridPtr++ += polSum ;
+                    }
+                  }
+                  sumWtPtr[gridPol+gridChan*nGridPol] += (*imgWtPtr) * weight_interp;
+                } // end if gridPol
+              } // end if !flagPtr
+            } // end for ipol
+	    }
+          } // end if ongrid
+        } // end if gridChan
+        imgWtPtr++;
+      } // end for visChan
+    } // end for inx
+  }
+
+
+  // ================================
+  // "Traditional" gridder
+
   template
   void LofarVisResampler::DataToGridImpl_p(Array<DComplex>& grid, LofarVBStore& vbs,
                                            const Vector<uInt>& rows,
@@ -42,7 +251,6 @@ namespace LOFAR {
 					Matrix<Double>& sumwt,const Bool& dopsf,
 					LofarCFStore& cfs) __restrict__;
 
-
   template <class T>
   void LofarVisResampler::DataToGridImpl_p(Array<T>& grid,  LofarVBStore& vbs,
                                            const Vector<uInt>& rows,
@@ -63,20 +271,29 @@ namespace LOFAR {
     Int nGridY    = grid.shape()[1];
     Int nGridPol  = grid.shape()[2];
     Int nGridChan = grid.shape()[3];
+    //cout<<"nGridPol<<nGridChan "<<nGridPol<<" "<<nGridChan<<endl;
+
     // Get visibility data size.
     Int nVisPol   = vbs.flagCube_p.shape()[0];
     Int nVisChan  = vbs.flagCube_p.shape()[1];
+    //cout<<"nVisPol<<nVisChan "<<nVisPol<<" "<<nVisChan<<endl;
     // Get oversampling and support size.
     Int sampx = SynthesisUtils::nint (cfs.sampling[0]);
     Int sampy = SynthesisUtils::nint (cfs.sampling[1]);
     Int supx = cfs.xSupport[0];
     Int supy = cfs.ySupport[0];
+
     ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
     ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
 
     Double* __restrict__ sumWtPtr = sumwt.data();
     Complex psfValues[4];
     psfValues[0] = psfValues[1] = psfValues[2] = psfValues[3] = Complex(1,0);
+    // psfValues[0] = -Complex(2,0);
+    // psfValues[1] = -Complex(1,1);
+    // psfValues[2] = -Complex(1,-1);
+    // psfValues[3] = -Complex(0,0);
+
 
     // Loop over all visibility rows to process.
     for (Int inx=rbeg; inx<=rend; ++inx) {
@@ -89,7 +306,14 @@ namespace LOFAR {
       // Skip channel if data are not needed.
       for (Int visChan=0; visChan<nVisChan; ++visChan) {
         Int gridChan = chanMap_p[visChan];
+
+
+	// !! dirty trick to select all channels
+	chanMap_p[visChan]=0;
+
+
         if (gridChan >= 0  &&  gridChan < nGridChan) {
+
           // Determine the grid position from the UV coordinates in wavelengths.
           Double recipWvl = vbs.freq_p[visChan] / C::c;
           Double posx = uvwScale_p[0] * uvwPtr[0] * recipWvl + offset_p[0];
@@ -115,8 +339,11 @@ namespace LOFAR {
           Int fsupy  = SynthesisUtils::nint (supy / freqFact);
 
           // Only use visibility point if the full support is within grid.
+
           if (locx-supx >= 0  &&  locx+supx < nGridX  &&
               locy-supy >= 0  &&  locy+supy < nGridY) {
+
+
             ///            cout << "in grid"<<endl;
             // Get pointer to data and flags for this channel.
             Int doff = (irow * nVisChan + visChan) * nVisPol;
@@ -128,9 +355,12 @@ namespace LOFAR {
             // Handle a visibility if not flagged.
             for (Int ipol=0; ipol<nVisPol; ++ipol) {
               if (! flagPtr[ipol]) {
+
                 // Map to grid polarization. Only use pol if needed.
                 Int gridPol = polMap_p(ipol);
                 if (gridPol >= 0  &&  gridPol < nGridPol) {
+
+  		  //cout<<"ipol: "<<ipol<<endl;
                   // Get the offset in the grid data array.
                   Int goff = (gridChan*nGridPol + gridPol) * nGridX * nGridY;
                   // Loop over the scaled support.
@@ -138,25 +368,41 @@ namespace LOFAR {
                     // Get the pointer in the grid for the first x in this y.
                     T* __restrict__ gridPtr = grid.data() + goff +
                                               (locy+sy)*nGridX + locx-supx;
+  		    //cout<<"goff<<locy<<sy<<nGridX<<locx<<supx "<<goff<<" "<<locy<<" "<<sy<<" "<<nGridX<<" "<<locx<<" "<<supx<<endl;
                     // Get pointers to the first element to use in the 4
                     // convolution functions for this channel,pol.
-                    const Complex* __restrict__ cf[4];
+
+		    // Fast version
+
+                    const Complex* __restrict__ cf[1];
                     Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
-                    for (int i=0; i<4; ++i) {
-                      cf[i] = (*cfs.vdata)[gridChan][ipol][i].data() + cfoff;
-                    }
+		    cf[0] = (*cfs.vdata)[gridChan][0][0].data() + cfoff;
                     for (Int sx=-fsupx; sx<=fsupx; ++sx) {
                       // Loop over polarizations to correct for leakage.
                       Complex polSum(0,0);
-                      for (Int i=0; i<nVisPol; ++i) {
-                        ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
-                        polSum += visPtr[i] * *cf[i];
-                        cf[i] += fsampx;
-                      }
-                      ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<visPtr[i]<<endl;
-		      polSum *= *imgWtPtr;
+		      polSum += visPtr[ipol] * *cf[0];
+		      cf[0] += fsampx;
+  		      polSum *= *imgWtPtr;
                       *gridPtr++ += polSum;
                     }
+
+		    // // Full version
+                    // const Complex* __restrict__ cf[4];
+                    // Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+                    // for (int i=0; i<4; ++i) {
+                    //   cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
+                    // }
+                    // for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+                    //   // Loop over polarizations to correct for leakage.
+                    //   Complex polSum(0,0);
+                    //   for (Int i=0; i<4; ++i) {
+                    //     polSum += visPtr[i] * *cf[i];
+                    //     cf[i] += fsampx;
+                    //   }
+  		    //   polSum *= *imgWtPtr;
+                    //   *gridPtr++ += polSum;
+                    // }
+
                   }
                   sumWtPtr[gridPol+gridChan*nGridPol] += *imgWtPtr;
                 } // end if gridPol
@@ -169,6 +415,9 @@ namespace LOFAR {
     } // end for inx
   }
 
+
+
+
   /*
   template <class T>
   void LofarVisResampler::DataToGridImpl_p(Array<T>& grid,  LofarVBStore& vbs,
@@ -232,7 +481,7 @@ namespace LOFAR {
       }
     }
     //cout<<"cfs.vdata= "<<&cfs<<endl;
-      
+
     const Double *freq  = vbs.freq_p.data();
 
     // Cache increment values for adding to grid in gridInc.  This is
@@ -256,7 +505,7 @@ namespace LOFAR {
     // 	      grid(tt)*=1.0;
     // }
 
-    for(Int inx=rbeg; inx< rend; inx++){
+    for(Int inx=rbeg; inx<=rend; inx++){
         Int irow = rows[inx];
 	for(Int ichan=0; ichan< nDataChan; ichan++){
 	    Int achan=chanMap_p[ichan];
@@ -357,6 +606,17 @@ namespace LOFAR {
   */
 
 
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+  //=====================================================================================================================================
+
+
+
+
   //
   //-----------------------------------------------------------------------------------
   // Re-sample VisBuffer from a regular grid (griddedData) (a.k.a. de-gridding)
@@ -390,6 +650,13 @@ namespace LOFAR {
     ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
     ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
 
+    vector< Float > Weights_Lin_Interp;
+    Weights_Lin_Interp.resize(4);
+    vector< Int > deltax_pix_interp;
+    deltax_pix_interp.resize(4);
+    vector< Int > deltay_pix_interp;
+    deltay_pix_interp.resize(4);
+
     // Loop over all visibility rows to process.
     for (Int inx=rbeg; inx<=rend; ++inx) {
       Int irow = rows[inx];
@@ -399,6 +666,11 @@ namespace LOFAR {
       // Skip channel if data are not needed.
       for (Int visChan=0; visChan<nVisChan; ++visChan) {
         Int gridChan = chanMap_p[visChan];
+
+
+	// !! dirty trick to select all channels
+	chanMap_p[visChan]=0;
+
         if (gridChan >= 0  &&  gridChan < nGridChan) {
           // Determine the grid position from the UV coordinates in wavelengths.
           Double recipWvl = vbs.freq_p[visChan] / C::c;
@@ -410,6 +682,12 @@ namespace LOFAR {
           ///if (diffx < 0) diffx += 1;
           Double diffy = locy - posy;
           ///if (diffy < 0) diffy += 1;
+
+	  Weights_Lin_Interp[0]=(1.-diffx)*(1.-diffy);
+	  Weights_Lin_Interp[1]=(1.-diffx)*diffy;
+	  Weights_Lin_Interp[2]=diffx*(1.-diffy);
+	  Weights_Lin_Interp[3]=diffx*diffy;
+
           Int offx = SynthesisUtils::nint (diffx * sampx); // location in
           Int offy = SynthesisUtils::nint (diffy * sampy); // oversampling
           ///          cout<<"  pos= ["<<posx<<", "<<posy<<"]"
@@ -435,9 +713,11 @@ namespace LOFAR {
             // Handle a visibility if not flagged.
             for (Int ipol=0; ipol<nVisPol; ++ipol) {
               if (! flagPtr[ipol]) {
-                visPtr[ipol] = Complex(0,0);
+		visPtr[ipol] = Complex(0,0);
               }
             }
+	    //for (Int w=0; w<4; ++w) {
+	    //  Double weight_interp(Weights_Lin_Interp[w]);
             for (Int ipol=0; ipol<nVisPol; ++ipol) {
               if (! flagPtr[ipol]) {
                 // Map to grid polarization. Only use pol if needed.
@@ -453,31 +733,160 @@ namespace LOFAR {
                                                   (locy+sy)*nGridX + locx-supx;
                     // Get pointers to the first element to use in the 4
                     // convolution functions for this channel,pol.
-                    const Complex* __restrict__ cf[4];
+
+		    // fast version
+                    const Complex* __restrict__ cf[1];
                     Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
-                    for (int i=0; i<4; ++i) {
-                      cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
-                    }
+		    cf[0] = (*cfs.vdata)[gridChan][0][0].data() + cfoff;
                     for (Int sx=-fsupx; sx<=fsupx; ++sx) {
-                      // Loop over polarizations to correct for leakage.
-                      for (Int i=0; i<nGridPol; ++i) {
-                        ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
-                        visPtr[i] += *gridPtr * *cf[i];
-                        cf[i] += fsampx;
-                      }
-                      ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<nvalue<<endl;
+		      visPtr[ipol] += *gridPtr * *cf[0];
+		      cf[0] += fsampx;
                       gridPtr++;
                     }
+
+		    // // Full version
+                    // const Complex* __restrict__ cf[4];
+                    // Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+                    // for (int i=0; i<4; ++i) {
+                    //   cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
+                    // }
+                    // for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+                    //   for (Int i=0; i<nVisPol; ++i) {
+                    //     visPtr[i] += *gridPtr * *cf[i];
+                    //     cf[i] += fsampx;
+                    //   }
+                    //   gridPtr++;
+                    // }
+
                   }
                 } // end if gridPol
               } // end if !flagPtr
             } // end for ipol
           } // end if ongrid
         } // end if gridChan
+	//}
       } // end for visChan
     } // end for inx
   }
 
+  // void LofarVisResampler::lofarGridToData(LofarVBStore& vbs,
+  //                                         const Array<Complex>& grid,
+  //                                         const Vector<uInt>& rows,
+  //                                         Int rbeg, Int rend,
+  //                                         LofarCFStore& cfs)
+  // {
+  //   // grid[nx,ny,np,nf]
+  //   // vbs.data[np,nf,nrow]
+  //   // cfs[nmx,nmy,nf,ncx,ncy]   (mueller,freq,convsize)
+
+  //   // Get size of convolution functions.
+  //   Int nConvX = (*(cfs.vdata))[0][0][0].shape()[0];
+  //   Int nConvY = (*(cfs.vdata))[0][0][0].shape()[1];
+  //   // Get size of grid.
+  //   Int nGridX    = grid.shape()[0];
+  //   Int nGridY    = grid.shape()[1];
+  //   Int nGridPol  = grid.shape()[2];
+  //   Int nGridChan = grid.shape()[3];
+  //   // Get visibility data size.
+  //   Int nVisPol   = vbs.flagCube_p.shape()[0];
+  //   Int nVisChan  = vbs.flagCube_p.shape()[1];
+  //   // Get oversampling and support size.
+  //   Int sampx = SynthesisUtils::nint (cfs.sampling[0]);
+  //   Int sampy = SynthesisUtils::nint (cfs.sampling[1]);
+  //   Int supx = cfs.xSupport[0];
+  //   Int supy = cfs.ySupport[0];
+  //   ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
+  //   ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
+
+  //   // Loop over all visibility rows to process.
+  //   for (Int inx=rbeg; inx<=rend; ++inx) {
+  //     Int irow = rows[inx];
+  //     const Double*  __restrict__ uvwPtr   = vbs.uvw_p.data() + irow*3;
+  //     // Loop over all channels in the visibility data.
+  //     // Map the visibility channel to the grid channel.
+  //     // Skip channel if data are not needed.
+  //     for (Int visChan=0; visChan<nVisChan; ++visChan) {
+  //       Int gridChan = chanMap_p[visChan];
+  //       if (gridChan >= 0  &&  gridChan < nGridChan) {
+  //         // Determine the grid position from the UV coordinates in wavelengths.
+  //         Double recipWvl = vbs.freq_p[visChan] / C::c;
+  //         Double posx = uvwScale_p[0] * uvwPtr[0] * recipWvl + offset_p[0];
+  //         Double posy = uvwScale_p[1] * uvwPtr[1] * recipWvl + offset_p[1];
+  //         Int locx = SynthesisUtils::nint (posx);    // location in grid
+  //         Int locy = SynthesisUtils::nint (posy);
+  //         Double diffx = locx - posx;
+  //         ///if (diffx < 0) diffx += 1;
+  //         Double diffy = locy - posy;
+  //         ///if (diffy < 0) diffy += 1;
+  //         Int offx = SynthesisUtils::nint (diffx * sampx); // location in
+  //         Int offy = SynthesisUtils::nint (diffy * sampy); // oversampling
+  //         ///          cout<<"  pos= ["<<posx<<", "<<posy<<"]"
+  //         ///              <<", loc= ["<<locx<<", "<<locy<<"]"
+  //         ///              <<", off= ["<<offx<<", "<<offy<<"]" << endl;
+  //         offx += (nConvX-1)/2;
+  //         offy += (nConvY-1)/2;
+  //         // Scaling with frequency is not necessary (according to Cyril).
+  //         Double freqFact = 1;   // = cfFreq / vbs.freq_p[visChan];
+  //         Int fsampx = SynthesisUtils::nint (sampx * freqFact);
+  //         Int fsampy = SynthesisUtils::nint (sampy * freqFact);
+  //         Int fsupx  = SynthesisUtils::nint (supx / freqFact);
+  //         Int fsupy  = SynthesisUtils::nint (supy / freqFact);
+
+  //         // Only use visibility point if the full support is within grid.
+  //         if (locx-supx >= 0  &&  locx+supx < nGridX  &&
+  //             locy-supy >= 0  &&  locy+supy < nGridY) {
+  //           ///            cout << "in grid"<<endl;
+  //           // Get pointer to data and flags for this channel.
+  //           Int doff = (irow * nVisChan + visChan) * nVisPol;
+  //           Complex* __restrict__ visPtr  = vbs.visCube_p.data()  + doff;
+  //           const Bool*    __restrict__ flagPtr = vbs.flagCube_p.data() + doff;
+  //           // Handle a visibility if not flagged.
+  //           for (Int ipol=0; ipol<nVisPol; ++ipol) {
+  //             if (! flagPtr[ipol]) {
+  //               visPtr[ipol] = Complex(0,0);
+  //             }
+  //           }
+  //           for (Int ipol=0; ipol<nVisPol; ++ipol) {
+  //             if (! flagPtr[ipol]) {
+  //               // Map to grid polarization. Only use pol if needed.
+  //               Int gridPol = polMap_p(ipol);
+  //               if (gridPol >= 0  &&  gridPol < nGridPol) {
+  //                 /// Complex norm(0,0);
+  //                 // Get the offset in the grid data array.
+  //                 Int goff = (gridChan*nGridPol + gridPol) * nGridX * nGridY;
+  //                 // Loop over the scaled support.
+  //                 for (Int sy=-fsupy; sy<=fsupy; ++sy) {
+  //                   // Get the pointer in the grid for the first x in this y.
+  //                   const Complex* __restrict__ gridPtr = grid.data() + goff +
+  //                                                 (locy+sy)*nGridX + locx-supx;
+  //                   // Get pointers to the first element to use in the 4
+  //                   // convolution functions for this channel,pol.
+  //                   const Complex* __restrict__ cf[4];
+  //                   Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+  //                   for (int i=0; i<4; ++i) {
+  //                     cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
+  //                   }
+  //                   for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+  //                     // Loop over polarizations to correct for leakage.
+  //                     for (Int i=0; i<nVisPol; ++i) {
+  //                       ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
+  //                       visPtr[i] += *gridPtr * *cf[i];
+  //                       cf[i] += fsampx;
+  //                     }
+  //                     ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<nvalue<<endl;
+  //                     gridPtr++;
+  //                   }
+  //                 }
+  //               } // end if gridPol
+  //             } // end if !flagPtr
+  //           } // end for ipol
+  //         } // end if ongrid
+  //       } // end if gridChan
+  //     } // end for visChan
+  //   } // end for inx
+  // }
+
+
   /*
   void LofarVisResampler::lofarGridToData(LofarVBStore& vbs,
                                           const Array<Complex>& grid,
@@ -536,14 +945,14 @@ namespace LOFAR {
       //store2(im,"Aterm-ch"+String::toString(i)+".img");
       }
     }
-    
-    
+
+
     // Vector<Double> UVWSCALE_MOI(uvwScale_p*1.4);
     // Vector<Double> UVWOFF_MOI(offset_p);
     // UVWOFF_MOI(0)=320;
     // UVWOFF_MOI(1)=320;
     // UVWOFF_MOI(2)=0;
-    
+
     Double *freq=vbs.freq_p.getStorage(Dummy);
 
     Matrix<Float>&  imagingWeight=vbs.imagingWeight_p;
@@ -557,7 +966,7 @@ namespace LOFAR {
     cacheAxisIncrements(grid.shape().asVector(), gridInc_p);
     cacheAxisIncrements(cfShape, cfInc_p);
 
-    for(Int inx=rbeg; inx<rend; inx++) {
+    for(Int inx=rbeg; inx<=rend; inx++) {
         Int irow = rows[inx];
 
 	for (Int ichan=0; ichan < nDataChan; ichan++) {
@@ -574,7 +983,7 @@ namespace LOFAR {
 	    uvwScale_p,offset_p,sampling);
 	    //sgrid(pos,loc,off,phasor,irow,uvw,dphase_p[irow],freq[ichan],
 	//	  UVWSCALE_MOI,UVWOFF_MOI,sampling);
-	    
+
 
 
 	    iloc[2]=max(0, min(nw-1, loc[2]));
@@ -651,31 +1060,36 @@ namespace LOFAR {
     IPosition start(vbDataShape), last(vbDataShape);
     start=0; start(2)=rbeg;
     last(2)=rend; //last=last-1;
+    //cout<<"vbDataShape "<<vbDataShape<<" ,last "<<" ,start "<<start<<" ,vbs.modelCube_p "<< (vbs.modelCube_p).shape() << endl;
 
     //cout<<"//////////////////// Compuute residual!!!!!!"<<"vbs.useCorrected_p"<<vbs.useCorrected_p<<endl;
 
+
+
     if (!vbs.useCorrected_p)
       {
     	for(uInt ichan = start(0); ichan < last(0); ichan++)
     	  for(uInt ipol = start(1); ipol < last(1); ipol++)
     	    for(uInt irow = start(2); irow < last(2); irow++)
     	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.visCube_p(ichan,ipol,irow);
-	
+
       }
     else
       {
-    	for(uInt ichan = start(0); ichan < last(0); ichan++)
-    	  for(uInt ipol = start(1); ipol < last(1); ipol++)
-    	    for(uInt irow = start(2); irow < last(2); irow++){
+    	for(uInt ichan = start(0); ichan < last(0); ichan++){
+	  //cout<< ichan << vbs.modelCube_p(ichan,0,347) <<vbs.correctedCube_p(ichan,0,347)<< endl;
+    	  for(uInt ipol = start(1); ipol < last(1); ipol++){
+	    for(uInt irow = start(2); irow < last(2); irow++){
     	      //cout<<"===="<<endl;
 	      //if(!(abs(vbs.modelCube_p(ichan,ipol,irow))==0.)){cout<<ipol<<" "<<ichan<<" "<<irow<<" "<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;};
-    	      
+
 	      //if(!(abs(vbs.modelCube_p(ichan,ipol,irow))==0.)){cout<<"data "<<ipol<<" "<<ichan<<" "<<irow<<" "<<vbs.modelCube_p(ichan,ipol,irow)<<" "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;};
-	 
+
     	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.correctedCube_p(ichan,ipol,irow);
     	      //cout<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;
-    	    };
-	
+    	    }
+	  }
+	}
       }
 
     // if (!vbs.useCorrected_p)
@@ -684,7 +1098,7 @@ namespace LOFAR {
     // 	  for(uInt ipol = start(1); ipol < last(1); ipol++)
     // 	    for(uInt irow = start(2); irow < last(2); irow++)
     // 	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.visCube_p(ichan,ipol,irow);
-	
+
     //   }
     // else
     //   {
@@ -696,7 +1110,7 @@ namespace LOFAR {
     // 	      vbs.correctedCube_p(ichan,ipol,irow) = vbs.correctedCube_p(ichan,ipol,irow) - vbs.modelCube_p(ichan,ipol,irow);
     // 	      //cout<<vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.modelCube_p(ichan,ipol,irow)<<endl;
     // 	    };
-	
+
     //   }
 
 
diff --git a/CEP/Imager/LofarFT/src/LofarVisResamplerOld.cc b/CEP/Imager/LofarFT/src/LofarVisResamplerOld.cc
new file mode 100644
index 0000000000000000000000000000000000000000..15808792852dcfdc173ed1373d15ced6aa5ead86
--- /dev/null
+++ b/CEP/Imager/LofarFT/src/LofarVisResamplerOld.cc
@@ -0,0 +1,741 @@
+//# LofarVisResamplerOld.cc: Implementation of the LofarVisResamplerOld class
+//#
+//# Copyright (C) 2011
+//# 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 <LofarFT/LofarVisResamplerOld.h>
+#include <synthesis/MeasurementComponents/Utils.h>
+#include <coordinates/Coordinates/SpectralCoordinate.h>
+#include <coordinates/Coordinates/CoordinateSystem.h>
+#include<cassert>
+
+namespace LOFAR {
+
+    // Instantiate both templates.
+  template
+  void LofarVisResamplerOld::DataToGridImpl_p(Array<DComplex>& grid, LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+					Matrix<Double>& sumwt,const Bool& dopsf,
+					LofarCFStore& cfs) __restrict__;
+  template
+  void LofarVisResamplerOld::DataToGridImpl_p(Array<Complex>& grid, LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+					Matrix<Double>& sumwt,const Bool& dopsf,
+					LofarCFStore& cfs) __restrict__;
+
+
+  template <class T>
+  void LofarVisResamplerOld::DataToGridImpl_p(Array<T>& grid,  LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+                                           Matrix<Double>& sumwt,
+                                           const Bool& dopsf,
+                                           LofarCFStore& cfs) __restrict__
+  {
+    // grid[nx,ny,np,nf]
+    // vbs.data[np,nf,nrow]
+    // cfs[nmx,nmy,nf,ncx,ncy]   (mueller,freq,convsize)
+
+    // Get size of convolution functions.
+    Int nConvX = (*(cfs.vdata))[0][0][0].shape()[0];
+    Int nConvY = (*(cfs.vdata))[0][0][0].shape()[1];
+    // Get size of grid.
+    Int nGridX    = grid.shape()[0];
+    Int nGridY    = grid.shape()[1];
+    Int nGridPol  = grid.shape()[2];
+    Int nGridChan = grid.shape()[3];
+    // Get visibility data size.
+    Int nVisPol   = vbs.flagCube_p.shape()[0];
+    Int nVisChan  = vbs.flagCube_p.shape()[1];
+    // Get oversampling and support size.
+    Int sampx = SynthesisUtils::nint (cfs.sampling[0]);
+    Int sampy = SynthesisUtils::nint (cfs.sampling[1]);
+    Int supx = cfs.xSupport[0];
+    Int supy = cfs.ySupport[0];
+    ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
+    ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
+
+    Double* __restrict__ sumWtPtr = sumwt.data();
+    Complex psfValues[4];
+    psfValues[0] = psfValues[1] = psfValues[2] = psfValues[3] = Complex(1,0);
+
+    // Loop over all visibility rows to process.
+    for (Int inx=rbeg; inx<=rend; ++inx) {
+      Int irow = rows[inx];
+      const Double*  __restrict__ uvwPtr   = vbs.uvw_p.data() + irow*3;
+      const Float*   __restrict__ imgWtPtr = vbs.imagingWeight_p.data() +
+                                             irow * nVisChan;
+      // Loop over all channels in the visibility data.
+      // Map the visibility channel to the grid channel.
+      // Skip channel if data are not needed.
+      for (Int visChan=0; visChan<nVisChan; ++visChan) {
+        Int gridChan = chanMap_p[visChan];
+        if (gridChan >= 0  &&  gridChan < nGridChan) {
+          // Determine the grid position from the UV coordinates in wavelengths.
+          Double recipWvl = vbs.freq_p[visChan] / C::c;
+          Double posx = uvwScale_p[0] * uvwPtr[0] * recipWvl + offset_p[0];
+          Double posy = uvwScale_p[1] * uvwPtr[1] * recipWvl + offset_p[1];
+          Int locx = SynthesisUtils::nint (posx);    // location in grid
+          Int locy = SynthesisUtils::nint (posy);
+          Double diffx = locx - posx;
+          ///if (diffx < 0) diffx += 1;
+          Double diffy = locy - posy;
+          ///if (diffy < 0) diffy += 1;
+          Int offx = SynthesisUtils::nint (diffx * sampx); // location in
+          Int offy = SynthesisUtils::nint (diffy * sampy); // oversampling
+          ///          cout<<"  pos= ["<<posx<<", "<<posy<<"]"
+          ///              <<", loc= ["<<locx<<", "<<locy<<"]"
+          ///              <<", off= ["<<offx<<", "<<offy<<"]" << endl;
+          offx += (nConvX-1)/2;
+          offy += (nConvY-1)/2;
+          // Scaling with frequency is not necessary (according to Cyril).
+          Double freqFact = 1;   // = cfFreq / vbs.freq_p[visChan];
+          Int fsampx = SynthesisUtils::nint (sampx * freqFact);
+          Int fsampy = SynthesisUtils::nint (sampy * freqFact);
+          Int fsupx  = SynthesisUtils::nint (supx / freqFact);
+          Int fsupy  = SynthesisUtils::nint (supy / freqFact);
+
+          // Only use visibility point if the full support is within grid.
+          if (locx-supx >= 0  &&  locx+supx < nGridX  &&
+              locy-supy >= 0  &&  locy+supy < nGridY) {
+            ///            cout << "in grid"<<endl;
+            // Get pointer to data and flags for this channel.
+            Int doff = (irow * nVisChan + visChan) * nVisPol;
+            const Complex* __restrict__ visPtr  = vbs.visCube_p.data()  + doff;
+            const Bool*    __restrict__ flagPtr = vbs.flagCube_p.data() + doff;
+            if (dopsf) {
+              visPtr = psfValues;
+            }
+            // Handle a visibility if not flagged.
+            for (Int ipol=0; ipol<nVisPol; ++ipol) {
+              if (! flagPtr[ipol]) {
+                // Map to grid polarization. Only use pol if needed.
+                Int gridPol = polMap_p(ipol);
+                if (gridPol >= 0  &&  gridPol < nGridPol) {
+                  // Get the offset in the grid data array.
+                  Int goff = (gridChan*nGridPol + gridPol) * nGridX * nGridY;
+                  // Loop over the scaled support.
+                  for (Int sy=-fsupy; sy<=fsupy; ++sy) {
+                    // Get the pointer in the grid for the first x in this y.
+                    T* __restrict__ gridPtr = grid.data() + goff +
+                                              (locy+sy)*nGridX + locx-supx;
+                    // Get pointers to the first element to use in the 4
+                    // convolution functions for this channel,pol.
+                    const Complex* __restrict__ cf[4];
+                    Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+                    for (int i=0; i<4; ++i) {
+                      cf[i] = (*cfs.vdata)[gridChan][ipol][i].data() + cfoff;
+                    }
+                    for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+                      // Loop over polarizations to correct for leakage.
+                      Complex polSum(0,0);
+                      for (Int i=0; i<nVisPol; ++i) {
+                        ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
+                        polSum += visPtr[i] * *cf[i];
+                        cf[i] += fsampx;
+                      }
+                      ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<visPtr[i]<<endl;
+		      polSum *= *imgWtPtr;
+                      *gridPtr++ += polSum;
+                    }
+                  }
+                  sumWtPtr[gridPol+gridChan*nGridPol] += *imgWtPtr;
+                } // end if gridPol
+              } // end if !flagPtr
+            } // end for ipol
+          } // end if ongrid
+        } // end if gridChan
+        imgWtPtr++;
+      } // end for visChan
+    } // end for inx
+  }
+
+  /*
+  template <class T>
+  void LofarVisResamplerOld::DataToGridImpl_p(Array<T>& grid,  LofarVBStore& vbs,
+                                           const Vector<uInt>& rows,
+                                           Int rbeg, Int rend,
+                                           Matrix<Double>& sumwt,
+                                           const Bool& dopsf,
+                                           LofarCFStore& cfs)
+  {
+    Vector<Float> sampling(2);
+    Vector<Double> pos(3);
+    Vector<Int> support(2),loc(3), off(3), iloc(4),tiloc(4);
+    Vector<Int> scaledSampling(2), scaledSupport(2);
+    Vector<Int> igrdpos(4);
+    //Float sampling[2];
+    //Double pos[3]
+    //  Int support[2], loc[3], off[3], iloc[4], tiloc[4];
+    //Int scaledSampling[2], scledSupport[2];
+    //Int igrdpos[4];
+
+    Double norm=0.0;
+    Complex phasor, nvalue, wt;
+    // A conv. fucntion per pol.
+    // For time being only one channel.
+    Vector<Int> cfShape(4,1);
+    cfShape[0] = (*(cfs.vdata))[0][0][0].shape()[0];
+    cfShape[1] = (*(cfs.vdata))[0][0][0].shape()[1];
+    Vector<Int> convOrigin = (cfShape-1)/2;
+
+    Int nx = grid.shape()[0];
+    Int ny = grid.shape()[1];
+    Int nw = 1;
+    Int nGridPol = grid.shape()[2];
+    Int nGridChan = grid.shape()[3];
+
+    Int nDataPol  = vbs.flagCube_p.shape()[0];
+    Int nDataChan = vbs.flagCube_p.shape()[1];
+
+    sampling[0] = sampling[1] = cfs.sampling[0];
+    support[0] = cfs.xSupport[0];
+    support[1] = cfs.ySupport[0];
+
+    T* __restrict__ gridStore = grid.data();
+    const Int * __restrict__ iPosPtr = igrdpos.data();
+    // const Complex* __restrict__ convFuncV[4];
+    // for (int i=0; i<4; ++i) {
+    //   convFuncV[i] = (*(cfs.vdata))[0][i][i].data();
+    // }
+
+    const Complex* __restrict__ convFuncV[4][4];
+    for (int i=0; i<4; ++i) {
+      for (int j=0; j<4; ++j) {
+        const Array<Complex>& conv = (*(cfs.vdata))[0][j][i];
+        if (conv.empty()) {
+          convFuncV[j][i] = 0;
+        } else {
+          convFuncV[j][i] = conv.data();
+        }
+      //Matrix<Complex> im((*(cfs.vdata))[0][i][i]);
+      //store2(im,"Aterm-ch"+String::toString(i)+".img");
+      }
+    }
+    //cout<<"cfs.vdata= "<<&cfs<<endl;
+      
+    const Double *freq  = vbs.freq_p.data();
+
+    // Cache increment values for adding to grid in gridInc.  This is
+    // supplied to addTo4DArray later.
+    cacheAxisIncrements(grid.shape().asVector(), gridInc_p);
+    // Cache the CF related increments internally in
+    // VisibilityResamplerBase for use in getFrom4DArray later.
+    cacheAxisIncrements(cfShape, cfInc_p);
+
+    const Bool * __restrict__ flagCube_ptr=vbs.flagCube_p.data();
+    const Float * __restrict__ imgWts_ptr = vbs.imagingWeight_p.data();
+    const Complex * __restrict__ visCube_ptr = vbs.visCube_p.data();
+    Double * __restrict__ sumWt_ptr = sumwt.data();
+
+    // {
+    //   IPosition tt(4);
+    //   for(tt(0)=0;tt(0)<grid.shape()(0);tt(0)++)
+    // 	for(tt(1)=0;tt(1)<grid.shape()(1);tt(1)++)
+    // 	  for(tt(2)=0;tt(2)<grid.shape()(2);tt(2)++)
+    // 	    for(tt(3)=0;tt(3)<grid.shape()(3);tt(3)++)
+    // 	      grid(tt)*=1.0;
+    // }
+
+    for(Int inx=rbeg; inx< rend; inx++){
+        Int irow = rows[inx];
+	for(Int ichan=0; ichan< nDataChan; ichan++){
+	    Int achan=chanMap_p[ichan];
+
+	    if((achan>=0) && (achan<nGridChan)) {
+
+	      scaledSampling[0] = SynthesisUtils::nint(sampling[0]);
+	      scaledSampling[1] = SynthesisUtils::nint(sampling[1]);
+	      scaledSupport[0]  = support[0];
+	      scaledSupport[1]  = support[1];
+
+	      sgrid(pos,loc,off, phasor, irow,
+		    vbs.uvw_p, dphase_p[irow], freq[ichan],
+		    uvwScale_p, offset_p, sampling);
+
+///	      cout<<"  pos= ["<<pos[0]<<", "<<pos[1]<<"]"
+///                  <<", loc= ["<<loc[0]<<", "<<loc[1]<<", "<<loc[2]<<"]"
+///                  <<", off= ["<<off[0]<<", "<<off[1]<<", "<<off[2]<<"] "
+///                  << nx << ' '<<ny<<' '<<support[0]<<' '<<support[1]
+///                  <<endl;
+
+	      iloc[2]=max(0, min(nw-1, loc[2]));
+
+	      //cout<< nx <<" "<<ny<<" "<<nw<<" "<<loc<<" "<< support<<" "<<onGrid(nx, ny, nw, loc, support)<<endl;
+	      //assert(false);
+	      if (onGrid(nx, ny, nw, loc, support)) {
+///                cout << "on grid"<<endl;
+
+		for(Int ipol=0; ipol< nDataPol; ipol++) {
+		  //		  if((!flagCube(ipol,ichan,irow))){
+		  if((!(*(flagCube_ptr + ipol + ichan*nDataPol + irow*nDataPol*nDataChan)))){
+		    Int apol=polMap_p(ipol);
+		    if ((apol>=0) && (apol<nGridPol)) {
+		      igrdpos[2]=apol; igrdpos[3]=achan;
+
+		      norm=0.0;
+		      //int ConjPlane = cfMap_p[ipol];
+		      //int PolnPlane = conjCFMap_p[ipol];
+
+		      iloc[3]=ipol; //PolnPlane;
+
+		      //cout<<"Weight= "<<Complex(*(imgWts_ptr + ichan + irow*nDataChan))<<", Vis= "<<(*(visCube_ptr+ipol+ichan*nDataPol+irow*nDataChan*nDataPol)*phasor)<<endl;
+
+
+		      if(dopsf)  nvalue=Complex(*(imgWts_ptr + ichan + irow*nDataChan));
+		      else	 nvalue= *(imgWts_ptr+ichan+irow*nDataChan)*
+		      		   (*(visCube_ptr+ipol+ichan*nDataPol+irow*nDataChan*nDataPol)*phasor);
+
+
+		      //cout<<"nvalue: "<<nvalue<<endl;
+
+		      for(Int iy=-scaledSupport[1]; iy <= scaledSupport[1]; iy++)
+			{
+			  iloc[1]=(Int)(scaledSampling[1]*iy+off[1]);
+			  igrdpos[1]=loc[1]+iy;
+			  for(Int ix=-scaledSupport[0]; ix <= scaledSupport[0]; ix++)
+			    {
+			      iloc[0]=(Int)(scaledSampling[0]*ix+off[0]);
+			      tiloc=iloc;
+                              if (reindex(iloc,tiloc, 0, 1,
+                                          convOrigin, cfShape)) {
+                                //cout << "reindexed"<<iloc<<tiloc<<cfShape<<endl;
+
+                                for (int ic=0; ic<4; ++ic) {
+                                  if (convFuncV[iloc[3]][ic]) {
+				    //cout<<ic<<" "<<iloc[3]<<" "<<tiloc[0]<<endl;
+                                    wt = convFuncV[iloc[3]][ic][tiloc[1]*cfInc_p[1]+tiloc[0]];
+///                                    cout<<"cf="<<iloc[3]<<' '<<tiloc[1]*cfInc_p[1]+tiloc[0]<<',';
+				    //cout<<wt<<endl;
+				    //wt=convFuncV[iloc[3]][tiloc[1]*cfInc_p[1]+tiloc[0]];
+				//wt = (*(cfs.vdata))[0][iloc[3]][iloc[3]](tiloc[0],tiloc[1]);
+                                ///                              wt = getFrom4DArray(convFuncV, tiloc,cfInc_p);
+				    igrdpos[0]=loc[0]+ix;
+				//				  grid(igrdpos) += nvalue*wt;
+				    //cout<<igrdpos[0]<<endl;
+				    //cout<<"ipol="<<ipol<<", iloc[1]="<<iloc[1]<<", cfInc_p[1]="<<cfInc_p[1]<<", iloc[0]="<<iloc[0]<<", wt="<<wt<<", vis="<<nvalue<<endl;
+                                //assert (wt > 1e-10  &&  wt < 1);
+				// The following uses raw index on the 4D grid
+///                                    cout << "add " << igrdpos<< gridInc_p
+///                                         << igrdpos[0] + igrdpos[1]*gridInc_p[1] + igrdpos[2]*gridInc_p[2] +igrdpos[3]*gridInc_p[3]<<endl;
+                                    addTo4DArray(gridStore,iPosPtr,gridInc_p, nvalue,wt);
+				//				  norm+=real(wt);
+				  }
+				}
+                              }
+			    }
+			}
+		      //		      sumwt(apol,achan)+=imagingWeight(ichan,irow);// *norm;
+		      *(sumWt_ptr+apol+achan*nGridChan)+= *(imgWts_ptr+ichan+irow*nDataChan);
+		    }
+		  }
+		}
+	      }
+	    }
+        }
+    }
+  }
+  */
+
+
+  //
+  //-----------------------------------------------------------------------------------
+  // Re-sample VisBuffer from a regular grid (griddedData) (a.k.a. de-gridding)
+  //
+  void LofarVisResamplerOld::lofarGridToData(LofarVBStore& vbs,
+                                          const Array<Complex>& grid,
+                                          const Vector<uInt>& rows,
+                                          Int rbeg, Int rend,
+                                          LofarCFStore& cfs)
+  {
+    // grid[nx,ny,np,nf]
+    // vbs.data[np,nf,nrow]
+    // cfs[nmx,nmy,nf,ncx,ncy]   (mueller,freq,convsize)
+
+    // Get size of convolution functions.
+    Int nConvX = (*(cfs.vdata))[0][0][0].shape()[0];
+    Int nConvY = (*(cfs.vdata))[0][0][0].shape()[1];
+    // Get size of grid.
+    Int nGridX    = grid.shape()[0];
+    Int nGridY    = grid.shape()[1];
+    Int nGridPol  = grid.shape()[2];
+    Int nGridChan = grid.shape()[3];
+    // Get visibility data size.
+    Int nVisPol   = vbs.flagCube_p.shape()[0];
+    Int nVisChan  = vbs.flagCube_p.shape()[1];
+    // Get oversampling and support size.
+    Int sampx = SynthesisUtils::nint (cfs.sampling[0]);
+    Int sampy = SynthesisUtils::nint (cfs.sampling[1]);
+    Int supx = cfs.xSupport[0];
+    Int supy = cfs.ySupport[0];
+    ///AlwaysAssert ((2*supx+1)*sampx == nConvX, AipsError);
+    ///AlwaysAssert ((2*supy+1)*sampy == nConvY, AipsError);
+
+    // Loop over all visibility rows to process.
+    for (Int inx=rbeg; inx<=rend; ++inx) {
+      Int irow = rows[inx];
+      const Double*  __restrict__ uvwPtr   = vbs.uvw_p.data() + irow*3;
+      // Loop over all channels in the visibility data.
+      // Map the visibility channel to the grid channel.
+      // Skip channel if data are not needed.
+      for (Int visChan=0; visChan<nVisChan; ++visChan) {
+        Int gridChan = chanMap_p[visChan];
+        if (gridChan >= 0  &&  gridChan < nGridChan) {
+          // Determine the grid position from the UV coordinates in wavelengths.
+          Double recipWvl = vbs.freq_p[visChan] / C::c;
+          Double posx = uvwScale_p[0] * uvwPtr[0] * recipWvl + offset_p[0];
+          Double posy = uvwScale_p[1] * uvwPtr[1] * recipWvl + offset_p[1];
+          Int locx = SynthesisUtils::nint (posx);    // location in grid
+          Int locy = SynthesisUtils::nint (posy);
+          Double diffx = locx - posx;
+          ///if (diffx < 0) diffx += 1;
+          Double diffy = locy - posy;
+          ///if (diffy < 0) diffy += 1;
+          Int offx = SynthesisUtils::nint (diffx * sampx); // location in
+          Int offy = SynthesisUtils::nint (diffy * sampy); // oversampling
+          ///          cout<<"  pos= ["<<posx<<", "<<posy<<"]"
+          ///              <<", loc= ["<<locx<<", "<<locy<<"]"
+          ///              <<", off= ["<<offx<<", "<<offy<<"]" << endl;
+          offx += (nConvX-1)/2;
+          offy += (nConvY-1)/2;
+          // Scaling with frequency is not necessary (according to Cyril).
+          Double freqFact = 1;   // = cfFreq / vbs.freq_p[visChan];
+          Int fsampx = SynthesisUtils::nint (sampx * freqFact);
+          Int fsampy = SynthesisUtils::nint (sampy * freqFact);
+          Int fsupx  = SynthesisUtils::nint (supx / freqFact);
+          Int fsupy  = SynthesisUtils::nint (supy / freqFact);
+
+          // Only use visibility point if the full support is within grid.
+          if (locx-supx >= 0  &&  locx+supx < nGridX  &&
+              locy-supy >= 0  &&  locy+supy < nGridY) {
+            ///            cout << "in grid"<<endl;
+            // Get pointer to data and flags for this channel.
+            Int doff = (irow * nVisChan + visChan) * nVisPol;
+            Complex* __restrict__ visPtr  = vbs.visCube_p.data()  + doff;
+            const Bool*    __restrict__ flagPtr = vbs.flagCube_p.data() + doff;
+            // Handle a visibility if not flagged.
+            for (Int ipol=0; ipol<nVisPol; ++ipol) {
+              if (! flagPtr[ipol]) {
+                visPtr[ipol] = Complex(0,0);
+              }
+            }
+            for (Int ipol=0; ipol<nVisPol; ++ipol) {
+              if (! flagPtr[ipol]) {
+                // Map to grid polarization. Only use pol if needed.
+                Int gridPol = polMap_p(ipol);
+                if (gridPol >= 0  &&  gridPol < nGridPol) {
+                  /// Complex norm(0,0);
+                  // Get the offset in the grid data array.
+                  Int goff = (gridChan*nGridPol + gridPol) * nGridX * nGridY;
+                  // Loop over the scaled support.
+                  for (Int sy=-fsupy; sy<=fsupy; ++sy) {
+                    // Get the pointer in the grid for the first x in this y.
+                    const Complex* __restrict__ gridPtr = grid.data() + goff +
+                                                  (locy+sy)*nGridX + locx-supx;
+                    // Get pointers to the first element to use in the 4
+                    // convolution functions for this channel,pol.
+                    const Complex* __restrict__ cf[4];
+                    Int cfoff = (offy + sy*fsampy)*nConvX + offx - fsupx*fsampx;
+                    for (int i=0; i<4; ++i) {
+                      cf[i] = (*cfs.vdata)[gridChan][i][ipol].data() + cfoff;
+                    }
+                    for (Int sx=-fsupx; sx<=fsupx; ++sx) {
+                      // Loop over polarizations to correct for leakage.
+                      for (Int i=0; i<nGridPol; ++i) {
+                        ///                        cout<<"cf="<< cf[i]-(*cfs.vdata)[gridChan][ipol][i].data()<<',';
+                        visPtr[i] += *gridPtr * *cf[i];
+                        cf[i] += fsampx;
+                      }
+                      ///                      cout<<"  g="<<gridPtr-grid.data()<<' '<<nvalue<<endl;
+                      gridPtr++;
+                    }
+                  }
+                } // end if gridPol
+              } // end if !flagPtr
+            } // end for ipol
+          } // end if ongrid
+        } // end if gridChan
+      } // end for visChan
+    } // end for inx
+  }
+
+  /*
+  void LofarVisResamplerOld::lofarGridToData(LofarVBStore& vbs,
+                                          const Array<Complex>& grid,
+                                          const Vector<uInt>& rows,
+                                          Int rbeg, Int rend,
+                                          LofarCFStore& cfs)
+  {
+    Int nDataChan, nDataPol, nGridPol, nGridChan, nx, ny,nw;
+    Int achan, apol, PolnPlane, ConjPlane;
+    Vector<Float> sampling(2);
+    Vector<Int> support(2),loc(3), off(3), iloc(4),tiloc(4), scaledSampling(2), scaledSupport(2);
+    Vector<Double> pos(3);
+
+    IPosition grdpos(4);
+
+    Complex phasor, nvalue, norm, wt;
+    Vector<Int> cfShape(4,1);
+    cfShape[0] = (*(cfs.vdata))[0][0][0].shape()[0];
+    cfShape[1] = (*(cfs.vdata))[0][0][0].shape()[1];
+    //    Vector<Int> convOrigin = (cfShape-1)/2;
+    Vector<Int> convOrigin = (cfShape-1)/2;
+    Double sinDPA=0.0, cosDPA=1.0;
+
+    nx       = grid.shape()[0]; ny        = grid.shape()[1];
+    nw       = cfShape[2];
+    nGridPol = grid.shape()[2]; nGridChan = grid.shape()[3];
+
+    nDataPol  = vbs.flagCube_p.shape()[0];
+    nDataChan = vbs.flagCube_p.shape()[1];
+
+    sampling[0] = sampling[1] = cfs.sampling[0];
+    support(0) = cfs.xSupport[0];
+    support(1) = cfs.ySupport[0];
+    //
+    // The following code reduces most array accesses to the simplest
+    // possible to improve performance.  However this made no
+    // difference in the run-time performance compared to Vector,
+    // Matrix and Cube indexing.
+    //
+    Bool Dummy;
+    const Complex *gridStore = grid.getStorage(Dummy);
+    Vector<Int> igrdpos(4);
+    const Int *iPosPtr = igrdpos.getStorage(Dummy);
+
+    // Take all Mueller elements into account.
+    const Complex* __restrict__ convFuncV[4][4];
+    for (int i=0; i<4; ++i) {
+      for (int j=0; j<4; ++j) {
+        const Array<Complex>& conv = (*(cfs.vdata))[0][j][i];
+        if (conv.empty()) {
+          convFuncV[j][i] = 0;
+        } else {
+          convFuncV[j][i] = conv.data();
+        }
+      //Matrix<Complex> im((*(cfs.vdata))[0][i][i]);
+      //store2(im,"Aterm-ch"+String::toString(i)+".img");
+      }
+    }
+    
+    
+    // Vector<Double> UVWSCALE_MOI(uvwScale_p*1.4);
+    // Vector<Double> UVWOFF_MOI(offset_p);
+    // UVWOFF_MOI(0)=320;
+    // UVWOFF_MOI(1)=320;
+    // UVWOFF_MOI(2)=0;
+    
+    Double *freq=vbs.freq_p.getStorage(Dummy);
+
+    Matrix<Float>&  imagingWeight=vbs.imagingWeight_p;
+    Matrix<Double>& uvw=vbs.uvw_p;
+    Cube<Complex>&  visCube=vbs.visCube_p;
+    Cube<Bool>&     flagCube=vbs.flagCube_p;
+
+    Vector<Int> gridInc, cfInc;
+
+    //    cacheAxisIncrements(nx,ny,nGridPol, nGridChan);
+    cacheAxisIncrements(grid.shape().asVector(), gridInc_p);
+    cacheAxisIncrements(cfShape, cfInc_p);
+
+    for(Int inx=rbeg; inx<rend; inx++) {
+        Int irow = rows[inx];
+
+	for (Int ichan=0; ichan < nDataChan; ichan++) {
+	  achan=chanMap_p[ichan];
+
+	  if((achan>=0) && (achan<nGridChan)) {
+
+	    scaledSampling[0] = SynthesisUtils::nint(sampling[0]);
+	    scaledSampling[1] = SynthesisUtils::nint(sampling[1]);
+	    scaledSupport[0]  = support[0];
+	    scaledSupport[1]  = support[1];
+
+	    sgrid(pos,loc,off,phasor,irow,uvw,dphase_p[irow],freq[ichan],
+	    uvwScale_p,offset_p,sampling);
+	    //sgrid(pos,loc,off,phasor,irow,uvw,dphase_p[irow],freq[ichan],
+	//	  UVWSCALE_MOI,UVWOFF_MOI,sampling);
+	    
+
+
+	    iloc[2]=max(0, min(nw-1, loc[2]));
+	    //cout<<"-----------------------"<<endl;
+	    if (onGrid(nx, ny, nw, loc, support)) {
+	      for(Int ipol=0; ipol < nDataPol; ipol++) {
+		//cout<<"ipol "<<ipol<<endl;
+		if(!flagCube(ipol,ichan,irow)) {
+		  apol=polMap_p[ipol];
+
+		  if((apol>=0) && (apol<nGridPol)) {
+		    igrdpos[2]=apol; igrdpos[3]=achan;
+                    nvalue=0.0;
+                    norm  =0.0;
+
+		    //ConjPlane = cfMap_p(ipol);
+		    //PolnPlane = conjCFMap_p(ipol);
+
+		    iloc[3]=ipol;
+
+		    for(Int iy=-scaledSupport[1]; iy <= scaledSupport[1]; iy++)
+		      {
+			iloc(1)=(Int)(scaledSampling[1]*iy+off[1]);
+			igrdpos[1]=loc[1]+iy;
+
+			for(Int ix=-scaledSupport[0]; ix <= scaledSupport[0]; ix++)
+			  {
+			    iloc(0)=(Int)(scaledSampling[0]*ix+off[0]);
+			    igrdpos[0]=loc[0]+ix;
+			    tiloc=iloc;
+			    if (reindex(iloc,tiloc,sinDPA, cosDPA,
+			    		convOrigin, cfShape))
+			      {
+                                // Use polarization leakage terms if defined.
+                                for (int ic=0; ic<4; ++ic) {
+                                  if (convFuncV[ic][iloc[3]]) {
+				    //cout<<"iloc[3]<<ic "<<iloc[3]<<" "<<ic<<endl;
+                                    wt = convFuncV[iloc[3]][ic][tiloc[1]*cfInc_p[1]+tiloc[0]];
+                                    //wt = conj(convFuncV[ic][iloc[3]][tiloc[1]*cfInc_p[1]+tiloc[0]]);
+                                    norm+=(wt);
+				    //			    nvalue+=wt*grid(grdpos);
+				// The following uses raw index on the 4D grid
+				//				nvalue+=wt*getFrom4DArray(gridStore,iPosPtr,gridInc);
+                                    igrdpos[2] = ic;
+                                    //igrdpos[2] = iloc[3];//ic;
+				    Complex wt2=getFrom4DArray(gridStore,igrdpos,gridInc_p);
+				    //cout<<"Resampler : ic iloc cf sumcf vis: "<<ic<<" "<<iloc[3]<<" "<<wt<<" "<<nvalue<<" "<<wt2<<endl;
+                                    nvalue+=wt*wt2;
+				    //cout<<"wt wt2 wt*wt2 = "<<wt<<" "<<wt2<<" "<<wt*wt2<<endl;
+                                  }
+                                }
+			      }
+			  }
+		      }
+		    //cout<<"nvalue<<" "<<conj(phasor)<<" "<<norm= "<<nvalue<<" "<<conj(phasor)<<" "<<norm<<endl;
+		    visCube(ipol,ichan,irow)=nvalue;//(nvalue*conj(phasor))/norm;
+        	    //cout<<"Vis  "<<visCube(ipol,ichan,irow)<<"  "<<ipol<<"  "<<ichan<<"  "<<irow<<endl;
+		    //modelCube(ipol,ichan,irow)=(nvalue*conj(phasor))/norm;
+		    //cout<<"modelCube  = "<<modelCube(ipol,ichan,irow)<<endl;
+		  }
+		}
+	      }
+	    }
+	  }
+	}
+    }
+  }
+  */
+
+  void LofarVisResamplerOld::lofarComputeResiduals(LofarVBStore& vbs)
+  {
+    Int rbeg = vbs.beginRow_p, rend = vbs.endRow_p;
+    IPosition vbDataShape=vbs.modelCube_p.shape();
+    IPosition start(vbDataShape), last(vbDataShape);
+    start=0; start(2)=rbeg;
+    last(2)=rend; //last=last-1;
+
+    //cout<<"//////////////////// Compuute residual!!!!!!"<<"vbs.useCorrected_p"<<vbs.useCorrected_p<<endl;
+
+    if (!vbs.useCorrected_p)
+      {
+    	for(uInt ichan = start(0); ichan < last(0); ichan++)
+    	  for(uInt ipol = start(1); ipol < last(1); ipol++)
+    	    for(uInt irow = start(2); irow < last(2); irow++)
+    	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.visCube_p(ichan,ipol,irow);
+	
+      }
+    else
+      {
+    	for(uInt ichan = start(0); ichan < last(0); ichan++)
+    	  for(uInt ipol = start(1); ipol < last(1); ipol++)
+    	    for(uInt irow = start(2); irow < last(2); irow++){
+    	      //cout<<"===="<<endl;
+	      //if(!(abs(vbs.modelCube_p(ichan,ipol,irow))==0.)){cout<<ipol<<" "<<ichan<<" "<<irow<<" "<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;};
+    	      
+	      //if(!(abs(vbs.modelCube_p(ichan,ipol,irow))==0.)){cout<<"data "<<ipol<<" "<<ichan<<" "<<irow<<" "<<vbs.modelCube_p(ichan,ipol,irow)<<" "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;};
+	 
+    	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.correctedCube_p(ichan,ipol,irow);
+    	      //cout<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.modelCube_p(ichan,ipol,irow)<<"  "<<vbs.correctedCube_p(ichan,ipol,irow)<<endl;
+    	    };
+	
+      }
+
+    // if (!vbs.useCorrected_p)
+    //   {
+    // 	for(uInt ichan = start(0); ichan < last(0); ichan++)
+    // 	  for(uInt ipol = start(1); ipol < last(1); ipol++)
+    // 	    for(uInt irow = start(2); irow < last(2); irow++)
+    // 	      vbs.modelCube_p(ichan,ipol,irow) = vbs.modelCube_p(ichan,ipol,irow) - vbs.visCube_p(ichan,ipol,irow);
+	
+    //   }
+    // else
+    //   {
+    // 	for(uInt ichan = start(0); ichan < last(0); ichan++)
+    // 	  for(uInt ipol = start(1); ipol < last(1); ipol++)
+    // 	    for(uInt irow = start(2); irow < last(2); irow++){
+    // 	      //cout<<"===="<<endl;
+    // 	      //cout<<vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.modelCube_p(ichan,ipol,irow)<<endl;
+    // 	      vbs.correctedCube_p(ichan,ipol,irow) = vbs.correctedCube_p(ichan,ipol,irow) - vbs.modelCube_p(ichan,ipol,irow);
+    // 	      //cout<<vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.correctedCube_p(ichan,ipol,irow)<<"  "<< vbs.modelCube_p(ichan,ipol,irow)<<endl;
+    // 	    };
+	
+    //   }
+
+
+  }
+
+  void LofarVisResamplerOld::sgrid(Vector<Double>& pos, Vector<Int>& loc,
+			     Vector<Int>& off, Complex& phasor,
+			     const Int& irow, const Matrix<Double>& uvw,
+			     const Double& dphase, const Double& freq,
+			     const Vector<Double>& scale,
+			     const Vector<Double>& offset,
+			     const Vector<Float>& sampling)
+  {
+    Double phase;
+    Vector<Double> uvw_l(3,0); // This allows gridding of weights
+			       // centered on the uv-origin
+    if (uvw.nelements() > 0) for(Int i=0;i<3;i++) uvw_l[i]=uvw(i,irow);
+
+    pos(2)=0;//sqrt(abs(scale[2]*uvw_l(2)*freq/C::c))+offset[2];
+    loc(2)=0;//SynthesisUtils::nint(pos[2]);
+    off(2)=0;
+
+    for(Int idim=0;idim<2;idim++)
+      {
+	pos[idim]=scale[idim]*uvw_l(idim)*freq/C::c+offset[idim];
+        ///        cout<<scale[idim]<<' '<<uvw_l[idim]<<' '<<offset[idim]<<' '<<pos[idim]<<endl;
+	loc[idim]=SynthesisUtils::nint(pos[idim]);
+	//off[idim]=SynthesisUtils::nint((loc[idim]-pos[idim])*sampling[idim]); // Cyr: I've added "+1" next line, and it solves a difficult problem, i don't know why
+	////off[idim]=SynthesisUtils::nint((loc[idim]-pos[idim])*sampling[idim]+1);
+	off[idim]=SynthesisUtils::nint((loc[idim]-pos[idim])*sampling[idim]);
+      }
+
+    //if (dphase != 0.0)
+    //  {
+//	phase=-2.0*C::pi*dphase*freq/C::c;
+//	phasor=Complex(cos(phase), sin(phase));
+    //  }
+    //else
+      phasor=Complex(1.0);
+  }
+
+} // end namespace
diff --git a/CEP/Imager/LofarFT/src/awimager.cc b/CEP/Imager/LofarFT/src/awimager.cc
index 18f38d6d6f876086e3abf1d8bed5790362cfba4e..f782f4e58e14461766257328ef3af859504db643 100644
--- a/CEP/Imager/LofarFT/src/awimager.cc
+++ b/CEP/Imager/LofarFT/src/awimager.cc
@@ -1,4 +1,4 @@
-//# awzim.cc: Program to create and/or clean a LOFAR image
+//# awimager.cc: Program to create and/or clean a LOFAR image
 //# Copyright (C) 2011
 //# Associated Universities, Inc. Washington DC, USA.
 //#
@@ -39,6 +39,7 @@
 #include <casa/Utilities/Regex.h>
 #include <casa/Utilities/Assert.h>
 #include <casa/OS/Directory.h>
+#include <casa/OS/File.h>
 #include <casa/Exceptions/Error.h>
 #include <casa/OS/Timer.h>
 #include <casa/OS/PrecTimer.h>
@@ -128,7 +129,7 @@ void readFilter (const String& filter,
   }
 }
 
-Matrix<Bool> readMueller (const String& str)
+Matrix<Bool> readMueller (const String& str, String stokes, Bool grid)
 {
   Matrix<Bool> mat(4,4, True);
   String s(str);
@@ -147,6 +148,20 @@ Matrix<Bool> readMueller (const String& str)
       throw AipsError (str + " is an invalid Mueller specification");
     }
   }
+  if((stokes=="I")&&(grid)){
+    for(uInt i=0;i<4;++i){
+      mat(1,i)=0;
+      mat(2,i)=0;
+    };
+  }
+  if((stokes=="I")&&(!grid)){
+    for(uInt i=0;i<4;++i){
+      mat(1,i)=0;
+      mat(2,i)=0;
+      // mat(i,1)=0;
+      // mat(i,2)=0;
+    };
+  };
   return mat;
 }
 
@@ -163,6 +178,7 @@ void applyFactors (PagedImage<Float>& image, const Array<Float>& factors)
 {
   Array<Float> data;
   image.get (data);
+  ///  cout << "apply factor to " << data.data()[0] << ' ' << factors.data()[0]<<endl;
   // Loop over channels
   for (ArrayIterator<Float> iter1(data, 3); !iter1.pastEnd(); iter1.next()) {
     // Loop over Stokes.
@@ -173,10 +189,12 @@ void applyFactors (PagedImage<Float>& image, const Array<Float>& factors)
     }
   }
   image.put (data);
+  ///  cout << "applied factor to " << data.data()[0] << ' ' << factors.data()[0]<<endl;
 }
 
 void correctImages (const String& restoName, const String& modelName,
-                    const String& residName, const String& imgName)
+                    const String& residName, const String& imgName,
+                    LOFAR::LofarImager& imager, Bool CorrectElement)
 {
   // Copy the images to .corr ones.
   {
@@ -195,15 +213,14 @@ void correctImages (const String& restoName, const String& modelName,
                 restoredImage.shape() == modelImage.shape(), SynthesisError);
 
   // Get average primary beam and spheroidal.
-  Matrix<Float> avgPB = LOFAR::LofarConvolutionFunction::getAveragePB(imgName);
-  Matrix<Float> spheroidCut = LOFAR::LofarConvolutionFunction::getSpheroidCut(imgName);
-  //  String nameii(imgName + ".spheroid_cut_im");
-  //ostringstream nameiii(nameii);
-  //PagedImage<Float> restoredImageiii(nameiii.str().c_str());
-  //Slicer sliceiiii(IPosition(4,0,0,0,0), restoredImageiii.shape(), IPosition(4,1,1,1,1));
-  //Array<Float> spheroidCut;
-  //restoredImageiii.doGetSlice(spheroidCut , sliceiiii);
-
+  Matrix<Float> avgPB = LOFAR::LofarConvolutionFunction::getAveragePB(imgName+"0");
+  Matrix<Float> spheroidCut = LOFAR::LofarConvolutionFunction::getSpheroidCut(imgName+"0");
+  String nameii("Spheroid_cut_im_element.img");
+  ostringstream nameiii(nameii);
+  PagedImage<Float> tmpi(nameiii.str().c_str());
+  Slicer slicei(IPosition(4,0,0,0,0), tmpi.shape(), IPosition(4,1,1,1,1));
+  Array<Float> spheroidCutElement;
+  tmpi.doGetSlice(spheroidCutElement, slicei);
   // Use the inner part of the beam and spheroidal.
   Int nximg = restoredImage.shape()[0];
   Int nxpb  = avgPB.shape()[0];
@@ -219,7 +236,15 @@ void correctImages (const String& restoName, const String& modelName,
                                        IPosition(2, nximg, nximg)));
   Array<Float> sphinner = spheroidCut(Slicer(IPosition(2, offsph, offsph),
                                              IPosition(2, nximg, nximg)));
-  Array<Float> factors = sphinner / sqrt(pbinner);
+  Array<Float> factors;
+  if(CorrectElement){
+    Array<Float> sphinner_el = (spheroidCutElement(Slicer(IPosition(4, offsph, offsph,0,0),
+							  IPosition(4, nximg, nximg,1,1)))).nonDegenerate();
+    factors = sphinner_el *sphinner / sqrt(pbinner);//sphinner_el * sphinner / sqrt(pbinner);
+  } else{
+    
+    factors = sphinner / sqrt(pbinner);//sphinner_el * sphinner / sqrt(pbinner);
+  }
   applyFactors (restoredImage, factors);
   applyFactors (modelImage, factors);
   applyFactors (residualImage, factors);
@@ -292,14 +317,11 @@ int main (Int argc, char** argv)
     inputs.create ("wmax", "500.0",
 		   "omit data with w-term > wmax (in meters)",
 		   "float");
-    inputs.create ("beamelementpath", "$LOFARROOT/share",
-		   "directory where the Hamaker beam element files reside",
-		   "string");
     inputs.create ("muellergrid", "all",
-		   "Nueller elements to use when gridding (all,diagonal,band1,band2)",
+		   "Mueller elements to use when gridding (all,diagonal,band1,band2)",
 		   "string");
     inputs.create ("muellerdegrid", "all",
-		   "Nueller elements to use when degridding (all,diagonal,band1,band2)",
+		   "Mueller elements to use when degridding (all,diagonal,band1,band2)",
 		   "string");
     inputs.create ("cachesize", "512",
 		   "maximum size of gridding cache (in MBytes)",
@@ -354,7 +376,7 @@ int main (Int argc, char** argv)
 		   "string");
     inputs.create ("operation", "image",
                    ///		   "Operation (empty,image,clark,hogbom,csclean,multiscale,entropy)",
-		   "Operation (empty,image,csclean)",
+		   "Operation (empty,image,csclean,predict,psf)",
 		   "string");
     inputs.create ("niter", "1000",
 		   "Number of clean iterations",
@@ -404,12 +426,68 @@ int main (Int argc, char** argv)
     inputs.create ("oversample", "8",
 		   "oversampling for convolution functions",
 		   "int");
-
+    inputs.create ("uvdist", "",
+		   "UV Range",
+		   "string");
+    inputs.create ("RefFreq", "",
+		   "Reference Frequency (Hz)",
+		   "Double");
+    inputs.create ("nterms", "1",
+		   "Number of Taylor terms",
+		   "int");
+    inputs.create ("UseLIG", "false",
+		   "Use gridder using linear interpolation (not working yet, never to be)",
+		   "bool");
+    inputs.create ("UseEJones", "true",
+                   "Use the beam for the calculation of the convolution function (not working yet)",
+                   "bool");
+    inputs.create ("applyIonosphere", "false",
+                   "apply ionospheric correction",
+                   "bool");
+    inputs.create ("splitbeam", "true",
+                   "Evaluate station beam and element beam separately (splitbeam = true is faster)",
+                   "bool");
+    // inputs.create ("ApplyElement", "false",
+    // 		   "Apply the element beam",
+    // 		   "bool");
+    inputs.create ("PBCut", "1e-2",
+		   "Level below which the dirty images will be set to zero. Expressed in units of peak primary beam.",
+		   "Double");
+    inputs.create ("cyclefactor", "1.5",
+		   "Cycle Factor. See Casa definition.",
+		   "Double");
+    inputs.create ("cyclespeedup", "-1",
+		   "Cycle Factor. See Casa definition.",
+		   "Double");
+    inputs.create ("ModelImPredict", "",
+		   "Input Model image for the predict",
+		   "string");
+    inputs.create ("PsfImage", "",
+		   "Input PSF image for the cleaning",
+		   "string");
+    inputs.create ("StepApplyElement", "0",
+		   "If turned to >0, apply the element beam every N number of timewindows.",
+		   "int");
+    inputs.create ("UseMasks", "true",
+		   "When the element beam is applied (StepApplyElement), the addictional step of convolving the grid can be made more efficient by computing masks. If true, it will create a directory in which it stores the masks.",
+		   "bool");
+    inputs.create ("RowBlock", "0",
+		   "In certain obscure circounstances (taql, selection using uvdist), the RowBlocking used by the imager calculated from the timewindow value is not correct. This parameter can be used to specify the RowBlocking.",
+		   "int");
+    // inputs.create ("FillFactor", "1",
+    // 		   "Fraction of the data that will be selected from the selected MS. (don't use it yet)",
+    // 		   "Double");
+ 
     // Fill the input structure from the command line.
     inputs.readArguments (argc, argv);
 
     // Get the input specification.
     Bool fixed          = inputs.getBool("fixed");
+    Bool UseLIG         = inputs.getBool("UseLIG");
+    Bool UseEJones      = inputs.getBool("UseEJones");
+    Bool applyIonosphere = inputs.getBool("applyIonosphere");
+    Bool splitbeam = inputs.getBool("splitbeam");
+    Bool ApplyElement   ;//= inputs.getBool("ApplyElement");
     Bool constrainFlux  = inputs.getBool("constrainflux");
     Bool preferVelocity = inputs.getBool("prefervelocity");
     Bool displayProgress= inputs.getBool("displayprogress");
@@ -430,11 +508,15 @@ int main (Int argc, char** argv)
     Int verbose      = inputs.getInt("verbose");
     Int maxsupport   = inputs.getInt("maxsupport");
     Int oversample   = inputs.getInt("oversample");
+    Int StepApplyElement   = inputs.getInt("StepApplyElement");
+    if ((StepApplyElement%2 == 0)&&((StepApplyElement%2 != 0))) {
+      StepApplyElement++;
+    }
+    Int nterms   = inputs.getInt("nterms");
     Vector<Double> userScaleSizes(inputs.getDoubleVector("uservector"));
     Double padding   = inputs.getDouble("padding");
     Double gain      = inputs.getDouble("gain");
     Double maskValue = inputs.getDouble("maskvalue");
-    String beamDir   = inputs.getString("beamelementpath");
     String mode      = inputs.getString("mode");
     String operation = inputs.getString("operation");
     String weight    = inputs.getString("weight");
@@ -461,11 +543,21 @@ int main (Int argc, char** argv)
     String psfName   = inputs.getString("psf");
     String imageType = inputs.getString("data");
     String select    = inputs.getString("select");
+    String uvdist    = inputs.getString("uvdist");
     String maskName  = inputs.getString("mask");
     String mstrBlc   = inputs.getString("maskblc");
     String mstrTrc   = inputs.getString("masktrc");
-    Matrix<Bool> muelgrid   = readMueller (inputs.getString("muellergrid"));
-    Matrix<Bool> mueldegrid = readMueller (inputs.getString("muellerdegrid"));
+    Double RefFreq   = inputs.getDouble("RefFreq");
+    Double PBCut   = inputs.getDouble("PBCut");
+    Double cyclefactor   = inputs.getDouble("cyclefactor");
+    Double cyclespeedup  = inputs.getDouble("cyclespeedup");
+    Matrix<Bool> muelgrid   = readMueller (inputs.getString("muellergrid"), stokes, true);
+    Matrix<Bool> mueldegrid = readMueller (inputs.getString("muellerdegrid"), stokes, false);
+    String ModelImPredict    = inputs.getString("ModelImPredict");
+    String PsfImage    = inputs.getString("PsfImage");
+    Bool Use_masks    = inputs.getBool("UseMasks");
+    Int RowBlock   = inputs.getInt("RowBlock");
+    //Double FillFactor= 1.;//inputs.getDouble("FillFactor");
 
     // Check and interpret input values.
     Quantity qcellsize = readQuantity (cellsize);
@@ -534,13 +626,13 @@ int main (Int argc, char** argv)
       phaseCenter = readDirection (phasectr);
     }
     operation.downcase();
-    AlwaysAssertExit (operation=="empty" || operation=="image" || operation=="csclean");
+    AlwaysAssertExit (operation=="empty" || operation=="image" || operation=="csclean"|| operation=="msmfs"||operation=="predict"||operation=="psf");
     ///AlwaysAssertExit (operation=="empty" || operation=="image" || operation=="hogbom" || operation=="clark" || operation=="csclean" || operation=="multiscale" || operation =="entropy");
     IPosition maskBlc, maskTrc;
     Quantity threshold;
     Quantity sigma;
     Quantity targetFlux;
-    Bool doClean = (operation != "empty"  &&  operation != "image");
+    Bool doClean = (operation != "empty"  &&  operation != "image"&&  operation != "psf");
     if (doClean) {
       maskBlc = readIPosition (mstrBlc);
       maskTrc = readIPosition (mstrTrc);
@@ -548,6 +640,11 @@ int main (Int argc, char** argv)
       sigma = readQuantity (sigmaStr);
       targetFlux = readQuantity (targetStr);
     }
+    Bool doPSF =(operation=="psf");
+    if(doPSF==true){
+      operation="csclean";
+      niter=0;
+    }
     // Get axis specification from filter.
     Quantity bmajor, bminor, bpa;
     readFilter (filter, bmajor, bminor, bpa);
@@ -558,21 +655,54 @@ int main (Int argc, char** argv)
     Record params;
     params.define ("timewindow", timewindow);
     params.define ("wmax", wmax);
-    params.define ("beam.element.path", beamDir);
     params.define ("mueller.grid", muelgrid);
     params.define ("mueller.degrid", mueldegrid);
     params.define ("verbose", verbose);
     params.define ("maxsupport", maxsupport);
     params.define ("oversample", oversample);
     params.define ("imagename", imgName);
+    params.define ("UseLIG", UseLIG);
+    params.define ("UseEJones", UseEJones);
+    //params.define ("ApplyElement", ApplyElement);
+    params.define ("PBCut", PBCut);
+    params.define ("StepApplyElement", StepApplyElement);
+    Bool PredictFT(false);
+    if(operation=="predict"){PredictFT=true;}
+    params.define ("PredictFT", PredictFT);
+    params.define ("PsfImage", PsfImage);
+    params.define ("UseMasksDegrid", Use_masks);
+    params.define ("RowBlock", RowBlock);
+    params.define ("doPSF", doPSF);
+    params.define ("applyIonosphere", applyIonosphere);
+    params.define ("splitbeam", splitbeam);
+    //params.define ("FillFactor", FillFactor);
+    
     LOFAR::LofarImager imager(ms, params);
+
+    MSSpWindowColumns window(ms.spectralWindow());
+    // ROMSObservationColumns timerange(ms.observation());
+    // cout<<"timerange"<<timerange.timerange()<<endl;
+    Vector<Int> wind(window.nrow());
+    for(uInt iii=0;iii<window.nrow();++iii){wind(iii)=iii;};
+    cout<<"... Windows is shit"<<endl;
+
+    ROArrayColumn<Double> chfreq(window.chanFreq());
+
+    cout<<"Number of channels: "<<chfreq(0).shape()[0]<<endl;
+
+    Vector<Int> chansel(1);
+    chansel(0)=chfreq(0).shape()[0];
+    //chansel(1)=1;
+    //chansel(2)=2;
+    //chansel(3)=3;
+
     imager.setdata (chanmode,                       // mode
-		    nchan,
+		    chansel,//nchan,
 		    chanstart,
                     chanstep,
 		    MRadialVelocity(),              // mStart
 		    MRadialVelocity(),              // mStep
-		    spwid,
+		    wind,//spwid,
 		    Vector<Int>(1,fieldid),
 		    select,                         // msSelect
                     String(),                       // timerng
@@ -580,10 +710,22 @@ int main (Int argc, char** argv)
                     Vector<Int>(),                  // antIndex
                     String(),                       // antnames
                     String(),                       // spwstring
-                    String(),                       // uvdist
+                    uvdist,                       // uvdist
                     String(),                       // scan
                     True);                          // useModelCol
 
+
+    imager.setmfcontrol(cyclefactor,          //Float cyclefactor,
+  			cyclespeedup,         //Float cyclespeedup,
+  			0.8,                        //Float cyclemaxpsffraction, 
+  			2,                          //Int stoplargenegatives, 
+  			-1,                         //Int stoppointmode,
+  			"",                         //String& scaleType,
+  			0.1,                        //Float minPB,
+  			0.4,                        //loat constPB,
+  			Vector<String>(1, ""),      //Vector<String>& fluxscale,
+  			true);                      //Bool flatnoise);
+
     imager.defineImage (npix,                       // nx
                         npix,                       // ny
                         qcellsize,                  // cellx
@@ -598,9 +740,25 @@ int main (Int argc, char** argv)
                         MFrequency(),               // mFreqstart
                         MRadialVelocity(),          // mStart
                         Quantity(1,"km/s"),         // qstep, Def=1 km/s
-                        spwid,                      // spectralwindowids
+			wind,//spwid,                      // spectralwindowids
                         nfacet);                    // facets
 
+    if (operation=="predict"){
+      String ftmachine("ft");
+      if (wplanes > 0) {
+        ftmachine = "wproject";
+      }
+      imager.setoptions(ftmachine,                    // ftmachine
+                        cachesize*1024*(1024/8),      // cache
+                        16,                           // tile
+                        "SF",                         // gridfunction
+                        MPosition(),                  // mLocation
+                        padding,                      // padding
+                        wplanes);                     // wprojplanes
+      imager.ft(Vector<String>(1, ModelImPredict), "",
+		False);
+    } else{
+
     // Create empty image?
     if (operation == "empty" ) {
       makeEmpty (imager, imgName, fieldid);
@@ -707,25 +865,109 @@ int main (Int argc, char** argv)
                      Vector<String>(1, maskName),     // mask
                      Vector<String>(1, restoName),    // restored
                      Vector<String>(1, residName));   // residual
-        } else {
+        }
+        if (operation == "msmfs") {
+	  //uInt nterms(2);
+
+	  //imager.settaylorterms(nterms,5.95e+07);
+	  imager.settaylorterms(nterms,RefFreq);
+	  String scaleMethod;
+	  Vector<Float> userVector(1); userVector(0)=0;
+	  convertArray (userVector, userScaleSizes);
+	  if (userScaleSizes.size() > 1) {
+	    scaleMethod = "uservector";
+	  } else {
+	    scaleMethod = "nscales";
+	  }
+	  imager.setscales(scaleMethod, 1, userVector);
+	  cout<<imgName<<endl;
+	  makeEmpty (imager, imgName, 0);
+	  Directory filee(imgName);
+
+	  
+	  Vector<String> modelNames(nterms);
+	  for(uInt i=0;i<nterms;++i){
+	    modelNames(i)="test.img.model.tt"+String::toString(i);
+	    
+	    Directory filee0(modelNames(i));
+	    File file_model0(modelNames(i));
+	    if(file_model0.exists()){filee0.removeRecursive();};
+	    Path model0(modelNames(i)); 
+	    filee.copy(model0);
+	  };
+
+	  //	  assert(false);
+
+          imager.clean("msmfs",                     // algorithm,
+                       niter,                         // niter
+                       gain,                          // gain
+                       threshold,                     // threshold
+                       displayProgress,               // displayProgress
+                       //Vector<String>(1, modelName),  // model
+                       modelNames,
+                       Vector<Bool>(1, fixed),        // fixed
+                       "",                            // complist
+                       Vector<String>(1, maskName),   // mask
+                       Vector<String>(1, restoName),  // restored
+                       Vector<String>(1, residName),  // residual
+                       Vector<String>(1, psfName));   // psf
+	  
+	}
+	else {
+	  Vector<String> modelNames(2);
+	  modelNames[0]="model.main";
+	  modelNames[1]="model.outlier";
+	  File Dir_masks_file("JAWS_masks_degrid");
+	  Directory Dir_masks("JAWS_masks_degrid");
+	  if(Dir_masks_file.exists()){
+	    Dir_masks.removeRecursive();
+	  }
+	  if(Use_masks){
+	    Dir_masks.create();
+	  }
+	  // Vector<String> Namelist(5);
+	  // Namelist[0]=".spheroid_cut_im";
+ 	  // Namelist[1]=".residual";
+	  // Namelist[2]=".residual.corr";
+	  // Namelist[3]=".restored";
+	  // Namelist[4]=".restored.corr";
+	  // //Namelist[5]="0.avgpb";
+	  // for(uInt i=0; i<Namelist.size(); ++i){
+	  //   String avgpb_name(imgName + Namelist[i]);
+	  //   File avgpb_name_file(avgpb_name);
+	  //   Directory avgpb_name_dir(avgpb_name);
+	  //   cout<<avgpb_name<<endl;
+	  //   if(avgpb_name_file.exists()){
+	  //     cout<<"... remove"<<endl;
+	  //     avgpb_name_dir.removeRecursive();
+	  //   }
+	  // }
+	  // Regex rx1 (Regex::fromPattern ("*.avgpb"));
+	  // Vector<String> avgpbfiles;
+	  // avgpbfiles=Directory::find(rx1);
+
           imager.clean(operation,                     // algorithm,
                        niter,                         // niter
                        gain,                          // gain
                        threshold,                     // threshold
                        displayProgress,               // displayProgress
                        Vector<String>(1, modelName),  // model
+		      //  modelNames,
                        Vector<Bool>(1, fixed),        // fixed
                        "",                            // complist
                        Vector<String>(1, maskName),   // mask
                        Vector<String>(1, restoName),  // restored
                        Vector<String>(1, residName),  // residual
                        Vector<String>(1, psfName));   // psf
+
         }
         // Do the final correction for primary beam and spheroidal.
-        correctImages (restoName, modelName, residName, imgName);
+	ApplyElement=false;
+	if(StepApplyElement>0){ApplyElement=true;}
+        correctImages (restoName, modelName, residName, imgName, imager, ApplyElement);
         precTimer.stop();
         timer.show ("clean");
-        ///imager.showTimings (cout, precTimer.getReal());
+	///        imager.showTimings (cout, precTimer.getReal());
         // Convert result to fits if needed.
         if (! fitsName.empty()) {
           String error;
@@ -740,10 +982,10 @@ int main (Int argc, char** argv)
         }
       }
     }
-  } catch (AipsError& x) {
+    } }catch (AipsError& x) {
     cout << x.getMesg() << endl;
     return 1;
-  } 
-  cout << "awzim normally ended" << endl;
+  }
+  cout << "awimager normally ended" << endl;
   return 0;
 }
diff --git a/CEP/Imager/LofarFT/src/makefftwisdom2d.cc b/CEP/Imager/LofarFT/src/makefftwisdom2d.cc
index c86442986dabd3617b9c9c6899396aa79d8605a1..9259136d5bec368bcd3a3122b08743c6ef858d6a 100644
--- a/CEP/Imager/LofarFT/src/makefftwisdom2d.cc
+++ b/CEP/Imager/LofarFT/src/makefftwisdom2d.cc
@@ -92,7 +92,7 @@ int main (int argc, char* argv[])
   cerr << endl;
   cout << "Creating 2D FFTW wisdom for some multiples of 1024 (till 16384) ..."
        << endl;
-  int otherSizes[] = {512, 1024, 2048, 4096, 6144, 8192, 10240, 12288, 16384};
+  int otherSizes[] = {512, 1024};//, 2048, 4096, 6144, 8192, 10240, 12288, 16384};
   nsizes = sizeof(otherSizes) / sizeof(int);
   for (int i=0; i<2; ++i) {
     cerr << ' ' << otherSizes[i];
diff --git a/CEP/ParmDB/src/makesourcedb.cc b/CEP/ParmDB/src/makesourcedb.cc
index 11b227910083ffb6fc67a9e3fc5b2579dbad053b..8aaebb4b6bf56ad4e0b2f3ac995ff0303ecebe35 100644
--- a/CEP/ParmDB/src/makesourcedb.cc
+++ b/CEP/ParmDB/src/makesourcedb.cc
@@ -973,10 +973,7 @@ void make (const string& in, const string& out,
   int nrsource    = 0;
   int nrpatchfnd  = 0;
   int nrsourcefnd = 0;
-  if (in.empty()) {
-    process (string(), pdb, sdbf, check, nrpatch, nrsource,
-             nrpatchfnd, nrsourcefnd, searchInfo);
-  } else {
+  if (! in.empty()) {
     ifstream infile(in.c_str());
     ASSERTSTR (infile, "File " << in << " could not be opened");
     casa::Regex regexf("^[ \t]*[fF][oO][rR][mM][aA][tT][ \t]*=.*");
@@ -1015,11 +1012,11 @@ void make (const string& in, const string& out,
        << pdb.getParmDBMeta().getTableName() << endl;
   vector<string> dp(pdb.findDuplicatePatches());
   if (dp.size() > 0) {
-    cout << "Duplicate patches: " << dp << endl;
+    cerr << "Duplicate patches: " << dp << endl;
   }
   vector<string> ds(pdb.findDuplicateSources());
   if (ds.size() > 0) {
-    cout << "Duplicate sources: " << ds << endl;
+    cerr << "Duplicate sources: " << ds << endl;
   }
 }
 
@@ -1031,6 +1028,9 @@ string readFormat (string file, const string& catFile)
   if (file.empty()) {
     file = catFile;
   }
+  if (file.empty()) {
+    return string();
+  }
   // Read file until format line is found or until non-comment is found.
   ifstream infile(file.c_str());
   ASSERTSTR (infile, "File " << file
@@ -1075,13 +1075,12 @@ int main (int argc, char* argv[])
   try {
     // Get the inputs.
     Input inputs(1);
-    inputs.version ("GvD 2011-Sep-01");
+    inputs.version ("GvD 2011-Feb-17");
     inputs.create("in", "",
                   "Input file name", "string");
     inputs.create("out", "",
                   "Output sourcedb name", "string");
-    inputs.create("format", "Name,Type,Ra,Dec,I,Q,U,V,MajorAxis,"
-                            "MinorAxis,Orientation",
+    inputs.create("format", "",
                   "Format of the input lines or name of file containing format",
                   "string");
     inputs.create("append", "true",
@@ -1125,10 +1124,15 @@ int main (int argc, char* argv[])
       // Read format from file.
       format = readFormat (format.substr(st), in);
     }
+    // Use default if empty format.
+    if (format.empty()) {
+      cerr << "No format string found; using default format" << endl;
+      format = "Name,Type,Ra,Dec,I,Q,U,V,MajorAxis,MinorAxis,Orientation";
+    }
     make (in, out, format, append, check,
           getSearchInfo (center, radius, width));
   } catch (Exception& x) {
-    std::cerr << "Caught LOFAR exception: " << x << std::endl;
+    cerr << "Caught LOFAR exception: " << x << endl;
     return 1;
   }
   
diff --git a/LCS/ApplCommon/include/ApplCommon/Observation.h b/LCS/ApplCommon/include/ApplCommon/Observation.h
index 59aed628f08f85771e8c7888dfc393e7aaeca72d..aa3161f8195d892b2d32af646680557a2a4f4554 100644
--- a/LCS/ApplCommon/include/ApplCommon/Observation.h
+++ b/LCS/ApplCommon/include/ApplCommon/Observation.h
@@ -66,8 +66,6 @@ public:
 
 	// Returns a bitset containing the RCU's requested by the observation.
 	bitset<MAX_RCUS> getRCUbitset(int nrLBAs, int nrHBAs, const string& anAntennaSet);
-	// TEMP HACK
-	string getAntennaArrayName(bool hasSplitters) const;
 
 	// Support for dynamic dataslot allocation
 	vector<int>	getBeamAllocation(const string&	stationName = "") const;
@@ -76,6 +74,9 @@ public:
 	// for operator <<
 	ostream& print (ostream&	os) const;
 
+	// TEMP HACK
+	string getAntennaFieldName(bool hasSplitters, uint32 beamIdx = 0) const;
+
 	// data types
 	typedef bitset<MAX_RCUS> 	  RCUset_t;
 
diff --git a/LCS/ApplCommon/src/Observation.cc b/LCS/ApplCommon/src/Observation.cc
index 482c576d283fea238a75a6b4e853c43cb07d02ff..527ca5649449fce84b721d765e41d083e0552ba8 100644
--- a/LCS/ApplCommon/src/Observation.cc
+++ b/LCS/ApplCommon/src/Observation.cc
@@ -144,7 +144,8 @@ Observation::Observation(const ParameterSet*		aParSet,
 	}
 
 	// determine if DataslotLists are available in this parset
-	itsHasDataslots = aParSet->isDefined(prefix+str(format("Dataslots.%s%s.DataslotList") % stations[0] % antennaArray));
+	LOG_DEBUG_STR(str(format("Dataslots.%s%s.DataslotList") % stations[0] % getAntennaFieldName(itsStnHasDualHBA)));
+	itsHasDataslots = aParSet->isDefined(prefix+str(format("Dataslots.%s%s.DataslotList") % stations[0] % getAntennaFieldName(itsStnHasDualHBA)));
 	if (itsHasDataslots) {
 		itsDataslotParset = aParSet->makeSubset(prefix+"Dataslots.");		// save subset for later
 	}
@@ -232,9 +233,11 @@ Observation::Observation(const ParameterSet*		aParSet,
 		}
 
 		// finally update vector with beamnumbers
-		int	nrBeamlets = newBeam.subbands.size();
+		int	nrSubbands = newBeam.subbands.size();
 		if (!itsHasDataslots) {		// old situation
 			BeamBeamlets = aParSet->getInt32Vector(beamPrefix+"beamletList", vector<int32>(), true);	// true:expandable
+			int nrBeamlets = BeamBeamlets.size();
+			ASSERTSTR(nrBeamlets == nrSubbands, "Number of beamlets(" << nrBeamlets << ") != nr of subbands(" << nrSubbands << ") for Beam " << beamIdx);
 			for (int  i = 0; i < nrBeamlets; ++i) {
 				if (beamlet2beams[BeamBeamlets[i]] != -1) {
 					stringstream	os;
@@ -246,7 +249,7 @@ Observation::Observation(const ParameterSet*		aParSet,
 			} // for all beamlets
 		}
 		else { // new situation
-			for (int  i = 0; i < nrBeamlets; ++i) {
+			for (int  i = 0; i < nrSubbands; ++i) {	// Note nrBeamlets=nrSubbands
 				itsBeamSlotList.push_back(beamIdx);
 			}
 		} // itsHasDataslots
@@ -500,13 +503,15 @@ vector<int> Observation::getBeamAllocation(const string& stationName) const
 		}
 	}
 	// is DSL for this station available?
-	if (!itsDataslotParset.isDefined(str(format("%s%s.DataslotList") % station % antennaArray)) ||
-	    !itsDataslotParset.isDefined(str(format("%s%s.RSPBoardList") % station % antennaArray))) {
+	string	fieldName = getAntennaFieldName(itsStnHasDualHBA);
+	string	dsl(str(format("%s%s.DataslotList") % station % fieldName));
+	string	rbl(str(format("%s%s.RSPBoardList") % station % fieldName));
+	if (!itsDataslotParset.isDefined(dsl) || !itsDataslotParset.isDefined(rbl)) {
 		LOG_ERROR_STR("No dataslots defined for " << station << antennaArray);
 		return (b2b);
 	}
-	vector<int>	RSPboardList = itsDataslotParset.getIntVector(str(format("%s%s.RSPBoardList") % station % antennaArray),true);
-	vector<int>	DataslotList = itsDataslotParset.getIntVector(str(format("%s%s.DataslotList") % station % antennaArray),true);
+	vector<int>	RSPboardList = itsDataslotParset.getIntVector(rbl,true);
+	vector<int>	DataslotList = itsDataslotParset.getIntVector(dsl,true);
 
 	ASSERTSTR (RSPboardList.size() == DataslotList.size(), "RSPBoardlist (" << RSPboardList << 
 			") differs size of DataslotList(" << DataslotList << ") for station " << station);
@@ -536,8 +541,10 @@ vector<int> Observation::getBeamAllocation(const string& stationName) const
 vector<int>	Observation::getBeamlets (uint beamIdx, const string&	stationName) const
 {
 	uint	parsetIdx = (dualMode && itsStnHasDualHBA) ? beamIdx/2 : beamIdx;
+	string	fieldName = getAntennaFieldName(itsStnHasDualHBA, beamIdx);
 
 	if (!itsHasDataslots) {
+		// both fields use the same beamlet mapping
 		return (itsDataslotParset.getInt32Vector(str(format("Beam[%d].beamletList") % parsetIdx), vector<int32>(), true));	// true:expandable
 	}
 
@@ -552,14 +559,15 @@ vector<int>	Observation::getBeamlets (uint beamIdx, const string&	stationName) c
 	}
 		
 	// is DSL for this station available?
+	// both fields have their own beamlet mapping
+	string	dsl(str(format("%s%s.DataslotList") % station % fieldName));
+	string	rbl(str(format("%s%s.RSPBoardList") % station % fieldName));
 	vector<int>	result;
-	if (!itsDataslotParset.isDefined(str(format("%s%s.DataslotList") % station % antennaArray)) ||
-	    !itsDataslotParset.isDefined(str(format("%s%s.RSPBoardList") % station % antennaArray))) {
+	if (!itsDataslotParset.isDefined(dsl) || !itsDataslotParset.isDefined(rbl)) {
 		return (result);
 	}
-	vector<int>	RSPboardList = itsDataslotParset.getIntVector(str(format("%s%s.RSPBoardList") % station % antennaArray),true);
-	vector<int>	DataslotList = itsDataslotParset.getIntVector(str(format("%s%s.DataslotList") % station % antennaArray),true);
-
+	vector<int>	RSPboardList = itsDataslotParset.getIntVector(rbl,true);
+	vector<int>	DataslotList = itsDataslotParset.getIntVector(dsl,true);
 	uint	nrEntries = itsBeamSlotList.size();
 	for (uint i = 0; i < nrEntries; ++i) {
 		if (itsBeamSlotList[i] == parsetIdx) {
@@ -571,9 +579,11 @@ vector<int>	Observation::getBeamlets (uint beamIdx, const string&	stationName) c
 
 
 //
-// TEMP HACK TO GET THE ANTENNAARRAYNAME
+// TEMP HACK TO GET THE ANTENNAFIELDNAME
+//
+// Except for the beamIdx dependancy we should look in the antennaSet file.
 //
-string Observation::getAntennaArrayName(bool hasSplitters) const
+string Observation::getAntennaFieldName(bool hasSplitters, uint32	beamIdx) const
 {
 	string	result;
 	if (antennaSet.empty()) {
@@ -595,6 +605,7 @@ string Observation::getAntennaArrayName(bool hasSplitters) const
 	if (result == "HBA_ZERO") 	return ("HBA0");
 	if (result == "HBA_ONE") 	return ("HBA1");
 	if (result == "HBA_JOINED")	return ("HBA");
+	if (result == "HBA_DUAL")	return (beamIdx % 2 == 0 ? "HBA0" : "HBA1");
 	return ("HBA");
 }	
 
diff --git a/LCS/ApplCommon/test/tObservation.cc b/LCS/ApplCommon/test/tObservation.cc
index 3a6bea348e6a6ed3ae8e9b0322d8e75188216716..17c3a22ab7ded5c125d4846a6c1c01507f06829d 100644
--- a/LCS/ApplCommon/test/tObservation.cc
+++ b/LCS/ApplCommon/test/tObservation.cc
@@ -45,8 +45,8 @@ int main (int argc, char* argv[])
 			cout << "getRCUbitset(96,96,LBA_XXX) = " << someObs.getRCUbitset(96,96,"LBA_XXX") << endl;	// Core
 			cout << "getRCUbitset(96,48,HBA_XXX) = " << someObs.getRCUbitset(96,48,"HBA_XXX") << endl;	// Core
 			cout << "getRCUbitset(96,96,HBA_XXX) = " << someObs.getRCUbitset(96,96,"HBA_XXX") << endl;	// Core
-			vector<int>	b2b = someObs.getBeamAllocation("RS005");
-			cout << "BeamAlloc for RS005 : " << b2b << endl;
+			vector<int>	b2b = someObs.getBeamAllocation("CS002");
+			cout << "BeamAlloc for CS002 : " << b2b << endl;
 			return (0);
 		}
 
@@ -119,27 +119,27 @@ int main (int argc, char* argv[])
 		
 		// test translation of antennaSetname
 		obs3.antennaSet = "HBA_ZERO";
-		cout << "HBA_ZERO(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "HBA_ZERO(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "HBA_ZERO(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "HBA_ZERO(true)  = " << obs3.getAntennaFieldName(true) << endl;
 		obs3.antennaSet = "HBA_ONE";
-		cout << "HBA_ONE(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "HBA_ONE(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "HBA_ONE(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "HBA_ONE(true)  = " << obs3.getAntennaFieldName(true) << endl;
 		obs3.antennaSet = "HBA_DUAL";
-		cout << "HBA_DUAL(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "HBA_DUAL(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "HBA_DUAL(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "HBA_DUAL(true)  = " << obs3.getAntennaFieldName(true) << endl;
 		obs3.antennaSet = "HBA_JOINED";
-		cout << "HBA_JOINED(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "HBA_JOINED(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "HBA_JOINED(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "HBA_JOINED(true)  = " << obs3.getAntennaFieldName(true) << endl;
 
 		obs3.antennaSet = "LBA_INNER";
-		cout << "LBA_INNER(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "LBA_INNER(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "LBA_INNER(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "LBA_INNER(true)  = " << obs3.getAntennaFieldName(true) << endl;
 		obs3.antennaSet = "LBA_OUTER";
-		cout << "LBA_OUTER(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "LBA_OUTER(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "LBA_OUTER(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "LBA_OUTER(true)  = " << obs3.getAntennaFieldName(true) << endl;
 		obs3.antennaSet = "LBA_X";
-		cout << "LBA_X(false) = " << obs3.getAntennaArrayName(false) << endl;
-		cout << "LBA_X(true)  = " << obs3.getAntennaArrayName(true) << endl;
+		cout << "LBA_X(false) = " << obs3.getAntennaFieldName(false) << endl;
+		cout << "LBA_X(true)  = " << obs3.getAntennaFieldName(true) << endl;
 
 		// test old syntax agains new syntax
 		cout << ">>>" << endl;
diff --git a/LCS/ApplCommon/test/tObservation.in_newParset b/LCS/ApplCommon/test/tObservation.in_newParset
index 3da73e1b91c1688becdae98a717cf37f1f80f154..6965201eb8a21111f20d0e47516387276c58c303 100644
--- a/LCS/ApplCommon/test/tObservation.in_newParset
+++ b/LCS/ApplCommon/test/tObservation.in_newParset
@@ -30,12 +30,18 @@ ObsSW.Observation.VirtualInstrument.partitionList=[R001_128_0,R001_128_1,R001_12
 ObsSW.Observation.VirtualInstrument.stationList=[CS001,RS005,CS004]
 ObsSW.Observation.VirtualInstrument.storageCapacity=760
 ObsSW.Observation.VirtualInstrument.storageNodeList=[list001,list002]
-ObsSW.Observation.Dataslots.CS001HBA.DataslotList=[45..47,0..11]
-ObsSW.Observation.Dataslots.CS001HBA.RSPBoardList=[3*0,12*1]
-ObsSW.Observation.Dataslots.RS005HBA.DataslotList=[0..3,45..47,0..7]
-ObsSW.Observation.Dataslots.RS005HBA.RSPBoardList=[7*0,8*1]
-ObsSW.Observation.Dataslots.CS004HBA.DataslotList=[0..14]
-ObsSW.Observation.Dataslots.CS004HBA.RSPBoardList=[15*0]
+ObsSW.Observation.Dataslots.CS001HBA0.DataslotList=[45..47,0..11]
+ObsSW.Observation.Dataslots.CS001HBA0.RSPBoardList=[3*0,12*1]
+ObsSW.Observation.Dataslots.CS001HBA1.DataslotList=[45..47,0..11]
+ObsSW.Observation.Dataslots.CS001HBA1.RSPBoardList=[3*0,12*1]
+ObsSW.Observation.Dataslots.RS005HBA0.DataslotList=[0..3,45..47,0..7]
+ObsSW.Observation.Dataslots.RS005HBA0.RSPBoardList=[7*0,8*1]
+ObsSW.Observation.Dataslots.RS005HBA1.DataslotList=[0..3,45..47,0..7]
+ObsSW.Observation.Dataslots.RS005HBA1.RSPBoardList=[7*0,8*1]
+ObsSW.Observation.Dataslots.CS004HBA0.DataslotList=[0..14]
+ObsSW.Observation.Dataslots.CS004HBA0.RSPBoardList=[15*0]
+ObsSW.Observation.Dataslots.CS004HBA1.DataslotList=[0..14]
+ObsSW.Observation.Dataslots.CS004HBA1.RSPBoardList=[15*0]
 ObsSW.Observation.antennaArray=HBA
 ObsSW.Observation.antennaSet=HBA_DUAL
 ObsSW.Observation.bandFilter=HBA_210_250
diff --git a/LCS/ApplCommon/test/tObservation.stdout b/LCS/ApplCommon/test/tObservation.stdout
index 7985247fbd4e1772c92e55e202d2ee72ffcae24c..dfd78a1103e353cc59f960eeb7cb71cf1f62d782 100644
--- a/LCS/ApplCommon/test/tObservation.stdout
+++ b/LCS/ApplCommon/test/tObservation.stdout
@@ -1,4 +1,5 @@
 >>>
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 
 Observation  : 
 ObsID        : 5025
@@ -35,6 +36,7 @@ Beam[0].TAB[1]: 5.990000, 0.490000, J2000, 20.000000, incoherent
 beamlet2beams   : [0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999]
 nrAnaBeams   : 0
 
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 
 Observation  : 
 ObsID        : 5025
@@ -72,6 +74,7 @@ beamlet2beams   : [0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
 nrAnaBeams   : 0
 
 <<<
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 
 Observation  : 
 ObsID        : 5025
@@ -119,15 +122,22 @@ TABringsize : 0
 beamlet2beams   : [0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999]
 nrAnaBeams   : 0
 
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 >>>
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 INFO  LCS.ApplCommon - Clock of observation 5025 and 5026 conflict
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 INFO  LCS.ApplCommon - Conflicting use of receivers between observation 5025 and 5027
 DEBUG LCS.ApplCommon - receiverConflict: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111100000000
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 INFO  LCS.ApplCommon - Conflict in beamlets between observation 5025 and 5028
 DEBUG LCS.ApplCommon - First conflicting beamlet: 2
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 INFO  LCS.ApplCommon - Conflict in nrSlotsInFrame: 48<->54 for resp. observation 5025 and 5029
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 <<<
 No conflict found in file 5 which is oke.
+DEBUG LCS.ApplCommon - Dataslots.CS016HBA.DataslotList
 getRCUbitset(96,48,'') = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111
 getRCUbitset(96,96,'') = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111
 getRCUbitset(96,48,LBA_XXX) = 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111
@@ -139,7 +149,7 @@ HBA_ZERO(true)  = HBA0
 HBA_ONE(false) = HBA
 HBA_ONE(true)  = HBA1
 HBA_DUAL(false) = HBA
-HBA_DUAL(true)  = HBA
+HBA_DUAL(true)  = HBA0
 HBA_JOINED(false) = HBA
 HBA_JOINED(true)  = HBA
 LBA_INNER(false) = LBA
@@ -149,6 +159,7 @@ LBA_OUTER(true)  = LBA
 LBA_X(false) = LBA
 LBA_X(true)  = LBA
 >>>
+DEBUG LCS.ApplCommon - Dataslots.CS001HBA0.DataslotList
 OLD SYNTAX
 
 Observation  : 
@@ -164,8 +175,6 @@ filter       : HBA_210_250
 splitter     : ON
 nyquistZone  : 3
 
-Meas.set     : 
-
 (Receivers)  : [0..11]
 Stations     : [CS001,RS005,CS004]
 BLG nodes    : [bgl001..bgl003]
@@ -173,36 +182,53 @@ Storage nodes: [list001,list002]
 
 nrBeams      : 4
 Beam[0].name       : observation[5025]beam[0]_0
+Beam[0].target     : 
 Beam[0].antennaSet : HBA_ZERO
 Beam[0].momID      : 0
 Beam[0].subbandList: [2,3,4,5]
 Beam[0].beamletList: [0,1,2,3]
 nrPointings : 1
 Beam[0].pointing[0]: 6.000000, 0.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[1].name       : observation[5025]beam[0]_1
+Beam[1].target     : 
 Beam[1].antennaSet : HBA_ONE
 Beam[1].momID      : 0
 Beam[1].subbandList: [2,3,4,5]
 Beam[1].beamletList: [0,1,2,3]
 nrPointings : 1
 Beam[1].pointing[0]: 6.000000, 0.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[2].name       : observation[5025]beam[1]_0
+Beam[2].target     : 
 Beam[2].antennaSet : HBA_ZERO
 Beam[2].momID      : 0
 Beam[2].subbandList: [20,21,22,23,24,25,40,41,42,43,44]
 Beam[2].beamletList: [45,46,47,61,62,63,64,65,66,67,68]
 nrPointings : 1
 Beam[2].pointing[0]: 1.000000, 1.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[3].name       : observation[5025]beam[1]_1
+Beam[3].target     : 
 Beam[3].antennaSet : HBA_ONE
 Beam[3].momID      : 0
 Beam[3].subbandList: [20,21,22,23,24,25,40,41,42,43,44]
 Beam[3].beamletList: [45,46,47,61,62,63,64,65,66,67,68]
 nrPointings : 1
 Beam[3].pointing[0]: 1.000000, 1.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 beamlet2beams   : [0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,999,999,999,999,999,999,999,999,999,999,999,999,999,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999]
 nrAnaBeams   : 0
 
+DEBUG LCS.ApplCommon - Dataslots.CS001HBA0.DataslotList
 NEW SYNTAX
 
 Observation  : 
@@ -218,8 +244,6 @@ filter       : HBA_210_250
 splitter     : ON
 nyquistZone  : 3
 
-Meas.set     : 
-
 (Receivers)  : [0..11]
 Stations     : [CS001,RS005,CS004]
 BLG nodes    : [bgl001..bgl003]
@@ -227,33 +251,49 @@ Storage nodes: [list001,list002]
 
 nrBeams      : 4
 Beam[0].name       : observation[5025]beam[0]_0
+Beam[0].target     : 
 Beam[0].antennaSet : HBA_ZERO
 Beam[0].momID      : 0
 Beam[0].subbandList: [2,3,4,5]
 Beam[0].beamletList: [0,1,2,3]
 nrPointings : 1
 Beam[0].pointing[0]: 6.000000, 0.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[1].name       : observation[5025]beam[0]_1
+Beam[1].target     : 
 Beam[1].antennaSet : HBA_ONE
 Beam[1].momID      : 0
 Beam[1].subbandList: [2,3,4,5]
 Beam[1].beamletList: [0,1,2,3]
 nrPointings : 1
 Beam[1].pointing[0]: 6.000000, 0.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[2].name       : observation[5025]beam[1]_0
+Beam[2].target     : 
 Beam[2].antennaSet : HBA_ZERO
 Beam[2].momID      : 0
 Beam[2].subbandList: [20,21,22,23,24,25,40,41,42,43,44]
 Beam[2].beamletList: [45,46,47,61,62,63,64,65,66,67,68]
 nrPointings : 1
 Beam[2].pointing[0]: 1.000000, 1.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 Beam[3].name       : observation[5025]beam[1]_1
+Beam[3].target     : 
 Beam[3].antennaSet : HBA_ONE
 Beam[3].momID      : 0
 Beam[3].subbandList: [20,21,22,23,24,25,40,41,42,43,44]
 Beam[3].beamletList: [45,46,47,61,62,63,64,65,66,67,68]
 nrPointings : 1
 Beam[3].pointing[0]: 1.000000, 1.500000, J2000, 2008-Dec-16 15:30:00
+nrTABs      : 0
+nrTABrings  : 0
+TABringsize : 0
 beamlet2beams   : [0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,999,999,999,999,999,999,999,999,999,999,999,999,999,1,1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,999,999,999,999,999,999,999,999,999,999,999,999,999]
 nrAnaBeams   : 0
 
diff --git a/MAC/Deployment/data/OTDB/OLAP.comp b/MAC/Deployment/data/OTDB/OLAP.comp
index 0579289d0ee73cfaf329df5a84c6b52103612c0b..0098827a6e8b8fe12f6efef99a8a6e81e8c8a08b 100644
--- a/MAC/Deployment/data/OTDB/OLAP.comp
+++ b/MAC/Deployment/data/OTDB/OLAP.comp
@@ -30,7 +30,7 @@ node   CNProc_CoherentStokes     4.0.0  development 'node constraint'  "Coherent
 par  which                   I    ptext  -      10    0      "I|IQUV|XXYY;I"                           - "Which Stokes values to compute"
 par  channelsPerSubband      I    int    -      10    0      ">>Observation.channelsPerSubband"        - "Number of channels for Stokes data"
 par  timeIntegrationFactor   I    int    -      10    0      1                                         - "Time-wise integration of Stokes data (in samples)"
-par  subbandsPerFile         I	  int    -	10    0      1                                         - "the number of subbands each Stokes file will hold"
+par  subbandsPerFile         I	  int    -	10    0      512                                       - "the number of subbands each Stokes file will hold"
 
 # -- CNProc_IncoherentStokes --
 #
@@ -43,7 +43,7 @@ node   CNProc_IncoherentStokes   4.0.0  development 'node constraint'  "Incohere
 par  which                   I    ptext  -      10    0      "I|IQUV;I"                                - "Which Stokes values to compute"
 par  channelsPerSubband      I    int    -      10    0      ">>Observation.channelsPerSubband"        - "Number of channels for Stokes data"
 par  timeIntegrationFactor   I    int    -      10    0      1                                         - "Time-wise integration of Stokes data (in samples)"
-par  subbandsPerFile         I    int    -      10    0      1                                         - "the number of subbands each Stokes file will hold"
+par  subbandsPerFile         I    int    -      10    0      512                                       - "the number of subbands each Stokes file will hold"
 
 
 # -- OLAP_Conni --