Beispiel #1
0
DataView retrieveFeatureData(const Tag &tag, size_t feature_index) {
    if (tag.featureCount() == 0) {
        throw nix::OutOfBounds("There are no features associated with this tag!", 0);
    }
    if (feature_index > tag.featureCount()) {
        throw nix::OutOfBounds("Feature index out of bounds.", 0);
    }
    Feature feat = tag.getFeature(feature_index);
    DataArray data = feat.data();
    if (data == nix::none) {
        throw nix::UninitializedEntity();
        //return NDArray(nix::DataType::Float,{0});
    }
    if (feat.linkType() == nix::LinkType::Tagged) {
        NDSize offset, count;
        getOffsetAndCount(tag, data, offset, count);
        if (!positionAndExtentInData(data, offset, count)) {
            throw nix::OutOfBounds("Requested data slice out of the extent of the Feature!", 0);
        }
        DataView io = DataView(data, count, offset);
        return io;
    }
    // for untagged and indexed return the full data
    NDSize offset(data.dataExtent().size(), 0);
    DataView io = DataView(data, data.dataExtent(), offset);
    return io;
}
Beispiel #2
0
RangeDimension::RangeDimension(const DataArray &array)
    : ImplContainer()
{
    if (array.dataExtent().size() > 1) {
        throw InvalidRank("Error creating RangeDimension with DataArray: array must be 1-D!");
    }
}
Beispiel #3
0
DataView retrieveFeatureData(const MultiTag &tag, size_t position_index, size_t feature_index) {
    if (tag.featureCount() == 0) {
       throw nix::OutOfBounds("There are no features associated with this tag!", 0);
    }
    if (feature_index >= tag.featureCount()) {
        throw nix::OutOfBounds("Feature index out of bounds.", 0);
    }
    Feature feat = tag.getFeature(feature_index);
    DataArray data = feat.data();
    if (data == nix::none) {
        throw nix::UninitializedEntity();
        //return NDArray(nix::DataType::Float,{0});
    }
    if (feat.linkType() == nix::LinkType::Tagged) {
        NDSize offset, count;
        getOffsetAndCount(tag, data, position_index, offset, count);
        
        if (!positionAndExtentInData(data, offset, count)) {
            throw nix::OutOfBounds("Requested data slice out of the extent of the Feature!", 0);
        }
        DataView io = DataView(data, count, offset);
        return io;
    } else if (feat.linkType() == nix::LinkType::Indexed) {
        //FIXME does the feature data to have a setdimension in the first dimension for the indexed case?
        //For now it will just be a slice across the first dim.
        if (position_index > data.dataExtent()[0]){
            throw nix::OutOfBounds("Position is larger than the data stored in the feature.", 0);
        }
        NDSize offset(data.dataExtent().size(), 0);
        offset[0] = position_index;
        NDSize count(data.dataExtent());
        count[0] = 1;
        
        if (!positionAndExtentInData(data, offset, count)) {
            throw nix::OutOfBounds("Requested data slice out of the extent of the Feature!", 0);
        }
        DataView io = DataView(data, count, offset);
        return io;
    }
    // FIXME is this expected behavior? In the untagged case all data is returned
    NDSize offset(data.dataExtent().size(), 0);
    DataView io = DataView(data, data.dataExtent(), offset);
    return io;
}
Beispiel #4
0
bool positionInData(const DataArray &data, const NDSize &position) {
    NDSize data_size = data.dataExtent();
    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];
    }
    return valid;
}
Beispiel #5
0
Result validate(const DataArray &data_array) {
    Result result_base = validate_entity_with_sources(data_array);
    Result result = validator({
        must(data_array, &DataArray::dataType, notEqual<DataType>(DataType::Nothing), "data type is not set!"),
        must(data_array, &DataArray::dimensionCount, isEqual<size_t>(data_array.dataExtent().size()), "data dimensionality does not match number of defined dimensions!", {
            could(data_array, &DataArray::dimensions, notEmpty(), {
                must(data_array, &DataArray::dimensions, dimTicksMatchData(data_array), "in some of the Range dimensions the number of ticks differs from the number of data entries along the corresponding data dimension!"),
                must(data_array, &DataArray::dimensions, dimLabelsMatchData(data_array), "in some of the Set dimensions the number of labels differs from the number of data entries along the corresponding data dimension!") }) }),
        could(data_array, &DataArray::unit, notFalse(), {
            should(data_array, &DataArray::unit, isValidUnit(), "Unit is not SI or composite of SI units.") }),
        could(data_array, &DataArray::polynomCoefficients, notEmpty(), {
            should(data_array, &DataArray::expansionOrigin, notFalse(), "polynomial coefficients for calibration are set, but expansion origin is missing!") }),
        could(data_array, &DataArray::expansionOrigin, notFalse(), {
            should(data_array, &DataArray::polynomCoefficients, notEmpty(), "expansion origin for calibration is set, but polynomial coefficients are missing!") })
    });

    return result.concat(result_base);
}
Beispiel #6
0
DataView retrieveData(const MultiTag &tag, size_t position_index, size_t reference_index) {
    DataArray positions = tag.positions();
    DataArray extents = tag.extents();
    vector<DataArray> refs = tag.references();

    if (refs.size() == 0) { // Do I need this?
        throw nix::OutOfBounds("There are no references in this tag!", 0);
    }
    if (position_index >= positions.dataExtent()[0] ||
        (extents && position_index >= extents.dataExtent()[0])) {
        throw nix::OutOfBounds("Index out of bounds of positions or extents!", 0);
    }
    if (!(reference_index < tag.referenceCount())) {
        throw nix::OutOfBounds("Reference index out of bounds.", 0);
    }

    size_t dimension_count = refs[reference_index].dimensionCount();
    if (positions.dataExtent().size() == 1 && dimension_count != 1) {
        throw nix::IncompatibleDimensions("Number of dimensions in position or extent do not match dimensionality of data",
                                          "util::retrieveData");
    } else if (positions.dataExtent().size() > 1) {
        if (positions.dataExtent()[1] > dimension_count ||
            (extents && extents.dataExtent()[1] > dimension_count)) {
            throw nix::IncompatibleDimensions("Number of dimensions in position or extent do not match dimensionality of data",
                                              "util::retrieveData");
        }
    }

    NDSize offset, count;
    getOffsetAndCount(tag, refs[reference_index], position_index, offset, count);

    if (!positionAndExtentInData(refs[reference_index], offset, count)) {
        throw nix::OutOfBounds("References data slice out of the extent of the DataArray!", 0);
    }
    DataView io = DataView(refs[reference_index], count, offset);
    return io;
}
Beispiel #7
0
void BaseTestDataArray::testData() {
    typedef boost::multi_array<double, 3> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[3][4][2]);

    int values = 0;
    for(index i = 0; i != 3; ++i)
        for(index j = 0; j != 4; ++j)
            for(index k = 0; k != 2; ++k)
                A[i][j][k] = values++;

    CPPUNIT_ASSERT_EQUAL(array1.dataType(), nix::DataType::Double);
    CPPUNIT_ASSERT_EQUAL(array1.dataExtent(), nix::NDSize({0, 0, 0}));
    CPPUNIT_ASSERT(array1.getDimension(1) == false);

    array1.setData(A);

    array_type B(boost::extents[1][1][1]);
    array1.getData(B);

    int verify = 0;
    int errors = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += B[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(errors, 0);

    DataArray direct = block.createDataArray("da_direct", "double", A);
    array_type Adirect(boost::extents[3][4][2]);
    direct.getData(Adirect);

    errors = 0;
    verify = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += Adirect[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(0, errors);

    //test createDataArray overload that takes data but specify an storage datat type
    DataArray directFloat = block.createDataArray("da_direct_int", "int", A, DataType::Int32);
    CPPUNIT_ASSERT_EQUAL(DataType::Int32, directFloat.dataType());
    boost::multi_array<int, 3> AdirectFloat(boost::extents[3][4][2]);
    direct.getData(AdirectFloat);

    errors = 0;
    verify = 0;
    for(index i = 0; i != 3; ++i) {
        for(index j = 0; j != 4; ++j) {
            for(index k = 0; k != 2; ++k) {
                int v = verify++;
                errors += AdirectFloat[i][j][k] != v;
            }
        }
    }

    CPPUNIT_ASSERT_EQUAL(0, errors);

    typedef boost::multi_array<double, 2> array2D_type;
    typedef array_type::index index;
    array2D_type C(boost::extents[5][5]);

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            C[i][j] = 42.0;

    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({20, 20}));

    array2.setData(C, nix::NDSize({0, 0}));
    array2.dataExtent(nix::NDSize({40, 40}));
    CPPUNIT_ASSERT_EQUAL(array2.dataExtent(), nix::NDSize({40, 40}));

    array2D_type D(boost::extents[5][5]);
    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            D[i][j] = 42.0;


        array2.setData(D, nix::NDSize({ 20, 20 }));

    array2D_type E(boost::extents[1][1]);
    array2.getData(E, nix::NDSize({ 5, 5 }), nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], E[i][j],
                std::numeric_limits<double>::epsilon());


    array2D_type F(boost::extents[5][5]);

    array2.getData(F, nix::NDSize({ 20, 20 }));

    for(index i = 0; i != 5; ++i)
        for(index j = 0; j != 5; ++j)
            CPPUNIT_ASSERT_DOUBLES_EQUAL(D[i][j], F[i][j],
                std::numeric_limits<double>::epsilon());


    nix::DataArray da3 = block.createDataArray("direct-vector",
                                               "double",
                                               nix::DataType::Double,
                                               nix::NDSize({5}));

    CPPUNIT_ASSERT(da3.dataExtent() == nix::NDSize{5});
    CPPUNIT_ASSERT(da3.getDimension(1) == false);

    std::vector<double> dv = {1.0, 2.0, 3.0, 4.0, 5.0};
    da3.setData(nix::DataType::Double, dv.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    std::vector<double> dvin;
    dvin.resize(5);
    da3.getData(nix::DataType::Double, dvin.data(), nix::NDSize({ 5 }), nix::NDSize({ 0 }));

    for(size_t i = 0; i < dvin.size(); i++) {
        CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[i], dvin[i],
                                     std::numeric_limits<double>::epsilon());
    }

    // test IO of a scalar

    double scalar = -1.0;

    //value + offset + count
    // nix::NDSize({}) indicates a scalar
    scalar = -1.0;
    da3.getData(scalar, nix::NDSize({}), nix::NDSize({0}));
    CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[0], scalar,
                                 std::numeric_limits<double>::epsilon());


    // nix::NDSize({1, 1, ..., 1}) has a number of elemts == 1
    // so that should work too
    scalar = -1.0;
    da3.getData(scalar, nix::NDSize({1}), nix::NDSize({0}));
    CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[0], scalar,
                                 std::numeric_limits<double>::epsilon());

    scalar = -1.0;
    da3.getData(scalar, nix::NDSize({1, 1}), nix::NDSize({0}));
    CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[0], scalar,
                                 std::numeric_limits<double>::epsilon());

    //value + offset
    scalar = -1.0;
    da3.getData(scalar, nix::NDSize({0}));
    CPPUNIT_ASSERT_DOUBLES_EQUAL(dv[0], scalar,
                                 std::numeric_limits<double>::epsilon());

    //TODO: setData(scalar) + getData(scalar)

    DataArray daA = block.createDataArray("append", "double", DataType::Double , NDSize({0, 4, 5}));

    CPPUNIT_ASSERT_THROW(daA.appendData(DataType::Double, nullptr, NDSize({2, 4, 5}), 3), InvalidRank);
    CPPUNIT_ASSERT_THROW(daA.appendData(DataType::Double, nullptr, NDSize({2, 4, 5, 6}), 0), IncompatibleDimensions);
    CPPUNIT_ASSERT_THROW(daA.appendData(DataType::Double, nullptr, NDSize({4, 4, 6}), 0), IncompatibleDimensions);

    std::vector<double> append_data(3*4*5, 1);

    daA.appendData(DataType::Double, append_data.data(), {3, 4, 5}, 0);
    CPPUNIT_ASSERT_EQUAL(NDSize({3, 4, 5}), daA.dataExtent());

    std::fill(append_data.begin(), append_data.end(), 2);

    daA.appendData(DataType::Double, append_data.data(), {3, 4, 5}, 0);
    CPPUNIT_ASSERT_EQUAL(NDSize({6, 4, 5}), daA.dataExtent());

    std::vector<double> append_check(6*4*5, 0);

    daA.getData(DataType::Double, append_check.data(), {6, 4, 5}, {});

    for(size_t i = 0; i < 6*4*5; i++) {
        CPPUNIT_ASSERT_EQUAL(i > 3*4*5-1 ? 2.0 : 1.0, append_check[i]);
    }

}
Beispiel #8
0
void getOffsetAndCount(const MultiTag &tag, const DataArray &array, size_t index, NDSize &offsets, NDSize &counts) {
    DataArray positions = tag.positions();
    DataArray extents = tag.extents();
    NDSize position_size, extent_size;
    size_t dimension_count = array.dimensionCount();

    if (positions) {
        position_size = positions.dataExtent();
    }

    if (extents) {
        extent_size = extents.dataExtent();
    }

    if (!positions || index >= position_size[0]) {
        throw nix::OutOfBounds("Index out of bounds of positions!", 0);
    }

    if (extents && index >= extent_size[0]) {
        throw nix::OutOfBounds("Index out of bounds of positions or extents!", 0);
    }
    
    if (position_size.size() == 1 && dimension_count != 1) {
        throw nix::IncompatibleDimensions("Number of dimensions in positions does not match dimensionality of data", 
                                          "util::getOffsetAndCount");
    }

    if (position_size.size() > 1 && position_size[1] > dimension_count) {
        throw nix::IncompatibleDimensions("Number of dimensions in positions does not match dimensionality of data",
                                          "util::getOffsetAndCount");
    }
    
    if (extents && extent_size.size() > 1 && extent_size[1] > dimension_count) {
        throw nix::IncompatibleDimensions("Number of dimensions in extents does not match dimensionality of data",
                                          "util::getOffsetAndCount");
    }

    NDSize temp_offset = NDSize{static_cast<NDSize::value_type>(index), static_cast<NDSize::value_type>(0)};
    NDSize temp_count{static_cast<NDSize::value_type>(1), static_cast<NDSize::value_type>(dimension_count)};
    vector<double> offset;
    positions.getData(offset, temp_count, temp_offset);

    NDSize data_offset(dimension_count, static_cast<size_t>(0));
    NDSize data_count(dimension_count, static_cast<size_t>(1));
    vector<string> units = tag.units();
    
    for (size_t i = 0; i < offset.size(); ++i) {
        Dimension dimension = array.getDimension(i+1);
        string unit = "none";
        if (i <= units.size() && units.size() > 0) {
            unit = units[i];
        }
        data_offset[i] = positionToIndex(offset[i], unit, dimension);
    }
    
    if (extents) {
        vector<double> extent;
        extents.getData(extent, temp_count, temp_offset);
        for (size_t i = 0; i < extent.size(); ++i) {
            Dimension dimension = array.getDimension(i+1);
            string unit = "none";
            if (i <= units.size() && units.size() > 0) {
                unit = units[i];
            }
            ndsize_t c = positionToIndex(offset[i] + extent[i], unit, dimension) - data_offset[i];
            data_count[i] = (c > 1) ? c : 1;
        }
    }

    offsets = data_offset;
    counts = data_count;
}