From bd09e9a22e4d9d4516ee3b7988a66ac5832f7882 Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Fri, 15 Jan 2010 11:07:28 +0000
Subject: [PATCH] Bug 1237: AMCserver is not used anymore. Also not in the IBS
 protocol. All conversion are now done in the J2000Converter class. Since we
 link direct to casacore we also support B1950 and solarsystem objects.
 iBeamServer is still working for LBA antenna's only.

---
 MAC/APL/PAC/IBS_Protocol/configure.in         |   1 +
 .../include/APL/IBS_Protocol/Pointing.h       | 130 ++++-------
 MAC/APL/PAC/IBS_Protocol/src/Pointing.cc      | 114 ++--------
 MAC/APL/PAC/ITRFBeamServer/configure.in       |   2 +
 MAC/APL/PAC/ITRFBeamServer/src/Beam.cc        |   4 -
 MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc  |  67 +++---
 MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h   |   7 +-
 .../PAC/ITRFBeamServer/src/J2000Converter.cc  | 207 ++++++++++++++++++
 .../PAC/ITRFBeamServer/src/J2000Converter.h   |  94 ++++++++
 MAC/APL/PAC/ITRFBeamServer/src/Makefile.am    |   2 +-
 MAC/APL/PAC/ITRFBeamServer/src/beamctl.cc     |  10 +-
 11 files changed, 390 insertions(+), 248 deletions(-)
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.h

diff --git a/MAC/APL/PAC/IBS_Protocol/configure.in b/MAC/APL/PAC/IBS_Protocol/configure.in
index c8cb32f50f9..117ac030b21 100644
--- a/MAC/APL/PAC/IBS_Protocol/configure.in
+++ b/MAC/APL/PAC/IBS_Protocol/configure.in
@@ -52,6 +52,7 @@ dnl Check for LOFAR specific things
 dnl
 lofar_GENERAL
 lofar_INTERNAL(LCS/Common, Common, , 1, Common/LofarTypes.h,,)
+lofar_INTERNAL(MAC/MACIO, MACIO, , 1, MACIO/Marshalling.h,,)
 lofar_INTERNAL(MAC/APL/RTCCommon, RTCCommon, , 1, APL/RTCCommon/MarshallBlitz.h,,)
 lofar_EXTERNAL(BLITZ,1,blitz/blitz.h,,,,'gnu3:-Wno-unused gnu3:-ftemplate-depth-30',,-lm)
 
diff --git a/MAC/APL/PAC/IBS_Protocol/include/APL/IBS_Protocol/Pointing.h b/MAC/APL/PAC/IBS_Protocol/include/APL/IBS_Protocol/Pointing.h
index 7c9eda16fa1..d0365c9a315 100644
--- a/MAC/APL/PAC/IBS_Protocol/include/APL/IBS_Protocol/Pointing.h
+++ b/MAC/APL/PAC/IBS_Protocol/include/APL/IBS_Protocol/Pointing.h
@@ -23,129 +23,73 @@
 #ifndef POINTING_H_
 #define POINTING_H_
 
