<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <boost/test/unit_test.hpp>
#include <boost/cstdint.hpp>

#include <libpc/Header.hpp>
#include <libpc/PointBuffer.hpp>
#include <libpc/SchemaLayout.hpp>
#include <libpc/drivers/faux/Reader.hpp>
#include <libpc/drivers/faux/Iterator.hpp>

using namespace libpc;

BOOST_AUTO_TEST_SUITE(FauxReaderTest)

BOOST_AUTO_TEST_CASE(test_constant_mode_sequential_iter)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Constant);

    BOOST_CHECK_EQUAL(reader.getName(), "Faux Reader");

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_CLOSE(x, 2.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_EQUAL(t, i);
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_constant_mode_random_iter)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Constant);

    BOOST_CHECK_EQUAL(reader.getName(), "Faux Reader");

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 10);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    RandomIterator* iter = reader.createRandomIterator();

    boost::uint32_t numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i);
        }
    }

    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+10);
        }
    }

    boost::uint64_t newPos = iter->seek(99);
    BOOST_CHECK_EQUAL(newPos, 99);
    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+99);

        }
    }

    newPos = iter->seek(7);
    BOOST_CHECK_EQUAL(newPos, 7);
    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+7);

        }
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_random_mode)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Random);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_GE(x, 1.0);
        BOOST_CHECK_LE(x, 101.0);

        BOOST_CHECK_GE(y, 2.0);
        BOOST_CHECK_LE(y, 102.0);

        BOOST_CHECK_GE(z, 3.0);
        BOOST_CHECK_LE(z, 103.0);

        BOOST_CHECK_EQUAL(t, i);
        // BOOST_CHECK(x >= 1.0 && x <= 101.0);
        // BOOST_CHECK(y >= 2.0 && y <= 102.0);
        // BOOST_CHECK(z >= 3.0 && z <= 103.0);
        // BOOST_CHECK(t == i);
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_ramp_mode_1)
{
    Bounds<double> bounds(0,0,0,4,4,4);
    libpc::drivers::faux::Reader reader(bounds, 2, libpc::drivers::faux::Reader::Ramp);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 2);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 2);

    const int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    const int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    const int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    const int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    const double x0 = data.getField<double>(0, offsetX);
    const double y0 = data.getField<double>(0, offsetY);
    const double z0 = data.getField<double>(0, offsetZ);
    const boost::uint64_t t0 = data.getField<boost::uint64_t>(0, offsetT);

    const double x1 = data.getField<double>(1, offsetX);
    const double y1 = data.getField<double>(1, offsetY);
    const double z1 = data.getField<double>(1, offsetZ);
    const boost::uint64_t t1 = data.getField<boost::uint64_t>(1, offsetT);

    BOOST_CHECK_CLOSE(x0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(y0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(z0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_EQUAL(t0, 0);

    BOOST_CHECK_CLOSE(x1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(y1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(z1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_EQUAL(t1, 1);

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_ramp_mode_2)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 152.0, 203.0);
    libpc::drivers::faux::Reader reader(bounds, 750, libpc::drivers::faux::Reader::Ramp);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead,750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    double delX = (101.0 - 1.0) / (750.0 - 1.0);
    double delY = (152.0 - 2.0) / (750.0 - 1.0);
    double delZ = (203.0 - 3.0) / (750.0 - 1.0);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_CLOSE(x, 1.0 + delX*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(y, 2.0 + delY*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(z, 3.0 + delZ*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_EQUAL(t, i);

    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_custom_fields)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);

    Dimension dimY(Dimension::Field_Y, Dimension::Uint8);
    Dimension dimX(Dimension::Field_X, Dimension::Uint8);
    std::vector<Dimension> dims;
    dims.push_back(dimY);
    dims.push_back(dimX);

    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Random, dims);

    const Schema& schema = reader.getHeader().getSchema();
    BOOST_CHECK_EQUAL(schema.getDimensions().size(), 2);
    BOOST_CHECK_EQUAL(schema.getDimension(0).getField(), Dimension::Field_Y);
    BOOST_CHECK_EQUAL(schema.getDimension(1).getField(), Dimension::Field_X);

    return;
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>a cut-and-paste error and an off-by-one error at the same time :-)<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <boost/test/unit_test.hpp>
#include <boost/cstdint.hpp>

#include <libpc/Header.hpp>
#include <libpc/PointBuffer.hpp>
#include <libpc/SchemaLayout.hpp>
#include <libpc/drivers/faux/Reader.hpp>
#include <libpc/drivers/faux/Iterator.hpp>

using namespace libpc;

BOOST_AUTO_TEST_SUITE(FauxReaderTest)

BOOST_AUTO_TEST_CASE(test_constant_mode_sequential_iter)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Constant);

    BOOST_CHECK_EQUAL(reader.getName(), "Faux Reader");

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
        BOOST_CHECK_EQUAL(t, i);
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_constant_mode_random_iter)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Constant);

    BOOST_CHECK_EQUAL(reader.getName(), "Faux Reader");

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 10);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    RandomIterator* iter = reader.createRandomIterator();

    boost::uint32_t numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i);
        }
    }

    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+10);
        }
    }

    boost::uint64_t newPos = iter->seek(99);
    BOOST_CHECK_EQUAL(newPos, 99);
    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+99);

        }
    }

    newPos = iter->seek(7);
    BOOST_CHECK_EQUAL(newPos, 7);
    numRead = iter->read(data);
    BOOST_CHECK_EQUAL(numRead, 10);

    {
        for (boost::uint32_t i=0; i<numRead; i++)
        {
            double x = data.getField<double>(i, offsetX);
            double y = data.getField<double>(i, offsetY);
            double z = data.getField<double>(i, offsetZ);
            boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

            BOOST_CHECK_CLOSE(x, 1.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(y, 2.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_CLOSE(z, 3.0, (std::numeric_limits<double>::min)());
            BOOST_CHECK_EQUAL(t, i+7);

        }
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_random_mode)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);
    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Random);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_GE(x, 1.0);
        BOOST_CHECK_LE(x, 101.0);

        BOOST_CHECK_GE(y, 2.0);
        BOOST_CHECK_LE(y, 102.0);

        BOOST_CHECK_GE(z, 3.0);
        BOOST_CHECK_LE(z, 103.0);

        BOOST_CHECK_EQUAL(t, i);
        // BOOST_CHECK(x >= 1.0 && x <= 101.0);
        // BOOST_CHECK(y >= 2.0 && y <= 102.0);
        // BOOST_CHECK(z >= 3.0 && z <= 103.0);
        // BOOST_CHECK(t == i);
    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_ramp_mode_1)
{
    Bounds<double> bounds(0,0,0,4,4,4);
    libpc::drivers::faux::Reader reader(bounds, 2, libpc::drivers::faux::Reader::Ramp);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 2);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead, 2);

    const int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    const int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    const int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    const int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    const double x0 = data.getField<double>(0, offsetX);
    const double y0 = data.getField<double>(0, offsetY);
    const double z0 = data.getField<double>(0, offsetZ);
    const boost::uint64_t t0 = data.getField<boost::uint64_t>(0, offsetT);

    const double x1 = data.getField<double>(1, offsetX);
    const double y1 = data.getField<double>(1, offsetY);
    const double z1 = data.getField<double>(1, offsetZ);
    const boost::uint64_t t1 = data.getField<boost::uint64_t>(1, offsetT);

    BOOST_CHECK_CLOSE(x0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(y0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(z0, 0.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_EQUAL(t0, 0);

    BOOST_CHECK_CLOSE(x1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(y1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_CLOSE(z1, 4.0, (std::numeric_limits<double>::min)());
    BOOST_CHECK_EQUAL(t1, 1);

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_ramp_mode_2)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 152.0, 203.0);
    libpc::drivers::faux::Reader reader(bounds, 750, libpc::drivers::faux::Reader::Ramp);

    const Schema& schema = reader.getHeader().getSchema();
    SchemaLayout layout(schema);

    PointBuffer data(layout, 750);

    SequentialIterator* iter = reader.createSequentialIterator();
    boost::uint32_t numRead = iter->read(data);

    BOOST_CHECK_EQUAL(numRead,750);

    int offsetX = schema.getDimensionIndex(Dimension::Field_X);
    int offsetY = schema.getDimensionIndex(Dimension::Field_Y);
    int offsetZ = schema.getDimensionIndex(Dimension::Field_Z);
    int offsetT = schema.getDimensionIndex(Dimension::Field_Time);

    double delX = (101.0 - 1.0) / (750.0 - 1.0);
    double delY = (152.0 - 2.0) / (750.0 - 1.0);
    double delZ = (203.0 - 3.0) / (750.0 - 1.0);

    for (boost::uint32_t i=0; i<numRead; i++)
    {
        double x = data.getField<double>(i, offsetX);
        double y = data.getField<double>(i, offsetY);
        double z = data.getField<double>(i, offsetZ);
        boost::uint64_t t = data.getField<boost::uint64_t>(i, offsetT);

        BOOST_CHECK_CLOSE(x, 1.0 + delX*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(y, 2.0 + delY*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_CLOSE(z, 3.0 + delZ*i, (std::numeric_limits<double>::min)());
        BOOST_CHECK_EQUAL(t, i);

    }

    delete iter;

    return;
}

BOOST_AUTO_TEST_CASE(test_custom_fields)
{
    Bounds<double> bounds(1.0, 2.0, 3.0, 101.0, 102.0, 103.0);

    Dimension dimY(Dimension::Field_Y, Dimension::Uint8);
    Dimension dimX(Dimension::Field_X, Dimension::Uint8);
    std::vector<Dimension> dims;
    dims.push_back(dimY);
    dims.push_back(dimX);

    libpc::drivers::faux::Reader reader(bounds, 1000, libpc::drivers::faux::Reader::Random, dims);

    const Schema& schema = reader.getHeader().getSchema();
    BOOST_CHECK_EQUAL(schema.getDimensions().size(), 2);
    BOOST_CHECK_EQUAL(schema.getDimension(0).getField(), Dimension::Field_Y);
    BOOST_CHECK_EQUAL(schema.getDimension(1).getField(), Dimension::Field_X);

    return;
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>//******************************************************************************
//
// Copyright (c) Microsoft. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************

#include <windows.h>
#include <TestFramework.h>
#include <memory>
#include <roapi.h>
#include <WexTestClass.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.storage.h>

#include <CoreFoundation/CoreFoundation.h>

#include "DrawingTestConfig.h"

using namespace ABI::Windows::Storage;
using namespace Microsoft::WRL;
using namespace Windows::Foundation;

Wrappers::HString GetAppDataPath() {
    Wrappers::HString toReturn;
    ComPtr<IStorageFolder> folder;
    ComPtr<IApplicationDataStatics> applicationDataStatics;
    ComPtr<IApplicationData> applicationData;
    ComPtr<IStorageItem> storageItem;

    if (FAILED(Windows::Foundation::GetActivationFactory(Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
                                                         &applicationDataStatics))) {
        return toReturn;
    }

    if (FAILED(applicationDataStatics->get_Current(&applicationData))) {
        return toReturn;
    }

    if (FAILED(applicationData->get_LocalFolder(&folder))) {
        return toReturn;
    }

    if (FAILED(folder.As<IStorageItem>(&storageItem))) {
        return toReturn;
    }

    if (FAILED(storageItem->get_Path(toReturn.GetAddressOf()))) {
        return toReturn;
    }

    return toReturn;
}

static std::string __ModuleDirectory() {
    static std::string modulePath = GetCurrentTestDirectory();
    return modulePath;
}

static std::string __OutputDirectory() {
    static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    Wrappers::HString appDataDirectory = GetAppDataPath();
    return converter.to_bytes(WindowsGetStringRawBuffer(appDataDirectory.Get(), nullptr));
}

class TAEFDrawingTestConfigImpl : public DrawingTestConfigImpl {
private:
    DrawingTestMode _mode;
    std::string _outputPath;
    std::string _comparisonPath;

public:
    TAEFDrawingTestConfigImpl()
        : _mode(DrawingTestMode::Compare), _outputPath(__OutputDirectory()), _comparisonPath(GetCurrentTestDirectory() + "/data/reference") {
        static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

        WEX::Common::String outputPath;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"out", outputPath);
        if (!outputPath.IsEmpty()) {
            _outputPath = converter.to_bytes(std::wstring(outputPath));
        }

        WEX::Common::String comparisonPath;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"compare", comparisonPath);
        if (!comparisonPath.IsEmpty()) {
            _comparisonPath = converter.to_bytes(std::wstring(comparisonPath));
        }

        WEX::Common::String generateMode;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"generate", generateMode);
        if (generateMode.CompareNoCase(L"true") || generateMode.CompareNoCase(L"yes")) {
            _mode = DrawingTestMode::Generate;
        }
    }

    virtual DrawingTestMode GetMode() override {
        return _mode;
    }

    virtual std::string GetOutputPath() override {
        return _outputPath;
    }

    virtual std::string GetComparisonPath() override {
        return _comparisonPath;
    }

    virtual std::string GetResourcePath(const std::string& resource) override {
        // Using / as a path separator is valid on both Windows and OS X.
        return __ModuleDirectory() + "/data/" + resource;
    }
};

std::shared_ptr<DrawingTestConfigImpl> _configImpl;
/* static */ DrawingTestConfigImpl* DrawingTestConfig::Get() {
    return _configImpl.get();
}

BEGIN_MODULE()
MODULE_PROPERTY(L"RunAs", L"UAP")
END_MODULE()

MODULE_SETUP(ModuleSetup) {
    if (FAILED(RoInitialize(RO_INIT_MULTITHREADED))) {
        return FALSE;
    }

    Wrappers::HString path = GetAppDataPath();
    if (path.IsValid()) {
        unsigned int rawLength;
        _wchdir(WindowsGetStringRawBuffer(path.Get(), &rawLength));
    }

    int argc = 1;
    char* argv[] = { "UnitTests" };
    testing::InitGoogleTest(&argc, argv);

    _configImpl = std::move(std::make_shared<TAEFDrawingTestConfigImpl>());

    return TRUE;
}

MODULE_CLEANUP(ModuleCleanup) {
    RoUninitialize();
    return true;
}<commit_msg>Fix the tests being stuck in generate mode & always passing.<commit_after>//******************************************************************************
//
// Copyright (c) Microsoft. All rights reserved.
//
// This code is licensed under the MIT License (MIT).
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//******************************************************************************

#include <windows.h>
#include <TestFramework.h>
#include <memory>
#include <roapi.h>
#include <WexTestClass.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
#include <windows.storage.h>

#include <CoreFoundation/CoreFoundation.h>

#include "DrawingTestConfig.h"

using namespace ABI::Windows::Storage;
using namespace Microsoft::WRL;
using namespace Windows::Foundation;

Wrappers::HString GetAppDataPath() {
    Wrappers::HString toReturn;
    ComPtr<IStorageFolder> folder;
    ComPtr<IApplicationDataStatics> applicationDataStatics;
    ComPtr<IApplicationData> applicationData;
    ComPtr<IStorageItem> storageItem;

    if (FAILED(Windows::Foundation::GetActivationFactory(Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
                                                         &applicationDataStatics))) {
        return toReturn;
    }

    if (FAILED(applicationDataStatics->get_Current(&applicationData))) {
        return toReturn;
    }

    if (FAILED(applicationData->get_LocalFolder(&folder))) {
        return toReturn;
    }

    if (FAILED(folder.As<IStorageItem>(&storageItem))) {
        return toReturn;
    }

    if (FAILED(storageItem->get_Path(toReturn.GetAddressOf()))) {
        return toReturn;
    }

    return toReturn;
}

static std::string __ModuleDirectory() {
    static std::string modulePath = GetCurrentTestDirectory();
    return modulePath;
}

static std::string __OutputDirectory() {
    static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    Wrappers::HString appDataDirectory = GetAppDataPath();
    return converter.to_bytes(WindowsGetStringRawBuffer(appDataDirectory.Get(), nullptr));
}

class TAEFDrawingTestConfigImpl : public DrawingTestConfigImpl {
private:
    DrawingTestMode _mode;
    std::string _outputPath;
    std::string _comparisonPath;

public:
    TAEFDrawingTestConfigImpl()
        : _mode(DrawingTestMode::Compare), _outputPath(__OutputDirectory()), _comparisonPath(GetCurrentTestDirectory() + "/data/reference") {
        static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

        WEX::Common::String outputPath;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"out", outputPath);
        if (!outputPath.IsEmpty()) {
            _outputPath = converter.to_bytes(std::wstring(outputPath));
        }

        WEX::Common::String comparisonPath;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"compare", comparisonPath);
        if (!comparisonPath.IsEmpty()) {
            _comparisonPath = converter.to_bytes(std::wstring(comparisonPath));
        }

        WEX::Common::String generateMode;
        WEX::TestExecution::RuntimeParameters::TryGetValue(L"generate", generateMode);
        if (generateMode.CompareNoCase(L"true") == 0 || generateMode.CompareNoCase(L"yes") == 0) {
            _mode = DrawingTestMode::Generate;
        }
    }

    virtual DrawingTestMode GetMode() override {
        return _mode;
    }

    virtual std::string GetOutputPath() override {
        return _outputPath;
    }

    virtual std::string GetComparisonPath() override {
        return _comparisonPath;
    }

    virtual std::string GetResourcePath(const std::string& resource) override {
        // Using / as a path separator is valid on both Windows and OS X.
        return __ModuleDirectory() + "/data/" + resource;
    }
};

