From d52ff943ee15ab89d7fc4041335efd495bce679a Mon Sep 17 00:00:00 2001 From: Simon Perkins Date: Tue, 28 Jan 2025 19:04:21 +0200 Subject: [PATCH] Link Measurement Set subtables during creation --- cpp/arcae/table_factory.cc | 113 +++++++++++++++-------------- src/arcae/tests/test_descriptor.py | 9 ++- 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/cpp/arcae/table_factory.cc b/cpp/arcae/table_factory.cc index 52f2cd31..408d6cd8 100644 --- a/cpp/arcae/table_factory.cc +++ b/cpp/arcae/table_factory.cc @@ -39,6 +39,7 @@ using ::casacore::Table; using ::casacore::TableProxy; using ::casacore::MeasurementSet; +using ::casacore::MS; using ::casacore::MSAntenna; using ::casacore::MSDataDescription; using ::casacore::MSDoppler; @@ -61,24 +62,7 @@ namespace arcae { namespace { /// Table and subtable names -static constexpr char kAntenna[] = "ANTENNA"; static constexpr char kMain[] = "MAIN"; -static constexpr char kDataDescription[] = "DATA_DESCRIPTION"; -static constexpr char kDoppler[] = "DOPPLER"; -static constexpr char kFeed[] = "FEED"; -static constexpr char kField[] = "FIELD"; -static constexpr char kFlagCmd[] = "FLAG_CMD"; -static constexpr char kFreqOffset[] = "FREQ_OFFSET"; -static constexpr char kHistory[] = "HISTORY"; -static constexpr char kObservation[] = "OBSERVATION"; -static constexpr char kPointing[] = "POINTING"; -static constexpr char kPolarization[] = "POLARIZATION"; -static constexpr char kProcessor[] = "PROCESSOR"; -static constexpr char kSource[] = "SOURCE"; -static constexpr char kSpectralWindow[] = "SPECTRAL_WINDOW"; -static constexpr char kState[] = "STATE"; -static constexpr char kSyscal[] = "SYSCAL"; -static constexpr char kWeather[] = "WEATHER"; } // namespace @@ -105,7 +89,7 @@ Result> DefaultMS(const std::string& name, const std::string& json_table_desc, const std::string& json_dminfo) { // Upper case subtable name - auto usubtable = std::string(subtable.size(), '0'); + casacore::String usubtable(subtable.size(), '0'); std::transform(std::begin(subtable), std::end(subtable), std::begin(usubtable), [](unsigned char c) { return std::toupper(c); }); @@ -122,49 +106,72 @@ Result> DefaultMS(const std::string& name, DefaultMSFactory(modname, usubtable, json_table_desc, json_dminfo)); return NewTableProxy::Make([&]() -> Result> { + // MAIN Measurement Set case if (usubtable.empty() || usubtable == kMain) { auto ms = MeasurementSet(setup_new_table); // Create the MS default subtables ms.createDefaultSubtables(Table::New); // Create a table proxy return std::make_shared(ms); - } else if (usubtable == kAntenna) { - return std::make_shared(MSAntenna(setup_new_table)); - } else if (usubtable == kDataDescription) { - return std::make_shared(MSDataDescription(setup_new_table)); - } else if (usubtable == kDoppler) { - return std::make_shared(MSDoppler(setup_new_table)); - } else if (usubtable == kFeed) { - return std::make_shared(MSFeed(setup_new_table)); - } else if (usubtable == kField) { - return std::make_shared(MSField(setup_new_table)); - } else if (usubtable == kFlagCmd) { - return std::make_shared(MSFlagCmd(setup_new_table)); - } else if (usubtable == kFreqOffset) { - return std::make_shared(MSFreqOffset(setup_new_table)); - } else if (usubtable == kHistory) { - return std::make_shared(MSHistory(setup_new_table)); - } else if (usubtable == kObservation) { - return std::make_shared(MSObservation(setup_new_table)); - } else if (usubtable == kPointing) { - return std::make_shared(MSPointing(setup_new_table)); - } else if (usubtable == kPolarization) { - return std::make_shared(MSPolarization(setup_new_table)); - } else if (usubtable == kProcessor) { - return std::make_shared(MSProcessor(setup_new_table)); - } else if (usubtable == kSource) { - return std::make_shared(MSSource(setup_new_table)); - } else if (usubtable == kSpectralWindow) { - return std::make_shared(MSSpectralWindow(setup_new_table)); - } else if (usubtable == kState) { - return std::make_shared(MSState(setup_new_table)); - } else if (usubtable == kSyscal) { - return std::make_shared(MSSysCal(setup_new_table)); - } else if (usubtable == kWeather) { - return std::make_shared(MSWeather(setup_new_table)); } - return arrow::Status::Invalid("Uknown table type: ", usubtable); + // Open the base Measurement Set table in order to link the subtable + Table ms; + + try { + ms = Table(name, Table::Update); + } catch (const casacore::AipsError& error) { + return arrow::Status::IOError("Error opening Measurement Set ", name, + " for linking against subtable ", usubtable, ": ", + error.what()); + } + + // Create the subtable + std::shared_ptr subtable = nullptr; + + if (usubtable == MS::keywordName(MS::ANTENNA)) { + subtable = std::make_shared(MSAntenna(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::DATA_DESCRIPTION)) { + subtable = std::make_shared(MSDataDescription(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::DOPPLER)) { + subtable = std::make_shared(MSDoppler(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::FEED)) { + subtable = std::make_shared(MSFeed(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::FIELD)) { + subtable = std::make_shared(MSField(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::FLAG_CMD)) { + subtable = std::make_shared(MSFlagCmd(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::FREQ_OFFSET)) { + subtable = std::make_shared(MSFreqOffset(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::HISTORY)) { + subtable = std::make_shared(MSHistory(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::OBSERVATION)) { + subtable = std::make_shared(MSObservation(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::POINTING)) { + subtable = std::make_shared(MSPointing(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::POLARIZATION)) { + subtable = std::make_shared(MSPolarization(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::PROCESSOR)) { + subtable = std::make_shared(MSProcessor(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::SOURCE)) { + subtable = std::make_shared(MSSource(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::SPECTRAL_WINDOW)) { + subtable = std::make_shared(MSSpectralWindow(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::STATE)) { + subtable = std::make_shared(MSState(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::SYSCAL)) { + subtable = std::make_shared(MSSysCal(setup_new_table)); + } else if (usubtable == MS::keywordName(MS::WEATHER)) { + subtable = std::make_shared(MSWeather(setup_new_table)); + } + + if (!subtable) { + return arrow::Status::Invalid("Uknown table type: ", usubtable); + } + + // Link the table against the Measurement Set + ms.rwKeywordSet().defineTable(usubtable, subtable->table()); + return subtable; }); } diff --git a/src/arcae/tests/test_descriptor.py b/src/arcae/tests/test_descriptor.py index c36ec255..fe503626 100644 --- a/src/arcae/tests/test_descriptor.py +++ b/src/arcae/tests/test_descriptor.py @@ -24,9 +24,10 @@ def test_ms_addrows(tmp_path_factory): def test_ms_and_weather_subtable(tmp_path_factory): ms = tmp_path_factory.mktemp("test") / "test.ms" - with Table.ms_from_descriptor(str(ms)): + with Table.ms_from_descriptor(str(ms)) as T: assert (ms / "table.dat").exists() assert not (ms / "WEATHER").exists() + assert "WEATHER" not in T.tabledesc()["_keywords_"] # Basic descriptor table_desc = ms_descriptor("WEATHER", complete=False) @@ -67,6 +68,12 @@ def test_ms_and_weather_subtable(tmp_path_factory): "WIND_SPEED_FLAG", ] + # Weather table is linked in the Measurement Set + with Table.from_filename(str(ms)) as T: + td = T.tabledesc() + assert "WEATHER" in td["_keywords_"] + assert td["_keywords_"]["WEATHER"] == f"Table: {ms}/WEATHER" + def test_weather_subtable_descriptor(): # Test required and complete descriptor for the WEATHER subtable