-#include <blitz/array.h>
 #include <APL/RTCCommon/Timestamp.h>
 
 namespace LOFAR {
-
-  // forward declarations
-  namespace AMC {
-    class Converter;
-    class Position;
-  };
-
   namespace IBS_Protocol {
 
-    /**
-     * Class with 
-     */
-    class Pointing
-      {
-      public:
-	/**
-	 * A direction can have one of these three types.
-	 */
-	enum Type {
-	  J2000 = 1,
-	  AZEL = 2,
-
-	  /**
-	   * The LOFAR station local coordinate system.
-	   * For the definition of this coordinate system see [ref].
-	   */
-	  LOFAR_LMN = 3,
-	};
-
+class Pointing
+{
+public:
 	//@{
-	/**
-	 * Constructors and destructors for a pointing.
-	 */
+	// Constructors and destructors for a pointing.
 	Pointing();
-	Pointing(double angle0, double angle1, RTC::Timestamp time, Type type);
+	Pointing(double angle0, double angle1, RTC::Timestamp time, const string& type);
 	virtual ~Pointing();
 	//@}
 
 	//@{
-	/**
-	 * 'set' methods to set the time and
-	 * direction of a pointing.
-	 */
+	// 'set' methods to set the time and
+	// direction of a pointing.
 	void setDirection(double angle0, double angle1);
 	void setTime(RTC::Timestamp time);
-	void setType(Type type);
+	void setType(const string& type);
 	//@}
 
 	//@{
-	/**
-	 * Accessor methods. Get the time and
-	 * direction of a pointing.
-	 */
+	// Accessor methods. Get the time and
+	// direction of a pointing.
 	double         			angle0()    const;
 	double         			angle1()    const;
 	RTC::Timestamp 			time()      const;
 	bool           			isTimeSet() const;
-	blitz::Array<double,1>	cartesian() const;	// convert the 2 angles to xyz elements.
+	string					getType()	const;
 	//@}
 
-	/**
-	 * Get the type of pointing.
-	 */
-	Type      getType() const;
-
-	/**
-	 * Convert pointing from J2000 or AZEL format to LMN format
-	 * if it is not already in LMN format.
-	 * param conv Pointer to the converter (must be != 0 for J2000 type).
-	 * param pos Pointer to position on earth for conversion (must be != 0 for J2000 type).
-	 */
-	Pointing convert(AMC::Converter* conv, AMC::Position* pos, Type reqtype = LOFAR_LMN);
-
-	/**
-	 * Compare the time of two pointings.
-	 * Needed for priority queue of pointings.
-	 */
+	// Compare the time of two pointings.
+	// Needed for priority queue of pointings.
 	bool operator<(Pointing const & right) const;
 
-      public:
 	/*@{*/
-	/**
-	 * marshalling methods
-	 */
+	// marshalling methods
 	unsigned int getSize();
 	unsigned int pack  (void* buffer);
 	unsigned int unpack(void *buffer);
 	/*@}*/
 
-      private:
-	double         m_angle0_2pi;
-	double         m_angle1_pi;
-	RTC::Timestamp m_time;
-	Type           m_type;
-      };
-
-    inline void   Pointing::setTime(RTC::Timestamp time) { m_time = time; }
-    inline void   Pointing::setType(Type type) { m_type = type; }
-    inline void   Pointing::setDirection(double angle0, double angle1) { m_angle0_2pi = angle0; m_angle1_pi = angle1; }
-    inline RTC::Timestamp Pointing::time() const      { return m_time;  }
-    inline bool   Pointing::isTimeSet() const { return !(0 == m_time.sec() && 0 == m_time.usec()); }
-    inline Pointing::Type Pointing::getType() const   { return m_type; }
-    inline double Pointing::angle0() const    { return m_angle0_2pi; }
-    inline double Pointing::angle1() const    { return m_angle1_pi; }
-
-	inline blitz::Array<double,1> Pointing::cartesian() const {
-		blitz::Array<double,1> tmpArr(3);
-		tmpArr(0) = ::cos(m_angle1_pi) * ::cos(m_angle0_2pi);  // x
-		tmpArr(1) = ::cos(m_angle1_pi) * ::sin(m_angle0_2pi);  // y
-		tmpArr(2) = ::sin(m_angle1_pi);  // z
-		return (tmpArr);
-	}
-
-    inline bool   Pointing::operator<(Pointing const & right) const
-      {
-        // inverse priority, earlier times are at the front of the queue
-        return (m_time > right.m_time);
-      }
-  };
+private:
+	double         itsAngle2Pi;
+	double         itsAnglePi;
+	RTC::Timestamp itsTime;
+	string         itsType;
 };
 
+inline void			  Pointing::setTime(RTC::Timestamp time) { itsTime = time; }
+inline void			  Pointing::setType(const string& type)	 { itsType = type; }
+inline void			  Pointing::setDirection(double angle0, double angle1) { itsAngle2Pi = angle0; itsAnglePi = angle1; }
+inline RTC::Timestamp Pointing::time() const      { return itsTime;  }
+inline bool			  Pointing::isTimeSet() const { return !(0 == itsTime.sec() && 0 == itsTime.usec()); }
+inline string		  Pointing::getType() const   { return itsType; }
+inline double		  Pointing::angle0() const    { return itsAngle2Pi; }
+inline double		  Pointing::angle1() const    { return itsAnglePi; }
+
+inline bool   Pointing::operator<(Pointing const & right) const
+{
+	// inverse priority, earlier times are at the front of the queue
+	return (itsTime > right.itsTime);
+}
+
+  }; // namespace IBS_Protocol
+}; // namespace LOFAR
+
 #endif /* POINTING_H_ */
diff --git a/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc b/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
index ed5407b7805..42c6ccb3b77 100644
--- a/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
+++ b/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
@@ -24,29 +24,23 @@
 #include <Common/LofarLogger.h>
 #include <Common/LofarTypes.h>
 #include <APL/IBS_Protocol/Pointing.h>
-
-#include <AMCBase/Converter.h>
-#include <AMCBase/RequestData.h>
-#include <AMCBase/ResultData.h>
-
-#include <cmath>
+#include <MACIO/Marshalling.h>
 
 using namespace LOFAR;
 using namespace IBS_Protocol;
-using namespace AMC;
 
 //
 // Pointing()
 //
 Pointing::Pointing() : 
-	m_angle0_2pi(0.0), m_angle1_pi(0.0), m_time(), m_type(LOFAR_LMN)
+	itsAngle2Pi(0.0), itsAnglePi(0.0), itsTime(), itsType("NONE")
 {}
 
 //
 // Pointing(angle, angle, time, type)
 //
-Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, Type type) :
-	m_angle0_2pi(angle0), m_angle1_pi(angle1), m_time(time), m_type(type)
+Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, const string& type) :
+	itsAngle2Pi(angle0), itsAnglePi(angle1), itsTime(time), itsType(type)
 {}
 
 //