std::shared_ptr<DrawingTestConfigImpl> _configImpl;
/* static */ DrawingTestConfigImpl* DrawingTestConfig::Get() {
    return _configImpl.get();
}

BEGIN_MODULE()
MODULE_PROPERTY(L"RunAs", L"UAP")
END_MODULE()

MODULE_SETUP(ModuleSetup) {
    if (FAILED(RoInitialize(RO_INIT_MULTITHREADED))) {
        return FALSE;
    }

    Wrappers::HString path = GetAppDataPath();
    if (path.IsValid()) {
        unsigned int rawLength;
        _wchdir(WindowsGetStringRawBuffer(path.Get(), &rawLength));
    }

    int argc = 1;
    char* argv[] = { "UnitTests" };
    testing::InitGoogleTest(&argc, argv);

    _configImpl = std::move(std::make_shared<TAEFDrawingTestConfigImpl>());

    return TRUE;
}

MODULE_CLEANUP(ModuleCleanup) {
    RoUninitialize();
    return true;
}<|endoftext|>


<commit_before>//MIT License
//
//Copyright(c) 2016 Matthias Moeller
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files(the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions :
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

#ifndef __TYTI_STEAM_VDF_PARSER_H__
#define __TYTI_STEAM_VDF_PARSER_H__

#include <vector>
#include <unordered_map>
#include <utility>
#include <fstream>

#include <memory>

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/config.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>

namespace tyti
{
    namespace vdf
    {
        template<typename CharT>
        struct basic_object;

        template<typename iStreamT, typename charT = typename iStreamT::char_type>
        basic_object<charT> read(iStreamT& inStream, bool *ok = 0);

        namespace detail
        {
            ///////////////////////////////////////////////////////////////////////////
            //  Grammar data structure
            ///////////////////////////////////////////////////////////////////////////
            template<typename T>
            struct parser_ast;

            template<typename charT>
            struct variant
            {
                typedef boost::variant <
                    boost::recursive_wrapper< parser_ast<charT> > //cildren
                    , std::pair<std::basic_string<charT>, std::basic_string<charT> > //attribute
                    , std::basic_string<charT> //includes
                > parser_node;
            };

            template<typename charT>
            struct parser_ast
            {
                std::basic_string<charT> name;                           // tag name
                std::vector< typename variant<charT>::parser_node > children;        // children
            };

            ///////////////////////////////////////////////////////////////////////////
            //  Helper functions selecting the right encoding (char/wchar_T)
            ///////////////////////////////////////////////////////////////////////////

            template<typename T>
            struct literal_macro_help
            {
                static const char* result(const char* c, const wchar_t* wc)
                {
                    return c;
                }
                static const char result(char c, wchar_t wc)
                {
                    return c;
                }
            };

            template<>
            struct literal_macro_help<wchar_t>
            {
                static const wchar_t* result(const char* c, const wchar_t* wc)
                {
                    return wc;
                }
                static const wchar_t result(char c, wchar_t wc)
                {
                    return wc;
                }
            };
#define TYTI_L(type, text) vdf::detail::literal_macro_help<type>::result(text, L##text)

            template<typename T>
            struct encoding_selector
            {
                typedef boost::spirit::standard::char_type char_type;
                typedef boost::spirit::standard::space_type space_type;
                static const char_type char_;
                static const space_type space;
            };

            template<>
            struct encoding_selector<wchar_t>
            {
                typedef boost::spirit::standard_wide::char_type char_type;
                typedef boost::spirit::standard_wide::space_type space_type;
                static const char_type char_;
                static const space_type space;
            };
            template<typename T>
            const typename encoding_selector<T>::char_type encoding_selector<T>::char_ = boost::spirit::standard::char_;
            template<typename T>
            const typename encoding_selector<T>::space_type encoding_selector<T>::space = boost::spirit::standard::space;
            const typename encoding_selector<wchar_t>::char_type encoding_selector<wchar_t>::char_ = boost::spirit::standard_wide::char_;
            const typename encoding_selector<wchar_t>::space_type encoding_selector<wchar_t>::space = boost::spirit::standard_wide::space;

            ///////////////////////////////////////////////////////////////////////////
            //  Grammar
            ///////////////////////////////////////////////////////////////////////////
            template<typename CharT, typename Iterator>
            struct vdf_skipper : public boost::spirit::qi::grammar<Iterator> {

            private:
                typedef encoding_selector<typename Iterator::value_type> es;
            public:

                vdf_skipper() : vdf_skipper::base_type(skip, "comment_skipper") {
                    //skip whitespace or C++ comment until next line
                    comment = (TYTI_L(CharT, "//") >> *(es::char_ - TYTI_L(CharT, '\n')));
                    skip = es::space | comment;
                }
                boost::spirit::qi::rule<Iterator> skip;
                boost::spirit::qi::rule<Iterator> comment;
            };

            template <typename CharT, typename Iterator>
            struct vdf_grammar
                : boost::spirit::qi::grammar<Iterator, parser_ast<CharT>(), boost::spirit::qi::locals< std::basic_string<CharT> >, vdf_skipper<CharT, Iterator> >
            {
                typedef CharT char_type;
                typedef std::basic_string<char_type> gr_string;
                typedef encoding_selector<char_type> es;
                typedef typename variant<char_type>::parser_node parser_node;
                vdf_grammar()
                    : vdf_grammar::base_type(vdf, "vdf")
                {
                    namespace spirit = boost::spirit;
                    namespace phoenix = boost::phoenix;
                    using spirit::qi::lit;
                    using spirit::qi::lexeme;
                    using spirit::qi::on_error;
                    using spirit::qi::fail;
                    using namespace spirit::qi::labels;

                    using phoenix::construct;
                    using phoenix::val;

                    quoted_string %= lexeme[TYTI_L(char_type, '"') >>
                        *(es::char_ - TYTI_L(char_type, '"')) >> TYTI_L(char_type, '"')];

                    include %= (lit(TYTI_L(char_type,"\"#base\"")) | lit(TYTI_L(char_type,"\"#include\""))) > quoted_string;
                    text %= quoted_string > quoted_string;
                    node %= vdf | include | text ;

                    vdf %=
                        quoted_string >> TYTI_L(char_type, "{")
                        >> *node >> TYTI_L(char_type, "}");

                    vdf.name("vdf");
                    node.name("node");
                    text.name("text");
                    quoted_string.name("string");

                    //on_error<fail>
                    //    (
                    //        vdf
                    //        , std::cout
                    //        << val("Error! Expecting ")
                    //        << spirit::_4                               // what failed?
                    //        << val(" here: \"")
                    //        << construct<std::string>(spirit::_3, spirit::_2)   // iterators to error-pos, end
                    //        << val("\"")
                    //        << std::endl
                    //        );
                }

                typedef vdf_skipper<CharT, Iterator> skipper;
                //typedef typename es::space_type skipper;

                boost::spirit::qi::rule<Iterator, parser_ast<CharT>(), boost::spirit::qi::locals<gr_string>, skipper> vdf;
                boost::spirit::qi::rule<Iterator, parser_node(), skipper> node;
                boost::spirit::qi::rule<Iterator, std::pair<gr_string, gr_string>(), skipper> text;
                boost::spirit::qi::rule<Iterator, gr_string(), skipper> quoted_string;
                boost::spirit::qi::rule<Iterator, gr_string(), skipper> include;
            };

            ///////////////////////////////////////////////////////////////////////////
            //  Visitor
            ///////////////////////////////////////////////////////////////////////////

            // trasformation from parser_ast to output tree via objects
            template<typename charT>
            struct vdf_praser_ast_visitor : public boost::static_visitor<>
            {
                typedef basic_object<charT> vis_object;
                typedef std::pair<std::basic_string<charT>, std::basic_string<charT> > vis_key_value;
                vis_object& m_currentObj;
            public:
                vdf_praser_ast_visitor(vis_object& t) : m_currentObj(t) {}
                void operator()(std::pair<std::basic_string<charT>, std::basic_string<charT> > in) const
                {
                    m_currentObj.attribs.insert(std::move(in));
                }
                void operator()(const std::basic_string<charT>& in) const
                {
                    std::basic_ifstream<charT> file(in);
                    if (!file.is_open())
                    {
                        std::cerr << "Could not open file: " << std::string(in.begin(), in.end()) << std::endl;
                        return;
                    }
                    auto obj = tyti::vdf::read(file);
					const std::basic_string<charT> n = obj.name;
                    m_currentObj.childs.emplace(std::move(n), std::make_shared<vis_object>(std::move(obj)));
                }
                void operator()(const parser_ast<charT>& x) const
                {
                    vis_object t;
                    t.name = x.name;
                    for (auto& i : x.children)
                        boost::apply_visitor(vdf_praser_ast_visitor<charT>(t), i);
                    m_currentObj.childs.emplace(x.name, std::make_shared<vis_object>(std::move(t)));
                }

            };

            ///////////////////////////////////////////////////////////////////////////
            //  Writer helper functions
            ///////////////////////////////////////////////////////////////////////////

            struct tabs
            {
                size_t t;
                tabs(size_t i) :t(i) {}
            };

            template<typename oStreamT>
            oStreamT& operator<<(oStreamT& s, tabs t)
            {
                for (; t.t > 0; --t.t)
                    s << "\t";
                return s;
            }
        } // end namespace detail

        ///////////////////////////////////////////////////////////////////////////
        //  Interface
        ///////////////////////////////////////////////////////////////////////////

        /// basic object node. Every object has a name and can contains attributes saved as key_value pairs or childrens
        template<typename CharT>
        struct basic_object
        {
            typedef CharT char_type;
            std::basic_string<char_type> name;
            std::unordered_map<std::basic_string<char_type>, std::basic_string<char_type> > attribs;
            std::unordered_map<std::basic_string<char_type>, std::shared_ptr< basic_object<char_type> > > childs;
        };

        typedef basic_object<char> object;
        typedef basic_object<wchar_t> wobject;

        /** \brief writes given object tree in vdf format to given stream.
        Uses tabs instead of whitespaces.
        */
        template<typename oStreamT, typename charT = typename oStreamT::char_type>
        void write(oStreamT& s, const basic_object<charT>& r, size_t t = 0)
        {
            using namespace detail;
            s << tabs(t) << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tabs(t) << TYTI_L(charT, "{\n");
            for (auto& i : r.attribs)
                s << tabs(t + 1) << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") << i.second << TYTI_L(charT, "\"\n");
            for (auto& i : r.childs)
                write(s, i, t + 1);
            s << tabs(t) << TYTI_L(charT, "}\n");
        }

        /** \brief Read VDF formatted sequences defined by the range [first, last).
        If the file is mailformatted, parser will try to read it until it can.
        @param first begin iterator
        @param end end iterator
        @param ok output bool. true, if parser successed, false, if parser failed
        */
        template<typename IterT, typename charT = typename IterT::value_type>
        basic_object<charT> read(IterT first, IterT last, bool* ok = 0)
        {
            using namespace detail;
            parser_ast<charT> ast;
            vdf_grammar<charT, IterT> parser;
            vdf_skipper<charT, IterT> skipper;
            bool r = boost::spirit::qi::phrase_parse(first, last, parser, skipper, ast);
            if (ok)
                *ok = r;

            basic_object<charT> root;
                for(auto& i : ast.children)
                boost::apply_visitor(vdf_praser_ast_visitor<charT>(root), i);
            root.name = ast.name;
            return root;
        }

        /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data.
        */
        template<typename iStreamT, typename charT>
        basic_object<charT> read(iStreamT& inStream, bool *ok)
        {
            // cache the file
            std::basic_string<charT> str;
            inStream.seekg(0, std::ios::end);
            str.resize(inStream.tellg());
            if (str.empty())
                return basic_object<charT>();

            inStream.seekg(0, std::ios::beg);
            inStream.read(&str[0], str.size());
            inStream.close();

            // parse it
            return read(str.begin(), str.end(), ok);
        }

    } // end namespace vdf
} // end namespace tyti
#ifndef TYTI_NO_L_UNDEF
#undef TYTI_L
#endif

