Skip to content

Commit

Permalink
Merge pull request #558 from norlab-ulaval/issue_556-failed_transform…
Browse files Browse the repository at this point in the history
…ation_unit_tests

fix: Change unit tests floating point type to double and add a precision argument to output streams
  • Loading branch information
boxanm authored Jan 29, 2024
2 parents 941b2a1 + 02d19f4 commit 1652178
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 71 deletions.
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

0 comments on commit 1652178

Please sign in to comment.