From 5523be75d554f78fedd8c9aff43714f9bab675ad Mon Sep 17 00:00:00 2001
From: Ruud Overeem <overeem@astron.nl>
Date: Thu, 21 Jan 2010 15:01:55 +0000
Subject: [PATCH] Bug 1237: Datamodel of beam split into a base class Beam (=
 collection of pointings and rcus) and two derived classes DigitalBeam (+=
 subbands and beamlets) and AnalogueBeam (+= rank). Introduced a AnaBeamMgr to
 manage the analogue beams. Made several classes printable.

---
 .../include/APL/IBS_Protocol/Pointing.h       |  50 ++-
 .../PAC/IBS_Protocol/src/IBS_Protocol.prot    |  48 ++-
 MAC/APL/PAC/IBS_Protocol/src/Pointing.cc      |  47 ++-
 MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.cc  | 318 ++++++++++++++++++
 MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.h   | 108 ++++++
 .../PAC/ITRFBeamServer/src/AnalogueBeam.cc    | 176 ++++++++++
 MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.h |  71 ++++
 MAC/APL/PAC/ITRFBeamServer/src/Beam.cc        | 283 +++++++---------
 MAC/APL/PAC/ITRFBeamServer/src/Beam.h         |  99 ++----
 MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc  |  40 +--
 MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h   |  18 +-
 MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.cc |  88 +++++
 MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.h  | 121 +++++++
 MAC/APL/PAC/ITRFBeamServer/src/Makefile.am    |   9 +-
 MAC/APL/PAC/ITRFBeamServer/test/Makefile.am   |  13 +
 .../PAC/ITRFBeamServer/test/tAnaBeamMgr.cc    | 147 ++++++++
 MAC/APL/PAC/ITRFBeamServer/test/tConverter.cc | 188 +++++++++++
 .../ITRFBeamServer/test/tJ2000Converter.cc    |  84 +++++
 18 files changed, 1630 insertions(+), 278 deletions(-)
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.h
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.h
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.h
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/test/Makefile.am
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/test/tAnaBeamMgr.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/test/tConverter.cc
 create mode 100644 MAC/APL/PAC/ITRFBeamServer/test/tJ2000Converter.cc

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 d0365c9a315..84d4a6ff2b8 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
@@ -34,7 +34,7 @@ public:
 	//@{
 	// Constructors and destructors for a pointing.
 	Pointing();
-	Pointing(double angle0, double angle1, RTC::Timestamp time, const string& type);
+	Pointing(double angle0, double angle1, RTC::Timestamp time, uint duration, const string& type);
 	virtual ~Pointing();
 	//@}
 
@@ -42,8 +42,9 @@ public:
 	// 'set' methods to set the time and
 	// direction of a pointing.
 	void setDirection(double angle0, double angle1);
-	void setTime(RTC::Timestamp time);
-	void setType(const string& type);
+	void setTime	 (RTC::Timestamp time);
+	void setDuration (uint duration);
+	void setType	 (const string& type);
 	//@}
 
 	//@{
@@ -52,6 +53,8 @@ public:
 	double         			angle0()    const;
 	double         			angle1()    const;
 	RTC::Timestamp 			time()      const;
+	RTC::Timestamp			endTime()	const;
+	uint					duration()	const;
 	bool           			isTimeSet() const;
 	string					getType()	const;
 	//@}
@@ -60,6 +63,12 @@ public:
 	// Needed for priority queue of pointings.
 	bool operator<(Pointing const & right) const;
 
+	// Check if the pointing overlap each other.
+	bool overlap(const Pointing&	that) const;
+
+	// Output function
+	ostream& print (ostream& os) const;
+
 	/*@{*/
 	// marshalling methods
 	unsigned int getSize();
@@ -68,25 +77,40 @@ public:
 	/*@}*/
 
 private:
-	double         itsAngle2Pi;
-	double         itsAnglePi;
-	RTC::Timestamp itsTime;
-	string         itsType;
+	double      	itsAngle2Pi;
+	double      	itsAnglePi;
+	RTC::Timestamp	itsTime;
+	uint			itsDuration;
+	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 void			  Pointing::setDuration(uint duration) { itsDuration = duration; }
+inline RTC::Timestamp Pointing::time() const      { return (itsTime);  }
+inline RTC::Timestamp Pointing::endTime() const   { return (itsDuration ? itsTime+(long)itsDuration : RTC::Timestamp::maxTime());  }
+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 uint			  Pointing::duration() const  { return (itsDuration); }
 
+//
+// operator<
+//
 inline bool   Pointing::operator<(Pointing const & right) const
 {
 	// inverse priority, earlier times are at the front of the queue
-	return (itsTime > right.itsTime);
+	return (itsTime < right.itsTime);
+}
+
+//
+// operator<<
+//
+inline ostream& operator<< (ostream& os, const Pointing& pt) 
+{
+	return (pt.print(os));
 }
 
   }; // namespace IBS_Protocol
diff --git a/MAC/APL/PAC/IBS_Protocol/src/IBS_Protocol.prot b/MAC/APL/PAC/IBS_Protocol/src/IBS_Protocol.prot
index 379b3382a6d..6fb3182da24 100644
--- a/MAC/APL/PAC/IBS_Protocol/src/IBS_Protocol.prot
+++ b/MAC/APL/PAC/IBS_Protocol/src/IBS_Protocol.prot
@@ -15,6 +15,7 @@ include = '<Common/LofarConstants.h>';
 include = '<APL/IBS_Protocol/Beamlet2SubbandMap.h>';
 include = '<APL/IBS_Protocol/Pointing.h>';
 include = '<APL/RTCCommon/Timestamp.h>';
+include = '<MACIO/StringVector.h>';
 
 prelude = << PRELUDE_END
 
@@ -22,10 +23,10 @@ prelude = << PRELUDE_END
 // Errors
 //
 // IBS_NO_ERR			No errors
-// IBS_RANGE_ERR			Range error in message parameters
+// IBS_RANGE_ERR		Range error in message parameters
 // IBS_WRONG_RING_ERR	Rcu's specified in the wrong ring
 // IBS_SPLITTER_OFF_ERR	Splitter is off, no ring 1
-// IBS_BEAMALLOC_ERR		Could not alloc a beam
+// IBS_BEAMALLOC_ERR	Could not alloc a beam
 // IBS_BEAMFREE_ERR		Could not free the beam
 
 //
@@ -39,6 +40,11 @@ prelude = << PRELUDE_END
 // BEAMFREEACK   		(beamName, status);
 // BEAMPOINTTO   		(beamName, pointing, analogue);
 //
+// TYPEVALID			(typename);
+// TYPEVALIDACK			(typename, bool);
+// GETTYPES				();
+// GETTYPESACK			(vector<string>);
+//
 // pointing            : angle1, angle2, timestamp, coord.type
 // beamletAllocationMap: map<beamletnr, subbandnr>
 //
@@ -213,3 +219,41 @@ event = {
 	};
 };
 
+event = {
+	signal = TYPEVALID;
+	dir = IN;
+	param = {
+		name = "typeName";
+		type = "string";
+	};
+};
+
+event = {
+	signal = TYPEVALIDACK;
+	dir = OUT;
+	param = {
+		name = "typeName";
+		type = "string";
+	};
+	param = {
+		name = "valid";
+		type = "bool";
+	};
+};
+
+event = {
+	signal = GETTYPES;
+	dir = IN;
+};
+
+event = {
+	signal = GETTYPESACK;
+	dir = OUT;
+	param = {
+		name = "names";
+		type = "MACIO::StringVector";
+		userdefined;
+		printable;
+	};
+};
+
diff --git a/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc b/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
index 42c6ccb3b77..1bf81f47eb1 100644
--- a/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
+++ b/MAC/APL/PAC/IBS_Protocol/src/Pointing.cc
@@ -33,14 +33,14 @@ using namespace IBS_Protocol;
 // Pointing()
 //
 Pointing::Pointing() : 
-	itsAngle2Pi(0.0), itsAnglePi(0.0), itsTime(), itsType("NONE")
+	itsAngle2Pi(0.0), itsAnglePi(0.0), itsTime(), itsDuration(0), itsType("NONE")
 {}
 
 //
 // Pointing(angle, angle, time, type)
 //
-Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, const string& type) :
-	itsAngle2Pi(angle0), itsAnglePi(angle1), itsTime(time), itsType(type)
+Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, uint duration, const string& type) :
+	itsAngle2Pi(angle0), itsAnglePi(angle1), itsTime(time), itsDuration(duration), itsType(type)
 {}
 
 //