BOOST_FUSION_ADAPT_STRUCT(
    tyti::vdf::detail::parser_ast<char>,
    (std::string, name)
    (std::vector< tyti::vdf::detail::variant<char>::parser_node >, children)
)

BOOST_FUSION_ADAPT_STRUCT(
    tyti::vdf::detail::parser_ast<wchar_t>,
    (std::wstring, name)
    (std::vector< tyti::vdf::detail::variant<wchar_t>::parser_node >, children)
)

#endif //__TYTI_STEAM_VDF_PARSER_H__<commit_msg>add first no-boost-dep version<commit_after>//MIT License
//
//Copyright(c) 2016 Matthias Moeller
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files(the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions :
//
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

#ifndef __TYTI_STEAM_VDF_PARSER_H__
#define __TYTI_STEAM_VDF_PARSER_H__

#include <vector>
#include <unordered_map>
#include <utility>
#include <fstream>

#include <memory>
#include <stack>

namespace tyti
{
    namespace vdf
    {
        template<typename CharT>
        struct basic_object;

        template<typename iStreamT, typename charT = typename iStreamT::char_type>
        basic_object<charT> read(iStreamT& inStream, bool *ok = 0);

        namespace detail
        {
            ///////////////////////////////////////////////////////////////////////////
            //  Helper functions selecting the right encoding (char/wchar_T)
            ///////////////////////////////////////////////////////////////////////////

            template<typename T>
            struct literal_macro_help
            {
                static const char* result(const char* c, const wchar_t* wc)
                {
                    return c;
                }
                static const char result(char c, wchar_t wc)
                {
                    return c;
                }
            };

            template<>
            struct literal_macro_help<wchar_t>
            {
                static const wchar_t* result(const char* c, const wchar_t* wc)
                {
                    return wc;
                }
                static const wchar_t result(char c, wchar_t wc)
                {
                    return wc;
                }
            };
#define TYTI_L(type, text) vdf::detail::literal_macro_help<type>::result(text, L##text)

            ///////////////////////////////////////////////////////////////////////////
            //  Writer helper functions
            ///////////////////////////////////////////////////////////////////////////

            struct tabs
            {
                size_t t;
                tabs(size_t i) :t(i) {}
            };

            template<typename oStreamT>
            oStreamT& operator<<(oStreamT& s, tabs t)
            {
                for (; t.t > 0; --t.t)
                    s << "\t";
                return s;
            }
        } // end namespace detail

        ///////////////////////////////////////////////////////////////////////////
        //  Interface
        ///////////////////////////////////////////////////////////////////////////

        /// basic object node. Every object has a name and can contains attributes saved as key_value pairs or childrens
        template<typename CharT>
        struct basic_object
        {
            typedef CharT char_type;
            std::basic_string<char_type> name;
            std::unordered_map<std::basic_string<char_type>, std::basic_string<char_type> > attribs;
            std::unordered_map<std::basic_string<char_type>, std::shared_ptr< basic_object<char_type> > > childs;
        };

        typedef basic_object<char> object;
        typedef basic_object<wchar_t> wobject;

        /** \brief writes given object tree in vdf format to given stream.
        Uses tabs instead of whitespaces.
        */
        template<typename oStreamT, typename charT = typename oStreamT::char_type>
        void write(oStreamT& s, const basic_object<charT>& r, size_t t = 0)
        {
            using namespace detail;
            s << tabs(t) << TYTI_L(charT, '"') << r.name << TYTI_L(charT, "\"\n") << tabs(t) << TYTI_L(charT, "{\n");
            for (auto& i : r.attribs)
                s << tabs(t + 1) << TYTI_L(charT, '"') << i.first << TYTI_L(charT, "\"\t\t\"") << i.second << TYTI_L(charT, "\"\n");
            for (auto& i : r.childs)
                write(s, i, t + 1);
            s << tabs(t) << TYTI_L(charT, "}\n");
        }

        /** \brief Read VDF formatted sequences defined by the range [first, last).
        If the file is mailformatted, parser will try to read it until it can.
        @param first begin iterator
        @param end end iterator
        @param ok output bool. true, if parser successed, false, if parser failed
        */

        template<typename IterT, typename charT = typename IterT::value_type>
        basic_object<charT> read(IterT first, IterT last, bool* ok = 0)
        {
			if (ok)
				*ok = true;

			basic_object<charT> root;
			basic_object<charT>* cur = &root;
			std::stack< basic_object<charT>* > lvls;
			//read header
			// first, quoted name
			auto b = std::find(first, last, TYTI_L(charT, '\"'));
			auto bend = std::find(b + 1, last, TYTI_L(charT, '\"'));
			root.name = std::basic_string<charT>(b+1, bend);
			// second, get {}
			b = std::find(bend, last, TYTI_L(charT,'{'));
			lvls.push(&root);
			while (!lvls.empty() && b != last)
			{
				const std::basic_string<charT> startsym = TYTI_L(charT, "\"}");

				//find first starting attrib/child, or ending
				b = std::find_first_of(b, last, std::cbegin(startsym), std::cend(startsym));
				if (*b == '\"')
				{
					bend = std::find(b+1, last, TYTI_L(charT, '\"'));
					std::basic_string<charT> curName(b + 1, bend);
					b = bend + 1;

					const std::basic_string<charT> ecspsym = TYTI_L(charT, "\"{");
					b = std::find_first_of(b, last, std::cbegin(ecspsym), std::cend(ecspsym));
					if (*b == '\"')
					{
						bend = std::find(b+1, last, TYTI_L(charT, '\"'));
						auto value = std::basic_string<charT>(b + 1, bend);
						b = bend + 1;

						if (curName != TYTI_L(charT, "#include") && curName != TYTI_L(charT, "#base"))
							cur->attribs[curName] = value;
						else
						{
							std::basic_ifstream<charT> i(value);
							auto n = std::make_shared<basic_object<charT>>(read(i, ok));
							cur->childs[n->name] = n;
						}
					}
					else if (*b == '{')
					{
						lvls.push(cur);
						auto n = std::make_shared<basic_object<charT>>();
						cur->childs[curName] = n;
						cur = n.get();
						cur->name = curName;
						++b;
					}
				}
				else if (*b == '}')
				{
					cur = lvls.top();
					lvls.pop();
					++b;
				}
			}
            return root;
        }

        /** \brief Loads a stream (e.g. filestream) into the memory and parses the vdf formatted data.
        */
        template<typename iStreamT, typename charT>
        basic_object<charT> read(iStreamT& inStream, bool *ok)
        {
            // cache the file
            std::basic_string<charT> str;
            inStream.seekg(0, std::ios::end);
            str.resize(inStream.tellg());
            if (str.empty())
                return basic_object<charT>();

            inStream.seekg(0, std::ios::beg);
            inStream.read(&str[0], str.size());
            inStream.close();

            // parse it
            return read(str.begin(), str.end(), ok);
        }

    } // end namespace vdf
} // end namespace tyti
#ifndef TYTI_NO_L_UNDEF
#undef TYTI_L
#endif

#endif //__TYTI_STEAM_VDF_PARSER_H__<|endoftext|>


<commit_before>/*
 * Copyright 2006-2012 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <iostream>
#include <list>
#include <map>

#include <sstream>
#include <zorba/store_manager.h>
#include <zorba/zorba.h>
#include <zorba/zorba_exception.h>

using namespace std;
using namespace zorba;
using namespace zorba::locale;

bool
sctx_test_1(Zorba* const zorba)
{
  StaticContext_t lSctx = zorba->createStaticContext();

  Zorba_CompilerHints_t lHints;

  std::stringstream lProlog;
  lProlog << "declare namespace foo = 'http://www.example.com';";

  lSctx->loadProlog(lProlog.str(), lHints);

  NsBindings lBindings;
  lSctx->getNamespaceBindings(lBindings);

  bool lFooFound = false;

  for (NsBindings::const_iterator lIter = lBindings.begin();
       lIter != lBindings.end(); ++lIter)
  {
    std::cout << "prefix: " << lIter->first << " bound to "
      << lIter->second << std::endl;

    if (lIter->first.compare("foo") == 0)
    {
      lFooFound = true;
    }
  }

  return lFooFound && lBindings.size() == 6;
}

int static_context( int argc, char *argv[] ) {
  void *const zstore = StoreManager::getStore();
  Zorba *const zorba = Zorba::getInstance( zstore );

  if (!sctx_test_1(zorba))
    return 1;

  zorba->shutdown();
  StoreManager::shutdownStore( zstore );
  return 0;
}
/* vim:set et sw=2 ts=2: */

<commit_msg>There are now 6 built-in namespace bindings (including jn: ).<commit_after>/*
 * Copyright 2006-2012 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <iostream>
#include <list>
#include <map>

#include <sstream>
#include <zorba/store_manager.h>
#include <zorba/zorba.h>
#include <zorba/zorba_exception.h>

using namespace std;
using namespace zorba;
using namespace zorba::locale;

bool
sctx_test_1(Zorba* const zorba)
{
  StaticContext_t lSctx = zorba->createStaticContext();

  Zorba_CompilerHints_t lHints;

  std::stringstream lProlog;
  lProlog << "declare namespace foo = 'http://www.example.com';";

  lSctx->loadProlog(lProlog.str(), lHints);

  NsBindings lBindings;
  lSctx->getNamespaceBindings(lBindings);

  bool lFooFound = false;

  for (NsBindings::const_iterator lIter = lBindings.begin();
       lIter != lBindings.end(); ++lIter)
  {
    std::cout << "prefix: " << lIter->first << " bound to "
      << lIter->second << std::endl;

    if (lIter->first.compare("foo") == 0)
    {
      lFooFound = true;
    }
  }

  return lFooFound && lBindings.size() == 7;
}

int static_context( int argc, char *argv[] ) {
  void *const zstore = StoreManager::getStore();
  Zorba *const zorba = Zorba::getInstance( zstore );

  if (!sctx_test_1(zorba))
    return 1;

  zorba->shutdown();
  StoreManager::shutdownStore( zstore );
  return 0;
}
/* vim:set et sw=2 ts=2: */

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.png}, {ROISpot5Moving.png}
//    OUTPUTS: {SIFTResampling.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{itk}{DeformationFieldSource} will be used
// to generate a deformation field by using
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the
// appropriate header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
//#include "otbSiftFastImageFilter.h"
#include "otbImageToSIFTKeyPointSetFilter.h"

