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