@@ -55,90 +49,13 @@ Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, Type type)
 Pointing::~Pointing()
 {}
 
-//
-// convert(converter, position, requestedType)
-//
-// Converts a pointing to another coordinatesystem.
-// Supports: 
-//	J2000 --> AZEL
-//	J2000 --> LMN
-//	AZEL  --> LMN
-//
-Pointing Pointing::convert(Converter* conv, Position* pos, Pointing::Type reqType)
-{
-	if (getType() == reqType) {	// no conversion needed?
-		return (*this);
-	}
-
-	ASSERT(conv && pos);		// always need converter and position
-
-	// start with current coordinates
-	// angle0 = longitude = RA, Az or l
-	// angle1 = latitude  = Dec, El or m
-	Direction resultDir = Direction(angle0(), angle1());
-	double
-		mjd      = 0.0,
-		fraction = 0.0,
-		az       = angle0(),
-		el       = angle1(),
-		l        = angle0(),
-		m        = angle1(),
-		n        = 0.0;
-
-	// setup the AMC classes.
-	time().convertToMJD(mjd, fraction); // mjd,fraction in UTC
-	RequestData 	request(resultDir, *pos, Epoch(mjd, fraction));
-	ResultData 		resultdata;
-
-	switch (getType()) {		// determines when conversion chain begins
-	case J2000:
-		// convert J2000 to LMN
-		LOG_TRACE_VAR_STR("J2000(rad)=(" << resultDir.longitude() << ", " 
-										 << resultDir.latitude() << ")");
-		conv->j2000ToAzel(resultdata, request);
-		resultDir = resultdata.direction[0];
-		az = resultDir.longitude();
-		el = resultDir.latitude();
-
-		// now convert from azel to lmn by falling through to AZEL label
-		// Note: break omitted intentionally 
-
-	case AZEL:
-		// convert AZEL to LMN
-		LOG_TRACE_VAR_STR("AZEL(rad)=(" << az << ", " << el << ")");
-
-		if (reqType == AZEL) {					// return AZEL pointing?
-			return (Pointing(az, el, time(), AZEL));
-		}
-
-		// See LOFAR-ASTRON-MEM-105, top of page 7
-		l = ::cos(el) * ::sin(az);
-		m = ::cos(el) * ::cos(az);
-		n = ::sin(el);
-
-		// Note: break omitted intentionally
-
-	case LOFAR_LMN:
-		// coordinates are already in LMN format
-		LOG_DEBUG_STR("lmn=(" << l << ", " << m << ", " << n << ")");
-		break;
-
-	default:
-		LOG_FATAL("invalid switch value");
-		exit(EXIT_FAILURE);
-		break;
-	}
-
-	return Pointing(l, m, time(), LOFAR_LMN);	// return LOFAR_LMN pointing
-}
-
 // -------------------- routines for streaming the object --------------------
 //
 // getSize()
 //
 unsigned int Pointing::getSize()
 {
-	return (sizeof(double) * 2) + m_time.getSize() + sizeof(uint8);
+	return (sizeof(double) * 2) + itsTime.getSize() + MSH_STRING_SIZE(itsType);
 }
 
 //
@@ -148,14 +65,12 @@ unsigned int Pointing::pack  (void* buffer)
 {
 	unsigned int offset = 0;
 
-	memcpy((char*)buffer + offset, &m_angle0_2pi, sizeof(double));
+	memcpy((char*)buffer + offset, &itsAngle2Pi, sizeof(double));
 	offset += sizeof(double);
-	memcpy((char*)buffer + offset, &m_angle1_pi, sizeof(double));
+	memcpy((char*)buffer + offset, &itsAnglePi, sizeof(double));
 	offset += sizeof(double);
-	offset += m_time.pack((char*)buffer + offset);
-	uint8 	type = m_type;
-	memcpy((char*)buffer + offset, &type, sizeof(uint8));
-	offset += sizeof(uint8);
+	offset += itsTime.pack((char*)buffer + offset);
+	MSH_PACK_STRING(buffer, offset, itsType);
 
 	return (offset);
 }
@@ -167,15 +82,12 @@ unsigned int Pointing::unpack(void *buffer)
 {
 	unsigned int offset = 0;
 
-	memcpy(&m_angle0_2pi, (char*)buffer + offset, sizeof(double));
+	memcpy(&itsAngle2Pi, (char*)buffer + offset, sizeof(double));
 	offset += sizeof(double);
-	memcpy(&m_angle1_pi, (char*)buffer + offset, sizeof(double));
+	memcpy(&itsAnglePi, (char*)buffer + offset, sizeof(double));
 	offset += sizeof(double);
-	offset += m_time.unpack((char*)buffer + offset);
-	uint8 	type = 0;
-	memcpy(&type, (char*)buffer + offset, sizeof(uint8));
-	m_type = (Type)type;
-	offset += sizeof(uint8);
+	offset += itsTime.unpack((char*)buffer + offset);
+	MSH_UNPACK_STRING(buffer , offset, itsType);
 
 	return (offset);
 }