// Disabling deprecation warning if on visual
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include "itkDeformationFieldSource.h"
// Enabling remaining deprecation warning
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbMacro.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbLeastSquareAffineTransformEstimator.h"
#include "itkResampleImageFilter.h"

int main (int argc, char* argv[])
{
  if (argc!= 9)
  {
    std::cerr <<"Usage: "<<argv[0];
    std::cerr<<"fixedFileName movingFileName resamplingImageFileName octaves scales threshold ratio secondOrderThreshold" << std::endl;
    return EXIT_FAILURE;
  }

  const char * fixedfname = argv[1];
  const char * movingfname = argv[2];
  const char * outputImageFilename = argv[3];

  const unsigned int octaves = atoi(argv[4]);
  const unsigned int scales = atoi(argv[5]);
  float threshold = atof(argv[6]);
  float ratio = atof(argv[7]);
  const double secondOrderThreshold = atof(argv[8]);

  const unsigned int Dimension = 2;

  // Software Guide : BeginLatex
  //
  // Then we must decide what pixel type to use for the image. We choose to do
  // all the computations in floating point precision and rescale the results
  // between 0 and 255 in order to export PNG images.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The SIFTs obtained for the matching will be stored in vector
  // form inside a point set. So we need the following types:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The filter for computing the SIFTs has a type defined as follows:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  //typedef otb::SiftFastImageFilter<ImageType,PointSetType>
  //ImageToSIFTKeyPointSetFilterType;
  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType,PointSetType>
  ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // Although many choices for evaluating the distances during the
  // matching procedure exist, we choose here to use a simple
  // Euclidean distance. We can then define the type for the matching filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
  EuclideanDistanceMatchingFilterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The following types are needed for dealing with the matched points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType
  LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one
  // for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(fixedfname);
  movingReader->SetFileName(movingfname);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
    ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
    ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
    EuclideanDistanceMatchingFilterType::New();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  //filter1->SetScalesNumber(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  //filter2->SetScalesNumber(3);

  // Software Guide : BeginCodeSnippet
  filter1->SetOctavesNumber(octaves);
  filter1->SetScalesNumber(scales);

  filter1->SetDoGThreshold(threshold);
  filter1->SetEdgeThreshold(ratio);

  filter2->SetOctavesNumber(octaves);
  filter2->SetScalesNumber(scales);

  filter2->SetDoGThreshold(threshold);
  filter2->SetEdgeThreshold(ratio);
// Software Guide : EndCodeSnippet

  filter1->Update();
  filter2->Update();

  //filter1->SetNumberOfThreads(1);
  //filter2->SetNumberOfThreads(1);

  //Take the minimum point set to compute euclidian diff
  PointSetType::Pointer ptSet1 = filter1->GetOutput();
  PointSetType::Pointer ptSet2 = filter2->GetOutput();

  typedef PointSetType::PointsContainer PointsContainer;
  typedef PointsContainer::Iterator PointsIterator;

  PointSetType::Pointer ptSet1bis = PointSetType::New();
  PointSetType::Pointer ptSet2bis = PointSetType::New();
  //PointsContainer::Pointer pt1Container;
  //PointsContainer::Pointer pt2Container;
  //bool 1isMin = ptSet1->GetNumberOfPoints() <= ptSet2->GetNumberOfPoints();
  //LandmarkListType::Iterator it
  unsigned int sizeMin=ptSet2->GetNumberOfPoints();
  if ( ptSet1->GetNumberOfPoints() < ptSet2->GetNumberOfPoints() )
  {
        sizeMin = ptSet1->GetNumberOfPoints();
  }

  //PointsIterator pointIterator = points->Begin();
  //PointsIterator end = points->End();
  unsigned int dataId =  0;
  //while ( pointIterator != end )
   //typedef PointSetType::PointContainer PointDataContainer;
   PointsContainer::Pointer      points1 = ptSet1->GetPoints();
   PointsContainer::Pointer      points2 = ptSet2->GetPoints();
   typedef PointsContainer::Iterator           PointsIterator;
   PointsIterator     pointsIterator1 = points1->Begin();
   PointsIterator     pointsIterator2 = points2->Begin();
   for (unsigned int dataId=0;dataId < sizeMin;++dataId)
   {
        ptSet1bis->SetPoint( dataId , pointsIterator1->Value() );
        ptSet2bis->SetPoint( dataId , pointsIterator2->Value() );
        std::cout <<  pointsIterator1->Value() << std::endl;

        ++pointsIterator1;
        ++pointsIterator2;
   }
std::cout << "add over"<< std::endl;
  euclideanMatcher->SetInput1(ptSet1);
std::cout << "add over"<< std::endl;
  euclideanMatcher->SetInput2(ptSet2);
std::cout << "add over"<< std::endl;
  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();
std::cout << "add over"<< std::endl;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Apply Mean square algorithm
  //
  // Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  typedef itk::Point<double,2>                                 MyPointType;
  typedef otb::LeastSquareAffineTransformEstimator<MyPointType> EstimatorType;

  // instantiation
  EstimatorType::Pointer estimator = EstimatorType::New();
  std::cout << "landmark list size " << landmarkList->Size() << std::endl;
  for (LandmarkListType::Iterator it = landmarkList->Begin();
     it != landmarkList->End(); ++it)
  {
        //otbMsgDevMacro(<<"landmark1" << it.Get()->GetPoint1() );
        //otbMsgDevMacro(<<"landmark2" << it.Get()->GetPoint2() );
        std::cout << "landmark1" << it.Get()->GetPoint1() << std::endl;
        std::cout << "landmark2" << it.Get()->GetPoint2() << std::endl;
        estimator->AddTiePoints(it.Get()->GetPoint1(),it.Get()->GetPoint2());
  }

  // Trigger computation
  estimator->Compute();
  // meanSquarestimator->SetInput(euclideanMatcher->GetOutput());
// Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Resample the initial image with the transformation evaluated
  //
  // Software Guide : EndLatex
//  Software Guide : BeginLatex
  //
  //  It is common, as the last step of a registration task, to use
  //  the resulting transform to map the moving image into the fixed
  //  image space.  This is easily done with the
  //  \doxygen{itk}{ResampleImageFilter}. First, a ResampleImageFilter
  //  type is instantiated using the image types. It is convenient to
  //  use the fixed image type as the output type since it is likely
  //  that the transformed moving image will be compared with the
  //  fixed image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::ResampleImageFilter<
  ImageType,
  OutputImageType >    ResampleFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  A resampling filter is created and the moving image is connected as
  //  its input.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
  resampler->SetInput( movingReader->GetOutput() );

  //typedef itk::ImageRegistrationMethod<
  //ImageType,
  //ImageType >    RegistrationType;

  //RegistrationType::Pointer   registration  = RegistrationType::New();

  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The Transform that is produced as output need to be inversed to
  //  We apply here the resampling algorithm to the "fixed" image
  // to produce the moving image. Or apply to the moving image
  //
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // Get the output transform
  typedef EstimatorType::AffineTransformType AffineTransformType;
  AffineTransformType::Pointer transform = AffineTransformType::New();
  transform->GetInverse( estimator->GetAffineTransform() );

  resampler->SetTransform( transform );
  resampler->SetSize( fixedReader->GetOutput()->GetLargestPossibleRegion().GetSize() );
  resampler->SetOutputOrigin( fixedReader->GetOutput()->GetOrigin() );
  resampler->SetOutputSpacing( fixedReader->GetOutput()->GetSpacing() );
  resampler->SetDefaultPixelValue( 100 );

  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( outputImageFilename );
  writer->Update();

  return EXIT_SUCCESS;
}

