Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Change unit tests floating point type to double and add a precision argument to output streams #558

Merged
merged 5 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions pointmatcher/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,38 +806,39 @@ PointMatcher<double>::DataPoints PointMatcherIO<double>::loadCSV(const std::stri

//! Save a point cloud to a file, determine format from extension
template<typename T>
void PointMatcher<T>::DataPoints::save(const std::string& fileName, bool binary) const
void PointMatcher<T>::DataPoints::save(const std::string& fileName, bool binary, unsigned precision) const
{
const boost::filesystem::path path(fileName);
const string& ext(boost::filesystem::extension(path));
if (boost::iequals(ext, ".vtk"))
return PointMatcherIO<T>::saveVTK(*this, fileName, binary);
return PointMatcherIO<T>::saveVTK(*this, fileName, binary, precision);

if (binary)
throw runtime_error("save(): Binary writing is not supported together with extension \"" + ext + "\". Currently binary writing is only supported with \".vtk\".");

if (boost::iequals(ext, ".csv"))
return PointMatcherIO<T>::saveCSV(*this, fileName);
return PointMatcherIO<T>::saveCSV(*this, fileName, precision);
else if (boost::iequals(ext, ".ply"))
return PointMatcherIO<T>::savePLY(*this, fileName);
return PointMatcherIO<T>::savePLY(*this, fileName, precision);
else if (boost::iequals(ext, ".pcd"))
return PointMatcherIO<T>::savePCD(*this, fileName);
return PointMatcherIO<T>::savePCD(*this, fileName, precision);
else
throw runtime_error("save(): Unknown extension \"" + ext + "\" for file \"" + fileName + "\", extension must be either \".vtk\", \".ply\", \".pcd\" or \".csv\"");
}

template
void PointMatcher<float>::DataPoints::save(const std::string& fileName, bool binary) const;
void PointMatcher<float>::DataPoints::save(const std::string& fileName, bool binary, unsigned precision) const;
template
void PointMatcher<double>::DataPoints::save(const std::string& fileName, bool binary) const;
void PointMatcher<double>::DataPoints::save(const std::string& fileName, bool binary, unsigned precision) const;

//! Save point cloud to a file as CSV
template<typename T>
void PointMatcherIO<T>::saveCSV(const DataPoints& data, const std::string& fileName)
void PointMatcherIO<T>::saveCSV(const DataPoints& data, const std::string& fileName, unsigned precision)
{
ofstream ofs(fileName.c_str());
if (!ofs.good())
throw runtime_error(string("Cannot open file ") + fileName);
ofs.precision(precision);
saveCSV(data, ofs);
}

Expand Down Expand Up @@ -901,9 +902,9 @@ void PointMatcherIO<T>::saveCSV(const DataPoints& data, std::ostream& os)
}

