Skip to content

Commit

Permalink
Merge 8e83e78 into 72d4e35
Browse files Browse the repository at this point in the history
  • Loading branch information
jgrewe committed Jan 20, 2019
2 parents 72d4e35 + 8e83e78 commit beb95c1
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 43 deletions.
110 changes: 72 additions & 38 deletions src/util/dataAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,6 @@ void scalePositions(const vector<double> &starts, const vector<double> &ends,
}


ndsize_t positionToIndex(double position, const string &unit, const Dimension &dimension) {
ndsize_t pos;
if (dimension.dimensionType() == DimensionType::Sample) {
SampledDimension dim;
dim = dimension;
pos = positionToIndex(position, unit, dim);
} else if (dimension.dimensionType() == DimensionType::Set) {
SetDimension dim;
dim = dimension;
pos = positionToIndex(position, unit, dim);
} else {
RangeDimension dim;
dim = dimension;
pos = positionToIndex(position, unit, dim);
}

return pos;
}


vector<pair<ndsize_t, ndsize_t>> positionToIndex(const vector<double> &start_positions,
const vector<double> end_positions,
const vector<string> &units,
Expand Down Expand Up @@ -257,9 +237,11 @@ void getOffsetAndCount(const MultiTag &tag, const DataArray &array, const vector
vector<Dimension> dimensions = array.dimensions();
vector<vector<double>> start_positions(dimensions.size());
vector<vector<double>> end_positions(dimensions.size());

for (size_t idx = 0; idx < indices.size(); ++idx) {
temp_offset[0] = indices[idx];
vector<double> offset, extent;

positions.getData(offset, temp_count, temp_offset);
if (extents) {
extents.getData(extent, temp_count, temp_offset);
Expand Down Expand Up @@ -325,32 +307,82 @@ bool positionAndExtentInData(const DataArray &data, const NDSize &position, cons
}


DataView dataSlice(const DataArray &array, const std::vector<double> &start, const std::vector<double> &end,
void fillPositionsExtentsAndUnits(const DataArray &array,
std::vector<double> &starts,
std::vector<double> &ends,
std::vector<std::string> &units) {
std::vector<nix::Dimension> dims = array.dimensions();
NDSize shape = array.dataExtent();
for (size_t i = 0; i < dims.size(); ++i) {
Dimension dim = dims[i];
DimensionType dt = dim.dimensionType();
if (dt == DimensionType::Sample) {
SampledDimension sd = dim.asSampledDimension();
if (i >= starts.size()) {
starts.push_back(sd.offset() ? *sd.offset() : 0.0);
}
if (i >= ends.size()) {
ends.push_back(sd[shape[i]-1]);
}
if (i >= units.size()) {
units.push_back(sd.unit() ? *sd.unit() : "none");
}
} else if (dt == DimensionType::Range) {
RangeDimension rd = dim.asRangeDimension();
if (i >= starts.size()) {
starts.push_back(rd.axis(1, 0)[0]);
}
if (i >= ends.size()) {
ends.push_back(rd.axis(1, shape[i]-1)[0]);
}
if (i >= units.size()) {
units.push_back(rd.unit() ? *rd.unit() : "none");
}
} else if (dt == DimensionType::Set) {
SetDimension sd = dim.asSetDimension();
if (i >= starts.size()) {
starts.push_back(0.0);
}
if (i >= ends.size()) {
ends.push_back(static_cast<double>(shape[i]-1));
}
if (i >= units.size()) {
units.push_back("none");
}
}
}
}


DataView dataSlice(const DataArray &array,
const std::vector<double> &start,
const std::vector<double> &end,
const std::vector<std::string> &units) {
std::vector<double> my_start(start);
std::vector<double> my_end(end);
std::vector<std::string> my_units(units);

if (array == nix::none) {
throw UninitializedEntity();
}
if (start.size() == 0 || start.size() != end.size()) {
throw std::invalid_argument("Number of start entries does not match number of end entries.");
ndsize_t dim_count = array.dimensionCount();
if (start.size() > dim_count || end.size() > dim_count || units.size() > dim_count) {
throw std::invalid_argument("More start/end/unit entries given than number of dimensions in the data!");
}
if (start.size() != array.dimensionCount()) {
throw std::invalid_argument("Number of start/end entries does not match dimensionality of the data.");
if (start.size() < dim_count || end.size() < dim_count || units.size() < dim_count) {
fillPositionsExtentsAndUnits(array, my_start, my_end, my_units);
}
if (units.size() > 0 && units.size() != start.size()) {
throw std::invalid_argument("Number of units does not match dimensionality of the data.");
}
NDSize count(start.size(), 1), offset(start.size(), 0);

for (size_t i = 0; i < start.size(); i++) {
NDSize count(my_start.size(), 1), offset(my_start.size(), 0);
for (size_t i = 0; i < my_start.size(); i++) {
Dimension dim = array.getDimension(i+1);
std::string unit = units.size() != 0 ? units[i] : "none";
if (unit.size() == 0) {
unit = "none";
}
if (start[i] > end[i]) {
if (my_start[i] > my_end[i]) {
throw std::invalid_argument("Start position must not be larger than end position.");
}
std::vector<std::pair<ndsize_t, ndsize_t>> indices = positionToIndex({start[i]}, {end[i]}, {unit}, dim);
std::vector<std::pair<ndsize_t, ndsize_t>> indices = positionToIndex({my_start[i]},
{my_end[i]},
{my_units[i]},
dim);
offset[i] = indices[0].first;
count[i] += indices[0].second - indices[0].first;
}
Expand All @@ -374,7 +406,8 @@ DataView retrieveData(const MultiTag &tag, ndsize_t position_index, const DataAr
}


vector<DataView> retrieveData(const MultiTag &tag, vector<ndsize_t> &position_indices,
vector<DataView> retrieveData(const MultiTag &tag,
vector<ndsize_t> &position_indices,
ndsize_t reference_index) {
vector<DataArray> refs = tag.references();
size_t ref_idx = check::fits_in_size_t(reference_index, "retrieveData() failed; reference_index > size_t.");
Expand All @@ -386,7 +419,8 @@ vector<DataView> retrieveData(const MultiTag &tag, vector<ndsize_t> &position_in
}


vector<DataView> retrieveData(const MultiTag &tag, vector<ndsize_t> &position_indices,
vector<DataView> retrieveData(const MultiTag &tag,
vector<ndsize_t> &position_indices,
const DataArray &array) {
vector<NDSize> counts, offsets;
vector<DataView> views;
Expand Down
44 changes: 39 additions & 5 deletions test/BaseTestDataAccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void BaseTestDataAccess::testPositionToIndexRangeDimension() {
std::string invalid_unit = "kV";
std::string scaled_unit = "s";
CPPUNIT_ASSERT_THROW(util::positionToIndex(5.0, invalid_unit, rangeDim), nix::IncompatibleDimensions);

CPPUNIT_ASSERT(util::positionToIndex(1.0, unit, rangeDim) == 0);
CPPUNIT_ASSERT(util::positionToIndex(8.0, unit, rangeDim) == 4);
CPPUNIT_ASSERT(util::positionToIndex(0.001, scaled_unit, rangeDim) == 0);
Expand Down Expand Up @@ -141,6 +142,10 @@ void BaseTestDataAccess::testRetrieveData() {
std::vector<DataView> slices = util::retrieveData(mtag2, temp, 0);
CPPUNIT_ASSERT(slices.size() == mtag2.positions().dataExtent()[0]);

// old-style calls, deprecated
CPPUNIT_ASSERT_NO_THROW(util::retrieveData(mtag2, 0, 0));
CPPUNIT_ASSERT_NO_THROW(util::retrieveData(mtag2, 0, mtag2.references()[0]));

slices = util::retrieveData(pointmtag, temp, 0);
CPPUNIT_ASSERT(slices.size() == pointmtag.positions().dataExtent()[0]);

Expand All @@ -162,13 +167,15 @@ void BaseTestDataAccess::testRetrieveData() {
CPPUNIT_ASSERT(data_size.size() == 3);
CPPUNIT_ASSERT(data_size[0] == 1 && data_size[1] == 7 && data_size[2] == 2);


DataView times_view = util::retrieveData(times_tag, 0);
data_size = times_view.dataExtent();
std::vector<double> times(data_size.size());
times_view.getData(times);
RangeDimension dim = times_tag.references()[0].dimensions()[0].asRangeDimension();
CPPUNIT_ASSERT(data_size.size() == 1);
CPPUNIT_ASSERT(data_size[0] == 77);

}


Expand Down Expand Up @@ -277,7 +284,15 @@ void BaseTestDataAccess::testMultiTagFeatureData() {
CPPUNIT_ASSERT(multi_tag.featureCount() == 3);

// indexed feature
DataView data_view = util::retrieveFeatureData(multi_tag, indices, 0)[0];
// read a single feature, old style function
DataView data_view = util::retrieveFeatureData(multi_tag, 1, 0);
CPPUNIT_ASSERT(data_view.dataExtent().size() == 2);
CPPUNIT_ASSERT(data_view.dataExtent().nelms() == 10);
CPPUNIT_ASSERT_THROW(util::retrieveFeatureData(multi_tag, 10, 0), nix::OutOfBounds);
CPPUNIT_ASSERT_NO_THROW(util::retrieveFeatureData(multi_tag, 1, index_feature));

// read feature data, multiple indices at once
data_view = util::retrieveFeatureData(multi_tag, indices, 0)[0];

NDSize data_size = data_view.dataExtent();
CPPUNIT_ASSERT(data_size.size() == 2);
Expand Down Expand Up @@ -342,11 +357,16 @@ void BaseTestDataAccess::testMultiTagFeatureData() {
CPPUNIT_ASSERT_THROW(util::retrieveFeatureData(multi_tag, indices, 3), nix::OutOfBounds);

// test multiple positions
std::vector<DataView> views = util::retrieveFeatureData(multi_tag, {0, 1}, 0);
std::vector<nix::DataView> views = util::retrieveFeatureData(multi_tag, {0, 1}, 0);
CPPUNIT_ASSERT(views.size() == 2);
CPPUNIT_ASSERT(views[0].dataExtent() == NDSize({1, 10}));
CPPUNIT_ASSERT(views[0].dataExtent() == NDSize({1, 10}));

// test positions without specifying
indices.clear();
views = util::retrieveFeatureData(multi_tag, indices, 0);
CPPUNIT_ASSERT(views.size() == multi_tag.positionCount());

// clean up
multi_tag.deleteFeature(index_feature.id());
multi_tag.deleteFeature(tagged_feature.id());
Expand Down Expand Up @@ -494,9 +514,22 @@ void BaseTestDataAccess::testDataSlice() {

// do the tests!
nix::DataArray no_array;
CPPUNIT_ASSERT_THROW(util::dataSlice(no_array, {1, 2}, {2,3}), nix::UninitializedEntity);

CPPUNIT_ASSERT_THROW(util::dataSlice(oned_array, {1, 2}, {2,3}), std::invalid_argument);
CPPUNIT_ASSERT_THROW(util::dataSlice(no_array, {1, 2}, {2, 3}), nix::UninitializedEntity);

// test incomplete information
nix::DataView view = util::dataSlice(oned_array, {}, {}, {});
CPPUNIT_ASSERT(view.dataExtent() == oned_array.dataExtent());
view = util::dataSlice(twod_array, {}, {}, {});
CPPUNIT_ASSERT(view.dataExtent() == twod_array.dataExtent());
view = util::dataSlice(twod_array2, {}, {}, {});
CPPUNIT_ASSERT(view.dataExtent() == twod_array2.dataExtent());
view = util::dataSlice(twod_array2, {0.0}, {9.0}, {"s"});
CPPUNIT_ASSERT(view.dataExtent()[1] == twod_array2.dataExtent()[1]);
view = util::dataSlice(twod_array2, {0.0, 0.0}, {9.0, 1000.}, {"s", "ms"});
CPPUNIT_ASSERT(view.dataExtent()[1] == (1/interval + 1));

// test scaling, exceptions etc.
CPPUNIT_ASSERT_THROW(util::dataSlice(oned_array, {1, 2}, {2, 3}), std::invalid_argument);
CPPUNIT_ASSERT_THROW(util::dataSlice(oned_array, {1}, {2}, {"ms", "mV"}), std::invalid_argument);
CPPUNIT_ASSERT_THROW(util::dataSlice(oned_array, {1, 2, 3}, {1, 2}), std::invalid_argument);
CPPUNIT_ASSERT_NO_THROW(util::dataSlice(oned_array, {0.0}, {1.0}));
Expand All @@ -517,6 +550,7 @@ void BaseTestDataAccess::testDataSlice() {
slice = util::dataSlice(twod_array, {0., 0.0}, {9.0, 1.0}, {"none", "s"});
CPPUNIT_ASSERT(slice.dataExtent()[0] == 10 && slice.dataExtent()[1] == 101);


b.deleteDataArray(oned_array);
b.deleteDataArray(twod_array);
file.deleteBlock(b);
Expand Down

0 comments on commit beb95c1

Please sign in to comment.