diff --git a/include/nix/DataView.hpp b/include/nix/DataView.hpp index 05e6503af..63586078f 100644 --- a/include/nix/DataView.hpp +++ b/include/nix/DataView.hpp @@ -19,7 +19,6 @@ class NIXAPI DataView : public DataSet { public: DataView(DataArray da, NDSize count, NDSize offset) : array(std::move(da)), offset(std::move(offset)), count(std::move(count)) { - if (this->offset.size() != array.dataExtent().size()) { throw IncompatibleDimensions("DataView offset dimensionality does not match dimensionality of data", "nix::DataView"); } @@ -28,7 +27,7 @@ class NIXAPI DataView : public DataSet { } if (this->offset + this->count > array.dataExtent()) { throw OutOfBounds("Trying to create DataView which is out of bounds"); - } + } } // the DataIO interface implementation @@ -59,4 +58,4 @@ class NIXAPI DataView : public DataSet { } // nix:: -#endif // DATA_VIEW_HPP \ No newline at end of file +#endif // DATA_VIEW_HPP diff --git a/include/nix/util/dataAccess.hpp b/include/nix/util/dataAccess.hpp index 935b6b22c..1349b349f 100644 --- a/include/nix/util/dataAccess.hpp +++ b/include/nix/util/dataAccess.hpp @@ -397,23 +397,23 @@ NIXAPI DEPRECATED DataView retrieveData(const Tag &tag, const DataArray &array, /** * @brief Checks whether a given position is in the extent of the given DataArray. * - * @param data The data array. + * @param data_size The extent of the data array. * @param position The position. * * @return True if the position is in the extent of the data array, false otherwise. */ -NIXAPI bool positionInData(const DataArray &data, const NDSize &position); +NIXAPI bool positionInData(const NDSize &data_size, const NDSize &position); /** - * @brief Checks whether a given position plus count is in the extent of the given DataArray. + * @brief Checks whether a given offset plus count is in the extent of the given DataArray. * * @param data The DataArray. - * @param position The position + * @param offset The offset * @param count The number of elements per dimension. * - * @return True if position and count are in the extent of the data array, false otherwise. + * @return True if offset and offset + count are in the extent of the data array, false otherwise. */ -NIXAPI bool positionAndExtentInData(const DataArray &data, const NDSize &position, const NDSize &count); +NIXAPI bool positionAndExtentInData(const DataArray &data, const NDSize &offset, const NDSize &count); /** * @brief Retruns the feature data associated with a Tag. diff --git a/src/Dimensions.cpp b/src/Dimensions.cpp index f86220084..c6ed758b9 100644 --- a/src/Dimensions.cpp +++ b/src/Dimensions.cpp @@ -263,14 +263,15 @@ boost::optional> SampledDimension::indexOf(const d boost::optional> SampledDimension::indexOf(double start, double end, const double sampling_interval, const double offset, const RangeMatch match) const { boost::optional> indices; - PositionMatch pos_match = match == RangeMatch::Inclusive ? PositionMatch::LessOrEqual : PositionMatch::Less; - if (start > end) { return indices; } + PositionMatch end_matching; + end_matching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less; + boost::optional si = getSampledIndex(start, offset, sampling_interval, PositionMatch::GreaterOrEqual); - boost::optional ei = getSampledIndex(end, offset, sampling_interval, pos_match); - + boost::optional ei = getSampledIndex(end, offset, sampling_interval, end_matching); + if (si && ei && *si <= *ei) { indices = std::pair(*si, *ei); } @@ -453,10 +454,12 @@ boost::optional> SetDimension::indexOf(double star if (start > end) { return index; } - PositionMatch end_match = match == RangeMatch::Inclusive ? PositionMatch::LessOrEqual : PositionMatch::Less; - + PositionMatch end_matching; + end_matching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less; + boost::optional si = getSetIndex(start, set_labels, PositionMatch::GreaterOrEqual); - boost::optional ei = getSetIndex(end, set_labels, end_match); + boost::optional ei = getSetIndex(end, set_labels, end_matching); + if (si && ei && *si <= *ei) { index = std::pair(*si, *ei); } @@ -662,8 +665,9 @@ boost::optional> RangeDimension::indexOf(double st if (!si) { return range; } - PositionMatch endMatching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less; - boost::optional ei = getIndex(end, ticks, endMatching); + PositionMatch end_matching; + end_matching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less; + boost::optional ei = getIndex(end, ticks, end_matching); if (ei && *si <= *ei) { range = std::pair(*si, *ei); } @@ -716,7 +720,6 @@ std::vector>> RangeDimension::inde if (start_positions.size() != end_positions.size()) { throw runtime_error("Dimension::IndexOf - Number of start and end positions must match!"); } - std::vector>> indices; vector ticks = this->ticks(); for (size_t i = 0; i < start_positions.size(); ++i) { diff --git a/src/util/dataAccess.cpp b/src/util/dataAccess.cpp index f5c71a758..b0df91c6d 100644 --- a/src/util/dataAccess.cpp +++ b/src/util/dataAccess.cpp @@ -480,9 +480,16 @@ void getOffsetAndCount(const MultiTag &tag, const DataArray &array, const vector vector>>> data_indices; for (size_t dim_index = 0; dim_index < dimensions.size(); ++dim_index) { vector temp_units(start_positions[dim_index].size(), units[dim_index]); - vector>> ranges = positionToIndex(start_positions[dim_index], end_positions[dim_index], - temp_units, match, dimensions[dim_index]); - + vector>> ranges; + RangeMatch rm; // The range match needs to be adjusted if the extent is 0.0 in that case we want have an inclusive matching + if (start_positions[dim_index] == end_positions[dim_index]) { + rm = RangeMatch::Inclusive; + } else { + rm = match; + } + ranges = positionToIndex(start_positions[dim_index], end_positions[dim_index], + temp_units, rm, dimensions[dim_index]); + data_indices.push_back(ranges); } // at this point we do have all the start and end indices of the tagged positions that the caller wants the data of. @@ -497,15 +504,17 @@ void getOffsetAndCount(const MultiTag &tag, const DataArray &array, const vector ndsize_t count = (*opt_range).second - (*opt_range).first; data_count[dim_index] += count; } else { + data_count[dim_index] = 0; if (end_positions[dim_index][i] == start_positions[dim_index][i]) { optional ofst = positionToIndex(end_positions[dim_index][i], units[dim_index], PositionMatch::GreaterOrEqual, dimensions[dim_index]); if (!ofst) { throw nix::OutOfBounds("util::offsetAndCount:An invalid range was encountered!"); } - temp_offset[i] = *ofst; + temp_offset[i] = *ofst; // I do not remember what this might be good for... } } } + offsets.push_back(data_offset); counts.push_back(data_count); } @@ -519,24 +528,24 @@ void getOffsetAndCount(const MultiTag &tag, const DataArray &array, ndsize_t ind } -bool positionInData(const DataArray &data, const NDSize &position) { - NDSize data_size = data.dataExtent(); +bool positionInData(const NDSize &data_size, const NDSize &position) { bool valid = true; - if (!(data_size.size() == position.size())) { return false; } for (size_t i = 0; i < data_size.size(); ++i) { - valid &= position[i] < data_size[i]; + valid &= position[i] <= data_size[i]; } return valid; } -bool positionAndExtentInData(const DataArray &data, const NDSize &position, const NDSize &count) { - NDSize pos = position + count; - pos -= 1; - return positionInData(data, pos); +bool positionAndExtentInData(const DataArray &data, const NDSize &offset, const NDSize &count) { + NDSize end_pos = offset + count; + NDSize data_size = data.dataExtent(); + bool valid = positionInData(data_size, offset); + valid &= positionInData(data_size, end_pos); + return valid; } @@ -675,6 +684,7 @@ vector taggedData(const MultiTag &tag, vector &position_indi vector counts, offsets; vector views; + // if no positions are given, we will return dataviews for all positions if (position_indices.size() < 1) { size_t pos_count = check::fits_in_size_t(tag.positions().dataExtent()[0], "Number of positions > size_t."); @@ -683,11 +693,7 @@ vector taggedData(const MultiTag &tag, vector &position_indi } getOffsetAndCount(tag, array, position_indices, offsets, counts, match); - for (size_t i = 0; i < offsets.size(); ++i) { - if (!positionAndExtentInData(array, offsets[i], counts[i])) { - throw OutOfBounds("References data slice out of the extent of the DataArray!", 0); - } DataView io = DataView(array, counts[i], offsets[i]); views.push_back(io); } diff --git a/test/BaseTestDataAccess.cpp b/test/BaseTestDataAccess.cpp index 895258d2e..9c38c8f26 100644 --- a/test/BaseTestDataAccess.cpp +++ b/test/BaseTestDataAccess.cpp @@ -198,7 +198,8 @@ void BaseTestDataAccess::testPositionToIndexSetDimension() { CPPUNIT_ASSERT_THROW(util::positionToIndex({5.0, 0.}, {10.5}, RangeMatch::Inclusive, setDim), std::runtime_error); - vector>> ranges = util::positionToIndex({5.0, 0.}, {10.5, 1.0}, RangeMatch::Inclusive, setDim); + vector>> ranges; + ranges = util::positionToIndex({5.0, 0.}, {10.5, 1.0}, RangeMatch::Inclusive, setDim); CPPUNIT_ASSERT(ranges.size() == 2); CPPUNIT_ASSERT(!ranges[0]); CPPUNIT_ASSERT(ranges[1] && (*ranges[1]).first == 0 && (*ranges[1]).second == 1); @@ -288,19 +289,18 @@ void BaseTestDataAccess::testOffsetAndCount() { CPPUNIT_ASSERT_THROW(util::getOffsetAndCount(multi_tag, data_array, -1, offsets, counts), nix::OutOfBounds); // not a valid position index CPPUNIT_ASSERT_THROW(util::getOffsetAndCount(multi_tag, data_array, 3, offsets, counts), nix::OutOfBounds); // not a valid position index - util::getOffsetAndCount(multi_tag, data_array, 0, offsets, counts); + util::getOffsetAndCount(multi_tag, data_array, 0, offsets, counts, RangeMatch::Inclusive); CPPUNIT_ASSERT(offsets.size() == 4); CPPUNIT_ASSERT(counts.size() == 4); CPPUNIT_ASSERT(offsets[0] == 0 && offsets[1] == 3 && offsets[2] == 2 && offsets[3] == 1); CPPUNIT_ASSERT(counts[0] == 1 && counts[1] == 7 && counts[2] == 2 && counts[3] == 3); - util::getOffsetAndCount(multi_tag, data_array, 0, offsets, counts, RangeMatch::Exclusive); CPPUNIT_ASSERT(offsets.size() == 4); CPPUNIT_ASSERT(counts.size() == 4); CPPUNIT_ASSERT(offsets[0] == 0 && offsets[1] == 3 && offsets[2] == 2 && offsets[3] == 1); - CPPUNIT_ASSERT(counts[0] == 1 && counts[1] == 6 && counts[2] == 2 && counts[3] == 2); + CPPUNIT_ASSERT(counts[0] == 1 && counts[1] == 7 && counts[2] == 2 && counts[3] == 3); - util::getOffsetAndCount(multi_tag, data_array, 1, offsets, counts); + util::getOffsetAndCount(multi_tag, data_array, 1, offsets, counts, RangeMatch::Inclusive); CPPUNIT_ASSERT(offsets.size() == 4); CPPUNIT_ASSERT(counts.size() == 4); CPPUNIT_ASSERT(offsets[0] == 0 && offsets[1] == 8 && offsets[2] == 1 && offsets[3] == 1); @@ -317,11 +317,19 @@ void BaseTestDataAccess::testOffsetAndCount() { void BaseTestDataAccess::testPositionInData() { NDSize offsets, counts; util::getOffsetAndCount(multi_tag, data_array, 0, offsets, counts); - CPPUNIT_ASSERT(util::positionInData(data_array, offsets)); + CPPUNIT_ASSERT(util::positionInData(data_array.dataExtent(), offsets)); CPPUNIT_ASSERT(util::positionAndExtentInData(data_array, offsets, counts)); util::getOffsetAndCount(multi_tag, data_array, 1, offsets, counts); - CPPUNIT_ASSERT(util::positionInData(data_array, offsets)); + CPPUNIT_ASSERT(util::positionInData(data_array.dataExtent(), offsets)); + CPPUNIT_ASSERT(!util::positionAndExtentInData(data_array, offsets, counts)); + + util::getOffsetAndCount(multi_tag, data_array, 0, offsets, counts, RangeMatch::Exclusive); + CPPUNIT_ASSERT(util::positionInData(data_array.dataExtent(), offsets)); + CPPUNIT_ASSERT(util::positionAndExtentInData(data_array, offsets, counts)); + + util::getOffsetAndCount(multi_tag, data_array, 1, offsets, counts, RangeMatch::Exclusive); + CPPUNIT_ASSERT(util::positionInData(data_array.dataExtent(), offsets)); CPPUNIT_ASSERT(!util::positionAndExtentInData(data_array, offsets, counts)); } @@ -454,7 +462,6 @@ void BaseTestDataAccess::testMultiTagFeatureData() { } } index_data.setData(data1); - DataArray tagged_data = block.createDataArray("tagged feature data", "test", nix::DataType::Double, {10, 20, 10, 10}); dim1 = tagged_data.appendSampledDimension(1.0); dim1.unit("ms"); diff --git a/test/BaseTestDimension.cpp b/test/BaseTestDimension.cpp index cd19a866e..644d4d62c 100644 --- a/test/BaseTestDimension.cpp +++ b/test/BaseTestDimension.cpp @@ -661,7 +661,7 @@ void BaseTestDimension::testRangeDimUnit() { std::vector ticks; for (size_t i = 0; i < 5; i++) { - ticks.push_back(i * boost::math::constants::pi()); + ticks.push_back(i * boost::math::constants::pi()); } Dimension d = data_array.appendRangeDimension(ticks); CPPUNIT_ASSERT(d.dimensionType() == DimensionType::Range); @@ -822,6 +822,11 @@ void BaseTestDimension::testRangeDimIndexOf() { CPPUNIT_ASSERT(!range); range = rd.indexOf(100., -100., {}, RangeMatch::Exclusive); CPPUNIT_ASSERT(!range); + range = rd.indexOf(-100., -100, {}, RangeMatch::Inclusive); + CPPUNIT_ASSERT(range); + CPPUNIT_ASSERT(range && (*range).first == 0 && (*range).second == 0); + range = rd.indexOf(-100., -100, {}, RangeMatch::Exclusive); + CPPUNIT_ASSERT(!range); range = rd.indexOf(100., -100., rd.ticks(), RangeMatch::Exclusive); CPPUNIT_ASSERT(!range);