template
void PointMatcherIO<float>::saveCSV(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<float>::saveCSV(const DataPoints& data, const std::string& fileName, unsigned precision);
template
void PointMatcherIO<double>::saveCSV(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<double>::saveCSV(const DataPoints& data, const std::string& fileName, unsigned precision);

//! Load point cloud from a file as VTK
template<typename T>
Expand Down Expand Up @@ -1258,22 +1259,23 @@ PointMatcherIO<double>::DataPoints PointMatcherIO<double>::loadVTK(const std::st

//! Save point cloud to a file as VTK
template<typename T>
void PointMatcherIO<T>::saveVTK(const DataPoints& data, const std::string& fileName, bool binary)
void PointMatcherIO<T>::saveVTK(const DataPoints& data, const std::string& fileName, bool binary, unsigned precision)
{
typedef typename InspectorsImpl<T>::VTKFileInspector VTKInspector;

Parametrizable::Parameters param;
boost::assign::insert(param) ("baseFileName", "");
boost::assign::insert(param) ("writeBinary", toParam(binary));
boost::assign::insert(param) ("precision", toParam(precision));
VTKInspector vtkInspector(param);
vtkInspector.dumpDataPoints(data, fileName);
}


template
void PointMatcherIO<float>::saveVTK(const PointMatcherIO<float>::DataPoints& data, const std::string& fileName, bool binary);
void PointMatcherIO<float>::saveVTK(const PointMatcherIO<float>::DataPoints& data, const std::string& fileName, bool binary, unsigned precision);
template
void PointMatcherIO<double>::saveVTK(const PointMatcher<double>::DataPoints& data, const std::string& fileName, bool binary);
void PointMatcherIO<double>::saveVTK(const PointMatcher<double>::DataPoints& data, const std::string& fileName, bool binary, unsigned precision);

//! @brief Load polygon file format (ply) file
//! @param fileName a string containing the path and the file name
Expand Down Expand Up @@ -1651,14 +1653,15 @@ typename PointMatcherIO<T>::DataPoints PointMatcherIO<T>::loadPLY(std::istream&

template<typename T>
void PointMatcherIO<T>::savePLY(const DataPoints& data,
const std::string& fileName)
const std::string& fileName, unsigned precision)
{
//typedef typename DataPoints::Labels Labels;

ofstream ofs(fileName.c_str());
if (!ofs.good())
throw runtime_error(string("Cannot open file ") + fileName);

ofs.precision(precision);
const int pointCount(data.features.cols());
const int featCount(data.features.rows());
const int descRows(data.descriptors.rows());
Expand Down Expand Up @@ -1719,9 +1722,9 @@ void PointMatcherIO<T>::savePLY(const DataPoints& data,
}

template
void PointMatcherIO<float>::savePLY(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<float>::savePLY(const DataPoints& data, const std::string& fileName, unsigned precision);
template
void PointMatcherIO<double>::savePLY(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<double>::savePLY(const DataPoints& data, const std::string& fileName, unsigned precision);

//! @(brief) Regular PLY property constructor
template<typename T>
Expand Down Expand Up @@ -2255,11 +2258,11 @@ typename PointMatcherIO<T>::DataPoints PointMatcherIO<T>::loadPCD(std::istream&

template<typename T>
void PointMatcherIO<T>::savePCD(const DataPoints& data,
const std::string& fileName) {
const std::string& fileName, unsigned precision) {
ofstream ofs(fileName.c_str());
if (!ofs.good())
throw runtime_error(string("Cannot open file ") + fileName);

ofs.precision(precision);
const int pointCount(data.features.cols());
const int featCount(data.features.rows());
const int descRows(data.descriptors.rows());
Expand Down Expand Up @@ -2345,9 +2348,9 @@ void PointMatcherIO<T>::savePCD(const DataPoints& data,
}

template
void PointMatcherIO<float>::savePCD(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<float>::savePCD(const DataPoints& data, const std::string& fileName, unsigned precision);
template
void PointMatcherIO<double>::savePCD(const DataPoints& data, const std::string& fileName);
void PointMatcherIO<double>::savePCD(const DataPoints& data, const std::string& fileName, unsigned precision);



8 changes: 4 additions & 4 deletions pointmatcher/IO.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ struct PointMatcherIO
static DataPoints loadCSV(const std::string& fileName);
static DataPoints loadCSV(std::istream& is);

static void saveCSV(const DataPoints& data, const std::string& fileName);
static void saveCSV(const DataPoints& data, const std::string& fileName, unsigned precision);
static void saveCSV(const DataPoints& data, std::ostream& os);

// VTK
Expand Down Expand Up @@ -212,19 +212,19 @@ struct PointMatcherIO
static DataPoints loadVTK(const std::string& fileName);
static DataPoints loadVTK(std::istream& is);

static void saveVTK(const DataPoints& data, const std::string& fileName, bool binary = false);
static void saveVTK(const DataPoints& data, const std::string& fileName, bool binary = false, unsigned precision = 7);

// PLY
static DataPoints loadPLY(const std::string& fileName);
static DataPoints loadPLY(std::istream& is);

static void savePLY(const DataPoints& data, const std::string& fileName); //!< save datapoints to PLY point cloud format
static void savePLY(const DataPoints& data, const std::string& fileName, unsigned precision); //!< save datapoints to PLY point cloud format

// PCD
static DataPoints loadPCD(const std::string& fileName);
static DataPoints loadPCD(std::istream& is);

static void savePCD(const DataPoints& data, const std::string& fileName); //!< save datapoints to PCD point cloud format
static void savePCD(const DataPoints& data, const std::string& fileName, unsigned precision); //!< save datapoints to PCD point cloud format

//! Information to exploit a reading from a file using this library. Fields might be left blank if unused.
struct FileInfo
Expand Down
7 changes: 5 additions & 2 deletions pointmatcher/InspectorsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ InspectorsImpl<T>::AbstractVTKInspector::AbstractVTKInspector(const std::string&
bDumpDataLinks(Parametrizable::get<bool>("dumpDataLinks")),
bDumpReading(Parametrizable::get<bool>("dumpReading")),
bDumpReference(Parametrizable::get<bool>("dumpReference")),
bWriteBinary(Parametrizable::get<bool>("writeBinary"))
bWriteBinary(Parametrizable::get<bool>("writeBinary")),
precision(Parametrizable::get<unsigned>("precision"))
{
}

Expand Down Expand Up @@ -369,6 +370,7 @@ template<typename T>
void InspectorsImpl<T>::AbstractVTKInspector::dumpDataPoints(const DataPoints& filteredReference, const std::string& name)
{
ostream* stream(openStream(name));
stream->precision(precision);
dumpDataPoints(filteredReference, *stream);
closeStream(stream);
}
Expand Down Expand Up @@ -718,7 +720,8 @@ InspectorsImpl<T>::VTKFileInspector::VTKFileInspector(const Parameters& params):
bDumpIterationInfo(Parametrizable::get<bool>("dumpIterationInfo")),
bDumpDataLinks(Parametrizable::get<bool>("dumpDataLinks")),
bDumpReading(Parametrizable::get<bool>("dumpReading")),
bDumpReference(Parametrizable::get<bool>("dumpReference"))
bDumpReference(Parametrizable::get<bool>("dumpReference")),
precision(Parametrizable::get<unsigned>("precision"))
{
}

Expand Down
5 changes: 4 additions & 1 deletion pointmatcher/InspectorsImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ struct InspectorsImpl
const bool bDumpReading;
const bool bDumpReference;
const bool bWriteBinary;
const unsigned precision;

public:
AbstractVTKInspector(const std::string& className, const ParametersDoc paramsDoc, const Parameters& params);
Expand Down Expand Up @@ -171,7 +172,8 @@ struct InspectorsImpl
{"dumpDataLinks", "dump data links at each iteration", "0" },
{"dumpReading", "dump the reading cloud at each iteration", "0"},
{"dumpReference", "dump the reference cloud at each iteration", "0"},
{"writeBinary", "write binary VTK files", "0"}
{"writeBinary", "write binary VTK files", "0"},
{"precision", "default output precision", "7"}
};
}

Expand All @@ -180,6 +182,7 @@ struct InspectorsImpl
const bool bDumpDataLinks;
const bool bDumpReading;
const bool bDumpReference;
const unsigned precision;

protected:
virtual std::ostream* openStream(const std::string& role);
Expand Down
2 changes: 1 addition & 1 deletion pointmatcher/PointMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ struct PointMatcher
unsigned getDescriptorDim() const;
unsigned getTimeDim() const;

void save(const std::string& fileName, bool binary = false) const;
void save(const std::string& fileName, bool binary = false, unsigned precision = 7) const;
static DataPoints load(const std::string& fileName);

void concatenate(const DataPoints& dp);
Expand Down
2 changes: 1 addition & 1 deletion python/pointmatcher/data_points.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ All channels contain scalar values of type ScalarType.)pbdoc";
.def("getNbGroupedDescriptors", &DataPoints::getNbGroupedDescriptors)
.def("getDescriptorDim", &DataPoints::getDescriptorDim).def("getTimeDim", &DataPoints::getTimeDim)

.def("save", &DataPoints::save, py::arg("fileName"), py::arg("binary") = false)
.def("save", &DataPoints::save, py::arg("fileName"), py::arg("binary") = false, py::arg("precision") = 6)
.def_static("load", &DataPoints::load, py::arg("filename"))

.def("concatenate", &DataPoints::concatenate, py::arg("dp"))
Expand Down
8 changes: 4 additions & 4 deletions python/pointmatcher/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The order is important (i.e., nx before ny). This can also be used to remap 1D d

pyPointMatcherIO
.def_static("loadCSV", (DataPoints (*)(const std::string&)) &PMIO::loadCSV, py::arg("fileName"))
.def_static("saveCSV", (void (*)(const DataPoints&, const std::string&)) &PMIO::saveCSV, py::arg("data"), py::arg("fileName"));
.def_static("saveCSV", (void (*)(const DataPoints&, const std::string&, unsigned precision)) &PMIO::saveCSV, py::arg("data"), py::arg("fileName"), py::arg("precision"));

using SupportedVTKDataTypes = PMIO::SupportedVTKDataTypes;
py::enum_<SupportedVTKDataTypes>(pyPointMatcherIO, "SupportedVTKDataTypes", "Enumeration of legacy VTK data types that can be parsed")
Expand All @@ -71,13 +71,13 @@ The order is important (i.e., nx before ny). This can also be used to remap 1D d

pyPointMatcherIO
.def_static("loadVTK", (DataPoints (*)(const std::string&)) &PMIO::loadVTK, py::arg("fileName"))
.def_static("saveVTK", (void (*)(const DataPoints&, const std::string&, bool)) &PMIO::saveVTK, py::arg("data"), py::arg("fileName"), py::arg("binary") = false)
.def_static("saveVTK", (void (*)(const DataPoints&, const std::string&, bool, unsigned precision)) &PMIO::saveVTK, py::arg("data"), py::arg("fileName"), py::arg("binary") = false, py::arg("precision") = 7)

.def_static("loadPLY", (DataPoints (*)(const std::string&)) &PMIO::loadPLY, py::arg("fileName"))
.def_static("savePLY", (void (*)(const DataPoints&, const std::string&)) &PMIO::savePLY, py::arg("data"), py::arg("fileName"), "save datapoints to PLY point cloud format")
.def_static("savePLY", (void (*)(const DataPoints&, const std::string&, unsigned precision)) &PMIO::savePLY, py::arg("data"), py::arg("fileName"), py::arg("precision"), "save datapoints to PLY point cloud format")

.def_static("loadPCD", (DataPoints (*)(const std::string&)) &PMIO::loadPCD, py::arg("fileName"))
.def_static("savePCD", (void (*)(const DataPoints&, const std::string&)) &PMIO::savePCD, py::arg("data"), py::arg("fileName"), "save datapoints to PCD point cloud format");
.def_static("savePCD", (void (*)(const DataPoints&, const std::string&, unsigned precision)) &PMIO::savePCD, py::arg("data"), py::arg("fileName"), py::arg("precision"), "save datapoints to PCD point cloud format");

using FileInfo = PMIO::FileInfo;
using Vector3 = FileInfo::Vector3;
Expand Down
14 changes: 7 additions & 7 deletions utest/ui/DataFilters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ TEST_F(DataFilterTest, RemoveNaNDataPointsFilter)
// build test cloud
DP ref2DCopy(ref2D);
int goodCount(0);
const float nan(std::numeric_limits<float>::quiet_NaN());
const NumericType nan(std::numeric_limits<NumericType>::quiet_NaN());
for (int i(0); i < ref2DCopy.features.cols(); ++i)
{
if (rand() % 3 == 0)
Expand Down Expand Up @@ -456,7 +456,7 @@ TEST_F(DataFilterTest, OctreeGridDataPointsFilter)

for(const int meth : {0,1,2,3})
for(const size_t maxData : {1,5})
for(const float maxSize : {0.,0.05})
for(const NumericType maxSize : {0.,0.05})
{
params.clear();
params["maxPointByNode"] = toParam(maxData);
Expand Down Expand Up @@ -515,7 +515,7 @@ TEST_F(DataFilterTest, NormalSpaceDataPointsFilter)

//Evaluate filter
std::vector<size_t> samples = {/* 2*nbPts2D/3, nbPts2D,*/ 1500, 5000, nbPts, nbPts3D};
for(const float epsilon : {M_PI/6., M_PI/32., M_PI/64.})
for(const NumericType epsilon : {M_PI/6., M_PI/32., M_PI/64.})
for(const size_t nbSample : samples)
{
icp.readingDataPointsFilters.clear();
Expand Down Expand Up @@ -960,7 +960,7 @@ TEST_F(DataFilterTest, AddDescriptorDataPointsFilter)

std::string descriptorName = "test_descriptor";
std::size_t descriptorDimension = 3;
std::vector<float> descriptorValues{2, 3, 4};
std::vector<NumericType> descriptorValues{2, 3, 4};

// This filter adds a new descriptor
params = PM::Parameters();
Expand All @@ -978,7 +978,7 @@ TEST_F(DataFilterTest, AddDescriptorDataPointsFilter)
EXPECT_EQ(cloud.getDescriptorDim()+descriptorDimension, filteredCloud.getDescriptorDim());
EXPECT_EQ(cloud.getTimeDim(), filteredCloud.getTimeDim());

Eigen::Matrix<float, 1, Eigen::Dynamic> row = Eigen::Matrix<float, 1, Eigen::Dynamic>::Ones(cloud.getNbPoints());
Eigen::Matrix<NumericType, 1, Eigen::Dynamic> row = Eigen::Matrix<NumericType, 1, Eigen::Dynamic>::Ones(cloud.getNbPoints());
EXPECT_EQ(filteredCloud.descriptorLabels.back().text, descriptorName);
EXPECT_EQ(filteredCloud.descriptorLabels.back().span, descriptorDimension);
for(unsigned i = 0; i < descriptorDimension; ++i)
Expand All @@ -987,7 +987,7 @@ TEST_F(DataFilterTest, AddDescriptorDataPointsFilter)
}


descriptorValues = std::vector<float>{-2, -3, -4};
descriptorValues = std::vector<NumericType>{-2, -3, -4};
params["descriptorValues"] = toParam(descriptorValues);

addDescriptorFilter = PM::get().DataPointsFilterRegistrar.create(
Expand All @@ -1002,7 +1002,7 @@ TEST_F(DataFilterTest, AddDescriptorDataPointsFilter)
}


descriptorValues = std::vector<float>{-2, -3, -4, -5};
descriptorValues = std::vector<NumericType>{-2, -3, -4, -5};
params["descriptorDimension"] = toParam(4);
params["descriptorValues"] = toParam(descriptorValues);
addDescriptorFilter = PM::get().DataPointsFilterRegistrar.create(
Expand Down
10 changes: 5 additions & 5 deletions utest/ui/IO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ TEST(IOTest, loadYaml)

TEST(IOTest, loadCSV)
{
typedef PointMatcherIO<float> IO;
typedef PointMatcherIO<NumericType> IO;
std::istringstream is;
std::ostringstream os;
DP pts;
Expand Down Expand Up @@ -183,7 +183,7 @@ TEST(IOTest, loadCSV)

TEST(IOTest, loadPLY)
{
typedef PointMatcherIO<float> IO;
typedef PointMatcherIO<NumericType> IO;
std::istringstream is;

is.str(
Expand Down Expand Up @@ -257,7 +257,7 @@ TEST(IOTest, loadPLY)

TEST(IOTest, loadPCD)
{
typedef PointMatcherIO<float> IO;
typedef PointMatcherIO<NumericType> IO;
std::istringstream is;

// Empty file
Expand Down Expand Up @@ -371,7 +371,7 @@ class IOLoadSaveTest : public testing::Test
ptCloud.addDescriptor(descriptorName, PM::Matrix::Random(rows, nbPts));
}

virtual void loadSaveTest(const string& testFileName, bool plyFormat = false, const int nbPts = 10, bool binary = false)
virtual void loadSaveTest(const string& testFileName, bool plyFormat = false, const int nbPts = 10, bool binary = false, unsigned precision=12)
{
this->testFileName = testFileName;

Expand All @@ -394,7 +394,7 @@ class IOLoadSaveTest : public testing::Test
}
}

ptCloud.save(testFileName, binary);
ptCloud.save(testFileName, binary, precision);

ptCloudFromFile = DP::load(testFileName);

Expand Down
Loading
Loading