<commit_msg>TEST:estimate affine<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROISpot5.png}, {ROISpot5Moving.png}
//    OUTPUTS: {SIFTResampling.png}
//  Software Guide : EndCommandLineArgs

// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{KeyPointSetsMatchingFilter} for disparity map
// estimation. The idea here is to match SIFTs extracted from both the
// fixed and the moving images. The use of SIFTs is demonstrated in
// section \ref{sec:SIFTDetector}. The
// \doxygen{itk}{DeformationFieldSource} will be used
// to generate a deformation field by using
// interpolation on the deformation values from the point set. More
// advanced methods for deformation field interpolation are also
// available.
//
// The first step toward the use of these filters is to include the
// appropriate header files.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet

#include "otbKeyPointSetsMatchingFilter.h"
//#include "otbSiftFastImageFilter.h"
#include "otbImageToSIFTKeyPointSetFilter.h"

// Disabling deprecation warning if on visual
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996)
#endif
#include "itkDeformationFieldSource.h"
// Enabling remaining deprecation warning
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "itkWarpImageFilter.h"

// Software Guide : EndCodeSnippet

#include "otbImage.h"
#include "otbMacro.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkPointSet.h"
#include "otbMultiToMonoChannelExtractROI.h"
#include "otbLeastSquareAffineTransformEstimator.h"
#include "itkResampleImageFilter.h"