diff --git a/MAC/APL/PAC/ITRFBeamServer/configure.in b/MAC/APL/PAC/ITRFBeamServer/configure.in
index 3f795fbca9d..b0560a9e5f6 100644
--- a/MAC/APL/PAC/ITRFBeamServer/configure.in
+++ b/MAC/APL/PAC/ITRFBeamServer/configure.in
@@ -60,6 +60,7 @@ dnl Check for LOFAR specific things
 dnl
 lofar_GENERAL
 lofar_COMPILETOOLS
+lofar_AIPSPP(1,"-lmeasures -ltables -lscimath -lscimath_f -lcasa")
 
 lofar_INTERNAL(LCS/Common, Common, , 1, Common/LofarTypes.h,,)
 lofar_INTERNAL(LCS/ApplCommon, ApplCommon, , 1, ApplCommon/StationConfig.h,,)
@@ -81,4 +82,5 @@ AC_CONFIG_FILES([test/runctest.sh:autoconf_share/runctest.sh.in],
 AC_OUTPUT(
 	Makefile
 	src/Makefile
+	test/Makefile
 )
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc b/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
index 00b0b0e4b3c..fd4592bb90d 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
+++ b/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
@@ -25,9 +25,6 @@
 #include <Common/LofarLocators.h>
 #include <Common/LofarConstants.h>
 
-#include <AMCBase/Converter.h>
-#include <AMCBase/Position.h>
-
 #include <APL/RTCCommon/PSAccess.h>
 #include "BeamServerConstants.h"
 #include "Beam.h"
@@ -43,7 +40,6 @@
 
 using namespace blitz;
 using namespace LOFAR;
-using namespace AMC;
 using namespace BS;
 using namespace IBS_Protocol;
 using namespace std;
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
index c1c6899c423..12bbb3c0b50 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
+++ b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
@@ -35,13 +35,6 @@
 #include <APL/RSP_Protocol/RSP_Protocol.ph>
 #include <APL/CAL_Protocol/CAL_Protocol.ph>
 
-#include <AMCBase/Converter.h>
-#include <AMCBase/RequestData.h>
-#include <AMCBase/ResultData.h>
-#include <AMCBase/Position.h>
-#include <AMCBase/Direction.h>
-#include <AMCBase/Epoch.h>
-
 #include "BeamServer.h"
 #include "BeamServerConstants.h"
 #include "Package__Version.h"
@@ -63,7 +56,6 @@ namespace LOFAR {
   using namespace IBS_Protocol;
   using namespace RSP_Protocol;
   using namespace GCF::TM;
-  using namespace AMC;
   namespace BS {
 
 int	gBeamformerGain = 0;
@@ -78,7 +70,6 @@ BeamServer::BeamServer(const string& name, long	timestamp) :
 	itsListener				(0),
 	itsRSPDriver			(0),
 	itsCalServer			(0),
-	itsAMCclient			("localhost"),
 	itsBeamsModified		(false),
 	itsUpdateInterval		(UPDATE_INTERVAL),
 	itsComputeInterval		(COMPUTE_INTERVAL),
@@ -1354,7 +1345,7 @@ inline complex<int16_t> convert2complex_int16_t(complex<double> cd)
 // This method is called once every period of COMPUTE_INTERVAL seconds
 // to calculate the weights for all beamlets.
 //
-void BeamServer::compute_weights(Timestamp weightTime)
+bool BeamServer::compute_weights(Timestamp weightTime)
 {
 	// TEMP CODE FOR EASY TESTING THE BEAMSERVER VALUES
 	if (itsTestSingleShotTimestamp) {
@@ -1382,10 +1373,16 @@ void BeamServer::compute_weights(Timestamp weightTime)
 		blitz::Array<double, 2> rcuPosITRF = LBAfield ? itsAntennaPos->LBARCUPos() : itsAntennaPos->HBARCUPos();
 		LOG_DEBUG_STR("ITRFRCUPos = " << rcuPosITRF);
 
-		// Get geographical location of subarray in ITRF and place it in an AMC Position class.
+		// Get geographical location of subarray in ITRF
 		blitz::Array<double, 1> fieldCentreITRF = LBAfield ? itsAntennaPos->LBACentre() : itsAntennaPos->HBACentre();
-		Position	fieldPositionITRF(Coord3D(blitz2vector(fieldCentreITRF)), Position::ITRF);
-		LOG_DEBUG_STR("ITRF position antennaField: " << fieldPositionITRF);
+		LOG_DEBUG_STR("ITRF position antennaField: " << fieldCentreITRF);
+
+		// convert ITRF position of all antennas to J2000 for timestamp t
+		blitz::Array<double,2>	rcuJ2000Pos;
+		if (!itsJ2000Converter.doConversion("ITRF", rcuPosITRF, fieldCentreITRF, weightTime, rcuJ2000Pos)) {
+			LOG_FATAL_STR("Conversion of antennas to J2000 failed");
+			return(false);
+		}
 
 		// Lengths of the vector of the antennaPosition i.r.t. the fieldCentre,
 		blitz::Array<double,1>	rcuPosLengths = LBAfield ? itsAntennaPos->LBARCULengths() : itsAntennaPos->HBARCULengths();
@@ -1400,19 +1397,16 @@ void BeamServer::compute_weights(Timestamp weightTime)
 			}
 			// Get the right pointing
 			Pointing	currentPointing = beamIter->second->currentPointing(weightTime);
-			double mjd(0);
-			double mjd_fraction(0);
-			currentPointing.time().convertToMJD(mjd, mjd_fraction);
-
-			// Convert pointing of source to J2000 for centre of Antennafield
-			// TODO: REO 111109: next line wil only work for J2000, AZEL to J2000 is not implemented in Pointing.cc
-			blitz::Array<double,1>	sourceJ2000xyz(3);
-			sourceJ2000xyz(Range::all())  = currentPointing.convert(&itsAMCclient, &fieldPositionITRF, Pointing::J2000).cartesian();
+			blitz::Array<double,2>	sourceJ2000xyz;
+			blitz::Array<double,2>	curPoint(1,2);
+			curPoint(0,0) = currentPointing.angle0();
+			curPoint(0,1) = currentPointing.angle1();
+			if (!itsJ2000Converter.doConversion(currentPointing.getType(), curPoint, fieldCentreITRF, weightTime, sourceJ2000xyz)) {
+				LOG_FATAL_STR("Conversion of source to J2000 failed");
+				return(false);
+			}
 			LOG_DEBUG_STR("sourceJ2000xyz:" << sourceJ2000xyz);
 
-			// declare J2000SingleRCUPos
-			blitz::Array<double,1>	J2000SingleRCUPos(3);
-
 			bitset<MAX_RCUS>	RCUallocation(beamIter->second->rcuMask());
 			for (int rcu = 0; rcu < MAX_RCUS; rcu++) {
 				if (!RCUallocation.test(rcu)) {			// all RCUS switched on in LBA/HBA mode
@@ -1424,19 +1418,8 @@ void BeamServer::compute_weights(Timestamp weightTime)
 				//
 				// Convert the ITRF position of this RCU to J2000 for time=weightTime
 				//
-				RequestData	request(Direction(Coord3D(blitz2vector(rcuPosITRF(rcu, Range::all()))), Direction::ITRF),
-									fieldPositionITRF,
-									Epoch(mjd, mjd_fraction));
-				ResultData	result;
-				itsAMCclient.itrfToJ2000(result, request);
-				vector<double>	direction = result.direction[0].coord().get();
-
-				// Note AMCServer returns an unit vector.
-				J2000SingleRCUPos(0) = direction[0] * rcuPosLengths(rcu);
-				J2000SingleRCUPos(1) = direction[1] * rcuPosLengths(rcu);
-				J2000SingleRCUPos(2) = direction[2] * rcuPosLengths(rcu);
-				LOG_DEBUG_STR("J2000RCUPos[" << rcu << "]=[" << J2000SingleRCUPos(0) << ", " << 
-								J2000SingleRCUPos(1) << ", " << J2000SingleRCUPos(2) << "]");
+				rcuJ2000Pos(rcu, Range::all()) *= rcuPosLengths(rcu);
+				LOG_DEBUG_STR("J2000RCUPos[" << rcu << "]=" << rcuJ2000Pos(rcu, Range::all()));
 				// END OF NOTE.
 
 				//
@@ -1451,9 +1434,9 @@ void BeamServer::compute_weights(Timestamp weightTime)
 					}
 
 					itsWeights(rcu, beamlet) = exp(itsBeamletAllocation[beamlet].scaling * 
-							(J2000SingleRCUPos(0) * sourceJ2000xyz(0) +
-							 J2000SingleRCUPos(1) * sourceJ2000xyz(1) +
-							 J2000SingleRCUPos(2) * sourceJ2000xyz(2)));
+							(rcuJ2000Pos(rcu, 0) * sourceJ2000xyz(0) +
+							 rcuJ2000Pos(rcu, 1) * sourceJ2000xyz(1) +
+							 rcuJ2000Pos(rcu, 2) * sourceJ2000xyz(2)));
 
 					// some debugging
 					if (itsWeights(rcu, beamlet) != complex<double>(1,0)) {
@@ -1462,7 +1445,7 @@ void BeamServer::compute_weights(Timestamp weightTime)
 					// some more debugging
 					if (rcu==4 && beamlet==6) {
 						LOG_DEBUG_STR("###scaling     = " << itsBeamletAllocation[beamlet].scaling);
-						LOG_DEBUG_STR("###J2000RCUpos = " << J2000SingleRCUPos(Range::all()));
+						LOG_DEBUG_STR("###J2000RCUpos = " << rcuJ2000Pos(rcu, Range::all()));
 						LOG_DEBUG_STR("###J2000xyz    = " << sourceJ2000xyz(Range::all()));
 					}
 				} // beamlets
@@ -1474,6 +1457,8 @@ void BeamServer::compute_weights(Timestamp weightTime)
 	itsWeights16 = convert2complex_int16_t(itsWeights);
 
 	LOG_DEBUG(formatString("sizeof(itsWeights16) = %d", itsWeights16.size()*sizeof(int16_t)));
+
+	return (true);
 }
 
 //
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
index cea46a7c5a1..517dfa714fe 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
+++ b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
@@ -25,10 +25,9 @@
 
 #include <Common/lofar_string.h>
 #include <APL/IBS_Protocol/IBS_Protocol.ph>
+#include "J2000Converter.h"
 #include "Beam.h"
 
-#include <AMCBase/ConverterClient.h>
-
 #include <GCF/TM/GCF_Control.h>
 //#include <GCF/TM/GCF_TimerPort.h>
 #include <APL/APLCommon/AntennaSets.h>
@@ -147,7 +146,7 @@ public:
 
 	// Time to compute some more weights.
 	// @param current_seconds Time in seconds since 1 Jan 1970
-	void compute_weights(RTC::Timestamp time);
+	bool compute_weights(RTC::Timestamp time);
 
 	// Send weights to the board.
 	void send_weights(RTC::Timestamp time);
@@ -227,9 +226,9 @@ private:
 
 	BeamTransaction				itsBeamTransaction; 	// current beam transaction
 
+	J2000Converter				itsJ2000Converter;		// casacore based converter to J2000
 	GCFTCPPort* 				itsRSPDriver;			// connection to RSPDriver
 	GCFTCPPort*					itsCalServer;  			// connection to CalServer
-	AMC::ConverterClient		itsAMCclient;
 	GCFTimerPort*  				itsHeartbeatTimer;  	//
 	GCFTimerPort*  				itsTimerPort;		  	// General purpose timer
 	bool     					itsBeamsModified;		//
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.cc b/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.cc
new file mode 100644
index 00000000000..ec1efea6265
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.cc
@@ -0,0 +1,207 @@
+//#  J2000Converter.cc: one_line_description
+//#
+//#  Copyright (C) 2010
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+//# Always #include <lofar_config.h> first!
+#include <lofar_config.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+
+#include <measures/Measures.h>
+#include <measures/Measures/MEpoch.h>
+#include <measures/Measures/MPosition.h>
+#include <measures/Measures/MDirection.h>
+#include <measures/Measures/MeasConvert.h>
+#include <measures/Measures/MCDirection.h>
+
+#include "J2000Converter.h"
+
+namespace LOFAR {
+  namespace BS {
+
+using namespace casa;
+using namespace blitz;
+using namespace RTC;
+
+char*	supportedTypes[] = { "ITRF", "B1950", "AZEL", 
+							 "MERCURY", "VENUS", "MARS", "JUPITER", "SATURN", "URANUS", "NEPTUNE", "PLUTO", "SUN", "MOON"  
+							 "" };
+
+
+//
+// J2000Converter()
+//
+J2000Converter::J2000Converter()
+{
+	// First setup a map with the supported conversion types.
+	MDirection::Types		aType;
+	int	t = 0;
+	while (supportedTypes[t]) {
+		if (!MDirection::getType(aType, supportedTypes[t])) {
+			LOG_ERROR_STR("Type " << supportedTypes[t] << " not supported by this version of casacore!");
+		}
+		LOG_DEBUG_STR("Adding support for " << supportedTypes[t]);
+		itsDirectionTypes[supportedTypes[t]] = aType;
+		t++;
+	}
+	ASSERTSTR(!itsDirectionTypes.empty(), "Can not resolve any coordinatesystem in casacore.");
+}
+
+//
+// ~J2000Converter()
+//
+J2000Converter::~J2000Converter()
+{
+	// cleanup all our variables.
+	itsConverters.clear();
+	itsDirectionTypes.clear();
+}
+
+//
+// _getConverter(types)
+//
+J2000Converter::converter_t* J2000Converter::_getConverter(MDirection::Types		theType)
+{
+	// simplify logging
+	string	typeName(MDirection::showType(theType));
+
+	// try to find the converter. If it is already there then we are done
+	map<MDirection::Types, converter_t>::iterator     iter(itsConverters.find(theType));
+	if (iter != itsConverters.end()) {
+		LOG_INFO_STR("Using existing " << typeName << " to J2000 converter");
+		return (&(iter->second));
+	}
+
+	// convertor not yet defined
+	converter_t		newConverter;
+	try {
+		newConverter.frame.set(MEpoch(Quantity(55000.0, "d"), MEpoch::UTC)); // somewhere in 2009
+		newConverter.frame.set(MPosition(MVPosition(0.0, 0.0, 0.0), MPosition::ITRF));
+		newConverter.conv = MDirection::Convert(MDirection::Ref(theType), 
+												MDirection::Ref(MDirection::J2000, newConverter.frame));
+	}
+	catch (AipsError&	e) {
+		LOG_FATAL_STR("CASA ERROR while creating an convertor from "<< typeName << " to J2000: " << e.what());
+		return (NULL);
+	}
+
+	if (newConverter.conv.isNOP()) {
+		LOG_FATAL_STR("Unable to create a converter from " << typeName << " to J2000");
+		return (NULL);
+	}
+
+	LOG_INFO_STR("Created a converter from " << typeName << " to J2000");
+	itsConverters[theType] = newConverter;
+	return (&itsConverters[theType]);
+}
+
+//
+// _cartesian(angle2Pi, angle1Pi)
+//
+blitz::Array<double,1>	J2000Converter::_cartesian(double	angle2Pi, double	angle1Pi) {
+	blitz::Array<double,1> tmpArr(3);
+	double	cosPi = ::cos(angle1Pi);
+	tmpArr(0) = cosPi * ::cos(angle2Pi); // x
+	tmpArr(1) = cosPi * ::sin(angle2Pi); // y
+	tmpArr(2) = ::sin(angle1Pi); // z
+	return (tmpArr);
+}
+
+//
+// doConversion(vector<MDirectoin>, MPosition, timestamp)
+//
+// Convert directions or position from whatever coordinate system to J2000 positions.
+//
+bool  J2000Converter::doConversion(const string&					sourceType,
+								   const blitz::Array<double,2>& 	antPos,
+								   const blitz::Array<double,1>&	ITRFfieldPos,
+								   Timestamp						theTime,
+								   blitz::Array<double,2>&			result)
+{
+	// Are the sources directions or positions?
+	bool	srcIsDirection = (antPos.extent(secondDim) == 2);
+
+	// sanity check
+	ASSERTSTR(antPos.extent(secondDim) == 3 || antPos.extent(secondDim) == 2, 
+				"antPos must have 2 or 3 elements per row not " << antPos.extent(secondDim));
+	ASSERTSTR(ITRFfieldPos.extent(firstDim) == 3, 
+				"ITRFfieldPos must have 3 elements not " << ITRFfieldPos.extent(firstDim));
+
+	// clear result array
+	result.free();
+
+	// sleeping user?
+	if (sourceType == "J2000") {
+		if (srcIsDirection) {
+			result.resize(antPos.extent(firstDim), 3);
+			for (int i = antPos.extent(firstDim)-1; i >= 0; i--) {
+				result(i, Range::all()) = _cartesian(antPos(i,0), antPos(i,1));
+			}
+			return (true);
+		}
+		// source are positions, just copy to the result array.
+		result.resize(antPos.shape());
+		result = antPos;
+		return (true);
+	}
+
+	// find converter
+	map<string, MDirection::Types>::const_iterator	iter(itsDirectionTypes.find(sourceType));
+	if (iter == itsDirectionTypes.end()) {
+		LOG_FATAL_STR("No support for conversion from " << sourceType << " to J2000");
+		return (false);
+	}
+
+	converter_t*		theConv = _getConverter(iter->second);
+	if (theConv->conv.isNOP()) {
+		LOG_FATAL_STR("No converter available, returning empty result");
+		return (false);
+	}
+
+	// reinit the frame of the converter
+	theConv->frame.resetPosition(MPosition(MVPosition(ITRFfieldPos(0),ITRFfieldPos(1),ITRFfieldPos(2)), MPosition::ITRF));
+	double	mjd;
+	double	mjdFraction;
+	theTime.convertToMJD(mjd, mjdFraction);
+	theConv->frame.resetEpoch(MVEpoch(mjd, mjdFraction));
+
+	// do the conversions
+	int	nrDirections(antPos.extent(firstDim));
+	result.resize(nrDirections, 3);
+	MDirection	J2000Dir;
+	for (int d = 0; d < nrDirections; d++) {
+		if (srcIsDirection) {
+			J2000Dir = theConv->conv(MVDirection(antPos(d,0), antPos(d,1)));
+		}
+		else {
+			J2000Dir = theConv->conv(MVDirection(antPos(d,0), antPos(d,1), antPos(d,2)));
+		}
+		casa::Vector<Double>	angles = J2000Dir.getValue().get();
+		result(d, Range::all()) = _cartesian(angles(0), angles(1));
+	}
+
+	return (true);
+}
+
+
+  } // namespace BS
+} // namespace LOFAR
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.h b/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.h
new file mode 100644
index 00000000000..323c7493934
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/J2000Converter.h
@@ -0,0 +1,94 @@
+//#  J2000Converter.h: one_line_description
+//#
+//#  Copyright (C) 2010
+//#  ASTRON (Netherlands Foundation for Research in Astronomy)
+//#  P.O.Box 2, 7990 AA Dwingeloo, The Netherlands, seg@astron.nl
+//#
+//#  This program is free software; you can redistribute it and/or modify
+//#  it under the terms of the GNU General Public License as published by
+//#  the Free Software Foundation; either version 2 of the License, or
+//#  (at your option) any later version.
+//#
+//#  This program is distributed in the hope that it will be useful,
+//#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//#  GNU General Public License for more details.
+//#
+//#  You should have received a copy of the GNU General Public License
+//#  along with this program; if not, write to the Free Software
+//#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//#
+//#  $Id$
+
+#ifndef BS_J2000_CONVERTER_H
+#define BS_J2000_CONVERTER_H
+
+// \file J2000Converter.h
+// one_line_description
+
+//# Never #include <config.h> or #include <lofar_config.h> in a header file!
+//# Includes
+#include <blitz/array.h>
+#include <measures/Measures.h>
+#include <measures/Measures/MEpoch.h>
+#include <measures/Measures/MPosition.h>
+#include <measures/Measures/MDirection.h>
+#include <measures/Measures/MeasConvert.h>
+#include <measures/Measures/MCDirection.h>
+#include <APL/RTCCommon/Timestamp.h>
+
+// Avoid 'using namespace' in headerfiles
+
+namespace LOFAR {
+  namespace BS {
+
+// \addtogroup package
+// @{
+
+//# --- Forward Declarations ---
+//# classes mentioned as parameter or returntype without virtual functions.
+
+
+// class_description
+// ...
+class J2000Converter
+{
+public:
+	J2000Converter();
+	~J2000Converter();
+
+	// Converts the given directions to J2000 directions for Position on Earth at time Timestamp
+	bool  doConversion(const string&					sourceType,
+					   const blitz::Array<double,2>&	antPos,
+					   const blitz::Array<double,1>&	ITRFfieldPos,
+					   RTC::Timestamp					theTime,
+					   blitz::Array<double,2>&			result);
+
+private:
+	// internal admin structures
+	typedef struct converter {
+		casa::MDirection::Convert	conv;
+		casa::MeasFrame				frame;
+	} converter_t;
+
+	// private helper routines
+	converter_t*			_getConverter(casa::MDirection::Types);
+	blitz::Array<double,1>	_cartesian(double	angle2Pi, double	angle1Pi);
+
+	// Copying is not allowed
+	J2000Converter(const J2000Converter&	that);
+	J2000Converter& operator=(const J2000Converter& that);
+
+	//# --- Datamembers ---
+	// name, type map
+	map<string, casa::MDirection::Types>		itsDirectionTypes;
+
+	// type, converter_t map
+	map<casa::MDirection::Types, converter_t>	itsConverters;
+};
+
+// @}
+  } // namespace PACKAGE
+} // namespace LOFAR
+
+#endif
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am b/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
index c85be739ee2..ab7eb3bf97f 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
+++ b/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
@@ -20,7 +20,7 @@ sysconf_DATA 			=
 bin_PROGRAMS 			= iBeamServer ibeamctl
 
 iBeamServer_SOURCES 		= BeamServerMain.cc BeamServer.h BeamServerConstants.h BeamServer.cc \
-							  Beam.h Beam.cc 
+							  Beam.h Beam.cc J2000Converter.h J2000Converter.cc
 iBeamServer_LDADD 			= 
 iBeamServer_DEPENDENCIES	= $(LOFAR_DEPEND)
 
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/beamctl.cc b/MAC/APL/PAC/ITRFBeamServer/src/beamctl.cc
index 54d05924be4..ea2dcd733f8 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/beamctl.cc
+++ b/MAC/APL/PAC/ITRFBeamServer/src/beamctl.cc
@@ -384,12 +384,13 @@ void beamctl::send_direction(double	longitude, double	latitude, const string&	di
 	pointto.beamName = itsBeamHandle;
 	pointto.pointing.setDirection(longitude, latitude);
 	pointto.analogue = isAnalogue;
+	// TODO UPDATE THIS TO THE NEW CASACORE INTERFACE
 	if (dirType == "J2000") {
-		pointto.pointing.setType(Pointing::J2000);
+		pointto.pointing.setType(dirType);
 	} else if (dirType == "AZEL") {
-		pointto.pointing.setType(Pointing::AZEL);
+		pointto.pointing.setType(dirType);
 	} else if (dirType == "LOFAR_LMN") {
-		pointto.pointing.setType(Pointing::LOFAR_LMN);
+		pointto.pointing.setType(dirType);
 	} else if (dirType != "SKYSCAN") {
 		LOG_FATAL_STR("Error: invalid coordinate type '" << dirType << "'");
 		exit(EXIT_FAILURE);
@@ -403,7 +404,8 @@ void beamctl::send_direction(double	longitude, double	latitude, const string&	di
 	// SKYSCAN
 	Timestamp time, end_time;
 	time.setNow(SKYSCAN_STARTDELAY); // start after appropriate delay
-	pointto.pointing.setType(Pointing::LOFAR_LMN);
+	// TODO HOW TO CONVERT THIS?
+//	pointto.pointing.setType(Pointing::LOFAR_LMN);
 
 	// step through l and m
 	int l_steps = static_cast<int>(longitude);
-- 
GitLab