diff --git a/.clang-tidy b/.clang-tidy index 7909488fd59b5b71df202f8aa69602a48612094c..6f3e52fc98dcc23aab0b9384063714cc50f9137f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -29,7 +29,7 @@ CheckOptions: - key: modernize-make-shared.MakeSmartPtrFunction value: 'std::make_shared' - key: modernize-loop-convert.UseCxx20ReverseRanges - value: 'true' + value: 'false' - key: modernize-use-override.FinalSpelling value: final - key: modernize-use-using.IgnoreMacros diff --git a/include/schaapcommon/h5parm/soltab.h b/include/schaapcommon/h5parm/soltab.h index bf93ed6ed29bea007f07758a06e812a1f0428620..7e7984ce94c7af011a31f36cd95b8e50515c5fdc 100644 --- a/include/schaapcommon/h5parm/soltab.h +++ b/include/schaapcommon/h5parm/soltab.h @@ -197,10 +197,17 @@ class SolTab : private H5::Group { size_t pol, size_t dir, bool nearest) const; - /// Get the values or weights of this SolTab for a given antenna given an - /// antenna name, a direction index, and a (range of) times and frequencies. - /// In the returned vector, the freq will be the fastest changing index, - /// irrespective of the axis ordering in the underlying h5 data structure. + std::tuple<int, int, int, int, int> GetSubArray( + const std::string& val_or_weight, const size_t start_antenna_index, + const size_t n_antennas, const size_t antenna_step, + const size_t start_time_index, const size_t n_times, + const size_t time_step, const size_t start_freq_index, + const size_t n_freqs, const size_t freq_step, + const size_t start_polarization_index, const size_t n_polarizations, + const size_t polarization_step, const size_t start_direction_index, + const size_t n_directions, const size_t direction_step, + std::vector<double>& buffer) const; + std::vector<double> GetSubArray(const std::string& val_or_weight, const std::string& antenna_name, size_t start_time_index, size_t n_times, @@ -212,6 +219,10 @@ class SolTab : private H5::Group { const std::string& value_or_weight, const size_t n_axes, const std::array<size_t, 5>& size_axis) const; + /// Get the values or weights of this SolTab for a given antenna given an + /// antenna name, a direction index, and a (range of) times and frequencies. + /// In the returned vector, the freq will be the fastest changing index, + /// irrespective of the axis ordering in the underlying h5 data structure. std::vector<double> GetValuesOrWeights(const std::string& val_or_weight, const std::string& antenna_name, const std::vector<double>& times, diff --git a/src/h5parm/soltab.cc b/src/h5parm/soltab.cc index 36e568316b88ba2b85599585c78deb8ed2bc8eca..56964c7abb25c3dea57eb8286ee783048ea7c535 100644 --- a/src/h5parm/soltab.cc +++ b/src/h5parm/soltab.cc @@ -411,12 +411,15 @@ TimesAndFrequencies SolTab::GetTimesAndFrequencies( return tf; } -std::vector<double> SolTab::GetSubArray( - const std::string& val_or_weight, const std::string& antenna_name, +std::tuple<int, int, int, int, int> SolTab::GetSubArray( + const std::string& val_or_weight, const size_t start_antenna_index, + const size_t n_antennas, const size_t antenna_step, const size_t start_time_index, const size_t n_times, const size_t time_step, const size_t start_freq_index, const size_t n_freqs, const size_t freq_step, - const size_t polarization, const size_t direction) const { - std::vector<double> res(n_times * n_freqs); + const size_t start_polarization_index, const size_t n_polarizations, + const size_t polarization_step, const size_t start_direction_index, + const size_t n_directions, const size_t direction_step, + std::vector<double>& buffer) const { H5::DataSet val = openDataSet(val_or_weight); // Set offsets and strides @@ -432,34 +435,64 @@ std::vector<double> SolTab::GetSubArray( for (const AxisInfo& axis_info : axes_) { hsize_t stride = 1; hsize_t count = 1; - hsize_t memdim = 1; hsize_t offset = 0; if (axis_info.name == "time") { offset = start_time_index; stride = time_step; count = n_times; - memdim = n_times; } else if (axis_info.name == "freq") { offset = start_freq_index; stride = freq_step; count = n_freqs; - memdim = n_freqs; } else if (axis_info.name == "ant") { - offset = GetAntIndex(antenna_name); + offset = start_antenna_index; + stride = antenna_step; + count = n_antennas; } else if (axis_info.name == "dir") { - offset = direction; + offset = start_direction_index; + stride = direction_step; + count = n_directions; } else if (axis_info.name == "pol") { - offset = polarization; + offset = start_polarization_index; + stride = polarization_step; + count = n_polarizations; } else if (axis_info.size != 1) { throw std::runtime_error("Axis \"" + axis_info.name + "\" in H5Parm is not understood"); } - memdims.push_back(memdim); + memdims.push_back(count); offsets.push_back(offset); counts.push_back(count); strides.push_back(stride); } + size_t antenna_stride = 0; + size_t time_stride = 0; + size_t freq_stride = 0; + size_t polarization_stride = 0; + size_t direction_stride = 0; + size_t stride = 1; + for (auto axis_info = axes_.rbegin(); axis_info != axes_.rend(); + ++axis_info) { + if (axis_info->name == "time") { + time_stride = stride; + stride *= n_times; + } else if (axis_info->name == "freq") { + freq_stride = stride; + stride *= n_freqs; + } else if (axis_info->name == "ant") { + antenna_stride = stride; + stride *= n_antennas; + } else if (axis_info->name == "dir") { + direction_stride = stride; + stride *= n_directions; + } else if (axis_info->name == "pol") { + polarization_stride = stride; + stride *= n_polarizations; + } + } + buffer.resize(stride); + H5::DataSpace dataspace = val.getSpace(); dataspace.selectHyperslab(H5S_SELECT_SET, counts.data(), offsets.data(), @@ -467,12 +500,36 @@ std::vector<double> SolTab::GetSubArray( // Setup memory dataspace H5::DataSpace memspace(axes_.size(), memdims.data()); + try { - val.read(res.data(), H5::PredType::NATIVE_DOUBLE, memspace, dataspace); + val.read(buffer.data(), H5::PredType::NATIVE_DOUBLE, memspace, dataspace); } catch (H5::DataSetIException& e) { e.printErrorStack(); throw std::runtime_error("Could not read data"); } + return {antenna_stride, time_stride, freq_stride, polarization_stride, + direction_stride}; +} + +std::vector<double> SolTab::GetSubArray( + const std::string& val_or_weight, const std::string& antenna_name, + const size_t start_time_index, const size_t n_times, const size_t time_step, + const size_t start_freq_index, const size_t n_freqs, const size_t freq_step, + const size_t polarization, const size_t direction) const { + std::vector<double> res(n_times * n_freqs); + + size_t antenna_index = 0; + try { + antenna_index = GetAntIndex(antenna_name); + } catch (const std::runtime_error& error) { + // A SolTab does not necessarily have an "ant" table. + // In that case just leave antenna_index at 0. + } + + GetSubArray(val_or_weight, antenna_index, 1, 1, start_time_index, n_times, + time_step, start_freq_index, n_freqs, freq_step, polarization, 1, + 1, direction, 1, 1, res); + return res; }