From 121016a50c0c035cb1a91b84397532eed1dffcf5 Mon Sep 17 00:00:00 2001 From: Jakob Maljaars <jakob.maljaars@stcorp.nl> Date: Mon, 13 Jul 2020 09:43:08 +0200 Subject: [PATCH] Resolve "Include LOFAR GriddedResponse" --- cpp/common/system.h | 33 ++++++ cpp/coords/coord_utils.h | 18 ++- cpp/gridded_response/griddedresponse.h | 76 +++++++------ cpp/gridded_response/lofargrid.cc | 150 +++++++++++++++++++++++++ cpp/gridded_response/lofargrid.h | 60 +++++----- cpp/load.cc | 14 +-- cpp/load.h | 6 +- cpp/options.h | 10 +- cpp/telescope/lofar.cc | 46 +++++++- cpp/telescope/lofar.h | 33 ++++-- cpp/telescope/telescope.h | 43 +++---- cpp/test/tload_lofar.cc | 7 +- demo/beam-helper.cpp | 6 +- external/README.md | 2 +- external/aocommon | 2 +- 15 files changed, 380 insertions(+), 126 deletions(-) create mode 100644 cpp/common/system.h diff --git a/cpp/common/system.h b/cpp/common/system.h new file mode 100644 index 00000000..8742f1c0 --- /dev/null +++ b/cpp/common/system.h @@ -0,0 +1,33 @@ +#ifndef EVERYBEAM_COMMON_SYSTEM_H_ +#define EVERYBEAM_COMMON_SYSTEM_H_ + +#include <string> +#include <sched.h> + +namespace everybeam { +namespace common { + +class System { + public: + static std::size_t ProcessorCount() { +#ifdef __APPLE__ + return sysconf(_SC_NPROCESSORS_ONLN); +#else + cpu_set_t cs; + CPU_ZERO(&cs); + sched_getaffinity(0, sizeof cs, &cs); + + int count = 0; + for (int i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, &cs)) count++; + } + + return count; +#endif + } +}; + +} // namespace common +} // namespace everybeam + +#endif // EVERYBEAM_COMMON_SYSTEM_H_ \ No newline at end of file diff --git a/cpp/coords/coord_utils.h b/cpp/coords/coord_utils.h index 913abce8..0ce31f9b 100644 --- a/cpp/coords/coord_utils.h +++ b/cpp/coords/coord_utils.h @@ -7,17 +7,23 @@ namespace everybeam { namespace coords { +struct CoordinateSystem { + std::size_t width, height; + double ra, dec, dl, dm, phase_centre_dl, phase_centre_dm; +}; + /** * @brief Convert Casacore itrfDir to vector3r_t * - * @param itrfDir + * @param itrf_dir * @param itrf */ -void setITRFVector(const casacore::MDirection& itrfDir, vector3r_t& itrf) { - const casacore::Vector<double>& itrfVal = itrfDir.getValue().getValue(); - itrf[0] = itrfVal[0]; - itrf[1] = itrfVal[1]; - itrf[2] = itrfVal[2]; +inline void SetITRFVector(const casacore::MDirection& itrf_dir, + vector3r_t& itrf) { + const casacore::Vector<double>& itrf_val = itrf_dir.getValue().getValue(); + itrf[0] = itrf_val[0]; + itrf[1] = itrf_val[1]; + itrf[2] = itrf_val[2]; } } // namespace coords } // namespace everybeam diff --git a/cpp/gridded_response/griddedresponse.h b/cpp/gridded_response/griddedresponse.h index 2910f6c7..35abf9d5 100644 --- a/cpp/gridded_response/griddedresponse.h +++ b/cpp/gridded_response/griddedresponse.h @@ -24,7 +24,15 @@ #ifndef EVERYBEAM_GRIDDEDRESPONSE_GRIDDEDRESPONSE_H_ #define EVERYBEAM_GRIDDEDRESPONSE_GRIDDEDRESPONSE_H_ +#include "./../coords/coord_utils.h" +#include "./../coords/ITRFDirection.h" +#include "./../coords/ITRFConverter.h" + #include <memory> +#include <vector> +#include <thread> +#include <aocommon/lane.h> +#include <casacore/measures/Measures/MDirection.h> namespace everybeam { @@ -32,12 +40,6 @@ namespace telescope { class Telescope; } -// TODO: just temporary location! -struct CoordinateSystem { - std::size_t width, height; - double ra, dec, dl, dm, phaseCentreDL, phaseCentreDM; -}; - namespace gridded_response { /** @@ -46,42 +48,50 @@ namespace gridded_response { */ class GriddedResponse { public: - typedef std::unique_ptr<GriddedResponse> Ptr; - - // TODO: can be deprecated in a later stage - virtual void CalculateStation(std::size_t station_id) = 0; - virtual void CalculateStation() = 0; - virtual void CalculateAllStations() = 0; + /** + * @brief Compute the Beam response for a single station + * + * @param buffer Output buffer + * @param station_idx Station index, must be smaller than number of stations + * in the Telescope + * @param time Time, modified Julian date, UTC, in seconds (MJD(UTC), s). + * @param frequency Frequency (Hz) + */ + virtual bool CalculateStation(std::complex<float>* buffer, double time, + double freq, const size_t station_idx) = 0; - // TODO: complete! - virtual void CalculateStation(std::complex<float>* buffer, size_t station_id, - double time, double freq) = 0; - // Repeated call of calculate single? - virtual void CalculateAllStations(std::complex<float>* buffer, double time, - double freq) = 0; + /** + * @brief Compute the Beam response for all stations in a Telescope + * + * @param buffer Output buffer + * @param time Time, modified Julian date, UTC, in seconds (MJD(UTC), s). + * @param frequency Frequency (Hz) + */ + virtual bool CalculateAllStations(std::complex<float>* buffer, double time, + double frequency) = 0; protected: /** * @brief Construct a new Gridded Response object * * @param telescope_ptr Pointer to telescope::Telescope object - * @param coordinateSystem CoordinateSystem struct + * @param coordinate_system CoordinateSystem struct */ - GriddedResponse(const telescope::Telescope* telescope_ptr, - const CoordinateSystem& coordinateSystem) - : _telescope(telescope_ptr), - _width(coordinateSystem.width), - _height(coordinateSystem.height), - _ra(coordinateSystem.ra), - _dec(coordinateSystem.dec), - _dl(coordinateSystem.dl), - _dm(coordinateSystem.dm), - _phaseCentreDL(coordinateSystem.phaseCentreDL), - _phaseCentreDM(coordinateSystem.phaseCentreDM){}; + GriddedResponse(const telescope::Telescope* const telescope_ptr, + const coords::CoordinateSystem& coordinate_system) + : telescope_(telescope_ptr), + width_(coordinate_system.width), + height_(coordinate_system.height), + ra_(coordinate_system.ra), + dec_(coordinate_system.dec), + dl_(coordinate_system.dl), + dm_(coordinate_system.dm), + phase_centre_dl_(coordinate_system.phase_centre_dl), + phase_centre_dm_(coordinate_system.phase_centre_dm){}; - const telescope::Telescope* _telescope; - size_t _width, _height; - double _ra, _dec, _dl, _dm, _phaseCentreDL, _phaseCentreDM; + const telescope::Telescope* const telescope_; + size_t width_, height_; + double ra_, dec_, dl_, dm_, phase_centre_dl_, phase_centre_dm_; }; } // namespace gridded_response } // namespace everybeam diff --git a/cpp/gridded_response/lofargrid.cc b/cpp/gridded_response/lofargrid.cc index e69de29b..e42bfc40 100644 --- a/cpp/gridded_response/lofargrid.cc +++ b/cpp/gridded_response/lofargrid.cc @@ -0,0 +1,150 @@ +#include "lofargrid.h" +#include "./../telescope/lofar.h" +#include "./../common/system.h" + +#include <aocommon/imagecoordinates.h> +#include <cmath> +// #include <casacore/measures/TableMeasures/ArrayMeasColumn.h> + +using namespace everybeam::gridded_response; + +LOFARGrid::LOFARGrid(telescope::Telescope* telescope_ptr, + const coords::CoordinateSystem& coordinate_system) + : GriddedResponse(telescope_ptr, coordinate_system) { + const telescope::LOFAR& lofartelescope = + static_cast<const telescope::LOFAR&>(*telescope_); + size_t ncpus = common::System::ProcessorCount(); + + // Set private members + nthreads_ = std::min(ncpus, lofartelescope.nstations_); + threads_.resize(nthreads_); + delay_dir_ = lofartelescope.ms_properties_.delay_dir; + tile_beam_dir_ = lofartelescope.ms_properties_.tile_beam_dir; + subband_frequency_ = lofartelescope.ms_properties_.subband_freq; + use_channel_frequency_ = lofartelescope.options_.useChannelFrequency; +}; + +bool LOFARGrid::CalculateStation(std::complex<float>* buffer, double time, + double frequency, const size_t station_idx) { + aocommon::Lane<Job> lane(nthreads_); + lane_ = &lane; + + SetITRFVectors(time); + double sb_freq = use_channel_frequency_ ? frequency : subband_frequency_; + // Dummy calculation of gain matrix, needed for multi-threading + telescope_->GetStation(station_idx) + ->Response(time, frequency, station0_, sb_freq, station0_, tile0_); + + for (size_t i = 0; i != nthreads_; ++i) { + threads_[i] = + std::thread(&LOFARGrid::CalcThread, this, buffer, time, frequency); + } + + for (size_t y = 0; y != height_; ++y) { + lane.write(Job{.y = y, .antenna_idx = station_idx}); + } + + lane.write_end(); + for (size_t i = 0; i != nthreads_; ++i) threads_[i].join(); + return true; +} + +bool LOFARGrid::CalculateAllStations(std::complex<float>* buffer, double time, + double frequency) { + aocommon::Lane<Job> lane(nthreads_); + lane_ = &lane; + + SetITRFVectors(time); + + double sb_freq = use_channel_frequency_ ? frequency : subband_frequency_; + + // Dummy loop, needed for multi-threading + for (size_t i = 0; i != telescope_->GetNrStations(); ++i) { + telescope_->GetStation(i)->Response(time, frequency, station0_, sb_freq, + station0_, tile0_); + } + + // Prepare threads + for (size_t i = 0; i != nthreads_; ++i) { + threads_[i] = + std::thread(&LOFARGrid::CalcThread, this, buffer, time, frequency); + } + + for (size_t y = 0; y != height_; ++y) { + for (size_t antenna_idx = 0; antenna_idx != telescope_->GetNrStations(); + ++antenna_idx) { + lane.write(Job{.y = y, .antenna_idx = antenna_idx}); + } + } + + lane.write_end(); + for (size_t i = 0; i != nthreads_; ++i) threads_[i].join(); + return true; +} + +void LOFARGrid::SetITRFVectors(double time) { + coords::ITRFConverter itrf_converter(time); + coords::SetITRFVector(itrf_converter.toDirection(delay_dir_), station0_); + coords::SetITRFVector(itrf_converter.toDirection(tile_beam_dir_), tile0_); + + const casacore::Unit rad_unit("rad"); + + casacore::MDirection l_dir( + casacore::MVDirection(casacore::Quantity(ra_ + M_PI / 2, rad_unit), + casacore::Quantity(0, rad_unit)), + casacore::MDirection::J2000); + coords::SetITRFVector(itrf_converter.toDirection(l_dir), l_vector_itrf_); + + casacore::MDirection m_dir( + casacore::MVDirection(casacore::Quantity(ra_, rad_unit), + casacore::Quantity(dec_ + M_PI / 2, rad_unit)), + casacore::MDirection::J2000); + coords::SetITRFVector(itrf_converter.toDirection(m_dir), m_vector_itrf_); + + casacore::MDirection n_dir( + casacore::MVDirection(casacore::Quantity(ra_, rad_unit), + casacore::Quantity(dec_, rad_unit)), + casacore::MDirection::J2000); + coords::SetITRFVector(itrf_converter.toDirection(n_dir), n_vector_itrf_); +} + +void LOFARGrid::CalcThread(std::complex<float>* buffer, double time, + double frequency) { + const size_t values_per_ant = width_ * height_ * 4; + double sb_freq = use_channel_frequency_ ? frequency : subband_frequency_; + + Job job; + while (lane_->read(job)) { + for (size_t x = 0; x != width_; ++x) { + double l, m, n; + aocommon::ImageCoordinates::XYToLM(x, job.y, dl_, dm_, width_, height_, l, + m); + l += phase_centre_dl_; + m += phase_centre_dm_; + n = sqrt(1.0 - l * l - m * m); + + vector3r_t itrf_direction; + + itrf_direction[0] = + l * l_vector_itrf_[0] + m * m_vector_itrf_[0] + n * n_vector_itrf_[0]; + itrf_direction[1] = + l * l_vector_itrf_[1] + m * m_vector_itrf_[1] + n * n_vector_itrf_[1]; + itrf_direction[2] = + l * l_vector_itrf_[2] + m * m_vector_itrf_[2] + n * n_vector_itrf_[2]; + + std::complex<float>* base_buffer = buffer + (x + job.y * height_) * 4; + + std::complex<float>* ant_buffer_ptr = + base_buffer + job.antenna_idx * values_per_ant; + matrix22c_t gain_matrix = telescope_->GetStation(job.antenna_idx) + ->Response(time, frequency, itrf_direction, + sb_freq, station0_, tile0_); + + // (Optional) differential beam logic is handled at WSClean level + ant_buffer_ptr[0] = gain_matrix[0][0]; + ant_buffer_ptr[1] = gain_matrix[0][1]; + ant_buffer_ptr[2] = gain_matrix[1][0]; + ant_buffer_ptr[3] = gain_matrix[1][1]; + } + } +} \ No newline at end of file diff --git a/cpp/gridded_response/lofargrid.h b/cpp/gridded_response/lofargrid.h index 5fc79d12..ea524aa6 100644 --- a/cpp/gridded_response/lofargrid.h +++ b/cpp/gridded_response/lofargrid.h @@ -26,7 +26,9 @@ #include "griddedresponse.h" #include <iostream> +#include <aocommon/matrix2x2.h> #include <complex> +#include <limits> namespace everybeam { namespace gridded_response { @@ -37,41 +39,17 @@ namespace gridded_response { */ class LOFARGrid final : public GriddedResponse { public: - typedef std::unique_ptr<LOFARGrid> Ptr; + // typedef std::unique_ptr<LOFARGrid> Ptr; /** * @brief Construct a new LOFARGrid object * * @param telescope_ptr Pointer to telescope::LOFAR object - * @param coordinateSystem CoordinateSystem struct + * @param coordinate_system CoordinateSystem struct */ LOFARGrid(telescope::Telescope* telescope_ptr, - const CoordinateSystem& coordinateSystem) - : GriddedResponse(telescope_ptr, coordinateSystem){}; + const coords::CoordinateSystem& coordinate_system); - // TODO: remove this placeholders - void CalculateStation() { std::cout << "One is good" << std::endl; }; - - // TODO: remove this placeholder - void CalculateStation(std::size_t station_id) { - auto station_tmp = _telescope->GetStation(station_id); - std::cout << "Station name for index " << station_id << " is " - << station_tmp->name() << std::endl; - }; - - // TODO: remove this placeholder - void CalculateAllStations() { - std::size_t val = 0; - for (std::size_t station_id = 0; station_id < _telescope->stations.size(); - ++station_id) { - val++; - // Repeated call to CalculateStation? - auto station_tmp = _telescope->GetStation(station_id); - }; - std::cout << "I just read " << val << " stations" << std::endl; - }; - - // Geared towards implementation /** * @brief Compute the Beam response for a single station * @@ -81,9 +59,9 @@ class LOFARGrid final : public GriddedResponse { * @param time Time, modified Julian date, UTC, in seconds (MJD(UTC), s). * @param freq Frequency (Hz) */ - void CalculateStation(std::complex<float>* buffer, size_t stationIdx, - double time, double freq) override{}; - // Repeated call of calculate single? + bool CalculateStation(std::complex<float>* buffer, double time, + double frequency, const size_t station_idx) override; + /** * @brief Compute the Beam response for all stations in a Telescope * @@ -91,8 +69,26 @@ class LOFARGrid final : public GriddedResponse { * @param time Time, modified Julian date, UTC, in seconds (MJD(UTC), s). * @param freq Frequency (Hz) */ - void CalculateAllStations(std::complex<float>* buffer, double time, - double freq) override{}; + bool CalculateAllStations(std::complex<float>* buffer, double time, + double frequency) override; + + private: + casacore::MDirection delay_dir_, tile_beam_dir_; + vector3r_t station0_, tile0_, l_vector_itrf_, m_vector_itrf_, n_vector_itrf_; + bool use_channel_frequency_; + double subband_frequency_; + + std::size_t nthreads_; + std::vector<std::thread> threads_; + + struct Job { + size_t y, antenna_idx; + }; + aocommon::Lane<Job>* lane_; + + void SetITRFVectors(double time); + + void CalcThread(std::complex<float>* buffer, double time, double frequency); }; } // namespace gridded_response } // namespace everybeam diff --git a/cpp/load.cc b/cpp/load.cc index ab4c5ee8..afa4cf63 100644 --- a/cpp/load.cc +++ b/cpp/load.cc @@ -15,14 +15,11 @@ TelescopeType Convert(const std::string &str) { else return UNKNOWN_TELESCOPE; } - -// Default options -// Options defaultOptions; } // namespace -telescope::Telescope::Ptr Load(const casacore::MeasurementSet &ms, - const ElementResponseModel model, - const Options &options) { +std::unique_ptr<telescope::Telescope> Load(casacore::MeasurementSet &ms, + const ElementResponseModel model, + const Options &options) { // Read Telescope name and convert to enum casacore::ScalarColumn<casacore::String> telescope_name_col(ms.observation(), "TELESCOPE_NAME"); @@ -30,8 +27,9 @@ telescope::Telescope::Ptr Load(const casacore::MeasurementSet &ms, TelescopeType telescope_name = Convert(telescope_name_col(0)); switch (telescope_name) { case LOFAR_TELESCOPE: { - auto telescope = - telescope::Telescope::Ptr(new telescope::LOFAR(ms, model, options)); + std::unique_ptr<telescope::Telescope> telescope = + std::unique_ptr<telescope::Telescope>( + new telescope::LOFAR(ms, model, options)); return telescope; } default: diff --git a/cpp/load.h b/cpp/load.h index 2d8dd411..19102da3 100644 --- a/cpp/load.h +++ b/cpp/load.h @@ -39,8 +39,8 @@ namespace everybeam { * @param options Options * @return telescope::Telescope::Ptr */ -telescope::Telescope::Ptr Load(const casacore::MeasurementSet &ms, - const ElementResponseModel model, - const Options &options = Options::GetDefault()); +std::unique_ptr<telescope::Telescope> Load( + casacore::MeasurementSet &ms, const ElementResponseModel model, + const Options &options = Options::GetDefault()); } // namespace everybeam #endif // EVERYBEAM_LOAD_H_ \ No newline at end of file diff --git a/cpp/options.h b/cpp/options.h index 4f291bea..afd7629c 100644 --- a/cpp/options.h +++ b/cpp/options.h @@ -24,6 +24,8 @@ #ifndef EVERYBEAM_OPTIONS_H_ #define EVERYBEAM_OPTIONS_H_ +#include <string> + namespace everybeam { /** @@ -33,7 +35,7 @@ namespace everybeam { */ class Options { public: - Options(){}; + Options() : useDifferentialBeam(false), useChannelFrequency(true){}; //! Default - empty - options class static Options GetDefault() { return Options(); }; @@ -41,8 +43,10 @@ class Options { // Scratch list of potential options // Specify path to element response coefficients file // std::string coeff_path; - // bool useDifferentialBeam - // bool useChannelFrequency + bool useDifferentialBeam; + bool useChannelFrequency; + std::string data_column_name; + vector3r_t diff_beam_centre; // }; } // namespace everybeam diff --git a/cpp/telescope/lofar.cc b/cpp/telescope/lofar.cc index 0947cd9d..e1b02a6b 100644 --- a/cpp/telescope/lofar.cc +++ b/cpp/telescope/lofar.cc @@ -1,7 +1,11 @@ #include "lofar.h" +#include "./../gridded_response/lofargrid.h" #include "./../common/math_utils.h" #include "./../common/casa_utils.h" + +#include <aocommon/banddata.h> #include <cassert> +#include <casacore/measures/TableMeasures/ArrayMeasColumn.h> using namespace everybeam; using namespace everybeam::telescope; @@ -113,16 +117,54 @@ vector3r_t readStationPhaseReference(const Table &table, unsigned int id) { } } // namespace -LOFAR::LOFAR(const MeasurementSet &ms, const ElementResponseModel model, +LOFAR::LOFAR(MeasurementSet &ms, const ElementResponseModel model, const Options &options) : Telescope(ms, model, options) { ReadAllStations(ms, model); + + // Populate MeasurementSet properties struct + aocommon::BandData band(ms.spectralWindow()); + MSAntenna antenna(ms.antenna()); + MPosition::ScalarColumn antenna_pos_col( + antenna, antenna.columnName(MSAntennaEnums::POSITION)); + MEpoch::ScalarColumn time_column(ms, + ms.columnName(casacore::MSMainEnums::TIME)); + + // Following is ms.field() related, first check whether field complies with + // LOFAR field + if (ms.field().nrow() != 1) + throw std::runtime_error("LOFAR MeasurementSet has multiple fields"); + + if (!ms.field().tableDesc().isColumn("LOFAR_TILE_BEAM_DIR")) { + throw std::runtime_error("LOFAR_TILE_BEAM_DIR column not found"); + } + + casacore::ScalarMeasColumn<casacore::MDirection> delay_dir_col( + ms.field(), + casacore::MSField::columnName(casacore::MSFieldEnums::DELAY_DIR)); + + casacore::ArrayMeasColumn<casacore::MDirection> tile_beam_dir_col( + ms.field(), "LOFAR_TILE_BEAM_DIR"); + + // Populate struct + ms_properties_ = {.subband_freq = band.CentreFrequency(), + .delay_dir = delay_dir_col(0), + .tile_beam_dir = *(tile_beam_dir_col(0).data())}; } +std::unique_ptr<gridded_response::GriddedResponse> LOFAR::GetGriddedResponse( + const coords::CoordinateSystem &coordinate_system) { + // Get and return GriddedResponse ptr + std::unique_ptr<gridded_response::GriddedResponse> grid( + new gridded_response::LOFARGrid(this, coordinate_system)); + // gridded_response::GriddedResponse grid(LOFARGrid(this, coordinate_system)); + return grid; +}; + Station::Ptr LOFAR::ReadStation(const MeasurementSet &ms, std::size_t id, const ElementResponseModel model) const { ROMSAntennaColumns antenna(ms.antenna()); - assert(this->_nstations > id && !antenna.flagRow()(id)); + assert(nstations_ > id && !antenna.flagRow()(id)); // Get station name. const string name(antenna.name()(id)); diff --git a/cpp/telescope/lofar.h b/cpp/telescope/lofar.h index bf68d8bb..860f8566 100644 --- a/cpp/telescope/lofar.h +++ b/cpp/telescope/lofar.h @@ -26,16 +26,26 @@ #define EVERYBEAM_TELESCOPE_LOFAR_H_ #include "telescope.h" -#include "./../gridded_response/lofargrid.h" + +#include <casacore/measures/Measures/MPosition.h> +#include <casacore/measures/Measures/MDirection.h> +#include <casacore/measures/Measures/MEpoch.h> +#include <memory> namespace everybeam { + +namespace gridded_response { +class LOFARGrid; +class GriddedResponse; +} // namespace gridded_response + namespace telescope { //! LOFAR telescope class class LOFAR final : public Telescope { - public: - typedef std::unique_ptr<LOFAR> Ptr; + friend class gridded_response::LOFARGrid; + public: /** * @brief Construct a new LOFAR object * @@ -43,22 +53,21 @@ class LOFAR final : public Telescope { * @param model Element Response model * @param options telescope options */ - LOFAR(const casacore::MeasurementSet &ms, const ElementResponseModel model, + LOFAR(casacore::MeasurementSet &ms, const ElementResponseModel model, const Options &options); - // Docstrings will be inherited from telescope::Telescope - gridded_response::GriddedResponse::Ptr GetGriddedResponse( - const CoordinateSystem &coordinate_system) override { - // Get and return GriddedResponse ptr - gridded_response::GriddedResponse::Ptr grid( - new gridded_response::LOFARGrid(this, coordinate_system)); - return grid; - }; + std::unique_ptr<gridded_response::GriddedResponse> GetGriddedResponse( + const coords::CoordinateSystem &coordinate_system) override; private: Station::Ptr ReadStation(const casacore::MeasurementSet &ms, const std::size_t id, const ElementResponseModel model) const override; + struct MSProperties { + double subband_freq; + casacore::MDirection delay_dir, tile_beam_dir; + }; + MSProperties ms_properties_; }; } // namespace telescope } // namespace everybeam diff --git a/cpp/telescope/telescope.h b/cpp/telescope/telescope.h index 1782383f..c73eb508 100644 --- a/cpp/telescope/telescope.h +++ b/cpp/telescope/telescope.h @@ -27,15 +27,22 @@ #include "./../station.h" #include "./../options.h" #include "./../element_response.h" -#include "./../gridded_response/griddedresponse.h" #include <vector> +#include <memory> +#include <cassert> #include <casacore/ms/MeasurementSets/MeasurementSet.h> #include <casacore/ms/MeasurementSets/MSAntennaColumns.h> namespace everybeam { +namespace gridded_response { +class GriddedResponse; +} + +namespace coords { struct CoordinateSystem; +} namespace telescope { @@ -45,19 +52,14 @@ namespace telescope { */ class Telescope { public: - typedef std::unique_ptr<Telescope> Ptr; - - // Will be filled by the private read_all_stations() method - std::vector<Station::Ptr> stations; - /** * @brief Return the gridded response object * * @param coordinate_system Coordinate system struct * @return GriddedResponse::Ptr */ - virtual gridded_response::GriddedResponse::Ptr GetGriddedResponse( - const CoordinateSystem &coordinate_system) = 0; + virtual std::unique_ptr<gridded_response::GriddedResponse> GetGriddedResponse( + const coords::CoordinateSystem &coordinate_system) = 0; /** * @brief Get station by index @@ -65,12 +67,14 @@ class Telescope { * @param station_id Station index to retrieve * @return Station::Ptr */ - Station::Ptr GetStation(std::size_t station_id) const { - // TODO: throw exception if idx >_nstations - - return stations[station_id]; + Station::Ptr GetStation(std::size_t station_idx) const { + // Assert only in DEBUG mode + assert(station_idx < nstations_); + return stations_[station_idx]; } + std::size_t GetNrStations() const { return nstations_; }; + protected: /** * @brief Construct a new Telescope object @@ -79,10 +83,10 @@ class Telescope { * @param model ElementResponse model * @param options telescope options */ - Telescope(const casacore::MeasurementSet &ms, - const ElementResponseModel model, const Options &options) - : _nstations(ms.antenna().nrow()), _options(options) { - stations.resize(_nstations); + Telescope(casacore::MeasurementSet &ms, const ElementResponseModel model, + const Options &options) + : nstations_(ms.antenna().nrow()), options_(options) { + stations_.resize(nstations_); }; /** @@ -97,12 +101,13 @@ class Telescope { casacore::ROMSAntennaColumns antenna(ms.antenna()); for (std::size_t i = 0; i < antenna.nrow(); ++i) { - this->stations[i] = ReadStation(ms, i, model); + stations_[i] = ReadStation(ms, i, model); } }; - std::size_t _nstations; - Options _options; + std::size_t nstations_; + Options options_; + std::vector<Station::Ptr> stations_; private: // Virtual method for reading a single telescope station diff --git a/cpp/test/tload_lofar.cc b/cpp/test/tload_lofar.cc index 4b9de6ee..6babadd5 100644 --- a/cpp/test/tload_lofar.cc +++ b/cpp/test/tload_lofar.cc @@ -2,6 +2,7 @@ #include "./../load.h" #include "./../options.h" +#include "./../gridded_response/lofargrid.h" #include "./../element_response.h" #include "config.h" @@ -21,19 +22,19 @@ BOOST_AUTO_TEST_CASE(load_lofar) { // Assert if correct number of stations std::size_t nstations = 70; - BOOST_CHECK_EQUAL(telescope->stations.size(), nstations); + BOOST_CHECK_EQUAL(telescope->GetNrStations(), nstations); // Assert if GetStation(stationd_id) behaves properly BOOST_CHECK_EQUAL(telescope->GetStation(0)->name(), "CS001HBA0"); // Get gridded response - CoordinateSystem coord_system; + coords::CoordinateSystem coord_system; auto grrp = telescope->GetGriddedResponse(coord_system); BOOST_CHECK(nullptr != dynamic_cast<gridded_response::LOFARGrid*>(grrp.get())); // TODO: add test - // grrp->CalculateStation(0); + // grrp->CalculateStation(0); // grrp->CalculateStation(); // grrp->CalculateAllStations(); } \ No newline at end of file diff --git a/demo/beam-helper.cpp b/demo/beam-helper.cpp index f2e5c444..26141de2 100644 --- a/demo/beam-helper.cpp +++ b/demo/beam-helper.cpp @@ -94,19 +94,19 @@ void GetITRFDirections( casacore::Quantity(ra + M_PI/2, radUnit), casacore::Quantity(0, radUnit)), casacore::MDirection::J2000); - everybeam::coords::setITRFVector(itrfConverter.toDirection(lDir), _l_vector_itrf); + everybeam::coords::SetITRFVector(itrfConverter.toDirection(lDir), _l_vector_itrf); casacore::MDirection mDir(casacore::MVDirection( casacore::Quantity(ra, radUnit), casacore::Quantity(dec + M_PI/2, radUnit)), casacore::MDirection::J2000); - everybeam::coords::setITRFVector(itrfConverter.toDirection(mDir), _m_vector_itrf); + everybeam::coords::SetITRFVector(itrfConverter.toDirection(mDir), _m_vector_itrf); casacore::MDirection nDir(casacore::MVDirection( casacore::Quantity(ra, radUnit), casacore::Quantity(dec, radUnit)), casacore::MDirection::J2000); - everybeam::coords::setITRFVector(itrfConverter.toDirection(nDir), _n_vector_itrf); + everybeam::coords::SetITRFVector(itrfConverter.toDirection(nDir), _n_vector_itrf); vector3r_t itrfDirection; diff --git a/external/README.md b/external/README.md index 0932f0e6..7cd736ab 100644 --- a/external/README.md +++ b/external/README.md @@ -3,7 +3,7 @@ External dependencies are included via git submodules, see .gitmodules in the ro Please note that the dependencies are fixed to a specific commit, to make sure tests do not break due to a silent updateing of the submodules. Dependencies are checked out on the following commits: -- `aocommon`: be6072490469977f513722b87f3032812438e968 +- `aocommon`: 1f77c0c5e0d70507f227892353df8c5410cd87a4 - `eigen`: `3.3.7` (https://gitlab.com/libeigen/eigen/-/tags/3.3.7) - `pybind11`: `v2.5.0` (https://github.com/pybind/pybind11/releases/tag/v2.5.0) diff --git a/external/aocommon b/external/aocommon index be607249..1f77c0c5 160000 --- a/external/aocommon +++ b/external/aocommon @@ -1 +1 @@ -Subproject commit be6072490469977f513722b87f3032812438e968 +Subproject commit 1f77c0c5e0d70507f227892353df8c5410cd87a4 -- GitLab