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