int main (int argc, char* argv[])
{
  if (argc!= 9)
  {
    std::cerr <<"Usage: "<<argv[0];
    std::cerr<<"fixedFileName movingFileName resamplingImageFileName octaves scales threshold ratio secondOrderThreshold" << std::endl;
    return EXIT_FAILURE;
  }

  const char * fixedfname = argv[1];
  const char * movingfname = argv[2];
  const char * outputImageFilename = argv[3];

  const unsigned int octaves = atoi(argv[4]);
  const unsigned int scales = atoi(argv[5]);
  float threshold = atof(argv[6]);
  float ratio = atof(argv[7]);
  const double secondOrderThreshold = atof(argv[8]);

  const unsigned int Dimension = 2;

  // Software Guide : BeginLatex
  //
  // Then we must decide what pixel type to use for the image. We choose to do
  // all the computations in floating point precision and rescale the results
  // between 0 and 255 in order to export PNG images.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef double        RealType;
  typedef unsigned char OutputPixelType;

  typedef otb::Image<RealType,Dimension> ImageType;
  typedef otb::Image<OutputPixelType,Dimension> OutputImageType;

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The SIFTs obtained for the matching will be stored in vector
  // form inside a point set. So we need the following types:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::VariableLengthVector<RealType> RealVectorType;
  typedef itk::PointSet<RealVectorType,Dimension> PointSetType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // The filter for computing the SIFTs has a type defined as follows:
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  //typedef otb::SiftFastImageFilter<ImageType,PointSetType>
  //ImageToSIFTKeyPointSetFilterType;
  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType,PointSetType>
  ImageToSIFTKeyPointSetFilterType;

  // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
  //
  // Although many choices for evaluating the distances during the
  // matching procedure exist, we choose here to use a simple
  // Euclidean distance. We can then define the type for the matching filter.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef itk::Statistics::EuclideanDistance<RealVectorType> DistanceType;
  typedef otb::KeyPointSetsMatchingFilter<PointSetType, DistanceType>
  EuclideanDistanceMatchingFilterType;
  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // The following types are needed for dealing with the matched points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef PointSetType::PointType PointType;
  typedef std::pair<PointType,PointType> MatchType;
  typedef std::vector<MatchType> MatchVectorType;
  typedef EuclideanDistanceMatchingFilterType::LandmarkListType
  LandmarkListType;

  typedef PointSetType::PointsContainer PointsContainerType;
  typedef PointsContainerType::Iterator PointsIteratorType;
  typedef PointSetType::PointDataContainer PointDataContainerType;
  typedef PointDataContainerType::Iterator PointDataIteratorType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We define the type for the image reader.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  typedef otb::ImageFileReader<ImageType> ReaderType;

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Two readers are instantiated : one for the fixed image, and one
  // for the moving image.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ReaderType::Pointer fixedReader = ReaderType::New();
  ReaderType::Pointer movingReader = ReaderType::New();

  fixedReader->SetFileName(fixedfname);
  movingReader->SetFileName(movingfname);
  fixedReader->UpdateOutputInformation();
  movingReader->UpdateOutputInformation();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We will now instantiate the 2 SIFT filters and the filter used
  // for the matching of the points.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
    ImageToSIFTKeyPointSetFilterType::New();
  ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
    ImageToSIFTKeyPointSetFilterType::New();
  EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
    EuclideanDistanceMatchingFilterType::New();

  // Software Guide : EndCodeSnippet
  // Software Guide : BeginLatex
  //
  // We plug the pipeline and set the parameters.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  bool useBackMatching = 0;

  filter1->SetInput(0, fixedReader->GetOutput() );
  //filter1->SetScalesNumber(3);
  filter2->SetInput(0, movingReader->GetOutput() );
  //filter2->SetScalesNumber(3);

  // Software Guide : BeginCodeSnippet
  filter1->SetOctavesNumber(octaves);
  filter1->SetScalesNumber(scales);

  filter1->SetDoGThreshold(threshold);
  filter1->SetEdgeThreshold(ratio);

  filter2->SetOctavesNumber(octaves);
  filter2->SetScalesNumber(scales);

  filter2->SetDoGThreshold(threshold);
  filter2->SetEdgeThreshold(ratio);
// Software Guide : EndCodeSnippet

  filter1->Update();
  filter2->Update();

  //filter1->SetNumberOfThreads(1);
  //filter2->SetNumberOfThreads(1);

  //Take the minimum point set to compute euclidian diff
  PointSetType::Pointer ptSet1 = filter1->GetOutput();
  PointSetType::Pointer ptSet2 = filter2->GetOutput();

  typedef PointSetType::PointsContainer PointsContainer;
  PointsContainer::Pointer ptContainer;

  unsigned int minPtSetSize=ptSet1->GetNumberOfPoints();
  ptContainer1 = ptSet1->GetPoints();
  ptContainer2 = ptSet2->GetPoints();
  if ( ptSet1->GetNumberOfPoints() > ptSet2->GetNumberOfPoints() )
  {
        //minPtSetSize = ptSet2->GetNumberOfPoints();
	//minPtSetSize = ptSet2->GetNumberOfPoints();
 	ptContainer1 = ptSet2->GetPoints();
  	ptContainer2 = ptSet1->GetPoints();
  }

  for (unsigned int id=ptContainer1->GetSize();id < ptContainer2->GetSize();++id)
  {
  	ptContainer2->DeleteIndex( id );
  }

  if ( ptSet1->GetNumberOfPoints() > ptSet2->GetNumberOfPoints() )
  {
        ptSet1->SetPoints(ptContainer2);
  }
  else
  {
  	ptSet2->SetPoints(ptContainer2);
  }
  /*
  typedef PointSetType::PointsContainer PointsContainer;
  typedef PointsContainer::Iterator PointsIterator;

  PointSetType::Pointer ptSet1bis = PointSetType::New();
  PointSetType::Pointer ptSet2bis = PointSetType::New();
  //PointsContainer::Pointer pt1Container;
  //PointsContainer::Pointer pt2Container;
  //bool 1isMin = ptSet1->GetNumberOfPoints() <= ptSet2->GetNumberOfPoints();
  //LandmarkListType::Iterator it
  unsigned int sizeMin=ptSet2->GetNumberOfPoints();
  if ( ptSet1->GetNumberOfPoints() < ptSet2->GetNumberOfPoints() )
  {
        sizeMin = ptSet1->GetNumberOfPoints();
  }

  //PointsIterator pointIterator = points->Begin();
  //PointsIterator end = points->End();
  unsigned int dataId =  0;
  //while ( pointIterator != end )
   //typedef PointSetType::PointContainer PointDataContainer;
   PointsContainer::Pointer      points1 = ptSet1->GetPoints();
   PointsContainer::Pointer      points2 = ptSet2->GetPoints();
   typedef PointsContainer::Iterator           PointsIterator;
   PointsIterator     pointsIterator1 = points1->Begin();
   PointsIterator     pointsIterator2 = points2->Begin();
   for (unsigned int dataId=0;dataId < sizeMin;++dataId)
   {
        ptSet1bis->SetPoint( dataId , pointsIterator1->Value() );
        ptSet2bis->SetPoint( dataId , pointsIterator2->Value() );
        std::cout <<  pointsIterator1->Value() << std::endl;

        ++pointsIterator1;
        ++pointsIterator2;
   }
*/

  euclideanMatcher->SetInput1(ptSet1);
  euclideanMatcher->SetInput2(ptSet2);

  euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
  euclideanMatcher->SetUseBackMatching(useBackMatching);
  euclideanMatcher->Update();

  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // The matched points will be stored into a landmark list.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet

  LandmarkListType::Pointer landmarkList;
  landmarkList = euclideanMatcher->GetOutput();

  // Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Apply Mean square algorithm
  //
  // Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
  typedef itk::Point<double,2>                                 MyPointType;
  typedef otb::LeastSquareAffineTransformEstimator<MyPointType> EstimatorType;

  // instantiation
  EstimatorType::Pointer estimator = EstimatorType::New();
  std::cout << "landmark list size " << landmarkList->Size() << std::endl;
  for (LandmarkListType::Iterator it = landmarkList->Begin();
     it != landmarkList->End(); ++it)
  {
        //otbMsgDevMacro(<<"landmark1" << it.Get()->GetPoint1() );
        //otbMsgDevMacro(<<"landmark2" << it.Get()->GetPoint2() );
        std::cout << "landmark1" << it.Get()->GetPoint1() << std::endl;
        std::cout << "landmark2" << it.Get()->GetPoint2() << std::endl;
        estimator->AddTiePoints(it.Get()->GetPoint1(),it.Get()->GetPoint2());
  }

  // Trigger computation
  estimator->Compute();
  // meanSquarestimator->SetInput(euclideanMatcher->GetOutput());
// Software Guide : EndCodeSnippet

 // Software Guide : BeginLatex
  //
  // Resample the initial image with the transformation evaluated
  //
  // Software Guide : EndLatex
//  Software Guide : BeginLatex
  //
  //  It is common, as the last step of a registration task, to use
  //  the resulting transform to map the moving image into the fixed
  //  image space.  This is easily done with the
  //  \doxygen{itk}{ResampleImageFilter}. First, a ResampleImageFilter
  //  type is instantiated using the image types. It is convenient to
  //  use the fixed image type as the output type since it is likely
  //  that the transformed moving image will be compared with the
  //  fixed image.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef itk::ResampleImageFilter<
  ImageType,
  OutputImageType >    ResampleFilterType;
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  A resampling filter is created and the moving image is connected as
  //  its input.
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
  resampler->SetInput( movingReader->GetOutput() );

  //typedef itk::ImageRegistrationMethod<
  //ImageType,
  //ImageType >    RegistrationType;

  //RegistrationType::Pointer   registration  = RegistrationType::New();

  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  //
  //  The Transform that is produced as output need to be inversed to
  //  We apply here the resampling algorithm to the "fixed" image
  // to produce the moving image. Or apply to the moving image
  //
  //
  //  Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  // Get the output transform
  typedef EstimatorType::AffineTransformType AffineTransformType;
  AffineTransformType::Pointer transform = AffineTransformType::New();
  transform->GetInverse( estimator->GetAffineTransform() );

  resampler->SetTransform( transform );
  resampler->SetSize( fixedReader->GetOutput()->GetLargestPossibleRegion().GetSize() );
  resampler->SetOutputOrigin( fixedReader->GetOutput()->GetOrigin() );
  resampler->SetOutputSpacing( fixedReader->GetOutput()->GetSpacing() );
  resampler->SetDefaultPixelValue( 100 );

  // Software Guide : EndCodeSnippet

  typedef otb::ImageFileWriter< OutputImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput( resampler->GetOutput() );
  writer->SetFileName( outputImageFilename );
  writer->Update();

  return EXIT_SUCCESS;
}

<|endoftext|>