@@ -49,13 +49,48 @@ Pointing::Pointing(double angle0, double angle1, RTC::Timestamp time, const stri
 Pointing::~Pointing()
 {}
 
+//
+// overlap(otherPT)
+//
+bool Pointing::overlap(const Pointing&	that) const
+{
+	long	thisEnd = itsTime + (long)itsDuration;
+	long	thatEnd = that.itsTime + (long)that.itsDuration;
+	long	thisBegin = itsTime;
+	long	thatBegin = that.itsTime;
+
+	// everlasting pointings are special
+	if (itsDuration == 0 && thatEnd > thisBegin)
+		return (true);
+	if (that.itsDuration == 0 && thisEnd > thatBegin)
+		return (true);
+	if (itsDuration ==0 && that.itsDuration == 0)
+		return (true);
+
+	// limited pointings: do they lay 'behind' each other? then no overlap
+	if ((thatEnd <= thisBegin) || (thatBegin >= thisEnd))
+		return (false);
+
+	return (true);
+}
+
+//
+// print
+//
+ostream& Pointing::print(ostream& os) const
+{
+	os << "[" << itsAngle2Pi << ", " << itsAnglePi << ", " << itsType << "]@" << 
+				 itsTime << " for " << itsDuration << " seconds";
+	return (os);
+}
+
 // -------------------- routines for streaming the object --------------------
 //
 // getSize()
 //
 unsigned int Pointing::getSize()
 {
-	return (sizeof(double) * 2) + itsTime.getSize() + MSH_STRING_SIZE(itsType);
+	return (sizeof(double) * 2) + itsTime.getSize() + + sizeof(uint) + MSH_STRING_SIZE(itsType);
 }
 
 //
@@ -70,6 +105,8 @@ unsigned int Pointing::pack  (void* buffer)
 	memcpy((char*)buffer + offset, &itsAnglePi, sizeof(double));
 	offset += sizeof(double);
 	offset += itsTime.pack((char*)buffer + offset);
+	memcpy((char*)buffer + offset, &itsDuration, sizeof(uint));
+	offset += sizeof(uint);
 	MSH_PACK_STRING(buffer, offset, itsType);
 
 	return (offset);
@@ -87,6 +124,8 @@ unsigned int Pointing::unpack(void *buffer)
 	memcpy(&itsAnglePi, (char*)buffer + offset, sizeof(double));
 	offset += sizeof(double);
 	offset += itsTime.unpack((char*)buffer + offset);
+	memcpy(&itsDuration, (char*)buffer + offset, sizeof(uint));
+	offset += sizeof(uint);
 	MSH_UNPACK_STRING(buffer , offset, itsType);
 
 	return (offset);
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.cc b/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.cc
new file mode 100644
index 00000000000..410f422efa0
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.cc
@@ -0,0 +1,318 @@
+//#  AnaBeamMgr.h: implementation of the Beam class
+//#
+//#  Copyright (C) 2002-2004
+//#  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$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/LofarLocators.h>
+#include <Common/LofarConstants.h>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include "AnaBeamMgr.h"
+
+#include <math.h>
+#include <iostream>
+#include <sys/time.h>
+#include <queue>
+
+#include <blitz/array.h>
+
+#include <fcntl.h>
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace BS;
+using namespace IBS_Protocol;
+using namespace std;
+using namespace RTC;
+
+//
+// AnaBeamMgr(name, subarray, nrSubbands)
+//
+AnaBeamMgr::AnaBeamMgr(uint		nrRCUsPerRing,
+					   uint		nrRings) :
+	itsRCUsPerRing		(nrRCUsPerRing),
+	itsNrRings			(nrRings)
+{}
+
+//
+// ~AnaBeamMgr
+//
+AnaBeamMgr::~AnaBeamMgr()
+{
+}
+
+//
+// addBeam(anaBeam))
+//
+bool AnaBeamMgr::addBeam(const AnalogueBeam& beam)
+{
+	// already in admin?
+	string		beamName(beam.name());
+	map<string, AnalogueBeam>::const_iterator	iter = itsBeams.find(beamName);
+	if (iter != itsBeams.end()) {
+		LOG_ERROR_STR("Beam " << beamName << " already in my admistration");
+		return (false);
+	}	
+
+	// remember the beam
+	itsBeams[beamName] = beam;
+
+	// add the pointing of this beam
+	vector<Pointing>	pointings = beam.getAllPointings();
+	size_t		nrPointings = pointings.size();
+	LOG_INFO_STR("Beam "  << beamName << " has " << nrPointings << " pointings");
+	for (size_t p = 0; p < nrPointings; ++p) {
+		PointingInfo	PI;
+		PI.beam		= beam;
+		PI.active	= false;
+		PI.pointing = pointings[p];
+
+		itsPointings.push_back(PI);
+	}
+	itsPointings.sort();
+	return (true);
+}
+
+//
+// deleteBeam(beam)
+//
+void AnaBeamMgr::deleteBeam(const AnalogueBeam& beam) 
+{
+	string		beamName(beam.name());
+	map<string, AnalogueBeam>::const_iterator	iter = itsBeams.find(beamName);
+	if (iter == itsBeams.end()) {
+		LOG_ERROR_STR("Beam " << beamName << " is not in my admistration, it cannot be deleted");
+		return;
+	}	
+	itsBeams.erase(beamName);
+
+	// delete all pointings
+	list<PointingInfo>::iterator	Piter = itsPointings.begin();
+	list<PointingInfo>::iterator	Pend  = itsPointings.end();
+	while (Piter != Pend) {
+		if (Piter->beam.name() == beamName) {
+			Piter = itsPointings.erase(Piter);
+		}
+		else {
+			++Piter;
+		}
+	}
+	LOG_INFO_STR("Beam " << beamName << " removed from administration");
+}
+
+
+//
+// activateBeams(timestamp)
+//
+void AnaBeamMgr::activateBeams(const Timestamp&	now)
+{
+	LOG_DEBUG_STR("activateBeams(" << now << ")");
+
+	// Note the pointings are in the order: rank, active, beamname, pointing time.
+	list<PointingInfo>::iterator	iter = itsPointings.begin();
+	list<PointingInfo>::iterator	end  = itsPointings.end();
+	bitset<MAX_RCUS>	usedRCUs;
+	while (iter != end) {
+		string	beamName(iter->beam.name());						// handle everything per beam
+
+		// Note: remember that the pointings/beams are already in order of importance. Whenever an active beam
+		//       conflicts with a (more important) beam we handled before we are allowed to switch it off.
+		bitset<MAX_RCUS>	conflictingRCUs = usedRCUs;				// calc conflicting RCUs.
+		conflictingRCUs &= iter->beam.rcuMask();
+		if (conflictingRCUs.any() && iter->active) {				// if there is a conflict, switch it off.
+			LOG_INFO_STR("Beam " << beamName << " is switched OFF");
+			iter->active = false;
+		}
+		bool	beamIsActive(iter->active);							// remember state of this beam
+		
+		// delete old (expired) pointings of this beam
+		while (iter != end && iter->beam.name() == beamName && iter->pointing.endTime() < now) {
+			LOG_DEBUG_STR("Removing pointing " << beamName << ":" << iter->pointing);
+			iter = itsPointings.erase(iter);
+		}
+		// reached end of this beam? restart our loop
+		if ((iter == end) || (iter != end && iter->beam.name() != beamName))  {
+			itsBeams.erase(beamName);
+			LOG_INFO_STR("Beam " << beamName << " has ended");
+			continue;
+		}
+		
+		if (beamIsActive) {									// active beams should stay active.
+			iter->active = true;							// make that pointing the active one
+			usedRCUs |= iter->beam.rcuMask();				// update occupied rcus
+		}
+		else {		// beam is not active try to activate it 
+			// activate the beam when that is possible.
+			if (conflictingRCUs.none() && iter->pointing.time() <= now) {
+				iter->active = true;
+				usedRCUs |= iter->beam.rcuMask();					// update occupied rcus
+				LOG_INFO_STR("Beam " << beamName << " is switched ON");
+			}
+		}
+		
+		// skip rest of the pointings of this beam
+		while (iter != end && iter->beam.name() == beamName) {
+			++iter;
+		}
+	} // while
+}
+
+//
+// showAdmin()
+//
+void AnaBeamMgr::showAdmin() const
+{
+	LOG_DEBUG_STR("Registered beams:");
+	map<string, AnalogueBeam>::const_iterator	bIter = itsBeams.begin();
+	map<string, AnalogueBeam>::const_iterator	bEnd  = itsBeams.end();
+	while (bIter != bEnd) {
+		LOG_DEBUG_STR(bIter->first);
+		++bIter;
+	}
+
+	LOG_DEBUG_STR("Registered Pointings:");
+	list<PointingInfo>::const_iterator		pIter = itsPointings.begin();
+	list<PointingInfo>::const_iterator		pEnd  = itsPointings.end();
+	while (pIter != pEnd) {
+		LOG_DEBUG_STR(pIter->beam.name() << "{" << pIter->beam.rankNr() << "}: " << (pIter->active ? "ON" : "off") << "==>" <<  pIter->pointing);
+		++pIter;
+	}
+}
+
+
+#if 0
+//
+// TODO CHANGE THIS TO IRTF
+//
+// calculateHBAdelays(timestamp, amcconverter, tileRelPosArray)
+// result is stored in itsHBAdelays
+//
+void Beam::calculateHBAdelays(RTC::Timestamp				timestamp,
+							  const blitz::Array<double,2>&	tileDeltas,
+							  const blitz::Array<double,1>&	elementDelays)
+{
+	LOG_DEBUG(formatString("current HBApointing=(%f,%f)",
+							currentPointing(timestamp).angle0(),
+							currentPointing(timestamp).angle1()));
+	
+	// calculate the mean of all posible delays to hold signal front in the midle of a tile
+	double meanElementDelay = blitz::mean(elementDelays);
+	LOG_DEBUG_STR("mean ElementDelay = " << meanElementDelay << " Sec"); 
+
+#if DOEN_WE_LATER
+	// Calculate the current values of AzEl.
+	Pointing	curPointing(itsCurrentPointing);
+	curPointing.setTime(timestamp);
+  // Get geographical location of subarray in WGS84 radians/meters
+	blitz::Array<double, 1> loc = itsSubArray.getGeoLoc();
+	Position location((loc(0) * M_PI) / 180.0,
+					  (loc(1) * M_PI) / 180.0,
+					   loc(2), Position::WGS84);
+	// go to lmn coordinates
+//	Pointing lmn	  = curPointing.convert(conv, &location, Pointing::LOFAR_LMN);
+	double itsHBA_L   = lmn.angle0();
+	double itsHBA_M   = lmn.angle1();
+	
+	// maybe not needed, but this code limits the max. posilble delay
+	if ((itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M) > 1) {
+		double modus = sqrt(itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M);
+		itsHBA_L = itsHBA_L / modus;
+		itsHBA_M = itsHBA_M / modus;
+	}
+	
+	LOG_INFO_STR("current HBA-pointing lmn=(" << itsHBA_L << "," << itsHBA_M << ") @" << curPointing.time());
+
+	// get position of antennas
+	// note: pos[antennes, polarisations, coordinates]
+	const Array<double,3>& pos  = itsSubArray.getAntennaPos();
+	int nrAntennas = pos.extent(firstDim);
+	int nrPols     = pos.extent(secondDim);
+	LOG_DEBUG_STR("SA.n_ant="<<nrAntennas <<",SA.n_pols="<<nrPols);
+	LOG_DEBUG_STR("antennaPos="<<pos);
+	
+	// get contributing RCUs
+	CAL::SubArray::RCUmask_t		rcuMask(itsSubArray.getRCUMask());
+	LOG_DEBUG_STR("rcumask="<<rcuMask);
+	
+	itsHBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
+	itsHBAdelays = 0;	// set all delays to 0
+	
+	int		localrcu  = 0;
+	int		globalrcu = 0;
+	for (globalrcu = 0; globalrcu < MEPHeader::MAX_N_RCUS; globalrcu++) {
+		//LOG_DEBUG_STR("globalrcu=" << globalrcu);
+		if (!rcuMask.test(globalrcu)) {
+			continue;
+		}
+		// RCU is in RCUmask, do the calculations
+		int	antenna(globalrcu/2);
+		int pol	   (globalrcu%2);
+		for (int element = 0; element < MEPHeader::N_HBA_DELAYS; element++) {
+					
+			// calculate tile delay
+			double	delay =
+				( (itsHBA_L * tileDeltas(element,0)) + 
+				  (itsHBA_M * tileDeltas(element,1)) ) / 
+					SPEED_OF_LIGHT_MS;
+			
+			// signal front stays in midle of tile
+			delay += meanElementDelay;
+			
+			LOG_DEBUG_STR("antenna="<<antenna <<", pol="<<pol <<", element="<<element  <<", delay("<<localrcu<<","<<element<<")="<<delay);
+			
+			// calculate approximate DelayStepNr
+			int delayStepNr = static_cast<int>(delay / 0.5E-9);
+			
+			// look for nearest matching delay step in range "delayStepNr - 2 .. delayStepNr + 2"
+			double minDelayDiff = fabs(delay - elementDelays(delayStepNr));
+			double difference;
+			int minStepNr = delayStepNr;
+			for (int i = (delayStepNr - 2); i <= (delayStepNr + 2); i++){
+				if (i == delayStepNr) continue; // skip approximate nr
+				difference = fabs(delay - elementDelays(i));
+				if (difference < minDelayDiff)	{
+					minStepNr = i;
+					minDelayDiff = difference;
+				}
+			}
+			delayStepNr = minStepNr;
+			
+			// range check for delayStepNr, max. 32 steps (0..31) 
+			if (delayStepNr < 0) delayStepNr = 0;
+			if (delayStepNr > 31) delayStepNr = 31;
+				
+			// bit1=0.25nS(not used), bit2=0.5nS, bit3=1nS, bit4=2nS, bit5=4nS, bit6=8nS 	
+			itsHBAdelays(localrcu,element) = (delayStepNr * 4) + (1 << 7); // assign
+		} // elements in tile
+		localrcu++;	 // globalrcu
+	}
+		
+	// temporary array needed to LOG "itsHBAdelays"
+	blitz::Array<int,2>	HBAdelays;
+	HBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
+	
+	HBAdelays = itsHBAdelays + 0; // copy to print values (uint8 are handled as chars)
+	LOG_DEBUG_STR("itsHBAdelays Nr = " << HBAdelays);
+#endif
+}
+#endif
+
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.h b/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.h
new file mode 100644
index 00000000000..66202710ead
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/AnaBeamMgr.h
@@ -0,0 +1,108 @@
+//#  AnaBeamMgr.h: interface of the AnaBeamMgr class
+//#
+//#  Copyright (C) 2002-2009
+//#  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 ANABEAMMGR_H_
+#define ANABEAMMGR_H_
+
+#include <lofar_config.h>
+#include <Common/lofar_string.h>
+#include <Common/lofar_list.h>
+#include <Common/lofar_map.h>
+#include <APL/RTCCommon/Timestamp.h>
+#include <APL/IBS_Protocol/Pointing.h>
+
+#include <queue>
+#include <blitz/array.h>
+
+#include "AnalogueBeam.h"
+
+namespace LOFAR {
+  namespace BS {
+
+class AnaBeamMgr {
+public:
+	// Constructor
+	// @param nrRCUs  The number of rcus that are in one ring.
+	// @param nrRings The number of active rings (1 | 2)
+	AnaBeamMgr(uint		nrRCUS, uint		nrRings);
+
+	// Destructor.
+	~AnaBeamMgr();
+
+	// Add a beam to the manager
+	bool addBeam(const AnalogueBeam& beam);
+
+	// Delete a beam to the manager
+	void deleteBeam(const AnalogueBeam& beam);
+
+	// Activate all possible analogue beams
+	void activateBeams(const RTC::Timestamp&	now);
+
+	// @return Current Direction in angle2Pi and anglePi.
+	bool currentDirection(double&	angle2Pi, double&	anglePi);
+
+	void calculateHBAdelays(RTC::Timestamp					timestamp,
+						    const blitz::Array<double,2>&	tileDeltas,
+						    const blitz::Array<double,1>&	elementDelays);
+
+	// for easy debugging
+	void showAdmin() const;
+
+private:
+	// Don't allow copying this object.
+	AnaBeamMgr (const AnaBeamMgr&);            // not implemented
+	AnaBeamMgr& operator= (const AnaBeamMgr&); // not implemented
+
+	class PointingInfo {
+	public:
+		PointingInfo() : active(false) {};
+		~PointingInfo() {};
+		AnalogueBeam			beam;
+		IBS_Protocol::Pointing	pointing;
+		bool					active;
+		bool operator<	(const PointingInfo& that) {
+			if (beam.rankNr() != that.beam.rankNr())    return (beam.rankNr() < that.beam.rankNr());
+			if (active != that.active) 					return (active);
+			if (beam.name() != that.beam.name())	 	return (beam.name() < that.beam.name()); 
+			return (beam.currentPointing().time() < that.beam.currentPointing().time());
+		};
+	};
+	
+	//# ----- DATAMEMBERS -----
+	// Constants
+	uint				itsRCUsPerRing;
+	uint				itsNrRings;
+
+	// RCUs participating in the active beams
+	bitset<MAX_RCUS>	itsActiveRCUs;
+
+	// queue of future pointings as delivered by the user.
+	map<string, AnalogueBeam>	itsBeams;
+	list<PointingInfo>			itsPointings;
+};
+
+//# -------------------- inline functions --------------------
+
+  }; //# namepsace BS
+}; //# namespace LOFAR
+
+#endif /* ANABEAMMGR_H_ */
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.cc b/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.cc
new file mode 100644
index 00000000000..9795033ce2b
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.cc
@@ -0,0 +1,176 @@
+//#  AnalogueBeam.h: implementation of the AnalogueBeam class
+//#
+//#  Copyright (C) 2002-2004
+//#  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$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/LofarLocators.h>
+#include <Common/LofarConstants.h>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include "BeamServerConstants.h"
+#include "AnalogueBeam.h"
+
+#include <math.h>
+#include <iostream>
+#include <sys/time.h>
+#include <queue>
+
+#include <blitz/array.h>
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace BS;
+using namespace IBS_Protocol;
+using namespace std;
+using namespace RTC;
+
+//
+// AnalogueBeam(name, subarray, nrSubbands)
+//
+AnalogueBeam::AnalogueBeam(const string& 				name, 
+						   const bitset<MAX_RCUS>&		rcuMask,
+						   uint							rankNr) :
+	Beam		(name, rcuMask),
+	itsRankNr	(rankNr)
+{}
+
+//
+// ~AnalogueBeam
+//
+AnalogueBeam::~AnalogueBeam()
+{
+}
+
+// TODO CHANGE THIS TO IRTF
+//
+// calculateHBAdelays(timestamp, amcconverter, tileRelPosArray)
+// result is stored in itsHBAdelays
+//
+void AnalogueBeam::calculateHBAdelays(RTC::Timestamp				timestamp,
+							  const blitz::Array<double,2>&	tileDeltas,
+							  const blitz::Array<double,1>&	elementDelays)
+{
+	LOG_DEBUG(formatString("current HBApointing=(%f,%f)",
+							pointingAtTime(timestamp).angle0(),
+							pointingAtTime(timestamp).angle1()));
+	
+	// calculate the mean of all posible delays to hold signal front in the midle of a tile
+	double meanElementDelay = blitz::mean(elementDelays);
+	LOG_DEBUG_STR("mean ElementDelay = " << meanElementDelay << " Sec"); 
+
+#if DOEN_WE_LATER
+	// Calculate the current values of AzEl.
+	Pointing	curPointing(itsCurrentPointing);
+	curPointing.setTime(timestamp);
+  // Get geographical location of subarray in WGS84 radians/meters
+	blitz::Array<double, 1> loc = itsSubArray.getGeoLoc();
+	Position location((loc(0) * M_PI) / 180.0,
+					  (loc(1) * M_PI) / 180.0,
+					   loc(2), Position::WGS84);
+	// go to lmn coordinates
+//	Pointing lmn	  = curPointing.convert(conv, &location, Pointing::LOFAR_LMN);
+	double itsHBA_L   = lmn.angle0();
+	double itsHBA_M   = lmn.angle1();
+	
+	// maybe not needed, but this code limits the max. posilble delay
+	if ((itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M) > 1) {
+		double modus = sqrt(itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M);
+		itsHBA_L = itsHBA_L / modus;
+		itsHBA_M = itsHBA_M / modus;
+	}
+	
+	LOG_INFO_STR("current HBA-pointing lmn=(" << itsHBA_L << "," << itsHBA_M << ") @" << curPointing.time());
+
+	// get position of antennas
+	// note: pos[antennes, polarisations, coordinates]
+	const Array<double,3>& pos  = itsSubArray.getAntennaPos();
+	int nrAntennas = pos.extent(firstDim);
+	int nrPols     = pos.extent(secondDim);
+	LOG_DEBUG_STR("SA.n_ant="<<nrAntennas <<",SA.n_pols="<<nrPols);
+	LOG_DEBUG_STR("antennaPos="<<pos);
+	
+	// get contributing RCUs
+	CAL::SubArray::RCUmask_t		rcuMask(itsSubArray.getRCUMask());
+	LOG_DEBUG_STR("rcumask="<<rcuMask);
+	
+	itsHBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
+	itsHBAdelays = 0;	// set all delays to 0
+	
+	int		localrcu  = 0;
+	int		globalrcu = 0;
+	for (globalrcu = 0; globalrcu < MEPHeader::MAX_N_RCUS; globalrcu++) {
+		//LOG_DEBUG_STR("globalrcu=" << globalrcu);
+		if (!rcuMask.test(globalrcu)) {
+			continue;
+		}
+		// RCU is in RCUmask, do the calculations
+		int	antenna(globalrcu/2);
+		int pol	   (globalrcu%2);
+		for (int element = 0; element < MEPHeader::N_HBA_DELAYS; element++) {
+					
+			// calculate tile delay
+			double	delay =
+				( (itsHBA_L * tileDeltas(element,0)) + 
+				  (itsHBA_M * tileDeltas(element,1)) ) / 
+					SPEED_OF_LIGHT_MS;
+			
+			// signal front stays in midle of tile
+			delay += meanElementDelay;
+			
+			LOG_DEBUG_STR("antenna="<<antenna <<", pol="<<pol <<", element="<<element  <<", delay("<<localrcu<<","<<element<<")="<<delay);
+			
+			// calculate approximate DelayStepNr
+			int delayStepNr = static_cast<int>(delay / 0.5E-9);
+			
+			// look for nearest matching delay step in range "delayStepNr - 2 .. delayStepNr + 2"
+			double minDelayDiff = fabs(delay - elementDelays(delayStepNr));
+			double difference;
+			int minStepNr = delayStepNr;
+			for (int i = (delayStepNr - 2); i <= (delayStepNr + 2); i++){
+				if (i == delayStepNr) continue; // skip approximate nr
+				difference = fabs(delay - elementDelays(i));
+				if (difference < minDelayDiff)	{
+					minStepNr = i;
+					minDelayDiff = difference;
+				}
+			}
+			delayStepNr = minStepNr;
+			
+			// range check for delayStepNr, max. 32 steps (0..31) 
+			if (delayStepNr < 0) delayStepNr = 0;
+			if (delayStepNr > 31) delayStepNr = 31;
+				
+			// bit1=0.25nS(not used), bit2=0.5nS, bit3=1nS, bit4=2nS, bit5=4nS, bit6=8nS 	
+			itsHBAdelays(localrcu,element) = (delayStepNr * 4) + (1 << 7); // assign
+		} // elements in tile
+		localrcu++;	 // globalrcu
+	}
+		
+	// temporary array needed to LOG "itsHBAdelays"
+	blitz::Array<int,2>	HBAdelays;
+	HBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
+	
+	HBAdelays = itsHBAdelays + 0; // copy to print values (uint8 are handled as chars)
+	LOG_DEBUG_STR("itsHBAdelays Nr = " << HBAdelays);
+#endif
+}
+
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.h b/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.h
new file mode 100644
index 00000000000..c98eec6b899
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/AnalogueBeam.h
@@ -0,0 +1,71 @@
+//#  AnalogueBeam.h: interface of the analogueBeam class
+//#
+//#  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 ANALOGUE_BEAM_H_
+#define ANALOGUE_BEAM_H_
+
+#include <lofar_config.h>
+#include "Beam.h"
+#include <blitz/array.h>
+
+namespace LOFAR {
+  namespace BS {
+
+class AnalogueBeam : public Beam {
+public:
+
+	// Default constructor
+	// @param name String identifying this beam uniquely in the OTDB, used with
+	// key-value logger as nodeid.
+	// @param rcuMask The RCUs that participate in this beam.
+	// @param ringNr The serdes segment the allocation is ment for.
+	AnalogueBeam(const string& 								name, 
+				 const bitset<MAX_RCUS>&					rcuMask,
+				 uint 										rankNr);
+	AnalogueBeam() : itsRankNr(0) {};
+
+	// Default destructor.
+	virtual ~AnalogueBeam();
+
+	// Get rank of this Beam
+	uint rankNr() const	{ return (itsRankNr); }
+
+	void calculateHBAdelays(RTC::Timestamp					timestamp,
+						    const blitz::Array<double,2>&	tileDeltas,
+						    const blitz::Array<double,1>&	elementDelays);
+private:
+	// Don't allow copying this object.
+//	AnalogueBeam (const AnalogueBeam&);            // not implemented
+//	AnalogueBeam& operator= (const AnalogueBeam&); // not implemented
+
+	//# ----- DATAMEMBERS -----
+
+	// the ranknumber of the beam (lower is more important)
+	int		itsRankNr;
+};
+
+//# -------------------- inline functions --------------------
+
+  }; //# namepsace BS
+}; //# namespace LOFAR
+
+#endif /* ANALOGUEBEAM_H_ */
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc b/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
index fd4592bb90d..a16affb066a 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
+++ b/MAC/APL/PAC/ITRFBeamServer/src/Beam.cc
@@ -1,4 +1,4 @@
-//#  ABSBeam.h: implementation of the Beam class
+//#  Beam.h: implementation of the Beam class
 //#
 //#  Copyright (C) 2002-2004
 //#  ASTRON (Netherlands Foundation for Research in Astronomy)
@@ -22,42 +22,21 @@
 
 #include <lofar_config.h>
 #include <Common/LofarLogger.h>
-#include <Common/LofarLocators.h>
-#include <Common/LofarConstants.h>
-
-#include <APL/RTCCommon/PSAccess.h>
-#include "BeamServerConstants.h"
 #include "Beam.h"
 
-#include <math.h>
-#include <iostream>
-#include <sys/time.h>
-#include <queue>
-
-#include <blitz/array.h>
-
-#include <fcntl.h>
-
-using namespace blitz;
 using namespace LOFAR;
 using namespace BS;
 using namespace IBS_Protocol;
-using namespace std;
 using namespace RTC;
+using namespace std;
 
 //
-// Beam(name, subarray, nrSubbands)
+// Beam(name, rcuMask)
 //
 Beam::Beam(const string& 				name, 
-		   const string& 				antennaSet, 
-		   const Beamlet2SubbandMap&	allocation, 
-		   const bitset<MAX_RCUS>&		rcuMask,
-		   uint							ringNr) :
-	itsName				(name), 
-	itsAntennaSet		(antennaSet),
-	itsBeamletAllocation(allocation),
-	itsRCUs				(rcuMask),
-	itsRingNr			(ringNr)
+		   const bitset<MAX_RCUS>&		rcuMask) :
+	itsName	(name), 
+	itsRCUs	(rcuMask)
 {}
 
 //
