diff --git a/CMakeLists.txt b/CMakeLists.txt index 83eb93053e88064040f7e4146831397923308b53..870d0fe4895755371f8922a5b528485e0417be54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -773,6 +773,7 @@ if(BUILD_TESTING) steps/test/unit/tMSBDAReader.cc steps/test/unit/tMSBDAWriter.cc steps/test/unit/tMsColumnReader.cc + steps/test/unit/tMSReader.cc steps/test/unit/tMSUpdater.cc steps/test/unit/tMSWriter.cc steps/test/unit/tNullStokes.cc diff --git a/base/DPInfo.cc b/base/DPInfo.cc index 01da262bab52b24ae5bce7ae65eb20178745b109..30a361aae83a35ce596f661b4d3870d5d43841cb 100644 --- a/base/DPInfo.cc +++ b/base/DPInfo.cc @@ -54,7 +54,8 @@ DPInfo::DPInfo(unsigned int n_correlations, unsigned int original_n_channels, resolutions_(1), // can retrieve a first list. effective_bandwidth_(1), total_bandwidth_(0.0), - spectral_window_(0) {} + spectral_window_(0), + polarizations_() {} void DPInfo::setTimes(double first_time, double last_time, double time_interval) { diff --git a/include/dp3/base/DPInfo.h b/include/dp3/base/DPInfo.h index 00cfd593af99201346829d2b04b2a715ffda43de..edaacc9d7e17dd407417774dd7b41fa6e48fc946 100644 --- a/include/dp3/base/DPInfo.h +++ b/include/dp3/base/DPInfo.h @@ -9,6 +9,10 @@ #ifndef DP3_BASE_DPINFO_H_ #define DP3_BASE_DPINFO_H_ +#include <set> + +#include <aocommon/polarization.h> + #include <casacore/measures/Measures/MDirection.h> #include <casacore/measures/Measures/MPosition.h> #include <casacore/measures/Measures/MeasureHolder.h> @@ -129,6 +133,11 @@ class DPInfo { phase_center_ = phase_center; } + void setPolarizations( + const std::set<aocommon::PolarizationEnum>& polarizations) { + polarizations_ = polarizations; + } + /// Get the info. ///@{ const std::string& msName() const { return ms_name_; } @@ -258,6 +267,10 @@ class DPInfo { /// Determine if the channels have a regular layout. bool channelsAreRegular() const; + const std::set<aocommon::PolarizationEnum>& polarizations() const { + return polarizations_; + } + private: /// Set which antennae are actually used. void setAntUsed(); @@ -317,6 +330,7 @@ class DPInfo { mutable std::vector<double> baseline_lengths_; /// For each antenna, the auto correlation index. mutable std::vector<int> auto_correlation_indices_; + std::set<aocommon::PolarizationEnum> polarizations_; }; } // namespace base diff --git a/pythondp3/PyDpInfo.cc b/pythondp3/PyDpInfo.cc index 0c01e3b6a25ec8a8162a23716aaef6829d2399f0..5436951012356686e1cd63a35cf81b5743a4c845 100644 --- a/pythondp3/PyDpInfo.cc +++ b/pythondp3/PyDpInfo.cc @@ -173,7 +173,10 @@ The start time equals the first time minus half a time interval)") /* Other properties */ .def_property("ms_name", &DPInfo::msName, &DPInfo::setMsName, - "The name of the measurement set"); + "The name of the measurement set") + .def_property("polarizations", &DPInfo::polarizations, + &DPInfo::setPolarizations, + "Polarizations of the measurement set"); } } // namespace pythondp3 diff --git a/resources/tNDPPP.in_MS.tgz b/resources/tNDPPP.in_MS.tgz index 57bef2b6821d647bf45bc685c4c224c13ba99312..f6c69512d122b7e7078da5f02d55385ea59de828 100644 Binary files a/resources/tNDPPP.in_MS.tgz and b/resources/tNDPPP.in_MS.tgz differ diff --git a/steps/MSReader.cc b/steps/MSReader.cc index 16fb07ac6a4f6f1a935ec9d18f94417cf4bb35d6..e4e2775b289ee03dbe14f9374f059cd4276ddf23 100644 --- a/steps/MSReader.cc +++ b/steps/MSReader.cc @@ -686,6 +686,29 @@ void MSReader::prepare2(int spectralWindow) { std::vector<double>(effbwBegin, effbwBegin + itsNrChan), refFreq, spectralWindow); } + + std::set<aocommon::PolarizationEnum> polarizations; + casacore::MSDataDescription data_description_table = itsMS.dataDescription(); + casacore::ScalarColumn<int> polarization_index_column( + data_description_table, + casacore::MSDataDescription::columnName( + casacore::MSDataDescription::POLARIZATION_ID)); + const size_t polarization_index = polarization_index_column(spectralWindow); + // Populate the polarization + casacore::MSPolarization pol_table = itsMS.polarization(); + casacore::ArrayColumn<int> corr_type_column( + pol_table, casacore::MSPolarization::columnName( + casacore::MSPolarizationEnums::CORR_TYPE)); + casacore::Array<int> corr_type_vec(corr_type_column(polarization_index)); + for (casacore::Array<int>::const_contiter p = corr_type_vec.cbegin(); + p != corr_type_vec.cend(); ++p) { + polarizations.emplace(aocommon::Polarization::AipsIndexToEnum(*p)); + } + if (polarizations.size() != 4) { + throw std::runtime_error( + "DP3 expects a measurement set with 4 polarizations"); + } + info().setPolarizations(polarizations); } void MSReader::skipFirstTimes() { diff --git a/steps/test/unit/tMSReader.cc b/steps/test/unit/tMSReader.cc new file mode 100644 index 0000000000000000000000000000000000000000..d43b710903422dfe209032f40b6ab01d5ada6343 --- /dev/null +++ b/steps/test/unit/tMSReader.cc @@ -0,0 +1,66 @@ +// Copyright (C) 2024 ASTRON (Netherlands Institute for Radio Astronomy) +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "../../MSReader.h" + +#include <memory> + +#include <boost/test/unit_test.hpp> + +#include <casacore/tables/TaQL/TableParse.h> +#include <casacore/tables/Tables/TableCopy.h> + +#include "../../../common/ParameterSet.h" +#include "../../../common/test/unit/fixtures/fDirectory.h" + +using casacore::Table; + +using dp3::common::ParameterSet; +using dp3::common::test::FixtureDirectory; +using dp3::steps::MSReader; + +const std::string kInputMs = "../tNDPPP_tmp.MS"; +const std::string kCopyMs = "tNDPPP_tmp.copy.MS"; +const std::string kCopyMsPol = "tNDPPP_tmp.copy.MS/POLARIZATION"; + +BOOST_AUTO_TEST_SUITE(msreader) + +class FixtureCopyAndUpdatePol : FixtureDirectory { + public: + FixtureCopyAndUpdatePol() : FixtureDirectory() { + Table(kInputMs).deepCopy(kCopyMs, Table::New); + casacore::tableCommand("update " + kCopyMsPol + + " set CORR_TYPE=[9, 12], " + "CORR_PRODUCT=[[0,0],[1,1]], NUM_CORR=2"); + } +}; + +BOOST_FIXTURE_TEST_CASE(polarization_initialization, FixtureDirectory) { + const casacore::MeasurementSet ms(kInputMs, + casacore::TableLock::AutoNoReadLocking); + ParameterSet parset; + parset.add("msin", kInputMs); + const MSReader reader(ms, parset, "msin."); + + const std::set<aocommon::PolarizationEnum> expected_polarizations{ + aocommon::PolarizationEnum::XX, aocommon::PolarizationEnum::XY, + aocommon::PolarizationEnum::YX, aocommon::PolarizationEnum::YY}; + + const std::set<aocommon::PolarizationEnum> actual_polarizations = + reader.getInfo().polarizations(); + + BOOST_CHECK_EQUAL_COLLECTIONS( + actual_polarizations.begin(), actual_polarizations.end(), + expected_polarizations.begin(), expected_polarizations.end()); +} + +BOOST_FIXTURE_TEST_CASE(expect_four_polarizations, FixtureCopyAndUpdatePol) { + casacore::MeasurementSet ms(kCopyMs, casacore::TableLock::AutoNoReadLocking); + ParameterSet parset; + parset.add("msin", kCopyMs); + + BOOST_CHECK_THROW(std::make_unique<MSReader>(ms, parset, "msin."), + std::runtime_error); +} + +BOOST_AUTO_TEST_SUITE_END()