diff --git a/.gitattributes b/.gitattributes index dfcc9272ed8b37317825ec6b7e328a76b932ac69..fbac7896145a5735313a27756fbe5f518d8c169c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -22,6 +22,7 @@ CEP/Calibration/BBSControl/src/calibrate-part -text CEP/Calibration/BBSKernel/include/BBSKernel/ElementBeamExpr.h -text CEP/Calibration/BBSKernel/include/BBSKernel/Expr/EquatorialCentroid.h -text CEP/Calibration/BBSKernel/include/BBSKernel/Expr/Scope.h -text +CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h -text CEP/Calibration/BBSKernel/include/BBSKernel/IonosphereExpr.h -text CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_HBA.coeff -text CEP/Calibration/BBSKernel/src/Contrib/JPH_DipoleBeam/element_beam_HAMAKER_LBA.coeff -text @@ -32,6 +33,7 @@ CEP/Calibration/BBSKernel/src/Contrib/SBY_DipoleBeam/hba_beam_theta.c -text CEP/Calibration/BBSKernel/src/ElementBeamExpr.cc -text CEP/Calibration/BBSKernel/src/Expr/EquatorialCentroid.cc -text CEP/Calibration/BBSKernel/src/Expr/Scope.cc -text +CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc -text CEP/Calibration/BBSKernel/src/IonosphereExpr.cc -text CEP/Calibration/BBSKernel/test/tJonesCMul3.cc -text CEP/Calibration/BBSKernel/test/tJonesCMul3.sh -text diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt index 0f4eb490bb51b01573d943acadde8c26bfb1af54..c47d4d37a1e8b853764d1bf42fcf958ba745160d 100644 --- a/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt +++ b/CEP/Calibration/BBSKernel/include/BBSKernel/CMakeLists.txt @@ -34,6 +34,7 @@ install(FILES Expr/BasicExpr.h Expr/Cache.h Expr/ConditionNumber.h + Expr/EquatorialCentroid.h Expr/Expr.h Expr/ExprId.h Expr/ExprAdaptors.h @@ -74,9 +75,9 @@ install(FILES Expr/Scope.h Expr/Source.h Expr/SpectralIndex.h - Expr/EquatorialCentroid.h Expr/StationShift.h Expr/StationUVW.h + Expr/TileArrayFactor.h Expr/ValueSet.h Expr/YatawattaDipole.h DESTINATION include/${PACKAGE_NAME}/Expr) diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h index c5587d6276363fe1d862fd09d2cc60539bf1c2dd..0c96970a0a770f864e156e4c01811a9eeeefcbc0 100644 --- a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h +++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/ArrayFactor.h @@ -43,7 +43,7 @@ class ArrayFactor: public BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix> public: ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction, const Expr<Vector<2> >::ConstPtr &reference, - const AntennaConfig &config, double referenceFreq); + const AntennaSelection &selection, double referenceFreq); protected: virtual const JonesMatrix::View evaluateImpl(const Grid &grid, @@ -51,8 +51,8 @@ protected: const; private: - AntennaConfig itsConfig; - double itsReferenceFreq; + AntennaSelection itsSelection; + double itsReferenceFreq; }; // @} diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h new file mode 100644 index 0000000000000000000000000000000000000000..73374903138fd8e72f5b000f20bb46f97461f352 --- /dev/null +++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Expr/TileArrayFactor.h @@ -0,0 +1,61 @@ +//# TileArrayFactor.h: Compute the array factor of a LOFAR HBA tile. +//# +//# Copyright (C) 2009 +//# ASTRON (Netherlands Institute for Radio Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +//# +//# This file is part of the LOFAR software suite. +//# The LOFAR software suite is free software: you can redistribute it and/or +//# modify it under the terms of the GNU General Public License as published +//# by the Free Software Foundation, either version 3 of the License, or +//# (at your option) any later version. +//# +//# The LOFAR software suite is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License along +//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. +//# +//# $Id$ + +#ifndef LOFAR_BBSKERNEL_EXPR_TILEARRAYFACTOR_H +#define LOFAR_BBSKERNEL_EXPR_TILEARRAYFACTOR_H + +// \file +// Compute the array factor of a LOFAR HBA tile. + +#include <BBSKernel/Expr/BasicExpr.h> +#include <BBSKernel/Instrument.h> +#include <measures/Measures/MDirection.h> + +namespace LOFAR +{ +namespace BBS +{ + +// \addtogroup Expr +// @{ + +class TileArrayFactor: public BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix> +{ +public: + TileArrayFactor(const Expr<Vector<2> >::ConstPtr &direction, + const Expr<Vector<2> >::ConstPtr &reference, const TileLayout &layout); + +protected: + virtual const JonesMatrix::View evaluateImpl(const Grid &grid, + const Vector<2>::View &direction, const Vector<2>::View &reference) + const; + +private: + TileLayout itsLayout; +}; + +// @} + +} //# namespace BBS +} //# namespace LOFAR + +#endif diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h index b82ce08e5fa8384d9f855ca5aca4a40ad005dceb..b5d38cb3cadc0004b253bc50f529c67128b6ae5b 100644 --- a/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h +++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Instrument.h @@ -41,40 +41,58 @@ namespace BBS // \addtogroup BBSKernel // @{ -class AntennaConfig +class AntennaSelection { public: + AntennaSelection(); + AntennaSelection(unsigned int size); + const string &name() const; - size_t size() const; - double operator()(unsigned int i, unsigned int j) const; + unsigned int size() const; + const double &operator()(unsigned int i0, unsigned int i1) const; + double &operator()(unsigned int i0, unsigned int i1); private: - friend istream &operator>>(istream &in, AntennaConfig &obj); + friend istream &operator>>(istream &in, AntennaSelection &obj); string itsName; casa::Matrix<double> itsPositions; }; -istream &operator>>(istream &in, AntennaConfig &obj); +istream &operator>>(istream &in, AntennaSelection &obj); + +class TileLayout +{ +public: + TileLayout(); + TileLayout(unsigned int size); + + unsigned int size() const; + const double &operator()(unsigned int i0, unsigned int i1) const; + double &operator()(unsigned int i0, unsigned int i1); + +private: + casa::Matrix<double> itsPositions; +}; class Station { public: -// Station(); Station(const string &name, const casa::MPosition &position); - Station(const string &name, const casa::MPosition &position, - const casa::Path &config); const string &name() const; const casa::MPosition &position() const; - const AntennaConfig &config(const string &name) const; + const AntennaSelection &selection(const string &name) const; + const TileLayout &tile(unsigned int i) const; - void readAntennaConfigurations(const casa::Path &file); + void readAntennaSelection(const casa::Path &file); + void readTileLayout(const casa::Path &file); private: - string itsName; - casa::MPosition itsPosition; - map<string, AntennaConfig> itsConfig; + string itsName; + casa::MPosition itsPosition; + map<string, AntennaSelection> itsAntennaSelection; + vector<TileLayout> itsTileLayout; }; class Instrument @@ -91,7 +109,7 @@ public: const Station &operator[](unsigned int i) const; const Station &operator[](const string &name) const; - void readAntennaConfigurations(const casa::Path &path); + void readLOFARAntennaConfig(const casa::Path &path); private: string itsName; @@ -103,14 +121,37 @@ private: // @} // -------------------------------------------------------------------------- // -// - AntennaConfig implementation - // +// - AntennaSelection implementation - // +// -------------------------------------------------------------------------- // + +inline const double &AntennaSelection::operator()(unsigned int i0, + unsigned int i1) const +{ + //# Swap axes to hide the Fortran index convention used by casa::Array. + return itsPositions(i1, i0); +} + +inline double &AntennaSelection::operator()(unsigned int i0, unsigned int i1) +{ + //# Swap axes to hide the Fortran index convention used by casa::Array. + return itsPositions(i1, i0); +} + +// -------------------------------------------------------------------------- // +// - TileLayout implementation - // // -------------------------------------------------------------------------- // -inline double AntennaConfig::operator()(unsigned int i, unsigned int j) +inline const double &TileLayout::operator()(unsigned int i0, unsigned int i1) const { //# Swap axes to hide the Fortran index convention used by casa::Array. - return itsPositions(j, i); + return itsPositions(i1, i0); +} + +inline double &TileLayout::operator()(unsigned int i0, unsigned int i1) +{ + //# Swap axes to hide the Fortran index convention used by casa::Array. + return itsPositions(i1, i0); } } // namespace BBS diff --git a/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am b/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am index 52aa5d15309505d5b3f0e69740428ea57acf68bc..9743a204ab4c0273c5d6784ef556e50de79bba51 100644 --- a/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am +++ b/CEP/Calibration/BBSKernel/include/BBSKernel/Makefile.am @@ -28,6 +28,7 @@ pkginclude_Expr_HEADERS = \ Expr/BasicExpr.h \ Expr/Cache.h \ Expr/ConditionNumber.h \ + Expr/EquatorialCentroid.h \ Expr/Expr.h \ Expr/ExprId.h \ Expr/ExprAdaptors.h \ @@ -68,9 +69,9 @@ pkginclude_Expr_HEADERS = \ Expr/Scope.h \ Expr/Source.h \ Expr/SpectralIndex.h \ - Expr/EquatorialCentroid.h \ Expr/StationShift.h \ Expr/StationUVW.h \ + Expr/TileArrayFactor.h \ Expr/ValueSet.h \ Expr/YatawattaDipole.h diff --git a/CEP/Calibration/BBSKernel/src/CMakeLists.txt b/CEP/Calibration/BBSKernel/src/CMakeLists.txt index b51150a6162c16b65f4458388f86273642df1735..066e0df9517424e88109deb03e674925ddc9d534 100644 --- a/CEP/Calibration/BBSKernel/src/CMakeLists.txt +++ b/CEP/Calibration/BBSKernel/src/CMakeLists.txt @@ -26,6 +26,7 @@ lofar_add_library(bbskernel Expr/AzEl.cc Expr/Cache.cc Expr/ConditionNumber.cc + Expr/EquatorialCentroid.cc Expr/Expr.cc Expr/ExprAdaptors.cc Expr/ExprParm.cc @@ -62,9 +63,9 @@ lofar_add_library(bbskernel Expr/Scope.cc Expr/Source.cc Expr/SpectralIndex.cc - Expr/EquatorialCentroid.cc Expr/StationShift.cc Expr/StationUVW.cc + Expr/TileArrayFactor.cc Expr/ValueSet.cc Expr/YatawattaDipole.cc) diff --git a/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc b/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc index 3ddb7edc6e49d53d8d37cf27b7eadf7c9142062b..8b1f46ae37b647308cf91f1975436d2e885f8f07 100644 --- a/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc +++ b/CEP/Calibration/BBSKernel/src/Expr/ArrayFactor.cc @@ -33,11 +33,11 @@ namespace BBS { ArrayFactor::ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction, - const Expr<Vector<2> >::ConstPtr &reference, const AntennaConfig &config, - double referenceFreq) + const Expr<Vector<2> >::ConstPtr &reference, + const AntennaSelection &selection, double referenceFreq) : BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>(direction, reference), - itsConfig(config), + itsSelection(selection), itsReferenceFreq(referenceFreq) { } @@ -45,7 +45,7 @@ ArrayFactor::ArrayFactor(const Expr<Vector<2> >::ConstPtr &direction, const JonesMatrix::View ArrayFactor::evaluateImpl(const Grid &grid, const Vector<2>::View &direction, const Vector<2>::View &reference) const { - const size_t nElement = itsConfig.size(); + const size_t nElement = itsSelection.size(); const size_t nFreq = grid[FREQ]->size(); const size_t nTime = grid[TIME]->size(); @@ -95,16 +95,17 @@ const JonesMatrix::View ArrayFactor::evaluateImpl(const Grid &grid, { // Compute the delay for a plane wave approaching from the direction of // interest with respect to the phase center of element i. - Matrix delay = (k[0] * itsConfig(i, 0) + k[1] * itsConfig(i, 1) - + k[2] * itsConfig(i, 2)) / C::c; + Matrix delay = (k[0] * itsSelection(i, 0) + k[1] * itsSelection(i, 1) + + k[2] * itsSelection(i, 2)) / C::c; // Compute the delay for a plane wave approaching from the phase // reference direction with respect to the phase center of element i. - Matrix delay0 = (k0[0] * itsConfig(i, 0) + k0[1] * itsConfig(i, 1) - + k0[2] * itsConfig(i, 2)) / C::c; + Matrix delay0 = (k0[0] * itsSelection(i, 0) + k0[1] * itsSelection(i, 1) + + k0[2] * itsSelection(i, 2)) / C::c; - DBGASSERT(delay.nx() == 1 && delay.ny() == nTime); - DBGASSERT(delay0.nx() == 1 && delay0.ny() == nTime); + DBGASSERT(delay.nx() == 1 && static_cast<size_t>(delay.ny()) == nTime); + DBGASSERT(delay0.nx() == 1 + && static_cast<size_t>(delay0.ny()) == nTime); double *p_delay = delay.doubleStorage(); double *p_delay0 = delay0.doubleStorage(); diff --git a/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc b/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc new file mode 100644 index 0000000000000000000000000000000000000000..67493028c9d37e9a843636e961589206346fd112 --- /dev/null +++ b/CEP/Calibration/BBSKernel/src/Expr/TileArrayFactor.cc @@ -0,0 +1,137 @@ +//# TileArrayFactor.cc: Compute the array factor of a LOFAR HBA tile. +//# +//# Copyright (C) 2009 +//# ASTRON (Netherlands Institute for Radio Astronomy) +//# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +//# +//# This file is part of the LOFAR software suite. +//# The LOFAR software suite is free software: you can redistribute it and/or +//# modify it under the terms of the GNU General Public License as published +//# by the Free Software Foundation, either version 3 of the License, or +//# (at your option) any later version. +//# +//# The LOFAR software suite is distributed in the hope that it will be useful, +//# but WITHOUT ANY WARRANTY; without even the implied warranty of +//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//# GNU General Public License for more details. +//# +//# You should have received a copy of the GNU General Public License along +//# with the LOFAR software suite. If not, see <http://www.gnu.org/licenses/>. +//# +//# $Id$ + +#include <lofar_config.h> +#include <BBSKernel/Expr/TileArrayFactor.h> + +#include <casa/BasicSL/Constants.h> + +using namespace casa; + +namespace LOFAR +{ +namespace BBS +{ + +TileArrayFactor::TileArrayFactor(const Expr<Vector<2> >::ConstPtr &direction, + const Expr<Vector<2> >::ConstPtr &reference, const TileLayout &layout) + : BasicBinaryExpr<Vector<2>, Vector<2>, JonesMatrix>(direction, + reference), + itsLayout(layout) +{ +} + +const JonesMatrix::View TileArrayFactor::evaluateImpl(const Grid &grid, + const Vector<2>::View &direction, const Vector<2>::View &reference) const +{ + const size_t nElement = itsLayout.size(); + const size_t nFreq = grid[FREQ]->size(); + const size_t nTime = grid[TIME]->size(); + + // Check preconditions. + ASSERT(!direction(0).isComplex() && !direction(1).isComplex()); + ASSERT(direction(0).nx() == 1 + && static_cast<size_t>(direction(0).ny()) == nTime); + ASSERT(direction(1).nx() == 1 + && static_cast<size_t>(direction(1).ny()) == nTime); + ASSERT(!reference(0).isComplex() && !reference(1).isComplex()); + ASSERT(reference(0).nx() == 1 + && static_cast<size_t>(reference(0).ny()) == nTime); + ASSERT(reference(1).nx() == 1 + && static_cast<size_t>(reference(1).ny()) == nTime); + + // Compute propagation vectors. + Matrix sin_phi = sin(direction(0)); + Matrix cos_phi = cos(direction(0)); + // Convert from elevation to zenith angle. + Matrix theta = Matrix(C::pi_2) - direction(1); + Matrix sin_theta = sin(theta); +// Matrix cos_theta = cos(theta); + + Matrix k[2]; + k[0] = -sin_theta * cos_phi; + k[1] = -sin_theta * sin_phi; +// k[2] = -cos_theta; + + Matrix sin_phi0 = sin(reference(0)); + Matrix cos_phi0 = cos(reference(0)); + // Convert from elevation to zenith angle. + Matrix theta0 = Matrix(C::pi_2) - reference(1); + Matrix sin_theta0 = sin(theta0); +// Matrix cos_theta0 = cos(theta0); + + Matrix k0[2]; + k0[0] = -sin_theta0 * cos_phi0; + k0[1] = -sin_theta0 * sin_phi0; +// k0[2] = -cos_theta0; + + // Compute difference vector. + k[0] = k0[0] - k[0]; + k[1] = k0[1] - k[1]; +// k[2] = k0[2] - k[2]; + + // Allocate result (initialized at 0+0i). + Matrix arrayFactor(makedcomplex(0.0, 0.0), nFreq, nTime); + for(size_t i = 0; i < nElement; ++i) + { + // Compute the effective delay for a plane wave approaching from the + // direction of interest with respect to the phase center of element i + // when beamforming in the reference direction using time delays. + Matrix delay = (k[0] * itsLayout(i, 0) + k[1] * itsLayout(i, 1)) / C::c; +// LOG_DEBUG_STR("el: " << i << " x: " << itsLayout(i, 0) << " y: " +// << itsLayout(i, 1)); + + DBGASSERT(delay.nx() == 1 && static_cast<size_t>(delay.ny()) == nTime); + + double *p_re, *p_im; + arrayFactor.dcomplexStorage(p_re, p_im); + double *p_delay = delay.doubleStorage(); + + for(size_t t = 0; t < nTime; ++t) + { + const double delay_t = *p_delay; + + for(size_t f = 0; f < nFreq; ++f) + { + const double shift = C::_2pi * grid[FREQ]->center(f) * delay_t; + + (*p_re) += std::cos(shift) / nElement; + (*p_im) += std::sin(shift) / nElement; + + ++p_re; + ++p_im; + } + + ++p_delay; + } + } + + JonesMatrix::View result; + result.assign(0, 0, arrayFactor); + result.assign(0, 1, Matrix(makedcomplex(0.0, 0.0))); + result.assign(1, 0, Matrix(makedcomplex(0.0, 0.0))); + result.assign(1, 1, arrayFactor); + return result; +} + +} //# namespace BBS +} //# namespace LOFAR diff --git a/CEP/Calibration/BBSKernel/src/Instrument.cc b/CEP/Calibration/BBSKernel/src/Instrument.cc index e3c04ec0caaa56b7d9a1c926cd6efebfacaa1d4a..8123b6f0c3e9772aac32fcfed44ab1d3dd166f91 100644 --- a/CEP/Calibration/BBSKernel/src/Instrument.cc +++ b/CEP/Calibration/BBSKernel/src/Instrument.cc @@ -31,22 +31,30 @@ namespace LOFAR namespace BBS { -const string &AntennaConfig::name() const +AntennaSelection::AntennaSelection() +{ +} + +AntennaSelection::AntennaSelection(unsigned int size) + : itsPositions(3, size, 0.0) +{ +} + +const string &AntennaSelection::name() const { return itsName; } -size_t AntennaConfig::size() const +unsigned int AntennaSelection::size() const { return itsPositions.shape()[1]; } -istream &operator>>(istream &in, AntennaConfig &obj) +istream &operator>>(istream &in, AntennaSelection &obj) { string line; // Parse configuration name. -// in >> ws; getline(in, line); size_t start = line.find_first_not_of(" \t\n"); size_t end = line.find_first_of(" \t\n", start); @@ -60,7 +68,6 @@ istream &operator>>(istream &in, AntennaConfig &obj) obj.itsName = line.substr(start, end); // Skip line containing phase center. -// in >> ws; getline(in, line); // Parse array shape. @@ -99,18 +106,24 @@ istream &operator>>(istream &in, AntennaConfig &obj) return in; } -Station::Station(const string &name, const casa::MPosition &position) - : itsName(name), - itsPosition(position) +TileLayout::TileLayout() +{ +} + +TileLayout::TileLayout(unsigned int size) + : itsPositions(2, size, 0.0) { } -Station::Station(const string &name, const casa::MPosition &position, - const casa::Path &config) +unsigned int TileLayout::size() const +{ + return itsPositions.shape()[1]; +} + +Station::Station(const string &name, const casa::MPosition &position) : itsName(name), itsPosition(position) { - readAntennaConfigurations(config); } const string &Station::name() const @@ -123,26 +136,38 @@ const casa::MPosition &Station::position() const return itsPosition; } -const AntennaConfig &Station::config(const string &name) const +const AntennaSelection &Station::selection(const string &name) const { - map<string, AntennaConfig>::const_iterator it = itsConfig.find(name); - if(it == itsConfig.end()) + map<string, AntennaSelection>::const_iterator it = + itsAntennaSelection.find(name); + if(it == itsAntennaSelection.end()) { - THROW(BBSKernelException, "Unknown antenna configuration for station " - << this->name() << ": " << name); + THROW(BBSKernelException, "Unknown antenna selection: " << name + << " for station: " << this->name()); } return it->second; } -void Station::readAntennaConfigurations(const casa::Path &file) +const TileLayout &Station::tile(unsigned int i) const +{ + if(i >= itsTileLayout.size()) + { + THROW(BBSKernelException, "Unknown tile: " << i << " for station: " + << this->name()); + } + + return itsTileLayout[i]; +} + +void Station::readAntennaSelection(const casa::Path &file) { casa::String path(file.expandedName()); ifstream ifs; ifs.exceptions(ifstream::failbit | ifstream::badbit); - map<string, AntennaConfig> result; + map<string, AntennaSelection> result; try { ifs.open(path.c_str()); @@ -163,7 +188,7 @@ void Station::readAntennaConfigurations(const casa::Path &file) continue; } - AntennaConfig config; + AntennaSelection config; ifs >> config; result[config.name()] = config; } @@ -171,10 +196,74 @@ void Station::readAntennaConfigurations(const casa::Path &file) catch(ifstream::failure &e) { THROW(BBSKernelException, "Error opening/reading antenna configuration" - " file: " << path); + " file: " << path); } - itsConfig = result; + itsAntennaSelection = result; + LOG_DEBUG_STR("" << name() << ": read " << result.size() << " antenna" + " selection(s) from: " << path); +} + +void Station::readTileLayout(const casa::Path &file) +{ + casa::String path(file.expandedName()); + + ifstream ifs; + ifs.exceptions(ifstream::failbit | ifstream::badbit); + + string line; + vector<TileLayout> result; + try + { + ifs.open(path.c_str()); + + // Skip to line after header. + size_t pos = string::npos; + while(pos == string::npos) + { + getline(ifs, line); + pos = line.find("HBAdeltas"); + } + + // Parse array shape. + char sep; + unsigned int shape[2]; + ifs >> shape[0] >> sep >> shape[1] >> sep; + + const unsigned int tileSize = 16; + if(!ifs.good() || sep != '[' || shape[0] == 0 || shape[1] != 2 + || (shape[0] % tileSize != 0)) + { + ifs.setstate(istream::failbit); + } + + // Parse array. + for(unsigned int j = 0; j < shape[0] / tileSize; ++j) + { + TileLayout tile(tileSize); + for(unsigned int i = 0; i < tileSize; ++i) + { + ifs >> tile(i, 0) >> tile(i, 1); + } + + result.push_back(tile); + } + + ifs >> sep; + if(!ifs.good() || sep != ']') + { + ifs.setstate(istream::failbit); + } + } + catch(ifstream::failure &e) + { + THROW(BBSKernelException, "Error opening/reading tile layout file: " + << path); + } + + itsTileLayout = result; + LOG_DEBUG_STR("" << name() << ": read " << result.size() << " HBA tile" + " layout(s) from: " << path); } Instrument::Instrument() @@ -225,13 +314,24 @@ const Station &Instrument::operator[](const string &name) const return itsStations[it->second]; } -void Instrument::readAntennaConfigurations(const casa::Path &path) +void Instrument::readLOFARAntennaConfig(const casa::Path &path) { for(unsigned int i = 0; i < itsStations.size(); ++i) { + ASSERT(itsStations[i].name().size() >= 5); + string name = itsStations[i].name().substr(0, 5); + + // Read station selections. casa::Path file(path); - file.append(itsStations[i].name() + "-AntennaArrays.conf"); - itsStations[i].readAntennaConfigurations(file); + file.append("AntennaArrays"); + file.append(name + "-AntennaArrays.conf"); + itsStations[i].readAntennaSelection(file); + + // Read layout of HBA tiles. + file = casa::Path(path); + file.append("HBADeltas"); + file.append(name + "-HBADeltas.conf"); + itsStations[i].readTileLayout(file); } } diff --git a/CEP/Calibration/BBSKernel/src/Makefile.am b/CEP/Calibration/BBSKernel/src/Makefile.am index 11ef97399a50cd9346b2639e147d5a17c5935d9b..84e5a32c3e7a50b55b4f871548c1ae47aa7be02c 100644 --- a/CEP/Calibration/BBSKernel/src/Makefile.am +++ b/CEP/Calibration/BBSKernel/src/Makefile.am @@ -35,6 +35,7 @@ libbbskernel_la_SOURCES = Package__Version.cc \ VisDimensions.cc \ VisExpr.cc \ VisSelection.cc \ + Expr/EquatorialCentroid.cc \ Expr/ArrayFactor.cc \ Expr/AzEl.cc \ Expr/Cache.cc \ @@ -75,9 +76,9 @@ libbbskernel_la_SOURCES = Package__Version.cc \ Expr/Scope.cc \ Expr/Source.cc \ Expr/SpectralIndex.cc \ - Expr/EquatorialCentroid.cc \ Expr/StationShift.cc \ Expr/StationUVW.cc \ + Expr/TileArrayFactor.cc \ Expr/ValueSet.cc \ Expr/YatawattaDipole.cc diff --git a/CEP/Calibration/BBSKernel/src/Model.cc b/CEP/Calibration/BBSKernel/src/Model.cc index 571713aa94b2e8737bcfe8ec7cdf1bc04fa3411e..d27f24fcd60235521b59ba68b4c0b5979b7b9653 100644 --- a/CEP/Calibration/BBSKernel/src/Model.cc +++ b/CEP/Calibration/BBSKernel/src/Model.cc @@ -30,6 +30,7 @@ #include <BBSKernel/Expr/ArrayFactor.h> #include <BBSKernel/Expr/AzEl.h> #include <BBSKernel/Expr/ConditionNumber.h> +#include <BBSKernel/Expr/EquatorialCentroid.h> #include <BBSKernel/Expr/ExprAdaptors.h> #include <BBSKernel/Expr/ExprVisData.h> #include <BBSKernel/Expr/FlagIf.h> @@ -49,7 +50,7 @@ #include <BBSKernel/Expr/Request.h> #include <BBSKernel/Expr/ScalarMatrixMul.h> #include <BBSKernel/Expr/SpectralIndex.h> -#include <BBSKernel/Expr/EquatorialCentroid.h> +#include <BBSKernel/Expr/TileArrayFactor.h> #include <BBSKernel/Expr/StationShift.h> #include <BBSKernel/Expr/StationUVW.h> @@ -140,7 +141,7 @@ void Model::makeForwardExpr(const ModelConfig &config, const VisData::Ptr&, const BeamConfig &beamConfig = config.getBeamConfig(); // Read antenna configurations. - itsInstrument.readAntennaConfigurations(beamConfig.getConfigPath()); + itsInstrument.readLOFARAntennaConfig(beamConfig.getConfigPath()); // Create a functor to generate element beam expression nodes. exprElementBeam = ElementBeamExpr::create(beamConfig, itsScope); @@ -317,7 +318,7 @@ void Model::makeInverseExpr(const ModelConfig &config, const BeamConfig &beamConfig = config.getBeamConfig(); // Read antenna configurations. - itsInstrument.readAntennaConfigurations(beamConfig.getConfigPath()); + itsInstrument.readLOFARAntennaConfig(beamConfig.getConfigPath()); // Create a functor to generate element beam expression nodes. exprElementBeam = ElementBeamExpr::create(beamConfig, itsScope); @@ -863,23 +864,76 @@ void Model::makeBeamExpr(const BeamConfig &config, { for(unsigned int i = 0; i < stations.size(); ++i) { - const unsigned int station = stations[i]; - - // Get station element configuration. - const AntennaConfig &antennaConfig = - itsInstrument[station].config(config.getConfigName()); + const Station &station = itsInstrument[stations[i]]; // Get element orientation. Expr<Scalar>::Ptr orientation = itsScope(INSTRUMENT, - "AntennaOrientation:" + itsInstrument[station].name()); + "AntennaOrientation:" + station.name()); + + AntennaSelection selection; + Expr<JonesMatrix>::Ptr exprBeam(exprElement->construct(exprAzEl(i), + orientation)); + + // Get LOFAR station name suffix. + // NB. THIS IS A TEMPORARY SOLUTION THAT CAN BE REMOVED AS SOON AS THE + // DIPOLE INFORMATION IS STORED AS META-DATA INSIDE THE MS. + const string suffix = station.name().substr(5); + if(suffix == "LBA") + { + try + { + selection = station.selection(config.getConfigName()); + } + catch(BBSKernelException &ex) + { + selection = station.selection("LBA"); + } + } + else if(suffix == "HBA0") + { + selection = station.selection("HBA_0"); + + Expr<JonesMatrix>::Ptr exprTileFactor = + Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i), + exprRefAzEl(i), station.tile(0))); + + exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor, + exprBeam)); + } + else if(suffix == "HBA1") + { + selection = station.selection("HBA_1"); + + Expr<JonesMatrix>::Ptr exprTileFactor = + Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i), + exprRefAzEl(i), station.tile(1))); + + exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor, + exprBeam)); + } + else if(suffix == "HBA") + { + selection = station.selection("HBA"); + + Expr<JonesMatrix>::Ptr exprTileFactor = + Expr<JonesMatrix>::Ptr(new TileArrayFactor(exprAzEl(i), + exprRefAzEl(i), station.tile(0))); + + exprBeam = Expr<JonesMatrix>::Ptr(new MatrixMul2(exprTileFactor, + exprBeam)); + } + else + { + THROW(BBSKernelException, "Illegal LOFAR station name encoutered: " + << station.name()); + } // Create ArrayFactor expression. Expr<JonesMatrix>::Ptr exprArrayFactor(new ArrayFactor(exprAzEl(i), - exprRefAzEl(i), antennaConfig, itsReferenceFreq)); + exprRefAzEl(i), selection, itsReferenceFreq)); accumulator(i) = compose(accumulator(i), - Expr<JonesMatrix>::Ptr(new MatrixMul2(exprArrayFactor, - exprElement->construct(exprAzEl(i), orientation)))); + Expr<JonesMatrix>::Ptr(new MatrixMul2(exprArrayFactor, exprBeam))); } }