@@ -65,172 +44,152 @@ Beam::Beam(const string& 				name,
 //
 Beam::~Beam()
 {
-	deallocate();
+	// clear the pointings
+	itsPointings.clear();
 }
 
 //
-// deallocate()
+// _resolveGaps()
+//
+// When there are 'holes' in the pointing sequence, fill them with NIL pointings
 //
-void Beam::deallocate()
+void Beam::_resolveGaps()
 {
-	// reset pointing to zenith
-	itsCurrentPointing = Pointing();
+	// Note: it is possible that there are already NIL pointings in the list.
+	//       To simplify the algorithms we first delete all NIL pointings and than add
+	//		 new NIL pointings again.
+	list<Pointing>::iterator	iter = itsPointings.begin();
+	list<Pointing>::iterator	end  = itsPointings.end();
+	while (iter != end) {
+		if (iter->getType() == "NONE") {
+			iter = itsPointings.erase(iter);
+		}
+		else {
+			++iter;
+		}
+	}
+	
+	// Loop over the new list and fill the gaps again.
+	iter = itsPointings.begin();
+	end  = itsPointings.end();
+	Timestamp	endTime = iter->time();
+	while (iter != end) {
+		// is there a gap between the last endtime and the current begintime add a NIL pointing
+		if (iter->time() > endTime) {
+			Pointing	nilPointing(0.0 ,0.0 ,endTime, int(iter->time()-endTime), "NONE");
+			itsPointings.insert(iter, nilPointing);
+		}
+			
+		if (iter->duration() == 0) {		// current pointings lasts forever?, delete rest of pointings.
+			itsPointings.erase(++iter, end);
+			return;
+		}
 
-	// clear the pointing queue
-	while (!itsPointingQ.empty()) {
-		itsPointingQ.pop();
+		endTime = iter->endTime();
+		++iter;
 	}
 
-	// clear allocation
-	itsBeamletAllocation().clear();
+}
+
+//
+// _pointingOverlaps(pointing)
+//
+// Check is the given pointings overlaps with others.
+//
+bool Beam::_pointingOverlaps(const IBS_Protocol::Pointing& pt) const
+{
+	list<Pointing>::const_iterator    iter = itsPointings.begin();
+	list<Pointing>::const_iterator    end  = itsPointings.end();
+	while (iter != end) {
+		if ((iter->getType() != "NONE") && (iter->overlap(pt))) {
+			return (true);
+		}
+		++iter;
+	}       
+
+	return (false);
 }
 
 //
 // addPointing(pointing)
 //
-void Beam::addPointing(const Pointing& pointing)
+bool Beam::addPointing(const Pointing& pointing)
 {
-	if (itsPointingQ.empty()) {	// make sure that currentPointing is always set
-		itsCurrentPointing = pointing;
+	// add pointing, sort the list and fill gaps with 'NONE' pointings
+	if (_pointingOverlaps(pointing)) {
+		LOG_ERROR_STR("Pointing " << pointing << " is NOT added to beam " << itsName << " because it overlaps with existing pointings");
+		return (false);
 	}
-	itsPointingQ.push(pointing);
+
+	// it's ok to add it, clean up the admin afterwards.
+	itsPointings.push_back(pointing);
+	itsPointings.sort();
+	_resolveGaps();
+	return (true);
 }
 
 //
-// currentPointing(pointing)
+// pointingAtTime(pointing)
 //
-Pointing Beam::currentPointing(const Timestamp& time)
+Pointing Beam::pointingAtTime(const Timestamp& time)
+{
+	list<Pointing>::const_iterator	iter = itsPointings.begin();
+	list<Pointing>::const_iterator	end  = itsPointings.end();
+	while (iter != end) {
+		if (iter->duration() == 0) {	// forever?
+			break;
+		}
+		if (iter->endTime() < time) {	// already finished? try next
+			++iter;
+			continue;
+		}
+	}
+
+	// if nothing found, return NIL pointing
+	if (iter == end) {			
+		return (Pointing());
+	}
+
+	Pointing 	result(*iter);
+	result.setTime(time);
+	return (result);
+}
+
+// Get all pointings in a vector. They are sorted in time order.
+vector<Pointing> Beam::getAllPointings() const
 {
-	if (!itsPointingQ.empty() && itsPointingQ.top().time() <= time) {
-		itsCurrentPointing = itsPointingQ.top();
-		itsPointingQ.pop();
+	vector<Pointing>	result;
+	list<Pointing>::const_iterator	iter = itsPointings.begin();
+	list<Pointing>::const_iterator	end  = itsPointings.end();
+	while (iter != end) {
+		result.push_back(*iter);
+		++iter;
 	}
-	itsCurrentPointing.setTime(time);
-	return (itsCurrentPointing);
+	return (result);
 }
 
-#if 0
 //
-// setSubarray(array)
+// print function for operator<<
 //
-void Beam::setSubarray(const CAL::SubArray& array)
+ostream& Beam::print (ostream& os) const
 {
-	itsSubArray = array;
+	os << "Beam " << itsName << ": curPt=" << itsCurrentPointing << endl;
+	os << "     RCU's= " << itsRCUs << endl;
+	return (os);
 }
-#endif
+
 
 //
-// TODO CHANGE THIS TO IRTF
-//
-// calculateHBAdelays(timestamp, amcconverter, tileRelPosArray)
-// result is stored in itsHBAdelays
+// send the pointing administration to the logfile at debug level
 //
-void Beam::calculateHBAdelays(RTC::Timestamp				timestamp,
-							  const blitz::Array<double,2>&	tileDeltas,
-							  const blitz::Array<double,1>&	elementDelays)
+void Beam::showPointings () const
 {
-	LOG_DEBUG(formatString("current HBApointing=(%f,%f)",
-							currentPointing(timestamp).angle0(),
-							currentPointing(timestamp).angle1()));
-	
-	// calculate the mean of all posible delays to hold signal front in the midle of a tile
-	double meanElementDelay = blitz::mean(elementDelays);
-	LOG_DEBUG_STR("mean ElementDelay = " << meanElementDelay << " Sec"); 
-
-#if DOEN_WE_LATER
-	// Calculate the current values of AzEl.
-	Pointing	curPointing(itsCurrentPointing);
-	curPointing.setTime(timestamp);
-  // Get geographical location of subarray in WGS84 radians/meters
-	blitz::Array<double, 1> loc = itsSubArray.getGeoLoc();
-	Position location((loc(0) * M_PI) / 180.0,
-					  (loc(1) * M_PI) / 180.0,
-					   loc(2), Position::WGS84);
-	// go to lmn coordinates
-//	Pointing lmn	  = curPointing.convert(conv, &location, Pointing::LOFAR_LMN);
-	double itsHBA_L   = lmn.angle0();
-	double itsHBA_M   = lmn.angle1();
-	
-	// maybe not needed, but this code limits the max. posilble delay
-	if ((itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M) > 1) {
-		double modus = sqrt(itsHBA_L*itsHBA_L + itsHBA_M*itsHBA_M);
-		itsHBA_L = itsHBA_L / modus;
-		itsHBA_M = itsHBA_M / modus;
+	LOG_DEBUG_STR("Pointings of beam " << itsName);
+	list<Pointing>::const_iterator	iter = itsPointings.begin();
+	list<Pointing>::const_iterator	end  = itsPointings.end();
+	while (iter != end) {
+		LOG_DEBUG_STR(*iter);
+		++iter;
 	}
-	
-	LOG_INFO_STR("current HBA-pointing lmn=(" << itsHBA_L << "," << itsHBA_M << ") @" << curPointing.time());
-
-	// get position of antennas
-	// note: pos[antennes, polarisations, coordinates]
-	const Array<double,3>& pos  = itsSubArray.getAntennaPos();
-	int nrAntennas = pos.extent(firstDim);
-	int nrPols     = pos.extent(secondDim);
-	LOG_DEBUG_STR("SA.n_ant="<<nrAntennas <<",SA.n_pols="<<nrPols);
-	LOG_DEBUG_STR("antennaPos="<<pos);
-	
-	// get contributing RCUs
-	CAL::SubArray::RCUmask_t		rcuMask(itsSubArray.getRCUMask());
-	LOG_DEBUG_STR("rcumask="<<rcuMask);
-	
-	itsHBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
-	itsHBAdelays = 0;	// set all delays to 0
-	
-	int		localrcu  = 0;
-	int		globalrcu = 0;
-	for (globalrcu = 0; globalrcu < MEPHeader::MAX_N_RCUS; globalrcu++) {
-		//LOG_DEBUG_STR("globalrcu=" << globalrcu);
-		if (!rcuMask.test(globalrcu)) {
-			continue;
-		}
-		// RCU is in RCUmask, do the calculations
-		int	antenna(globalrcu/2);
-		int pol	   (globalrcu%2);
-		for (int element = 0; element < MEPHeader::N_HBA_DELAYS; element++) {
-					
-			// calculate tile delay
-			double	delay =
-				( (itsHBA_L * tileDeltas(element,0)) + 
-				  (itsHBA_M * tileDeltas(element,1)) ) / 
-					SPEED_OF_LIGHT_MS;
-			
-			// signal front stays in midle of tile
-			delay += meanElementDelay;
-			
-			LOG_DEBUG_STR("antenna="<<antenna <<", pol="<<pol <<", element="<<element  <<", delay("<<localrcu<<","<<element<<")="<<delay);
-			
-			// calculate approximate DelayStepNr
-			int delayStepNr = static_cast<int>(delay / 0.5E-9);
-			
-			// look for nearest matching delay step in range "delayStepNr - 2 .. delayStepNr + 2"
-			double minDelayDiff = fabs(delay - elementDelays(delayStepNr));
-			double difference;
-			int minStepNr = delayStepNr;
-			for (int i = (delayStepNr - 2); i <= (delayStepNr + 2); i++){
-				if (i == delayStepNr) continue; // skip approximate nr
-				difference = fabs(delay - elementDelays(i));
-				if (difference < minDelayDiff)	{
-					minStepNr = i;
-					minDelayDiff = difference;
-				}
-			}
-			delayStepNr = minStepNr;
-			
-			// range check for delayStepNr, max. 32 steps (0..31) 
-			if (delayStepNr < 0) delayStepNr = 0;
-			if (delayStepNr > 31) delayStepNr = 31;
-				
-			// bit1=0.25nS(not used), bit2=0.5nS, bit3=1nS, bit4=2nS, bit5=4nS, bit6=8nS 	
-			itsHBAdelays(localrcu,element) = (delayStepNr * 4) + (1 << 7); // assign
-		} // elements in tile
-		localrcu++;	 // globalrcu
-	}
-		
-	// temporary array needed to LOG "itsHBAdelays"
-	blitz::Array<int,2>	HBAdelays;
-	HBAdelays.resize(rcuMask.count(), MEPHeader::N_HBA_DELAYS);
-	
-	HBAdelays = itsHBAdelays + 0; // copy to print values (uint8 are handled as chars)
-	LOG_DEBUG_STR("itsHBAdelays Nr = " << HBAdelays);
-#endif
 }
 
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/Beam.h b/MAC/APL/PAC/ITRFBeamServer/src/Beam.h
index 366a64bb29b..29cf8ca11a1 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/Beam.h
+++ b/MAC/APL/PAC/ITRFBeamServer/src/Beam.h
@@ -25,14 +25,11 @@
 
 #include <lofar_config.h>
 #include <Common/lofar_string.h>
+#include <Common/lofar_bitset.h>
+#include <Common/lofar_list.h>
+#include <Common/LofarConstants.h>
 #include <APL/RTCCommon/Timestamp.h>
-#include <APL/IBS_Protocol/Beamlet2SubbandMap.h>
 #include <APL/IBS_Protocol/Pointing.h>
-#include <APL/CAL_Protocol/AntennaGains.h>
-#include <APL/CAL_Protocol/SubArray.h>
-
-#include <queue>
-#include <blitz/array.h>
 
 namespace LOFAR {
   namespace BS {
@@ -45,44 +42,25 @@ public:
 	// Default constructor
 	// @param name String identifying this beam uniquely in the OTDB, used with
 	// key-value logger as nodeid.
-	// @param antennaSet The name of the AntenneField on which this beam is defined.
-	// @param allocation How the subbands of the beam are mapped tot the bemalets.
 	// @param rcuMask The RCUs that participate in this beam.
-	// @param ringNr The serdes segment the allocation is ment for.
-	Beam(const string& 								name, 
-		 const string& 								antenneSet, 
-		 const IBS_Protocol::Beamlet2SubbandMap&	allocation, 
-		 const bitset<MAX_RCUS>&					rcuMask,
-		 uint 										ringNr);
+	Beam(const string& 				name, 
+		 const bitset<MAX_RCUS>&	rcuMask);
+	Beam() {};
 
 	// Default destructor.
 	virtual ~Beam();
 
-	// Add a pointing to a beam.
-	void addPointing(const IBS_Protocol::Pointing& pointing);
-
-	// Get the allocation mapping for this beam.
-	// @return Beamlet2SubbandMap the mapping from beamlet to subband for this beam.
-	IBS_Protocol::Beamlet2SubbandMap& allocation() { return(itsBeamletAllocation); }
+	// Add a pointing to a beam if it not overlaps with other pointings
+	bool addPointing(const IBS_Protocol::Pointing& pointing);
 
 	// @return Current pointing.
-	IBS_Protocol::Pointing currentPointing(const RTC::Timestamp& time);
-
-	// Set the subarray (positions & rcu_index)
-//	void setSubarray(const CAL::SubArray& array);
-
-	// Return a reference to the subarray for this beam.
-	// @return reference to the subarray
-//	const CAL::SubArray& getSubarray() const { return itsSubArray; }
+	IBS_Protocol::Pointing currentPointing() const { return (itsCurrentPointing); } 
 
-	// setCalibration weights for the receivers
-//	void setCalibration(const CAL::AntennaGains& gains);
-
-	// Get the current calibration values.
-//	const CAL::AntennaGains& getCalibration() const;
+	// @return Current pointing.
+	IBS_Protocol::Pointing pointingAtTime(const RTC::Timestamp& time);
 
-	// Get the name of the subarray on which this beam operates.
-	string antennaSetName() const { return (itsAntennaSet); }
+	// Get all pointings in a vector. They are sorted in time order.
+	vector<IBS_Protocol::Pointing> getAllPointings() const;
 
 	// Get beam name (unique name, can be used as key in key-value logger).
 	string name() const { return (itsName); }
@@ -90,57 +68,46 @@ public:
 	// Get beam name (unique name, can be used as key in key-value logger).
 	const bitset<MAX_RCUS>& rcuMask() const { return (itsRCUs); }
 
-	// Get number of ringSegment
-	int ringNr() const	{ return (itsRingNr); }
+	// Output functions for easy debugging
+	void showPointings () const;
 
-	// Set handle (=uniq ID) from the CalServer
-	void  calibrationHandle(void	*handle) { itsCShandle = handle; }
-	void* calibrationHandle()				 { return (itsCShandle); }
+	// print function for operator<<
+	ostream& print (ostream& os) const;
 
-	void calculateHBAdelays(RTC::Timestamp					timestamp,
-						    const blitz::Array<double,2>&	tileDeltas,
-						    const blitz::Array<double,1>&	elementDelays);
 private:
 	// Don't allow copying this object.
-	Beam (const Beam&);            // not implemented
-	Beam& operator= (const Beam&); // not implemented
+//	Beam (const Beam&);            // not implemented
+//	Beam& operator= (const Beam&); // not implemented
 
 	// Method to undo an allocation.
 	void deallocate();
 
-	//# ----- DATAMEMBERS -----
+	void _resolveGaps();
+	bool _pointingOverlaps(const IBS_Protocol::Pointing& pt) const;
 
+	//# ----- DATAMEMBERS -----
 	// Name used as key in key-value logger.
 	string 		itsName;
 
-	// Name of the subarray on which the beam is allocated.
-	string 		itsAntennaSet;
-
-	// Allocation.
-	IBS_Protocol::Beamlet2SubbandMap 	itsBeamletAllocation;
-
 	// RCUs participating in the beam
-	bitset<MAX_RCUS>					itsRCUs;
-
-	// ringSegment the beam is allocated on
-	int									itsRingNr;
+	bitset<MAX_RCUS>		itsRCUs;
 
 	// current direction of the beam
-	IBS_Protocol::Pointing 				itsCurrentPointing;
+	IBS_Protocol::Pointing 	itsCurrentPointing;
 
 	// queue of future pointings as delivered by the user.
-	std::priority_queue<IBS_Protocol::Pointing>	itsPointingQ;
-
-	// The antenna array.
-//	CAL::SubArray 		itsSubArray;
-
-	// calserver handle	
-	// will become obsolete when new ITRF CalServer is used.
-	void*		itsCShandle;
-
+	list<IBS_Protocol::Pointing>	itsPointings;
 };
 
 //# -------------------- inline functions --------------------
+//
+// operator <<
+//
+inline ostream& operator<<(ostream& os, const Beam& beam)
+{
+	return (beam.print(os));
+}
+
 
   }; //# namepsace BS
 }; //# namespace LOFAR
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
index 12bbb3c0b50..21f7076a995 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
+++ b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.cc
@@ -626,7 +626,7 @@ GCFEvent::TResult BeamServer::beamalloc_state(GCFEvent& event, GCFPortInterface&
 			LOG_DEBUG_STR("ack.subarray.positions=" << ack.subarray.getAntennaPos());
 
 			// set positions on beam
-			Beam*	theBeam = itsBeamTransaction.getBeam();
+			DigitalBeam*	theBeam = itsBeamTransaction.getBeam();
 //TODO			theBeam->setSubarray(ack.subarray);
 
 			// set the scale of the beamlets: (-2PI * freq * i)/lightspeed
@@ -800,7 +800,7 @@ bool BeamServer::beamalloc_start(IBSBeamallocEvent& ba,
 {
 	// allocate the beam
 	int		beamError(IBS_NO_ERR);
-	Beam* beam = checkBeam(&port, ba.beamName, ba.antennaSet, ba.allocation, ba.rcumask, ba.ringNr, &beamError);
+	DigitalBeam* beam = checkBeam(&port, ba.beamName, ba.antennaSet, ba.allocation, ba.rcumask, ba.ringNr, &beamError);
 
 	if (!beam) {
 		LOG_FATAL_STR("BEAMALLOC: failed to allocate beam " << ba.beamName << " on " << ba.antennaSet);
@@ -823,7 +823,7 @@ bool BeamServer::beamalloc_start(IBSBeamallocEvent& ba,
 bool BeamServer::beamfree_start(IBSBeamfreeEvent&  bf,
 								GCFPortInterface& port)
 {
-	map<string, Beam*>::iterator	beamIter = itsBeamPool.find(bf.beamName);
+	map<string, DigitalBeam*>::iterator	beamIter = itsBeamPool.find(bf.beamName);
 	if (beamIter == itsBeamPool.end()) { 
 		LOG_FATAL_STR("BEAMFREE failed: beam '" << bf.beamName << "' does not exist");
 
@@ -847,7 +847,7 @@ bool BeamServer::beamfree_start(IBSBeamfreeEvent&  bf,
 bool BeamServer::beampointto_action(IBSBeampointtoEvent& pt,
 									GCFPortInterface& /*port*/)
 {
-	map<string, Beam*>::iterator	beamIter = itsBeamPool.find(pt.beamName);
+	map<string, DigitalBeam*>::iterator	beamIter = itsBeamPool.find(pt.beamName);
 	if (beamIter == itsBeamPool.end()) {
 		LOG_ERROR(formatString("BEAMPOINTTO: invalid beam '%s'", pt.beamName.c_str()));
 		return (false);
@@ -922,13 +922,13 @@ void BeamServer::destroyAllBeams(GCFPortInterface* port)
 	ASSERT(port);
 
 	// deallocate all beams for this client
-	set<Beam*>::iterator beamIter = itsClientBeams[port].begin();
-	set<Beam*>::iterator end      = itsClientBeams[port].end();
+	set<DigitalBeam*>::iterator beamIter = itsClientBeams[port].begin();
+	set<DigitalBeam*>::iterator end      = itsClientBeams[port].end();
 	while (beamIter != end) {
 		LOG_INFO_STR("Stopping beam " << (*beamIter)->name());
 		_releaseBeamlets((*beamIter)->allocation(), (*beamIter)->ringNr());
 		_unregisterBeam(**beamIter);
-		Beam*	beam = *beamIter;
+		DigitalBeam*	beam = *beamIter;
 		++beamIter;
 		delete beam;
 	}
@@ -938,7 +938,7 @@ void BeamServer::destroyAllBeams(GCFPortInterface* port)
 //
 // checkBeam(beamTransaction, port , name, subarray, beamletAllocation)
 //
-Beam* BeamServer::checkBeam(GCFPortInterface* 				port,
+DigitalBeam* BeamServer::checkBeam(GCFPortInterface* 				port,
 						  std::string 						name, 
 						  std::string 						antennaSetName, 
 						  IBS_Protocol::Beamlet2SubbandMap	allocation,
@@ -990,7 +990,7 @@ Beam* BeamServer::checkBeam(GCFPortInterface* 				port,
 		return (0);
 	}
 
-	Beam* beam = new Beam(name, antennaSetName, allocation, rcumask, ringNr);
+	DigitalBeam* beam = new DigitalBeam(name, antennaSetName, allocation, rcumask, ringNr);
 
 	if (beam) { // register new beam
 		itsClientBeams[port].insert(beam);
@@ -1127,7 +1127,7 @@ void BeamServer::_releaseBeamlets(IBS_Protocol::Beamlet2SubbandMap&	allocation,
 //
 // _registerBeam(beam)
 //
-void BeamServer::_registerBeam(const Beam&	beam)
+void BeamServer::_registerBeam(const DigitalBeam&	beam)
 {
 	bool	isLBAbeam = itsAntennaSets->usesLBAfield(beam.antennaSetName());
 	vector<uint>&		RCUcounts = isLBAbeam ? itsLBArcus : itsHBArcus;
@@ -1150,7 +1150,7 @@ void BeamServer::_registerBeam(const Beam&	beam)
 //
 // _unregisterBeam(beam)
 //
-void BeamServer::_unregisterBeam(const Beam&	beam)
+void BeamServer::_unregisterBeam(const DigitalBeam&	beam)
 {
 	bool	isLBAbeam = itsAntennaSets->usesLBAfield(beam.antennaSetName());
 	vector<uint>&		RCUcounts = isLBAbeam ? itsLBArcus : itsHBArcus;
@@ -1288,12 +1288,12 @@ void BeamServer::getAllHBAElementDelays(string filename)
 //
 void BeamServer::compute_HBAdelays(Timestamp time)
 {
-	map<string, Beam*>::iterator	beamIter = itsBeamPool.begin();
-	map<string, Beam*>::iterator	end		 = itsBeamPool.end();
+	map<string, DigitalBeam*>::iterator	beamIter = itsBeamPool.begin();
+	map<string, DigitalBeam*>::iterator	end		 = itsBeamPool.end();
 
 	// calculate HBA delays for all HBA beams.
 	while (beamIter != end) {
-		beamIter->second->calculateHBAdelays(time, itsTileRelPos, itsDelaySteps);
+//		beamIter->second->calculateHBAdelays(time, itsTileRelPos, itsDelaySteps);
 //TODO: pass reference to itsHBAdelays so that the can be updated.
 		beamIter++;
 	}
@@ -1388,15 +1388,15 @@ bool BeamServer::compute_weights(Timestamp weightTime)
 		blitz::Array<double,1>	rcuPosLengths = LBAfield ? itsAntennaPos->LBARCULengths() : itsAntennaPos->HBARCULengths();
 
 		// for all beams using this field
-		map<string, Beam*>::iterator	beamIter = itsBeamPool.begin();
-		map<string, Beam*>::iterator	end		 = itsBeamPool.end();
+		map<string, DigitalBeam*>::iterator	beamIter = itsBeamPool.begin();
+		map<string, DigitalBeam*>::iterator	end		 = itsBeamPool.end();
 		for ( ; beamIter != end; ++beamIter) {
 			// must be of the same antenna field.
 			if (itsAntennaSets->usesLBAfield(beamIter->second->antennaSetName()) != LBAfield) {
 				continue;
 			}
 			// Get the right pointing
-			Pointing	currentPointing = beamIter->second->currentPointing(weightTime);
+			Pointing	currentPointing = beamIter->second->pointingAtTime(weightTime);
 			blitz::Array<double,2>	sourceJ2000xyz;
 			blitz::Array<double,2>	curPoint(1,2);
 			curPoint(0,0) = currentPointing.angle0();
@@ -1529,10 +1529,10 @@ void BeamServer::send_sbselection()
 
 		// reconstruct the selection
 		Beamlet2SubbandMap selection;
-		map<string, Beam*>::iterator	beamIter = itsBeamPool.begin();
-		map<string, Beam*>::iterator	beamEnd  = itsBeamPool.end();
+		map<string, DigitalBeam*>::iterator	beamIter = itsBeamPool.begin();
+		map<string, DigitalBeam*>::iterator	beamEnd  = itsBeamPool.end();
 		while (beamIter != beamEnd) {
-			Beam*	beam = beamIter->second;
+			DigitalBeam*	beam = beamIter->second;
 			LOG_DEBUG_STR("Beam " << beam->name() << " is in ring " << beam->ringNr());
 			if (beam->ringNr() == ringNr) {
 				selection().insert(beam->allocation()().begin(), beam->allocation()().end());
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
index 517dfa714fe..72739c95fb2 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
+++ b/MAC/APL/PAC/ITRFBeamServer/src/BeamServer.h
@@ -26,7 +26,7 @@
 #include <Common/lofar_string.h>
 #include <APL/IBS_Protocol/IBS_Protocol.ph>
 #include "J2000Converter.h"
-#include "Beam.h"
+#include "DigitalBeam.h"
 
 #include <GCF/TM/GCF_Control.h>
 //#include <GCF/TM/GCF_TimerPort.h>
@@ -56,20 +56,20 @@ private:
 	public:
 		BeamTransaction() : m_port(0), m_beam(0), itsAllocDone(false) {}
 
-		void set(GCFPortInterface* port, Beam* beam) { m_port = port; m_beam = beam; }
+		void set(GCFPortInterface* port, DigitalBeam* beam) { m_port = port; m_beam = beam; }
 		inline void reset() 			{ set(0,0); itsAllocDone = false; }
 		inline void allocationDone() 	{ itsAllocDone = true; }
 		inline bool isAllocationDone()	{ return(itsAllocDone); }
 
 		GCFPortInterface* getPort() const { return m_port; }
-		Beam*             getBeam() const { return m_beam; }
+		DigitalBeam*      getBeam() const { return m_beam; }
 
 	private:
 		// Port on which the transaction is taking place.
 		GCFPortInterface* m_port;
 
 		// Beam that is the subject of the transaction
-		Beam* m_beam;
+		DigitalBeam* m_beam;
 
 		bool	itsAllocDone;
 	};
@@ -87,7 +87,7 @@ public:
 	void  destroyAllBeams(GCFPortInterface* port);
 
 	// Create new beam and update administration
-	Beam*	checkBeam(GCFPortInterface* 					port,
+	DigitalBeam*	checkBeam(GCFPortInterface* 					port,
 					string 								name, 
 					string 								subarrayname, 
 					IBS_Protocol::Beamlet2SubbandMap	allocation,
@@ -177,8 +177,8 @@ public:
 	vector<double>  blitz2vector(const blitz::Array<double,1>&    anBA) const;
 
 	// RCU administration
-	void _registerBeam   (const Beam&	beam);
-	void _unregisterBeam (const Beam&	beam);
+	void _registerBeam   (const DigitalBeam&	beam);
+	void _unregisterBeam (const DigitalBeam&	beam);
 	void _logBeamAdministration();
 
 private:
@@ -222,7 +222,7 @@ private:
 	list<GCFPortInterface*> 	itsClientList;	// list of currently connected clients
 	list<GCFPortInterface*> 	itsDeadClients;	// list of discon. clients to be removed
 
-	map<GCFPortInterface*, set<Beam*> >   itsClientBeams; // mapping from client port to set of beams
+	map<GCFPortInterface*, set<DigitalBeam*> >   itsClientBeams; // mapping from client port to set of beams
 
 	BeamTransaction				itsBeamTransaction; 	// current beam transaction
 
@@ -233,7 +233,7 @@ private:
 	GCFTimerPort*  				itsTimerPort;		  	// General purpose timer
 	bool     					itsBeamsModified;		//
 	bool						itsSplitterOn;			// state of the ringsplitter
-	map<string, Beam*> 			itsBeamPool;			//
+	map<string, DigitalBeam*> 	itsBeamPool;			//
 	
 	// constants
 	int    	itsMaxRCUs;				//
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.cc b/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.cc
new file mode 100644
index 00000000000..bc33622b65c
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.cc
@@ -0,0 +1,88 @@
+//#  DigitalBeam.h: implementation of the DigitalBeam class
+//#
+//#  Copyright (C) 2002-2004
+//#  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$
+
+#include <lofar_config.h>
+#include <Common/LofarLogger.h>
+#include <Common/LofarLocators.h>
+#include <Common/LofarConstants.h>
+
+#include <APL/RTCCommon/PSAccess.h>
+#include "BeamServerConstants.h"
+#include "DigitalBeam.h"
+
+#include <math.h>
+#include <iostream>
+#include <sys/time.h>
+#include <queue>
+
+#include <blitz/array.h>
+
+#include <fcntl.h>
+
+using namespace blitz;
+using namespace LOFAR;
+using namespace BS;
+using namespace IBS_Protocol;
+using namespace std;
+using namespace RTC;
+
+//
+// DigitalBeam(name, subarray, nrSubbands)
+//
+DigitalBeam::DigitalBeam(const string& 					name, 
+					     const string& 					antennaSet, 
+					     const Beamlet2SubbandMap&		allocation, 
+					     const bitset<MAX_RCUS>&		rcuMask,
+					     uint							ringNr) :
+	Beam 				(name, rcuMask),
+	itsAntennaSet		(antennaSet),
+	itsBeamletAllocation(allocation),
+	itsRingNr			(ringNr)
+{}
+
+//
+// ~DigitalBeam
+//
+DigitalBeam::~DigitalBeam()
+{
+	deallocate();
+}
+
+//
+// deallocate()
+//
+void DigitalBeam::deallocate()
+{
+	// clear allocation
+	itsBeamletAllocation().clear();
+}
+
+#if 0
+//
+// setSubarray(array)
+//
+void DigitalBeam::setSubarray(const CAL::SubArray& array)
+{
+	itsSubArray = array;
+}
+#endif
+
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.h b/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.h
new file mode 100644
index 00000000000..9e23ec3fb90
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/src/DigitalBeam.h
@@ -0,0 +1,121 @@
+//#  DigitalBeam.h: interface of the DigitalBeam class
+//#
+//#  Copyright (C) 2002-2009
+//#  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 DIGITALBEAM_H_
+#define DIGITALBEAM_H_
+
+#include <lofar_config.h>
+#include <Common/lofar_string.h>
+#include <APL/RTCCommon/Timestamp.h>
+#include <APL/IBS_Protocol/Beamlet2SubbandMap.h>
+#include <APL/CAL_Protocol/AntennaGains.h>
+#include <APL/CAL_Protocol/SubArray.h>
+#include "Beam.h"
+
+#include <queue>
+#include <blitz/array.h>
+
+namespace LOFAR {
+  namespace BS {
+
+// Class representing a single beam allocated by a client
+// using a BEAMALLOC event.
+class DigitalBeam : public Beam {
+public:
+
+	// Default constructor
+	// @param name String identifying this beam uniquely in the OTDB, used with
+	// key-value logger as nodeid.
+	// @param antennaSet The name of the AntenneField on which this beam is defined.
+	// @param allocation How the subbands of the beam are mapped tot the bemalets.
+	// @param rcuMask The RCUs that participate in this beam.
+	// @param ringNr The serdes segment the allocation is ment for.
+	DigitalBeam(const string& 							name, 
+			    const string& 							antenneSet, 
+			    const IBS_Protocol::Beamlet2SubbandMap&	allocation, 
+			    const bitset<MAX_RCUS>&					rcuMask,
+			    uint 									ringNr);
+
+	// Default destructor.
+	virtual ~DigitalBeam();
+
+	// Get the allocation mapping for this beam.
+	// @return Beamlet2SubbandMap the mapping from beamlet to subband for this beam.
+	IBS_Protocol::Beamlet2SubbandMap& allocation() { return(itsBeamletAllocation); }
+
+	// Set the subarray (positions & rcu_index)
+//	void setSubarray(const CAL::SubArray& array);
+
+	// Return a reference to the subarray for this beam.
+	// @return reference to the subarray
+//	const CAL::SubArray& getSubarray() const { return itsSubArray; }
+
+	// setCalibration weights for the receivers
+//	void setCalibration(const CAL::AntennaGains& gains);
+
+	// Get the current calibration values.
+//	const CAL::AntennaGains& getCalibration() const;
+
+	// Get the name of the subarray on which this beam operates.
+	string antennaSetName() const { return (itsAntennaSet); }
+
+	// Get number of ringSegment
+	int ringNr() const	{ return (itsRingNr); }
+
+	// Set handle (=uniq ID) from the CalServer
+	void  calibrationHandle(void	*handle) { itsCShandle = handle; }
+	void* calibrationHandle()				 { return (itsCShandle); }
+
+private:
+	// Don't allow copying this object.
+	DigitalBeam (const DigitalBeam&);            // not implemented
+	DigitalBeam& operator= (const DigitalBeam&); // not implemented
+
+	// Method to undo an allocation.
+	void deallocate();
+
+	//# ----- DATAMEMBERS -----
+
+	// Name of the subarray on which the beam is allocated.
+	string 		itsAntennaSet;
+
+	// Allocation.
+	IBS_Protocol::Beamlet2SubbandMap 	itsBeamletAllocation;
+
+	// ringSegment the beam is allocated on
+	int									itsRingNr;
+
+	// The antenna array.
+//	CAL::SubArray 		itsSubArray;
+
+	// calserver handle	
+	// will become obsolete when new ITRF CalServer is used.
+	void*		itsCShandle;
+
+};
+
+//# -------------------- inline functions --------------------
+
+  }; //# namepsace BS
+}; //# namespace LOFAR
+
+#endif /* DIGITALBEAM_H_ */
diff --git a/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am b/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
index ab7eb3bf97f..5fc1f19540d 100644
--- a/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
+++ b/MAC/APL/PAC/ITRFBeamServer/src/Makefile.am
@@ -19,8 +19,13 @@ sysconf_DATA 			=
 
 bin_PROGRAMS 			= iBeamServer ibeamctl
 
-iBeamServer_SOURCES 		= BeamServerMain.cc BeamServer.h BeamServerConstants.h BeamServer.cc \
-							  Beam.h Beam.cc J2000Converter.h J2000Converter.cc
+iBeamServer_SOURCES 		= BeamServerMain.cc BeamServerConstants.h \
+							  BeamServer.h BeamServer.cc \
+							  Beam.h Beam.cc \
+							  DigitalBeam.h DigitalBeam.cc \
+							  AnalogueBeam.h AnalogueBeam.cc \
+							  AnaBeamMgr.h AnaBeamMgr.cc \
+							  J2000Converter.h J2000Converter.cc
 iBeamServer_LDADD 			= 
 iBeamServer_DEPENDENCIES	= $(LOFAR_DEPEND)
 
diff --git a/MAC/APL/PAC/ITRFBeamServer/test/Makefile.am b/MAC/APL/PAC/ITRFBeamServer/test/Makefile.am
new file mode 100644
index 00000000000..d284ec972f9
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/test/Makefile.am
@@ -0,0 +1,13 @@
+check_PROGRAMS			= tConverter tJ2000Converter tAnaBeamMgr
+
+tConverter_SOURCES		= tConverter.cc
+tConverter_DEPENDENCIES	= $(LOFAR_DEPEND)
+
+tJ2000Converter_SOURCES			= tJ2000Converter.cc ../src/J2000Converter.cc
+tJ2000Converter_DEPENDENCIES	= $(LOFAR_DEPEND)
+
+tAnaBeamMgr_SOURCES			= tAnaBeamMgr.cc ../src/Beam.cc ../src/AnalogueBeam.cc ../src/AnaBeamMgr.cc
+tAnaBeamMgr_DEPENDENCIES	= $(LOFAR_DEPEND)
+
+
+include $(top_srcdir)/Makefile.common
diff --git a/MAC/APL/PAC/ITRFBeamServer/test/tAnaBeamMgr.cc b/MAC/APL/PAC/ITRFBeamServer/test/tAnaBeamMgr.cc
new file mode 100644
index 00000000000..38ac25ae89b
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/test/tAnaBeamMgr.cc
@@ -0,0 +1,147 @@
+//#  Class.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 <APL/RTCCommon/Timestamp.h>
+#include <APL/IBS_Protocol/Pointing.h>
+
+#include <blitz/array.h>
+#include <ITRFBeamServer/AnalogueBeam.h>
+#include <ITRFBeamServer/AnaBeamMgr.h>
+
+using namespace LOFAR;
+using namespace RTC;
+using namespace BS;
+using namespace IBS_Protocol;
+
+int main(int	argc, char*	argv[]) 
+{
+	INIT_LOGGER("tAnaBeamMgr");
+
+	// set up some rcuMask for the tests. Mask 1+2 or 2+3 can be scheduled at the same time.
+	// 1: 0000 0000 1111
+	// 2: 0011 1111 1100
+	// 3: 0000 0011 1100
+	// 4: 1111 0000 0000
+	bitset<MAX_RCUS>		rcuMask1(0x0000000F);	// overlaps with 2 and 3
+	bitset<MAX_RCUS>		rcuMask2(0x000002FC);	// overlaps all
+	bitset<MAX_RCUS>		rcuMask3(0x0000003C);	// overlaps with 1 and 2
+	bitset<MAX_RCUS>		rcuMask4(0x00000F00);	// overlaps with 2
+
+	// In these first tests we test the addPointing mechanism of the Beam class.
+	AnalogueBeam	beam1("beam1", rcuMask1, 1);
+	LOG_DEBUG("--- POINTING TEST 1: are contiguous pointings added in the right order");
+	beam1.addPointing(Pointing(0.1, 0.1,  Timestamp(1262700000,0), 1000, "J2000"));
+	beam1.addPointing(Pointing(0.1, 0.11, Timestamp(1262700000+1000,0), 1100, "J2000"));
+	beam1.showPointings();
+
+	LOG_DEBUG("--- POINTING TEST 2: are gaps recognized and filled with NONE pointings");
+	beam1.addPointing(Pointing(0.1, 0.2, Timestamp(1262700000+5000,0), 2200, "J2000"));
+	beam1.showPointings();
+
+	LOG_DEBUG("--- POINTING TEST 3: are overlapping pointings rejected");
+	beam1.addPointing(Pointing(0.1, 0.3, Timestamp(1262700000+1200,0), 200, "J2000"));
+	beam1.showPointings();
+	
+	LOG_DEBUG("--- POINTING TEST 4: are gaps splitted when a new pointing is inserted in the gap");
+	beam1.addPointing(Pointing(0.1, 0.4, Timestamp(1262700000+3000,0), 500, "J2000"));
+	beam1.showPointings();
+	
+	LOG_DEBUG("--- POINTING TEST 5: can we insert a pointing in 'reverse' order'");
+	beam1.addPointing(Pointing(0.1, 0.5, Timestamp(1262700000-600,0), 600, "J2000"));
+	beam1.showPointings();
+	
+	LOG_DEBUG("--- POINTING TEST 6: can we insert an everlasting pointing in the middle");
+	beam1.addPointing(Pointing(0.1, 0.6, Timestamp(1262700000+4000,0), 0, "J2000"));
+	beam1.showPointings();
+	
+	LOG_DEBUG("--- POINTING TEST 7: can we add an everlasting pointing at the end");
+	beam1.addPointing(Pointing(0.1, 0.7, Timestamp(1262700000+9000,0), 0, "J2000"));
+	beam1.showPointings();
+	
+	// In the second set of tests we test the mechanism of activating the right analogueBeams.
+	// Remember that this depends on many conditions like rank, rcu overlap and consistency in
+	// staying active when a beam is active.
+
+	LOG_DEBUG("--- SCHEDULE TEST 1: is something scheduled before the starttime is reached.");
+	AnaBeamMgr	beamMgr1(96, 1);
+	beamMgr1.addBeam(beam1);
+	beamMgr1.activateBeams(Timestamp(1262700000-1000, 0));
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 2: is beam made active when starttime is reached");
+	beamMgr1.activateBeams(Timestamp(1262700000-500, 0));	// note first pt at ...-600
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 3: are NONE pointings also scheduled and are old pointings deleted");
+	beamMgr1.activateBeams(Timestamp(1262700000+2500, 0));	
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 4: can we add an overlapping beam with the another rank");
+	AnalogueBeam	beam2("beam2", rcuMask2, 3);
+	beam2.addPointing(Pointing(0.2, 0.6, Timestamp(1262700000+2200,0), 400, "AZEL"));
+	beamMgr1.addBeam(beam2);
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 5: will the second beam become active also (it should not because of overlap)");
+	beamMgr1.activateBeams(Timestamp(1262700000+2500, 0));	// no change in time
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 6: can we add an overlapping beam with a higher rank as the previous beam");
+	AnalogueBeam	beam3("beam3", rcuMask3, 2);
+	beam3.addPointing(Pointing(0.3, 0.6, Timestamp(1262700000+2000,0), 1400, "ITRF"));
+	beamMgr1.addBeam(beam3);
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 7: will the third beam become active also (it should not because of overlap)");
+	beamMgr1.activateBeams(Timestamp(1262700000+2500, 0));	// no change in time
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 8: add an NON overlapping beam with an equal rank as the first beam which starts earlier");
+	AnalogueBeam	beam4("beam4", rcuMask4, 1);
+	beam4.addPointing(Pointing(0.4, 0.6, Timestamp(1262700000+2000,0), 1400, "MOON"));
+	beamMgr1.addBeam(beam4);
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 9: will the fourth beam become active also (it should)");
+	beamMgr1.activateBeams(Timestamp(1262700000+2500, 0));	// no change in time
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 10: delete beam 1");
+	beamMgr1.deleteBeam(beam1);	
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 11: will the third beam become active also (it should)");
+	beamMgr1.activateBeams(Timestamp(1262700000+2500, 0));	// no change in time
+	beamMgr1.showAdmin();
+
+	LOG_DEBUG("--- SCHEDULE TEST 12: jump into the future, all beams should disappear");
+	beamMgr1.activateBeams(Timestamp(1262700000+10000, 0));
+	beamMgr1.showAdmin();
+
+
+}
+
diff --git a/MAC/APL/PAC/ITRFBeamServer/test/tConverter.cc b/MAC/APL/PAC/ITRFBeamServer/test/tConverter.cc
new file mode 100644
index 00000000000..9919d03b277
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/test/tConverter.cc
@@ -0,0 +1,188 @@
+//#  Class.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>
+#include <Common/lofar_vector.h>
+
+//# Includes
+#include <Common/LofarLogger.h>
+#include <APL/RTCCommon/Timestamp.h>
+
+#include <casa/Exceptions/Error.h>
+#include <casa/Quanta/MVTime.h>
+#include <casa/Arrays/Vector.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 <AMCBase/Converter.h>
+#include <AMCBase/ConverterClient.h>
+#include <AMCBase/RequestData.h>
+#include <AMCBase/ResultData.h>
+#include <AMCBase/Position.h>
+#include <AMCBase/Direction.h>
+#include <AMCBase/Epoch.h>
+
+#include <blitz/array.h>
+
+using namespace casa;
+using namespace blitz;
+using namespace LOFAR;
+using namespace AMC;
+using namespace RTC;
+
+int main(int	argc, char*	argv[]) 
+{
+	// construct a frame with an epoch (with a trivial time).
+	MeasFrame	frame;
+	frame.set(MEpoch(Quantity(55000.0, "d"), MEpoch::UTC));	// somewhere in 2009
+	frame.set(MPosition(MVPosition(0.0, 0.0, 0.0), MPosition::ITRF));
+	// construct a converter (this takes some time).
+	MDirection::Convert		I2Jconverter(MDirection::Ref(MDirection::ITRF), MDirection::Ref(MDirection::J2000, frame));
+
+	// prepare fake input data
+	blitz::Array<double,2>		fieldPos(2,3);
+	fieldPos(0,0) = 3827945.959728817; 	fieldPos(0,1) = 459792.591297293; 	fieldPos(0,2) = 5063989.988; 	
+	fieldPos(1,0) = 3827931.695686471; 	fieldPos(1,1) = 459769.506299131; 	fieldPos(1,2) = 5064002.779; 	
+	blitz::Array<double,2>		antPos(3,3);
+	antPos(0,0) = 0.0; 		antPos(0,1) = 0.0; 		antPos(0,2) = 0.0; 	
+	antPos(1,0) = 100.0; 	antPos(1,1) = 0.0; 		antPos(1,2) = 0.0; 	
+	antPos(2,0) = 0.0;	 	antPos(2,1) = 100.0; 	antPos(2,2) = 0.0; 	
+
+	cout.precision(9);
+
+	// do the calculations for field 1
+	frame.resetPosition(MPosition(MVPosition(fieldPos(0,0), fieldPos(0,1), fieldPos(0,2)), MPosition::ITRF));
+	frame.resetEpoch(MVTime(2007,1,1,0.25));		// set some other time
+	cout << "01012007 " << MVTime(2007,1,1,0.25) << endl;
+	for (int i = 0; i < antPos.extent(firstDim); ++i) {
+		MVDirection	ITRFPos(antPos(i,0), antPos(i,1), antPos(i,2));
+		cout << i << ": Direction: " << ITRFPos << endl;
+		cout << i << ": Position : " << MPosition(MVPosition(fieldPos(0,0), fieldPos(0,1), fieldPos(0,2)), MPosition::ITRF) << endl;
+		cout << i << ": Epoch    : " << MVTime(2007,1,1,0.25) << endl;
+		MDirection	J2000Dir = I2Jconverter(ITRFPos);
+		cout << i << ": Result   : " << J2000Dir << endl;
+		casa::Vector<Double> angles = J2000Dir.getValue().get();
+		cout << i << " converted : " << Direction(angles(0),  angles(1), Direction::ITRF) << endl;
+
+		Int	nAll, nExtra;
+		const uInt* typ;
+//		const casa::String*	theTypes = J2000Dir.allTypes(nAll, nExtra, typ);
+		const casa::String*	theTypes = MDirection::allMyTypes(nAll, nExtra, typ);
+		cout << "nAll=" << nAll << ", nExtra=" << nExtra << ", typ=" << typ << endl;
+		for (int i=0; i < nAll; i++) {
+			cout << theTypes[i] << "=" << typ[i] << endl;
+		}
+	}
+
+#if 0
+	frame.resetEpoch(MVTime(2007,1,1,0.75));		// set some other time
+	cout << "01012007 " << MVTime(2007,1,1,0.75) << endl;
+	for (int i = 0; i < antPos.extent(firstDim); ++i) {
+		MVDirection	ITRFPos(antPos(i,0), antPos(i,1), MDirection::ITRF);
+		MDirection	J2000Dir = I2Jconverter(ITRFPos);
+		cout << J2000Dir.getAngle() << endl;
+	}
+
+	frame.resetEpoch(MVTime(2007,1,2,0.2472685));		// set some other time
+	cout << "02012007 " << MVTime(2007,1,1,0.2472685) << endl;
+	for (int i = 0; i < antPos.extent(firstDim); ++i) {
+		MVDirection	ITRFPos(antPos(i,0), antPos(i,1), MDirection::ITRF);
+		MDirection	J2000Dir = I2Jconverter(ITRFPos);
+		cout << J2000Dir.getAngle() << endl;
+	}
+#endif
+
+	// Now do the same with the use of AMC
+	ConverterClient		AMCclient("localhost");
+	vector<double>	fieldPosITRFVect(3);
+	fieldPosITRFVect[0] = fieldPos(0,0);
+	fieldPosITRFVect[1] = fieldPos(0,1);
+	fieldPosITRFVect[2] = fieldPos(0,2);
+	Position    		fieldPositionITRF(Coord3D(fieldPosITRFVect), Position::ITRF);
+
+	struct tm			jan2007;
+	jan2007.tm_sec  = 0;
+	jan2007.tm_min  = 0;
+	jan2007.tm_hour = 6;
+	jan2007.tm_mday = 1;
+	jan2007.tm_mon  = 0;
+	jan2007.tm_year = 107;
+	cout << asctime(&jan2007) << endl;
+	Timestamp			theTime(timegm(&jan2007), 0);
+	double				mjd, fraction;
+	theTime.convertToMJD(mjd, fraction);
+
+	for (int i = 0; i < antPos.extent(firstDim); ++i) {
+		cout << Epoch(mjd, fraction) << endl;
+		vector<double>	antPosVect(3);
+		antPosVect[0] = antPos(i,0);
+		antPosVect[1] = antPos(i,1);
+		antPosVect[2] = antPos(i,2);
+		RequestData 		request(Direction(Coord3D(antPosVect), Direction::ITRF), 
+									fieldPositionITRF, 
+									Epoch(mjd, fraction));
+		ResultData			result;
+		cout << i << ": Direction: " << Direction(Coord3D(antPosVect), Direction::ITRF) << endl;
+		cout << i << ": Position : " << fieldPositionITRF << endl;
+		cout << i << ": Epoch    : " << Epoch(mjd, fraction) << endl;
+		AMCclient.itrfToJ2000(result, request);
+		vector<double>	direction = result.direction[0].coord().get();
+		cout << i << ": Result   : " << direction[0] << ", " << direction[1] << ", " << direction[2] << endl;
+
+#if 0
+		double  originalLength = sqrt((antPos(i,0)*antPos(i,0)) +
+									  (antPos(i,1)*antPos(i,1)) +
+									  (antPos(i,2)*antPos(i,2)));
+		direction[0] *= originalLength;
+		direction[1] *= originalLength;
+		direction[2] *= originalLength;
+
+		cout << "scaled: " << direction[0] << ", " << direction[1] << ", " << direction[2] << endl;
+#endif
+	}
+
+}
+
+
+
+#if 0
+  J2000, 
+  B1950, 
+  AZEL, 
+  ITRF, 
+  MERCURY, 
+  VENUS, 
+  MARS, 
+  JUPITER, 
+  SATURN, 
+  URANUS, 
+  NEPTUNE, 
+  PLUTO, 
+  SUN, 
+  MOON, 
+#endif
+
diff --git a/MAC/APL/PAC/ITRFBeamServer/test/tJ2000Converter.cc b/MAC/APL/PAC/ITRFBeamServer/test/tJ2000Converter.cc
new file mode 100644
index 00000000000..91817a26546
--- /dev/null
+++ b/MAC/APL/PAC/ITRFBeamServer/test/tJ2000Converter.cc
@@ -0,0 +1,84 @@
+//#  Class.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 <APL/RTCCommon/Timestamp.h>
+
+#include <blitz/array.h>
+#include <ITRFBeamServer/J2000Converter.h>
+
+using namespace casa;
+using namespace blitz;
+using namespace LOFAR;
+using namespace RTC;
+using namespace BS;
+
+int main(int	argc, char*	argv[]) 
+{
+	INIT_LOGGER("tJ2000Converter");
+
+	// prepare fake input data
+	blitz::Array<double,2>		fieldPos(2,3);
+	fieldPos(0,0) = 3827945.959728817; 	fieldPos(0,1) = 459792.591297293; 	fieldPos(0,2) = 5063989.988; 	
+	fieldPos(1,0) = 3827931.695686471; 	fieldPos(1,1) = 459769.506299131; 	fieldPos(1,2) = 5064002.779; 	
+	blitz::Array<double,2>		antPos(3,3);
+	antPos(0,0) = 0.0; 		antPos(0,1) = 0.0; 		antPos(0,2) = 0.0; 	
+	antPos(1,0) = 100.0; 	antPos(1,1) = 0.0; 		antPos(1,2) = 0.0; 	
+	antPos(2,0) = 0.0;	 	antPos(2,1) = 100.0; 	antPos(2,2) = 0.0; 	
+
+	struct tm			jan2007;
+	jan2007.tm_sec  = 0;
+	jan2007.tm_min  = 0;
+	jan2007.tm_hour = 6;
+	jan2007.tm_mday = 1;
+	jan2007.tm_mon  = 0;
+	jan2007.tm_year = 107;
+	cout << asctime(&jan2007) << endl;
+	Timestamp			theTime(timegm(&jan2007), 0);
+
+	// the actual code
+	J2000Converter		theConverter;
+
+	blitz::Array<double,2>	result;
+	if (!theConverter.doConversion("ITRF", antPos, fieldPos(0, Range::all()), theTime, result)) {
+		LOG_FATAL("The conversion failed");
+		exit(1);
+	}
+	cout << theTime << endl;
+	cout << result;
+
+	bool	good = theConverter.isValidType("MOON");
+	cout << "'MOON' is " << (good ? "" : "NOT ") << "a supported conversion" << endl;
+	bool	bad  = theConverter.isValidType("CYGA");
+	cout << "'CYGA' is " << (bad ? "" : "NOT ") << "a supported conversion" << endl;
+
+	vector<string>	allTypes = theConverter.validTypes();
+	for (int i = 0; i < allTypes.size(); i++) {
+		cout << allTypes[i] << " ";
+	}
+	cout << endl;
+}
+
-- 
GitLab